使用 JWT 令牌时,Spring Boot 安全上下文返回 null

Rob*_*eia 7 java spring spring-mvc spring-security

我创建了一个需要使用 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);
}
Run Code Online (Sandbox Code Playgroud)

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);
  }
}
Run Code Online (Sandbox Code Playgroud)

我没有包含 JWT 身份验证的所有代码,因为 JWT 工作正常,用户访问也是如此。我相信问题出在过滤器或某些配置上。

然后,我使用以下代码(http://www.baeldung.com/get-user-in-spring-security上的方法 4 )facade在 aservice或上获取当前用户:controller

public Authentication getAuthentication() {
    return SecurityContextHolder.getContext().getAuthentication();
}
Run Code Online (Sandbox Code Playgroud)

但这不起作用。-SecurityContextHolder.getContext()返回org.springframework.security.core.context.SecurityContextImpl@ffffffff: Null authentication。-SecurityContextHolder.getContext().getAuthentication()返回的null对象。

更新(和解决方案)

在我的控制器中,如果我使用此代码:

SecurityContext context = SecurityContextHolder.getContext();
Authentication authentication = context.getAuthentication();
Run Code Online (Sandbox Code Playgroud)

我可以获得当前用户,但是在我的服务中,完全相同的代码不起作用。但是,我记得SecurityContext在另一个线程上“丢失”了(来源:https : //docs.spring.io/spring-security/site/docs/current/reference/html/concurrency.html),并且我的服务是异步的

@Async
public CompletableFuture<Optional<ViewUserDto>> findByLogin(String login) throws InterruptedException {
...
}
Run Code Online (Sandbox Code Playgroud)

因此,使用此处找到的代码:https : //stackoverflow.com/a/40347437/4794469,一切正常。我不知道这是否会给我的代码带来任何副作用(所有单元测试都有效)

vol*_*ldy 0

当我在网络应用程序上启用 JWT 时,我遇到了类似的问题。您需要:“Java 加密扩展 (JCE) 无限强度管辖策略文件”。

  1. 请从以下网址下载此包并替换 US_export_policy.jar、local_policy.jar (\jre\lib\security)

  2. 如果还是不行,则需要替换\lib\security位置下的上述jar文件

http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html