[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:
psevestre
2022-03-31 02:04:02 -03:00
committed by GitHub
parent 2cda833322
commit 81e22da07c
14 changed files with 548 additions and 1 deletions
@@ -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 );
}
}