首页 > 解决方案 > 为什么 AuthenticationFilter 完成后 RestController 不接收请求

问题描述

我有一个带有 Spring Security 的工作 Spring Boot。一切大部分都有效。我不明白为什么 RestController 在过滤器授权请求之后永远不会触发。

换句话说,我设置了一个休息控制器以接受来自 /foo/bar 的 POST 请求,并且我设置了一个 AuthenticationFilter 以在执行用户请求之前首先验证用户凭据。

鉴于我的 RestController 从不触发,我不得不在 Success Handler 中实现我的代码,但我的代码属于 Controller。

我试图通过单步调试 Spring Security 代码来调试它,但似乎没有任何迹象表明它会跳过我的 RestController。

@RestController
@RequestMapping("foo")
public class FooController {

  @PostMapping("bar") // this never executes
  public ResponseEntity<FooResponse> foobar(@RequestBody Credentials creds) {
    return new ResponseEntity<>(new FooResponse("baz"), HttpStatus.OK);
  }
}
@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

  @Bean
  public BCryptPasswordEncoder passwordEncoder(){
    return new BCryptPasswordEncoder();
  }

  @Bean
  @Override
  public AuthenticationManager authenticationManagerBean() throws Exception {
    return super.authenticationManagerBean();
  }

  @Bean
  public AuthenticationFilter authenticationTokenFilter() throws Exception {

    AuthenticationFilter filter = new AuthenticationFilter();
    filter.setAuthenticationManager(authenticationManager());
    filter.setAuthenticationSuccessHandler(new AuthenticationSuccessHandlerImpl());
    return filter;
  }

  @Override
  protected void configure(AuthenticationManagerBuilder auth) throws Exception {
      auth.userDetailsService(accountService)
          .passwordEncoder(passwordEncoder());
  }    

  @Override
  protected void configure(HttpSecurity http) throws Exception {

    http
      .cors()
      .and()
      .csrf().disable()
      .authorizeRequests()
      .antMatchers(HttpMethod.POST, "/foo/bar").permitAll()
      .and()
      .addFilter(new AuthorizationFilter(properties, authenticationManager(), tokenService)
      .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);              
    }

}
public class AuthenticationFilter extends AbstractAuthenticationProcessingFilter {  

  public AuthenticationFilter() {
    super("/foo/bar"); 
  }

  @Override
  public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) {
    Credentials creds = new ObjectMapper().readValue(request.getInputStream(), Credentials.class);
    return getAuthenticationManager().authenticate(
                    new UsernamePasswordAuthenticationToken(
                          creds.getUsername(),
                          creds.getPassword(),
                          new ArrayList<>())
                    );      
  }
}
public class AuthenticationSuccessHandlerImpl implements AuthenticationSuccessHandler {
  @Override
  public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
    Authentication authentication) throws IOException, ServletException {
    // do nothing and prevent redirect to /login, /logout, etc
  }
}

标签: javaspringspring-security

解决方案


您正在使用 http.cors()。你在别处配置过吗?如果不是,它可能认为您未通过身份验证。检查此链接:https ://docs.spring.io/spring-security/site/docs/5.0.x/reference/html/cors.html

如果您不打算使用它,我建议您将其删除

您还有一个简单的安全配置示例:https ://www.baeldung.com/spring-security-login

从我的角度来看,删除 cors() 应该可以解决您的问题(或以正确的方式配置它:)


推荐阅读