如何在Sping Boot 的Spring Security中自定义Token?

3pvhb19x  于 2023-04-06  发布在  Spring
关注(0)|答案(1)|浏览(215)

我在定制令牌时遇到了问题,其中包括Sping Boot 的Spring Security中的一些信息。
在生成令牌并为响应对象添加一些值之后,我得到了如下所示的消息。
下面是响应对象

return TokenDTO.builder()
                .username(userDetails.getUsername())
                .message("success")
                .accessToken("Bearer " + accessToken)
                .roles(roles)
                .refreshToken(refreshToken.getToken())
                .expireDate(expiryDate.getTime())
                .build();

下面是显示的消息

{
    "message": "success",
    "username": "username12",
    "accessToken": "Bearer accesstoken_string",
    "refreshToken": "refreshToken_string",
    "expireDate": 1680095658406,
    "roles": [
        "ROLE_ADMIN"
    ]
}

我想得到如下所示的响应消息

{
   "accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwiaWF0IjoxNTE2MjM5MDIyLCJleHAiOjE1MTYyMzkwMjIsInVzZXJuYW1lIjoiYWRtaW4tdXNlciIsInJvbGVzIjpbIkFETUlOIiwiU1VQRVJfQURNSU4iXX0.HRUslkLQPb3ujTCu_a4vs1TF1kidjziQsi9V369Edq0"
   "expireDate": 1220227200,
   "refreshToken: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwiaWF0IjoxNTE2MjM5MDIyLCJleHAiOjE1MTYyMzkwMjIsInVzZXJuYW1lIjoiYWRtaW4tdXNlciIsInJvbGVzIjpbIkFETUlOIiwiU1VQRVJfQURNSU4iXX0.HRUslkLQPb3ujTCu_a4vs1TF1kidjziQsi9V369Edq0"
}

下面是https://jwt.io/中标记的结果

{
  "sub": "1234567890",
  "iat": 1516239022,
  "exp": 1516239022,
  "username": "username12",
  "roles": [
    "ADMIN",
    "SUPER_ADMIN"
  ]
}

如何在Sping Boot App的Spring Security中自定义token(用于generateToken方法)?
下面是CustomJwtUserDetails

@RequiredArgsConstructor
public class CustomJwtUserDetails implements UserDetails {

    private final User user;

    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        UserRole roles = user.getUserRole();

        List<SimpleGrantedAuthority> authories = new ArrayList<>();
        authories.add(new SimpleGrantedAuthority(roles.name()));

        return authories;
    }

    @Override
    public String getPassword() {
        return user.getPassword();
    }

    @Override
    public String getUsername() {
        return user.getUsername();
    }

    @Override
    public boolean isAccountNonExpired() {
        return true;
    }

    @Override
    public boolean isAccountNonLocked() {
        return true;
    }

    @Override
    public boolean isCredentialsNonExpired() {
        return true;
    }

    @Override
    public boolean isEnabled() {
        return true;
    }

    public Long getId() {
        return user.getId();
    }

    public String getEmail() {
        return user.getEmail();
    }
}

下面是TokenProvider类

@Component
public class JwtTokenProvider {

    @Value("${token.secret}")
    private String APP_SECRET;

    @Value("${token.expires-in}")
    private long EXPIRES_IN;

    public String generateJwtToken(Authentication auth) {
        UserDetails userDetails = (UserDetails) auth.getPrincipal();
        Date now = new Date();
        Date expiryDate = new Date(now.getTime() + EXPIRES_IN);

        String token = Jwts.builder()
                .setSubject(userDetails.getUsername())
                .setIssuedAt(now)
                .setExpiration(expiryDate)
                .signWith(SignatureAlgorithm.HS512, APP_SECRET)
                .compact();

        return token;
    }

    public String getUserNameFromJwtToken(String token) {
        return Jwts.parser().setSigningKey(APP_SECRET).parseClaimsJws(token).getBody().getSubject();
    }

    public Long getUserIdFromJwt(String token) {
        Claims claims = Jwts.parser()
                .setSigningKey(APP_SECRET)
                .parseClaimsJws(token)
                .getBody();

        return Long.parseLong(claims.getSubject());
    }

    boolean validateToken(String token) {
        try {
            Jwts.parser().setSigningKey(APP_SECRET).parseClaimsJws(token);
            return !isTokenExpired(token);
        } catch (MalformedJwtException | ExpiredJwtException | UnsupportedJwtException | IllegalArgumentException e) {
            return false;
        }
    }

    private boolean isTokenExpired(String token) {
        Date expiration = Jwts.parser().setSigningKey(APP_SECRET).parseClaimsJws(token).getBody().getExpiration();
        return expiration.before(new Date());
    }
}
dxxyhpgq

dxxyhpgq1#

您可以在generateJwtToken中自定义jwt令牌,以在Jwts.builder中定义claims,如下所示

public String generateJwtToken(Authentication auth) {
        UserDetails userDetails = (UserDetails) auth.getPrincipal();
        Date now = new Date();
        Date expiryDate = new Date(now.getTime() + EXPIRES_IN);

        String token = Jwts.builder()
                .setSubject(userDetails.getUsername())
                .claim("roles", roles)  // HERE IS LINE
                .setIssuedAt(now)
                .setExpiration(expiryDate)
                .signWith(SignatureAlgorithm.HS512, APP_SECRET)
                .compact();

        return token;
    }

相关问题