Spring Security鉴权:文件上传需要携带token
在Spring Security的配置流程里,请求携带token时,会先执行 addFilterBefore(authenticationTokenFilter, UsernamePasswordAuthenticationFilter.class)
所添加的过滤器,之后再进行 authorizeHttpRequests
里的权限判断,下面为你详细解释:
1. 过滤器链的执行顺序
Spring Security是基于过滤器链来处理请求的。在配置中通过 addFilterBefore
添加的过滤器会按照配置的顺序插入到过滤器链中。authenticationTokenFilter
通常用于解析请求头中的token,验证其有效性,并且将用户信息加载到Spring Security的上下文里。
UsernamePasswordAuthenticationFilter
是Spring Security默认用于处理表单登录的过滤器。当你使用 addFilterBefore(authenticationTokenFilter, UsernamePasswordAuthenticationFilter.class)
时,意味着 authenticationTokenFilter
会在 UsernamePasswordAuthenticationFilter
之前执行。
2. 权限判断的时机
authorizeHttpRequests
方法用于配置请求的访问规则,这些规则是在过滤器链执行完成之后才进行判断的。也就是说,在请求经过一系列过滤器(包含 authenticationTokenFilter
)处理之后,才会依据 authorizeHttpRequests
中配置的规则来判断该请求是否被允许访问。
3. 执行流程示例
以下是一个简化的执行流程:
- 请求进入:客户端发送携带token的请求到服务器。
- 过滤器链执行:请求首先进入
authenticationTokenFilter
,该过滤器会从请求头中提取token,对其进行验证,若验证通过,就会将用户信息加载到Spring Security的上下文里。 - 其他过滤器处理:请求继续通过过滤器链中的其他过滤器进行处理。
- 权限判断:当请求通过所有过滤器之后,会依据
authorizeHttpRequests
中配置的规则进行权限判断。若请求的URL匹配到permitAll
的规则,那么请求会被允许访问;若匹配到authenticated
规则,就会检查Spring Security上下文中是否存在有效的认证信息,若存在则允许访问,反之则拒绝访问。
4. 代码示例说明
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;import javax.annotation.Resource;@Configuration
@EnableWebSecurity
public class SecurityConfig {@Resourceprivate JwtAuthenticationTokenFilter authenticationTokenFilter;@Beanpublic SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {http// 关闭csrf.csrf().disable()// 不通过Session获取SecurityContext.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).addFilterBefore(authenticationTokenFilter, UsernamePasswordAuthenticationFilter.class).authorizeHttpRequests((requests) -> {// 允许匿名访问的URL列表permitAllUrl.getUrls().forEach(url -> requests.antMatchers(url).permitAll());// 对于登录login 注册register 验证码captchaImage 允许匿名访问requests.antMatchers("/login", "/system/device/deviceData", "/register", "/captchaImage").permitAll().antMatchers("/system/category/**").permitAll()// 静态资源,可匿名访问.antMatchers(org.springframework.http.HttpMethod.GET, "/", "/*.html", "/**/*.html", "/**/*.css", "/**/*.js", "/profile/**").permitAll().antMatchers("/swagger-ui.html", "/swagger-resources/**", "/webjars/**", "/*/api-docs", "/druid/**").permitAll()// 除上面外的所有请求全部需要鉴权认证.anyRequest().authenticated();});return http.build();}
}
在这个配置中,authenticationTokenFilter
会在 UsernamePasswordAuthenticationFilter
之前执行,之后才会进行 authorizeHttpRequests
中的权限判断。
综上所述,携带token的请求会先经过 addFilterBefore
添加的过滤器,然后再进行 authorizeHttpRequests
中的权限判断。