java - 为什么 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
}
}
解决方案
您正在使用 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() 应该可以解决您的问题(或以正确的方式配置它:)
推荐阅读
- c - 错误:预期 '='、','、';'、'asm' 或 '__attribute__'
- mit-scratch - 有没有办法将临时 3.0 文件转换为 .swf 文件?
- mysql - 1 到 N 个映射列的特殊连接
- git - 构建错误:指定的路径、文件名或两者都太长
- flutter - 更改子项的属性不会触发 Flutter Getx 上的 UI 更改
- google-analytics - 在 Measurement Protocol 上查看 ID - Google Analytics
- docker - 无法在 docker 映像上运行本地集合
- javascript - GTM“在模板中发现无效的 HTML、CSS 或 JavaScript”
- python - 如何使用分隔符拆分文件?
- python - 如何使用函数对熊猫数据框进行布尔索引