public class AuthenticationFilter extends GenericFilterBean {
SecureService secureService;
public AuthenticationFilter(SecureService secureService) {
this.secureService=secureService;
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest httpServletRequest=(HttpServletRequest)servletRequest;
Authentication authentication=secureService.getAuthentication(httpServletRequest);
if(authentication!=null) {
SecurityContextHolder.getContext().setAuthentication(authentication);
filterChain.doFilter(servletRequest, servletResponse);
SecurityContextHolder.getContext().setAuthentication(null);
}
}
}
@Configuration
@EnableWebSecurity
public class AppSecurityConfiguration extends WebSecurityConfigurerAdapter {
@Autowired
SecureService secureService;
@Override
protected void configure(HttpSecurity http) throws Exception {
http.addFilterBefore(new AuthenticationFilter(secureService), BasicAuthenticationFilter.class)
.authorizeRequests()
.antMatchers(HttpMethod.GET, "/businesses/**").permitAll()
.antMatchers(HttpMethod.GET, "/users/login").permitAll()
.antMatchers(HttpMethod.POST, "/users/").permitAll()
.antMatchers(HttpMethod.GET, "/reviews/").permitAll()
.antMatchers(HttpMethod.GET, "/reviews/search").permitAll()
.antMatchers(HttpMethod.GET, "/reviews/**").permitAll()
.antMatchers("/").permitAll().and()
.authorizeRequests().anyRequest().authenticated();
}
@Bean
public AuthenticationManager authenticationManager() throws Exception {
return super.authenticationManagerBean();
}
}
这种配置有什么问题?我跟着这个link写了url身份验证。但是我的应用程序会阻止所有请求,忽略代码中指定的所有匹配器。我用谷歌搜索,有人说规则的顺序很重要。但即使我更改了订单,AuthenticationFilter
也会一直被调用并阻止所有请求。
答案 0 :(得分:0)
问题是您中断了过滤器链。如下所示,它应该工作。
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
Authentication authentication = secureService.getAuthentication(httpServletRequest);
if (authentication != null) {
SecurityContextHolder.getContext().setAuthentication(authentication);
}
filterChain.doFilter(servletRequest, servletResponse);
SecurityContextHolder.getContext().setAuthentication(null);
}
另一件事是,如果HttpServlerRequest不包含身份验证,则会在SecureService中抛出UserNotFoundException。 在AuthenticationFilter中你似乎期望在这种情况下为null?因此,如果不存在身份验证,则在SecureService中返回null:
public Authentication getAuthentication(HttpServletRequest httpServletRequest) {
final String token=httpServletRequest.getHeader(Headers.AUTH_HEADER_NAME);
if(token!=null){
final User user=parseToken(token);
if(user!=null){
return new UserAuthentication(user);
}
}
return null;
}
如果要保留UserNotFoundException,则只将doFilterMethod更改为以下内容:
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
try {
Authentication authentication = secureService.getAuthentication(httpServletRequest);
if (authentication != null) {
SecurityContextHolder.getContext().setAuthentication(authentication);
}
}catch(UserNotFoundException e){
}finally {
filterChain.doFilter(servletRequest, servletResponse);
SecurityContextHolder.getContext().setAuthentication(null);
}
}