我试图在自己的登录控制器中自定义登录过程,而不是使用UsernamePasswordAuthenticationFilter
@PostMapping(value = "/login")
public ResponseEntity<?> login(
HttpServletRequest httpRequest,
@RequestBody AuthenticationRequest authenticationRequest) {
// authentication code here
Authentication authenticate=this.authenticationManager.authenticate(authRequest);
SecurityContext context = SecurityContextHolder.getContext();
context.setAuthentication(authentication);
return handlerAuthLogin(httpRequest, result, authorizationRequest);
}
但是,如果我按如下所示成功登录,则无法在其他控制器中自动注入Principal:
@Controller
public class UsersController {
@RequestMapping(value = "/me")
public string getMyName(Principal principal){
return principal.getName(); // principal is null
}
}
有谁知道为什么要解决它?
答案 0 :(得分:0)
执行context.setAuthentication(authentication)
时,身份验证仅对当前请求有效。因此,对于第二个/me
请求,您还需要设置身份验证。
因此,您需要根据每个请求对用户进行身份验证。这可以通过实现GenericFilterBean
来完成:
public class CustomAuthenticationFilter extends GenericFilterBean {
private final AuthenticationManager authenticationManager;
public CustomAuthenticationFilter(
AuthenticationManager authenticationManager) {
this.authenticationManager = authenticationManager;
}
@Override
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) resp;
/*
Note that you need to receive the authentication token in different manner now.
Usually headers are used for that.
*/
Authentication authenticate = authenticationManager.authenticate(request.getHeader("authToken"));
SecurityContext context = SecurityContextHolder.getContext().setAuthentication(authentication);
chain.doFilter(request, response);
}
}
实现过滤器后,您需要将其注册到servlet容器中最合适的位置。 Spring Security根据WebsecutiryConfigurer
处理安全过滤器,因此您需要在用户各自的配置器的配置中注册过滤器。
作为示例,我将其放在ConcurrentSessionFilter
之后:
@Configuration
@Order(1)
public static class UserWebSecurity extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
CustomAuthenticationFilter filter = new PlayerAuthenticationFilter(jwtService,
objectMapper);
http.addFilterAfter(filter, ConcurrentSessionFilter.class);
(...)
}
}
查看有关filter ordering的文档,以找到最适合您的方法的位置。
关于这个主题,我写了更深入的blog post。随意检查一下。
答案 1 :(得分:-1)
@Marcus
感谢您的澄清,我找到了造成此案的原因。
我错误地配置了
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
public WebSecurityConfig() {
super(true); // I disable the default config, so the SecurityContextPersistenceFilter didn't be added by default and all my SecurityContext info is not persistent
}
}