[英]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 .注意: Jwts是io.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.