[BAEL-5259] Spring Security - Map Authorities from JWT (#11990)
* [BAEL-4849] Article code * [BAEL-4968] Article code * [BAEL-4968] Article code * [BAEL-4968] Article code * [BAEL-4968] Remove extra comments * [BAEL-5259] simple test case * [BAEL-5259] DSL-based rewrite * [BAEL-5259] Code formatting * [BAEL-5259] Test case naming * WIP: Article code * [BAEL-5259] Tests * [BAEL-5259] Tests
This commit is contained in:
parent
2cda833322
commit
81e22da07c
|
@ -24,6 +24,10 @@
|
|||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-oauth2-client</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,23 @@
|
|||
/**
|
||||
*
|
||||
*/
|
||||
package com.baeldung.openid.oidc.jwtauthorities;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.context.ApplicationContextInitializer;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
|
||||
import com.baeldung.openid.oidc.discovery.SpringOidcDiscoveryApplication;
|
||||
import com.baeldung.openid.oidc.utils.YamlLoaderInitializer;
|
||||
|
||||
@SpringBootApplication
|
||||
public class SpringOidcJwtAuthoritiesApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication application = new SpringApplication(SpringOidcJwtAuthoritiesApplication.class);
|
||||
ApplicationContextInitializer<ConfigurableApplicationContext> yamlInitializer = new YamlLoaderInitializer("jwtauthorities-application.yml");
|
||||
application.addInitializers(yamlInitializer);
|
||||
application.run(args);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
package com.baeldung.openid.oidc.jwtauthorities.config;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.oauth2.jwt.Jwt;
|
||||
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken;
|
||||
|
||||
import com.baeldung.openid.oidc.jwtauthorities.domain.Account;
|
||||
|
||||
public class AccountToken extends JwtAuthenticationToken {
|
||||
private static final long serialVersionUID = 1L;
|
||||
private final Account account;
|
||||
|
||||
public AccountToken(Jwt jwt, Collection<? extends GrantedAuthority> authorities, String name, Account account) {
|
||||
super(jwt, authorities, name);
|
||||
this.account = account;
|
||||
}
|
||||
|
||||
public Account getAccount() {
|
||||
return account;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
package com.baeldung.openid.oidc.jwtauthorities.config;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.security.authentication.AbstractAuthenticationToken;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.oauth2.jwt.Jwt;
|
||||
import org.springframework.security.oauth2.jwt.JwtClaimNames;
|
||||
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken;
|
||||
|
||||
import com.baeldung.openid.oidc.jwtauthorities.domain.Account;
|
||||
import com.baeldung.openid.oidc.jwtauthorities.service.AccountService;
|
||||
|
||||
public class CustomJwtAuthenticationConverter implements Converter<Jwt, AbstractAuthenticationToken> {
|
||||
|
||||
private final Converter<Jwt, Collection<GrantedAuthority>> jwtGrantedAuthoritiesConverter;
|
||||
private final String principalClaimName;
|
||||
private AccountService accountService;
|
||||
|
||||
public CustomJwtAuthenticationConverter(AccountService accountService, Converter<Jwt, Collection<GrantedAuthority>> jwtGrantedAuthoritiesConverter, String principalClaimName) {
|
||||
this.accountService = accountService;
|
||||
this.jwtGrantedAuthoritiesConverter = jwtGrantedAuthoritiesConverter;
|
||||
this.principalClaimName = principalClaimName != null ? principalClaimName : JwtClaimNames.SUB;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AbstractAuthenticationToken convert(Jwt source) {
|
||||
|
||||
Collection<GrantedAuthority> authorities = jwtGrantedAuthoritiesConverter.convert(source);
|
||||
String principalClaimValue = source.getClaimAsString(this.principalClaimName);
|
||||
Account acc = accountService.findAccountByPrincipal(principalClaimValue);
|
||||
return new AccountToken(source, authorities, principalClaimValue, acc);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
package com.baeldung.openid.oidc.jwtauthorities.config;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
|
||||
@ConfigurationProperties(prefix = "baeldung.jwt.mapping")
|
||||
public class JwtMappingProperties {
|
||||
|
||||
private String authoritiesPrefix;
|
||||
private String authoritiesClaimName;
|
||||
private String principalClaimName;
|
||||
private Map<String,String> scopes;
|
||||
|
||||
public String getAuthoritiesClaimName() {
|
||||
return authoritiesClaimName;
|
||||
}
|
||||
|
||||
public void setAuthoritiesClaimName(String authoritiesClaimName) {
|
||||
this.authoritiesClaimName = authoritiesClaimName;
|
||||
}
|
||||
|
||||
public String getAuthoritiesPrefix() {
|
||||
return authoritiesPrefix;
|
||||
}
|
||||
|
||||
public void setAuthoritiesPrefix(String authoritiesPrefix) {
|
||||
this.authoritiesPrefix = authoritiesPrefix;
|
||||
}
|
||||
|
||||
|
||||
public String getPrincipalClaimName() {
|
||||
return principalClaimName;
|
||||
}
|
||||
|
||||
public void setPrincipalClaimName(String principalClaimName) {
|
||||
this.principalClaimName = principalClaimName;
|
||||
}
|
||||
|
||||
public Map<String,String> getScopes() {
|
||||
return scopes;
|
||||
}
|
||||
|
||||
public void setScopes(Map<String,String> scopes) {
|
||||
this.scopes = scopes;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,84 @@
|
|||
package com.baeldung.openid.oidc.jwtauthorities.config;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
||||
import org.springframework.security.oauth2.jwt.Jwt;
|
||||
|
||||
public class MappingJwtGrantedAuthoritiesConverter implements Converter<Jwt, Collection<GrantedAuthority>> {
|
||||
|
||||
private static final Collection<String> WELL_KNOWN_AUTHORITIES_CLAIM_NAMES = Arrays.asList("scope", "scp");
|
||||
|
||||
private final Map<String,String> scopes;
|
||||
private String authoritiesClaimName = null;
|
||||
private String authorityPrefix = "SCOPE_";
|
||||
|
||||
MappingJwtGrantedAuthoritiesConverter(Map<String,String> scopes) {
|
||||
this.scopes = scopes == null ? Collections.emptyMap(): scopes;
|
||||
}
|
||||
|
||||
public void setAuthoritiesClaimName(String authoritiesClaimName) {
|
||||
this.authoritiesClaimName = authoritiesClaimName;
|
||||
}
|
||||
|
||||
public void setAuthorityPrefix(String authorityPrefix) {
|
||||
this.authorityPrefix = authorityPrefix;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<GrantedAuthority> convert(Jwt jwt) {
|
||||
|
||||
Collection<String> tokenScopes = parseScopesClaim(jwt);
|
||||
if ( tokenScopes.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
return tokenScopes.stream()
|
||||
.map(s -> scopes.getOrDefault(s, s))
|
||||
.map(s -> this.authorityPrefix + s)
|
||||
.map(SimpleGrantedAuthority::new)
|
||||
.collect(Collectors.toCollection(HashSet::new));
|
||||
}
|
||||
|
||||
protected Collection<String> parseScopesClaim(Jwt jwt) {
|
||||
|
||||
String scopeClaim;
|
||||
|
||||
if ( this.authoritiesClaimName == null ) {
|
||||
scopeClaim = WELL_KNOWN_AUTHORITIES_CLAIM_NAMES.stream()
|
||||
.filter( claim -> jwt.hasClaim(claim))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
|
||||
if ( scopeClaim == null ) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
else {
|
||||
scopeClaim = this.authoritiesClaimName;
|
||||
}
|
||||
|
||||
Object v = jwt.getClaim(scopeClaim);
|
||||
if ( v == null ) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
if ( v instanceof String) {
|
||||
return Arrays.asList(v.toString().split(" "));
|
||||
}
|
||||
else if ( v instanceof Collection ) {
|
||||
return ((Collection<?>)v).stream()
|
||||
.map( s -> s.toString())
|
||||
.collect(Collectors.toCollection(HashSet::new));
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
package com.baeldung.openid.oidc.jwtauthorities.config;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.security.authentication.AbstractAuthenticationToken;
|
||||
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.oauth2.jwt.Jwt;
|
||||
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationConverter;
|
||||
import org.springframework.security.oauth2.server.resource.authentication.JwtGrantedAuthoritiesConverter;
|
||||
import org.springframework.security.web.SecurityFilterChain;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import com.baeldung.openid.oidc.jwtauthorities.service.AccountService;
|
||||
|
||||
@Configuration
|
||||
@EnableConfigurationProperties(JwtMappingProperties.class)
|
||||
@EnableMethodSecurity
|
||||
public class SecurityConfig {
|
||||
|
||||
private final JwtMappingProperties mappingProps;
|
||||
private final AccountService accountService;
|
||||
|
||||
public SecurityConfig(JwtMappingProperties mappingProps, AccountService accountService) {
|
||||
this.mappingProps = mappingProps;
|
||||
this.accountService = accountService;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public String jwtGrantedAuthoritiesPrefix() {
|
||||
return mappingProps.getAuthoritiesPrefix();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Converter<Jwt, Collection<GrantedAuthority>> jwtGrantedAuthoritiesConverter() {
|
||||
MappingJwtGrantedAuthoritiesConverter converter = new MappingJwtGrantedAuthoritiesConverter(mappingProps.getScopes());
|
||||
|
||||
if (StringUtils.hasText(mappingProps.getAuthoritiesPrefix())) {
|
||||
converter.setAuthorityPrefix(mappingProps.getAuthoritiesPrefix()
|
||||
.trim());
|
||||
}
|
||||
|
||||
if (StringUtils.hasText(mappingProps.getAuthoritiesClaimName())) {
|
||||
converter.setAuthoritiesClaimName(mappingProps.getAuthoritiesClaimName());
|
||||
}
|
||||
return converter;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Converter<Jwt,AbstractAuthenticationToken> customJwtAuthenticationConverter(AccountService accountService) {
|
||||
return new CustomJwtAuthenticationConverter(
|
||||
accountService,
|
||||
jwtGrantedAuthoritiesConverter(),
|
||||
mappingProps.getPrincipalClaimName());
|
||||
}
|
||||
|
||||
@Bean
|
||||
SecurityFilterChain customJwtSecurityChain(HttpSecurity http) throws Exception {
|
||||
// @formatter:off
|
||||
return http.oauth2ResourceServer(oauth2 -> {
|
||||
oauth2.jwt()
|
||||
.jwtAuthenticationConverter(customJwtAuthenticationConverter(accountService));
|
||||
})
|
||||
.build();
|
||||
// @formatter:on
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
package com.baeldung.openid.oidc.jwtauthorities.domain;
|
||||
|
||||
public class Account {
|
||||
|
||||
private final Long id;
|
||||
private final String branch;
|
||||
private final String accountNumber;
|
||||
|
||||
public Account(Long id, String branch, String accountNumber) {
|
||||
this.id = id;
|
||||
this.branch = branch;
|
||||
this.accountNumber = accountNumber;
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getBranch() {
|
||||
return branch;
|
||||
}
|
||||
|
||||
public String getAccountNumber() {
|
||||
return accountNumber;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
package com.baeldung.openid.oidc.jwtauthorities.service;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.baeldung.openid.oidc.jwtauthorities.domain.Account;
|
||||
|
||||
@Service
|
||||
public class AccountService {
|
||||
|
||||
public Account findAccountByPrincipal(String principal) {
|
||||
// NOTE: real-world code would typically perform some sort of DB lookup
|
||||
return new Account(1l, "0001", "101888444-0");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
package com.baeldung.openid.oidc.jwtauthorities.web.controllers;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import com.baeldung.openid.oidc.jwtauthorities.config.AccountToken;
|
||||
import com.baeldung.openid.oidc.jwtauthorities.domain.Account;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/user")
|
||||
public class UserRestController {
|
||||
|
||||
@GetMapping("/authorities")
|
||||
@PreAuthorize("hasAuthority(@jwtGrantedAuthoritiesPrefix + 'profile.read')")
|
||||
public Map<String,Object> getPrincipalInfo( JwtAuthenticationToken principal) {
|
||||
|
||||
Collection<String> authorities = principal.getAuthorities()
|
||||
.stream()
|
||||
.map(GrantedAuthority::getAuthority)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
Map<String,Object> info = new HashMap<>();
|
||||
info.put("name", principal.getName());
|
||||
info.put("authorities", authorities);
|
||||
info.put("tokenAttributes", principal.getTokenAttributes());
|
||||
|
||||
if ( principal instanceof AccountToken ) {
|
||||
info.put( "account", ((AccountToken)principal).getAccount());
|
||||
}
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
@GetMapping("/account/{accountNumber}")
|
||||
@PreAuthorize("authentication.account.accountNumber == #accountNumber")
|
||||
public Account getAccountById(@PathVariable("accountNumber") String accountNumber, AccountToken authentication) {
|
||||
return authentication.getAccount();
|
||||
}
|
||||
}
|
|
@ -4,4 +4,3 @@ server:
|
|||
logging:
|
||||
level:
|
||||
org.springframework.web.client.RestTemplate: DEBUG
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
spring:
|
||||
security:
|
||||
oauth2:
|
||||
resourceserver:
|
||||
jwt:
|
||||
# issuer-uri: https://sts.windows.net/2e9fde3a-38ec-44f9-8bcd-c184dc1e8033/
|
||||
issuer-uri: http://localhost:8083/auth/realms/baeldung
|
||||
baeldung:
|
||||
jwt:
|
||||
mapping:
|
||||
authorities-prefix: "MY_SCOPE_"
|
||||
principal-claim-name: preferred_username
|
||||
scopes:
|
||||
profile: profile.read
|
||||
"profile_read": profile.read
|
|
@ -0,0 +1,59 @@
|
|||
package com.baeldung.openid.oidc.jwtauthorities.config;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.security.oauth2.jwt.Jwt;
|
||||
|
||||
import com.baeldung.openid.oidc.jwtauthorities.service.AccountService;
|
||||
|
||||
class CustomJwtAuthenticationConverterUnitTest {
|
||||
|
||||
@Test
|
||||
void testGivenCustomJwtAuthenticationConverter_whenConvert_thenReturnAccountToken() {
|
||||
|
||||
AccountService accountService = new AccountService();
|
||||
MappingJwtGrantedAuthoritiesConverter authoritiesConverter = new MappingJwtGrantedAuthoritiesConverter(new HashMap<>());
|
||||
|
||||
CustomJwtAuthenticationConverter converter = new CustomJwtAuthenticationConverter(
|
||||
accountService, authoritiesConverter, null);
|
||||
|
||||
Jwt jwt = Jwt.withTokenValue("NOTUSED")
|
||||
.header("typ", "JWT")
|
||||
.subject("user")
|
||||
.claim("scp", "openid email profile")
|
||||
.build();
|
||||
|
||||
Object auth = converter.convert(jwt);
|
||||
assertTrue(auth instanceof AccountToken, "Authentication must be instance of AccountToken");
|
||||
AccountToken token = AccountToken.class.cast(auth);
|
||||
|
||||
assertEquals("user", token.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGivenCustomPrincipalClaimName_whenConvert_thenReturnAccountToken() {
|
||||
|
||||
AccountService accountService = new AccountService();
|
||||
MappingJwtGrantedAuthoritiesConverter authoritiesConverter = new MappingJwtGrantedAuthoritiesConverter(new HashMap<>());
|
||||
|
||||
CustomJwtAuthenticationConverter converter = new CustomJwtAuthenticationConverter(
|
||||
accountService, authoritiesConverter, "preferred_username");
|
||||
|
||||
Jwt jwt = Jwt.withTokenValue("NOTUSED")
|
||||
.header("typ", "JWT")
|
||||
.claim("preferred_username", "user")
|
||||
.claim("scp", "openid email profile")
|
||||
.build();
|
||||
|
||||
Object auth = converter.convert(jwt);
|
||||
assertTrue(auth instanceof AccountToken, "Authentication must be instance of AccountToken");
|
||||
AccountToken token = AccountToken.class.cast(auth);
|
||||
|
||||
assertEquals("user", token.getName());
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,91 @@
|
|||
package com.baeldung.openid.oidc.jwtauthorities.config;
|
||||
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
||||
import org.springframework.security.oauth2.jwt.Jwt;
|
||||
|
||||
class MappingJwtGrantedAuthoritiesConverterUnitTest {
|
||||
|
||||
@Test
|
||||
void testGivenConverterWithScopeMap_whenConvert_thenResultHasMappedAuthorities() {
|
||||
Jwt jwt = Jwt.withTokenValue("NOTUSED")
|
||||
.header("typ", "JWT")
|
||||
.subject("user")
|
||||
.claim("scp", "openid email profile")
|
||||
.build();
|
||||
|
||||
Map<String, String> scopeMap = new HashMap<>();
|
||||
scopeMap.put("profile", "profile.read");
|
||||
MappingJwtGrantedAuthoritiesConverter converter = new MappingJwtGrantedAuthoritiesConverter(scopeMap);
|
||||
Collection<GrantedAuthority> result = converter.convert(jwt);
|
||||
|
||||
assertTrue("Result must contain the authoriry 'SCOPE_profile.read'",
|
||||
result.contains(new SimpleGrantedAuthority("SCOPE_profile.read")));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGivenConverterWithCustomScopeClaim_whenConvert_thenResultHasAuthorities() {
|
||||
Jwt jwt = Jwt.withTokenValue("NOTUSED")
|
||||
.header("typ", "JWT")
|
||||
.subject("user")
|
||||
.claim("myscope_claim", "openid email profile")
|
||||
.build();
|
||||
|
||||
Map<String, String> scopeMap = new HashMap<>();
|
||||
MappingJwtGrantedAuthoritiesConverter converter = new MappingJwtGrantedAuthoritiesConverter(scopeMap);
|
||||
converter.setAuthoritiesClaimName("myscope_claim");
|
||||
Collection<GrantedAuthority> result = converter.convert(jwt);
|
||||
|
||||
assertTrue("Result must contain the authoriry 'SCOPE_profile'",
|
||||
result.contains(new SimpleGrantedAuthority("SCOPE_profile")));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGivenTokenWithNonMappedScope_whenConvert_thenResultHasOriginalScope() {
|
||||
Jwt jwt = Jwt.withTokenValue("NOTUSED")
|
||||
.header("typ", "JWT")
|
||||
.subject("user")
|
||||
.claim("scp", "openid email profile custom")
|
||||
.build();
|
||||
|
||||
Map<String, String> scopeMap = new HashMap<>();
|
||||
scopeMap.put("profile", "profile.read");
|
||||
MappingJwtGrantedAuthoritiesConverter converter = new MappingJwtGrantedAuthoritiesConverter(scopeMap);
|
||||
Collection<GrantedAuthority> result = converter.convert(jwt);
|
||||
|
||||
assertTrue("Result must contain the authority SCOPE_custom",
|
||||
result.contains(new SimpleGrantedAuthority("SCOPE_custom")));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
void testGivenConverterWithCustomPrefix_whenConvert_thenAllAuthoritiesMustHaveTheCustomPrefix() {
|
||||
Jwt jwt = Jwt.withTokenValue("NOTUSED")
|
||||
.header("typ", "JWT")
|
||||
.subject("user")
|
||||
.claim("scp", "openid email profile custom")
|
||||
.build();
|
||||
|
||||
Map<String, String> scopeMap = new HashMap<>();
|
||||
scopeMap.put("profile", "profile.read");
|
||||
MappingJwtGrantedAuthoritiesConverter converter = new MappingJwtGrantedAuthoritiesConverter(scopeMap);
|
||||
converter.setAuthorityPrefix("MY_SCOPE");
|
||||
Collection<GrantedAuthority> result = converter.convert(jwt);
|
||||
|
||||
long count = result.stream()
|
||||
.map(GrantedAuthority::getAuthority)
|
||||
.filter(s -> !s.startsWith("MY_SCOPE"))
|
||||
.count();
|
||||
|
||||
assertTrue("All authorities names must start with custom prefix", count == 0 );
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue