【发布时间】:2017-09-04 20:03:00
【问题描述】:
我创建了一个需要使用 JWT 进行身份验证的 REST API。
我的实现与https://auth0.com/blog/securing-spring-boot-with-jwts/上的代码非常相似
当我尝试返回当前用户时,我总是收到 null 返回。
我的代码:
网络安全:
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable().authorizeRequests()
// login
.antMatchers(HttpMethod.POST, "/login")
.permitAll()
.anyRequest()
.authenticated()
.and()
.addFilterBefore(new JWTLoginFilter(
"/login", authenticationManager(), logService), UsernamePasswordAuthenticationFilter.class)
.addFilterBefore(new JWTAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
}
JWTAuthenticationFilter:
public class JWTAuthenticationFilter extends GenericFilterBean {
@Override
public void doFilter(
ServletRequest req,
ServletResponse res,
FilterChain filterChain) throws IOException, ServletException {
Authentication authentication = TokenAuthenticationService.getAuthentication((HttpServletRequest)req);
SecurityContextHolder.getContext().setAuthentication(authentication);
filterChain.doFilter(req, res);
}
}
我没有包含所有 JWT 身份验证的代码,因为 JWT 工作正常,用户访问也可以。 我认为问题出在过滤器或某些配置中。
然后,我创建了一个facade 以获取service 或controller 上的当前用户,使用以下代码(http://www.baeldung.com/get-user-in-spring-security 上的方法4):
public Authentication getAuthentication() {
return SecurityContextHolder.getContext().getAuthentication();
}
但这不起作用。
- SecurityContextHolder.getContext() 返回org.springframework.security.core.context.SecurityContextImpl@ffffffff: Null authentication。
- SecurityContextHolder.getContext().getAuthentication() 返回 null 对象。
更新(和解决方案):
在我的控制器中,如果我使用此代码:
SecurityContext context = SecurityContextHolder.getContext();
Authentication authentication = context.getAuthentication();
我可以获取当前用户,但在我的服务中,完全相同的代码不起作用。
但后来,我记得SecurityContext 在另一个线程上“丢失”了(来源:https://docs.spring.io/spring-security/site/docs/current/reference/html/concurrency.html),我的服务是异步的
@Async
public CompletableFuture<Optional<ViewUserDto>> findByLogin(String login) throws InterruptedException {
...
}
因此,使用此处的代码:https://stackoverflow.com/a/40347437/4794469,一切正常。 我不知道这是否会给我的代码带来任何副作用(所有单元测试都有效)
【问题讨论】:
标签: java spring spring-mvc spring-security