问题描述
大家好,我正在使用 Spring Security 和 JWT 令牌编写身份验证。
我在配置中添加了自己的过滤器。但是请求不包含在过滤器中。因此,即使没有令牌,对任何地址的所有请求都会被执行。
@Configuration
@EnableWebSecurity
@ComponentScan("my.pac")
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private JwtFilter jwtFilter;
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.httpBasic().disable()
.csrf().disable()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers("/register","/auth").permitAll()
.and()
.addFilterBefore(jwtFilter,UsernamePasswordAuthenticationFilter.class);
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
过滤
@Component
public class JwtFilter extends GenericFilterBean {
public static final String AUTHORIZATION = "Authorization";
@Autowired
private JwtProvider jwtProvider;
@Autowired
private CustomUserDetailsService customUserDetailsService;
@Override
public void doFilter(ServletRequest servletRequest,ServletResponse servletResponse,FilterChain filterChain) throws IOException,servletexception {
logger.info("do filter...");
String token = getTokenFromrequest((HttpServletRequest) servletRequest);
if (token != null && jwtProvider.validatetoken(token)) {
String userLogin = jwtProvider.getLoginFromToken(token);
CustomUserDetails customUserDetails = customUserDetailsService.loadUserByUsername(userLogin);
UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(customUserDetails,null,customUserDetails.getAuthorities());
SecurityContextHolder.getContext().setAuthentication(auth);
}
filterChain.doFilter(servletRequest,servletResponse);
}
private String getTokenFromrequest(HttpServletRequest request) {
String bearer = request.getHeader(AUTHORIZATION);
if (hasText(bearer) && bearer.startsWith("Bearer ")) {
return bearer.substring(7);
}
return null;
}}
更新:
此选项也不适用于过滤器:
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.httpBasic().disable()
.csrf().disable()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers("/register","/auth").permitAll()
.anyRequest().authenticated()
.and()
.addFilterBefore(jwtFilter,UsernamePasswordAuthenticationFilter.class);
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
解决方法
您只指定了 .antMatchers("/register","/auth").permitAll()
,要强制对其他必须添加 .anyRequest().authenticated()
的事物进行身份验证
所以像这样
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.httpBasic().disable()
.csrf().disable()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers("/register","/auth").permitAll()
.and()
.anyRequest().authenticated()
.and()
.addFilterBefore(jwtFilter,UsernamePasswordAuthenticationFilter.class);
}