我已经在 Spring Boot 代码中实现了 JWT 令牌安全性。如何在我的代码中的任何地方获取 jwt 令牌?需要保存审核

Posted

技术标签:

【中文标题】我已经在 Spring Boot 代码中实现了 JWT 令牌安全性。如何在我的代码中的任何地方获取 jwt 令牌?需要保存审核【英文标题】:I have implemented JWT token security in spring boot code. how will I get jwt token anywhere in my code? need to save audit 【发布时间】:2021-04-04 01:22:57 【问题描述】:

我通过参考 jwt 安全性视频在 Spring Boot 中实现了 jwt 安全性令牌。 所以登录后我得到生成的 jwt 令牌,为了进一步的端点命中,我需要从请求头传递 jwt 令牌,然后重新请求将在 JwtAuthenticationTokenFilter 类中的 dofilter() 方法中获得授权,如下所示。

public class JwtAuthenticationTokenFilter extends UsernamePasswordAuthenticationFilter 

    @Autowired
    private UserDetailsService userDetailsService;

    @Autowired
    private JwtTokenUtil jwtTokenUtil;

    @Value("$jwt.header")
    private String tokenHeader;

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException 

        String username = null;
        String authToken = null;
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        String header = httpRequest.getHeader(this.tokenHeader);
        if (header != null && header.startsWith("Bearer ")) 
            authToken = header.substring(7);
            try 
                username = jwtTokenUtil.getUsernameFromToken(authToken);
             catch (IllegalArgumentException e) 
                System.out.println("Unable to get JWT Token");
             catch (ExpiredJwtException e) 
                System.out.println("JWT Token has expired");
            
        

        if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) 
            UserDetails userDetails = this.userDetailsService.loadUserByUsername(username);
            if (jwtTokenUtil.validateToken(authToken, userDetails)) 
                UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(
                        userDetails, null, userDetails.getAuthorities());
                authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(httpRequest));
                SecurityContextHolder.getContext().setAuthentication(authentication);
            
        

        chain.doFilter(request, response);
    

但我需要在我的代码中任何我想要的地方获取该 jwt 令牌以从令牌中获取一些数据。 例如看下面的代码

public static AuditDetails createAudit() 
        AuditDetails auditDetails = new AuditDetails();
        **auditDetails.setCreateUser(token.getUsername());**
        auditDetails.setCreateTime(new Date()); 
        return auditDetails;
    

所以基本上我需要从令牌中获取用户名到相同的审计详细信息,但是我想如何在该代码或代码中的任何地方获取令牌?

【问题讨论】:

嗨。您是否考虑过一直使用 Spring Security,如下所示:auth0.com/blog/implementing-jwt-authentication-on-spring-boot 【参考方案1】:

令牌通过header (tokenHeader)发送到您的应用程序

编辑 如果您不想在任何地方使用您的HttpServletRequest 的内容,您可以按会话使用价值持有者,您可以在每个服务中使用Inject(自动装配)来使用提交的令牌。您可以尝试以下方法

@Component
@Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS)
public class MyHolder 
    private String authToken;

    public String getAuthToken() 
        return authToken;
    

    public void setAuthToken(String authToken) 
        this.authToken = authToken;
    

更改 JwtAuthenticationTokenFilter 中的令牌值

    @Autowired MyHolder myHolder;
    
    // ...

    String authToken = null;
    HttpServletRequest httpRequest = (HttpServletRequest) request;
    String header = httpRequest.getHeader(this.tokenHeader);
    if (header != null && header.startsWith("Bearer ")) 
        authToken = header.substring(7); // Here is your token
        
        // UPDATE THE TOKEN VALUE IN YOUR HOLDER HERE
        myHolder.setAuthToken(authToken);

        // ... 
    

通过自动装配 MyHolder 类在应用中的任何位置访问令牌

@Autowired MyHolder myHolder;

// ...
var token = myHolder.getAuthToken();

【讨论】:

如果您建议上述解决方案,我的代码结构是控制器 >> 服务 >> commonService >> dao 所以如果假设我正在使用您的建议,那么我需要将“ServletRequest request”从控制器带到 dao在每个端点

以上是关于我已经在 Spring Boot 代码中实现了 JWT 令牌安全性。如何在我的代码中的任何地方获取 jwt 令牌?需要保存审核的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Spring Boot 应用程序中关闭 Spring Security

Grails 3.0 中的 Spring Boot Security login.html 位置

Spring security - 允许匿名访问

如何在spring boot中实现jms队列

为什么我在spring微服务中实现了feign.RequestInterceptor接口,但是没有拦截

spring框架中实现了哪些servlet