如何:將許可權作為自定義宣告新增到 JWT 訪問令牌中

本指南演示瞭如何將資源所有者的許可權新增到JWT訪問令牌中。“許可權”一詞可能代表各種形式,如角色、許可權或資源所有者的組。

為了讓資源伺服器能夠獲取資源所有者的許可權,我們向訪問令牌新增自定義宣告。當客戶端使用訪問令牌訪問受保護資源時,資源伺服器將能夠獲取有關資源所有者訪問級別的資訊,以及其他潛在的用途和好處。

向JWT訪問令牌新增自定義宣告

您可以使用 OAuth2TokenCustomizer<JWTEncodingContext> @Bean 將自己的自定義宣告新增到訪問令牌中。請注意,這個 @Bean 只能定義一次,因此必須注意確保您正在定製適當的令牌型別——在本例中是訪問令牌。如果您對定製ID令牌感興趣,請參閱使用者資訊對映器指南以獲取更多資訊。

以下是向訪問令牌新增自定義宣告的示例——換句話說,授權伺服器頒發的每個訪問令牌都將填充自定義宣告。

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");
				});
			}
		};
	}
}

將許可權作為自定義宣告新增到JWT訪問令牌中

要將資源所有者的許可權新增到JWT訪問令牌中,我們可以參考上述自定義宣告對映方法,並用 Principal 的許可權填充自定義宣告。

我們定義一個帶有許可權集的示例使用者用於演示目的,並在訪問令牌中用這些許可權填充一個自定義宣告。

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 使用記憶體中的 UserDetailsService 定義示例使用者 user1
2 user1 分配角色。
3 定義一個 OAuth2TokenCustomizer<JwtEncodingContext> @Bean,允許定製JWT宣告。
4 檢查JWT是否是訪問令牌。
5 透過 JwtEncodingContext 訪問預設宣告。
6 Principal 物件中提取角色。角色資訊以 ROLE_ 為字首的字串形式儲存,因此我們在此處去除字首。
7 將自定義宣告 roles 設定為上一步收集的角色集。

透過這種定製,有關使用者的許可權資訊將作為自定義宣告包含在訪問令牌中。

© . This site is unofficial and not affiliated with VMware.