How-to: Add authorities as custom claims in JWT access tokens
本指南演示如何将资源所有者的权限添加到 JWT 访问令牌。术语“权限”可能表示资源所有者的不同形式,例如角色、权限或组。
This guide demonstrates how to add resource owner authorities to a JWT access token. The term "authorities" may represent varying forms such as roles, permissions, or groups of the resource owner.
为了让资源服务器可以使用资源所有者的权限,我们在访问令牌中添加了自定义声明。当客户端使用访问令牌访问受保护资源时,资源服务器将能够获取有关资源所有者访问级别的信息,以及其他可能的用途和好处。
To make resource owner’s authorities available to the resource server, we add custom claims to the access token. When the client uses the access token to access a protected resource, the resource server will be able to obtain the information about the resource owner’s level of access, among other potential uses and benefits.
Add custom claims to JWT access tokens
您可以使用 OAuth2TokenCustomizer<JWTEncodingContext>
@Bean
向访问令牌添加自己的自定义声明。请注意,此 @Bean
只可定义一次,因此必须注意确保自定义的是适当令牌类型 — 在本例中是访问令牌。如果您有兴趣自定义 ID 令牌,请参阅 User Info Mapper guide 以了解更多信息。
You may add your own custom claims to an access token using an OAuth2TokenCustomizer<JWTEncodingContext>
@Bean
.
Please note that this @Bean
may only be defined once, and so care must be taken to ensure that you are customizing the appropriate token type — an access token in this case.
If you are interested in customizing the ID Token, see the User Info Mapper guide for more information.
以下是向访问令牌添加自定义声明的一个示例——换句话说,授权服务器发行的每个访问令牌都将填入自定义声明。
The following is an example of adding custom claims to an access token — in other words, every access token that is issued by the authorization server will have the custom claims populated.
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.oauth2.server.authorization.OAuth2TokenType;
import org.springframework.security.oauth2.server.authorization.token.JwtEncodingContext;
import org.springframework.security.oauth2.server.authorization.token.OAuth2TokenCustomizer;
@Configuration
public class CustomClaimsConfiguration {
@Bean
public OAuth2TokenCustomizer<JwtEncodingContext> jwtTokenCustomizer() {
return (context) -> {
if (OAuth2TokenType.ACCESS_TOKEN.equals(context.getTokenType())) {
context.getClaims().claims((claims) -> {
claims.put("claim-1", "value-1");
claims.put("claim-2", "value-2");
});
}
};
}
}
Add authorities as custom claims to JWT access tokens
要将资源所有者的权限添加到 JWT 访问令牌,我们可以参考上述自定义声明映射方法,并使用 Principal
的权限填充自定义声明。
To add authorities of the resource owner to a JWT access token, we can refer to the custom claim mapping method above and populate a custom claim with the authorities of the Principal
.
我们定义了一个拥有权限集的示例用户用于演示,并在访问令牌中使用这些权限填充自定义声明。
We define a sample user with a set of authorities for demonstration purposes, and populate a custom claim in the access token with those authorities.
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.oauth2.server.authorization.OAuth2TokenType;
import org.springframework.security.oauth2.server.authorization.token.JwtEncodingContext;
import org.springframework.security.oauth2.server.authorization.token.OAuth2TokenCustomizer;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import java.util.Collections;
import java.util.Set;
import java.util.stream.Collectors;
@Configuration
public class CustomClaimsWithAuthoritiesConfiguration {
@Bean
public UserDetailsService users() {
UserDetails user = User.withDefaultPasswordEncoder()
.username("user1") (1)
.password("password")
.roles("user", "admin") (2)
.build();
return new InMemoryUserDetailsManager(user);
}
@Bean
public OAuth2TokenCustomizer<JwtEncodingContext> jwtTokenCustomizer() { (3)
return (context) -> {
if (OAuth2TokenType.ACCESS_TOKEN.equals(context.getTokenType())) { (4)
context.getClaims().claims((claims) -> { (5)
Set<String> roles = AuthorityUtils.authorityListToSet(context.getPrincipal().getAuthorities())
.stream()
.map(c -> c.replaceFirst("^ROLE_", ""))
.collect(Collectors.collectingAndThen(Collectors.toSet(), Collections::unmodifiableSet)); (6)
claims.put("roles", roles); (7)
});
}
};
}
}
1 | Define a sample user user1 with an in-memory UserDetailsService . |
2 | Assign the roles for user1 . |
3 | Define an OAuth2TokenCustomizer<JwtEncodingContext> @Bean that allows for customizing the JWT claims. |
4 | Check whether the JWT is an access token. |
5 | Access the default claims via the JwtEncodingContext . |
6 | Extract the roles from the Principal object. The role information is stored as a string prefixed with ROLE_ , so we strip the prefix here. |
7 | Set the custom claim roles to the set of roles collected from the previous step. |
通过此自定义,有关用户的权限信息将作为自定义声明包含在访问令牌中。
As a result of this customization, authorities information about the user will be included as a custom claim in the access token.