简体   繁体   English

如何将一些附加字段添加到此 Spring 引导服务生成的 JWT 令牌中?

[英]How can I add some additional fields into a JWT token generated by this Spring Boot service?

I am working on a Spring Boot microservice that generate a JWT token and I have the following doubt about the possibility to add additional information into the generated token.我正在研究生成 JWT 令牌的 Spring 引导微服务,我对向生成的令牌中添加其他信息的可能性有以下疑问。

Basically in my code I have done something like this (it works fine):基本上在我的代码中我做了这样的事情(它工作正常):

@Override
public UserDetails loadUserByUsername(String UserId) throws UsernameNotFoundException {
    
    String ErrMsg = "";
    
    if (UserId == null || UserId.length() < 2) {
        ErrMsg = "Nome utente assente o non valido";
        
        logger.warn(ErrMsg);
        
        throw new UsernameNotFoundException(ErrMsg); 
    } 
    
    User user = this.GetHttpValue(UserId);
    
    if (user == null) {
        ErrMsg = String.format("User %s not found!!", UserId);
        
        logger.warn(ErrMsg);
        
        throw new UsernameNotFoundException(ErrMsg);
    }
    
    UserBuilder builder = null;
    
    builder = org.springframework.security.core.userdetails.User.withUsername(user.getEMail());
    builder.password(user.getPswd());
    
    String[] operations = user.getUserTypes().stream()
            .map(UserType::getOperations)
            .flatMap(Set::stream)
            .map(Operation::getName)
            .distinct()
            .toArray(String[]::new);
    
    builder.authorities(operations);
    
    return builder.build();
        
}

As you can see in the previous code I have this method returning a UserDetails object (belonging to Spring Security, it is this class: org.springframework.security.core.userdetails.UserDetails ).正如你在前面的代码中看到的,我有这个方法返回一个UserDetails object(属于 Spring Security,就是这个 class: org.springframework.security.core )。 This UserDetails instance was created starting from this retrieved model object (it was retrieved performing a call to a REST endpoint):这个UserDetails实例是从这个检索到的 model object 开始创建的(它是在执行对 REST 端点的调用时检索到的):

User user = this.GetHttpValue(UserId);

Basically this UserDetails object is used to generate the JWT token by this second method that uses the previous UserDetails object:基本上,此UserDetails object 用于通过使用先前UserDetails object 的第二种方法生成 JWT 令牌:

private String doGenerateToken(Map<String, Object> claims, UserDetails userDetails) 
{
    final Date createdDate = clock.now();
    final Date expirationDate = calculateExpirationDate(createdDate);

    return Jwts.builder()
            .setClaims(claims)
            .setSubject(userDetails.getUsername())
            .claim("authorities", userDetails.getAuthorities().stream().map(GrantedAuthority::getAuthority).collect(Collectors.toList()))
            .setIssuedAt(createdDate)
            .setExpiration(expirationDate)
            .signWith(SignatureAlgorithm.HS512, jwtConfig.getSecret().getBytes())
            .compact();
}

NOTE: the Jwts is io.jsonwebtoken.Jwts .注意: Jwtsio.jsonwebtoken.Jwts

This generate a token containing the following payload information:这会生成一个包含以下有效负载信息的令牌:

{
  "sub": "xxx@gmail.com",
  "exp": 1637412048,
  "iat": 1637325648,
  "authorities": [
    "ADMIN"
  ]
}

It is correct but...is it possible to add some further information to this payload?这是正确的,但是......是否可以向这个有效载荷添加一些进一步的信息? In particular I need to add some information that are into my User DTO object but not into the previous Spring Security UserDetails instance.特别是我需要将一些信息添加到我的用户DTO object 但不添加到之前的 Spring Security UserDetails实例中。

I implemented this behavior following an Udemy tutorial and now I have the following doubt.我在 Udemy 教程之后实现了这种行为,现在我有以下疑问。

Why the previous doGenerateToken() method generate the token starting from the Spring Security UserDetails instance and not directly from the User DTO object (it contains more usefull information).为什么前面的doGenerateToken()方法从 Spring 安全UserDetails实例而不是直接从用户DTO object 生成令牌(它包含更多有用的信息)。

If there are some specific reason to use this UserDetails instance instead my simple User DTO object, exist a way to add these information to the UserDetails instance and then put these additional fields into my JWT token?如果有特定原因使用此UserDetails实例而不是我的简单用户DTO object,是否存在将这些信息添加到UserDetails实例然后将这些附加字段放入我的 JWT 令牌的方法?

You are passing a map of claims to the doGenerateToken method.您正在将声明的 map 传递给doGenerateToken方法。 These are then added to the token payload as claims.然后将它们作为声明添加到令牌有效负载中。 You can add whatever you like to this map to create the token.您可以将任何您喜欢的内容添加到此 map 以创建令牌。

As for the question why the doGenerateToken method doesn't use the User DTO?至于为什么doGenerateToken方法不使用User DTO 的问题? Well, if that method is not part of an interface, then you can have it accept any class, right?好吧,如果该方法不是接口的一部分,那么您可以让它接受任何 class,对吧? If you prefer to work with the User object, then I think you can.如果您更喜欢使用用户 object,那么我认为您可以。 If it's an implementation of an interface, then you should ask the authors what was the reason for that, but people rather have thought through those interfaces in Spring and there are good reasons why they are built this way or another.如果它是一个接口的实现,那么你应该问作者这是什么原因,但人们宁愿通过 Spring 中的这些接口进行思考,并且有充分的理由为什么它们以这种或另一种方式构建。 Even if at first they look weird.即使一开始它们看起来很奇怪。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Spring OAuth2 - 如何使用我生成的调用 Web 服务的 JWT 令牌来保护 Spring Boot REST API? - Spring OAuth2 - How to secure spring boot REST API using JWT token which i have generated calling webservice? JWT 在 Spring 引导中成功验证后未生成令牌 - JWT Token not generated after successful Authentication in Spring Boot 如何在资源服务器的安全上下文中获取JWT令牌中的其他字段 - How to get Additional fields in the JWT token in security context of Resource Server 如何在Spring Boot中使用JWT身份验证实现基本身份验证? - How can I implement Basic Authentication with JWT authentication in Spring Boot? 如何在Spring Boot中从旧令牌生成新的JWT令牌? - How to generate new JWT token from old token in Spring Boot? 我可以混合使用基本身份验证和 JWT 令牌身份验证来保护单个 Spring 引导项目的 API 吗? - Can I mix both basic authentication and JWT token authentication to protect APIs of a single Spring Boot project? 如何使用 spring 启动 jwt 注销 - How can logout using spring boot jwt 从 spring 引导中的 jwt 获取附加属性 - get additional attributes from jwt in spring boot 如何制作通用 Spring 服务来查找实体并仅返回某些字段 - How can I make a generic Spring Service to find entities and return only some fields 如何在Spring Boot中添加UrlRewriteFilter - How can I add UrlRewriteFilter in Spring Boot
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM