如何使用 JWT 在 Spring Boot 中获取 Refresh Token

Posted

技术标签:

【中文标题】如何使用 JWT 在 Spring Boot 中获取 Refresh Token【英文标题】:How to get Refresh Token in spring boot using JWT 【发布时间】:2018-09-11 10:28:04 【问题描述】:

我正在使用 JWT 为 REST API 做 Spring Security。我已经完成了创建具有到期时间的 Web 令牌并且工作正常。我已将时间限制设置为 5 分钟。 5 分钟后,令牌将过期。这给我带来了问题,所以任何人都可以指导我如何使用刷新令牌来解决这个问题,因为我对这个概念很陌生。

这是我的代码..

SpringSecurityConfiguration

 @Bean
 public JwtAuthenticationTokenFilter authenticationTokenFilter() 
    JwtAuthenticationTokenFilter filter = new 
    JwtAuthenticationTokenFilter();
    filter.setAuthenticationManager(authenticationManager());
    filter.setAuthenticationSuccessHandler(new JwtSuccessHandler());
    return filter;



@Override
protected void configure(HttpSecurity http) throws Exception 

    http.csrf().disable()
            .authorizeRequests().antMatchers("/admin/**").authenticated()
            .antMatchers("/admin/**").hasAnyAuthority("Admin")
            .and()
            .exceptionHandling().authenticationEntryPoint(entryPoint)
            .and()
            .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);

    http.addFilterBefore(authenticationTokenFilter(), UsernamePasswordAuthenticationFilter.class);
    http.headers().cacheControl();


令牌控制器

@RestController
@RequestMapping("/token")
public class TokenController 

private JwtGenerator jwtGenerator;

public TokenController(JwtGenerator jwtGenerator) 
    this.jwtGenerator = jwtGenerator;


@RequestMapping(method = RequestMethod.POST)
public String generate(@RequestBody final User user) 

    return jwtGenerator.generate(user);



JwtGenerator

@Component
public class JwtGenerator  
private Long expiration;
private String secret = "youtube";
static final String CLAIM_KEY_CREATED = "created";

public String generate(User user) 
    Claims claims = Jwts.claims()
            .setSubject(user.getFirstName());
    claims.put("password", String.valueOf(user.getPassword()));
    //claims.put("role", jwtUser.getRole());

    return Jwts.builder()
            .setClaims(claims)
            .setExpiration(generateExpirationDate())
            .signWith(SignatureAlgorithm.HS512, "youtube")
            .compact();


private Date generateExpirationDate() 
    return new Date(System.currentTimeMillis()  + (5 * 60 * 1000));


JwtAuthenticationProvider

@Override
protected UserDetails retrieveUser(String username, UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken) throws AuthenticationException 

    JwtAuthenticationToken jwtAuthenticationToken = (JwtAuthenticationToken) usernamePasswordAuthenticationToken;
    String token = jwtAuthenticationToken.getToken();

    User user = validator.validate(token);

    if (user == null) 
        throw new RuntimeException("JWT Token is incorrect");
    
    String firstname=user.getFirstName();
    User user1=userRepository.getRoleId(firstname);
    List<GrantedAuthority> grantedAuthorities = AuthorityUtils
            .commaSeparatedStringToAuthorityList(user1.getRole().getRoleName());
    return new JwtUserDetails(user.getFirstName(), user.getPassword(),
            token,
            grantedAuthorities);


@Override
public boolean supports(Class<?> aClass) 
    return (JwtAuthenticationToken.class.isAssignableFrom(aClass));

JwtValidator

@Component
public class JwtValidator 


private String secret = "youtube";

public User validate(String token) 

    User user = null;
    try 
        Claims body = Jwts.parser()
                .setSigningKey(secret)
                .parseClaimsJws(token)
                .getBody();

        user = new User();
        user.setFirstName(body.getSubject());
        user.setPassword((String) body.get("password"));
        //user.setRole((String) body.get("role"));
    
    catch (Exception e) 
        System.out.println(e);
    

    return user;

我正在传递用户名和密码以获取令牌。提前致谢

【问题讨论】:

你解决了吗? 我不会将密码放入 JWT 本身。除非你要加密它。无论哪种方式,都没有必要将密码放在那里,因为它必须从源头就知道。 【参考方案1】:

您可能需要更改一些现有解决方案。通常,您必须在成功授权后返回 2 个 JWT 令牌 - 一个“访问”JWT 令牌用于对服务器的任何其他授权请求,以及用于在第一个过期时检索新的“访问”JWT 令牌的“刷新”JWT 令牌.这也意味着您需要更改/修改/拦截应用程序的前端部分以应用这些规则。对我来说好点是JWT Authentication Tutorial - An example using Spring Boot。

【讨论】:

有史以来最好的例子。

以上是关于如何使用 JWT 在 Spring Boot 中获取 Refresh Token的主要内容,如果未能解决你的问题,请参考以下文章

Spring boot中使用jwt

如何使用 jwt 公钥在 Spring Boot 中验证承载访问令牌

如何使用spring boot jwt注销

如何在 Spring Boot 后端使用 jwt 令牌实现注销功能(使用休息端点)

如何使用 Spring Boot 测试 jwt.*?

如何在使用 Spring Boot 的 JWT 令牌时禁用同一用户帐户的多个登录