Add Documentation for ExpressionJwtGrantedAuthoritiesConverter
Closes gh-18300
This commit is contained in:
@@ -961,7 +961,11 @@ By default, Spring Security will wire the `JwtAuthenticationProvider` with a def
|
||||
|
||||
As part of configuring a `JwtAuthenticationConverter`, you can supply a subsidiary converter to go from `Jwt` to a `Collection` of granted authorities.
|
||||
|
||||
[[jwt-granted-authorities-custom-claim-name]]
|
||||
==== Using a Custom Claim Name
|
||||
|
||||
Let's say that your authorization server communicates authorities in a custom claim called `authorities`.
|
||||
|
||||
In that case, you can configure the claim that <<oauth2resourceserver-jwt-architecture-jwtauthenticationconverter,`JwtAuthenticationConverter`>> should inspect, like so:
|
||||
|
||||
.Authorities Claim Configuration
|
||||
@@ -1022,6 +1026,9 @@ Xml::
|
||||
----
|
||||
======
|
||||
|
||||
[[jwt-granted-authorities-custom-scope-prefix]]
|
||||
==== Using a Custom Scope Prefix
|
||||
|
||||
You can also configure the authority prefix to be different as well.
|
||||
Instead of prefixing each authority with `SCOPE_`, you can change it to `ROLE_` like so:
|
||||
|
||||
@@ -1153,6 +1160,17 @@ class CustomAuthenticationConverterConfig {
|
||||
----
|
||||
======
|
||||
|
||||
[[jwt-granted-authorities-spel-expression]]
|
||||
==== Using a SpEL Expression
|
||||
|
||||
In circumstances where the location of scopes is nested or complex in some other way, you can use `ExpressionJwtGrantedAuthoritiesConverter` with a SpEL expression to extract the scopes.
|
||||
|
||||
For example, if your JWT has a claim called `nested` and, inside of that, it has a claim called `scopes`, you can do:
|
||||
|
||||
include-code::./ExpressionJwtGrantedAuthoritiesConverterTests[tag=spel-expression,indent=0]
|
||||
|
||||
The SpEL expression result should be a `Collection`.
|
||||
|
||||
[[oauth2resourceserver-jwt-validation]]
|
||||
== Configuring Validation
|
||||
|
||||
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
package org.springframework.security.docs.servlet.oauth2.resourceserver.jwtgrantedauthoritiesspelexpression;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.expression.Expression;
|
||||
import org.springframework.expression.spel.standard.SpelExpressionParser;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.oauth2.jwt.Jwt;
|
||||
import org.springframework.security.oauth2.jwt.TestJwts;
|
||||
import org.springframework.security.oauth2.server.resource.authentication.ExpressionJwtGrantedAuthoritiesConverter;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
class ExpressionJwtGrantedAuthoritiesConverterTests {
|
||||
|
||||
@Test
|
||||
public void convertWhenTokenHasCustomClaimNameExpressionThenCustomClaimNameAttributeIsTranslatedToAuthorities() {
|
||||
// @formatter:off
|
||||
Jwt jwt = TestJwts.jwt()
|
||||
.claim("nested", Collections.singletonMap("scopes", Arrays.asList("read", "write")))
|
||||
.build();
|
||||
// @formatter:on
|
||||
// tag::spel-expression[]
|
||||
SpelExpressionParser parser = new SpelExpressionParser();
|
||||
Expression expression = parser.parseExpression("[nested][scopes]");
|
||||
ExpressionJwtGrantedAuthoritiesConverter converter = new ExpressionJwtGrantedAuthoritiesConverter(expression);
|
||||
Collection<GrantedAuthority> authorities = converter.convert(jwt);
|
||||
// end::spel-expression[]
|
||||
assertThat(authorities).extracting(GrantedAuthority::getAuthority)
|
||||
.containsExactly("SCOPE_read", "SCOPE_write");
|
||||
}
|
||||
}
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
package org.springframework.security.kt.docs.servlet.oauth2.resourceserver.jwtgrantedauthoritiesspelexpression
|
||||
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.assertj.core.api.Assertions.tuple
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.springframework.expression.spel.standard.SpelExpressionParser
|
||||
import org.springframework.security.core.GrantedAuthority
|
||||
import org.springframework.security.oauth2.jwt.TestJwts
|
||||
import org.springframework.security.oauth2.server.resource.authentication.ExpressionJwtGrantedAuthoritiesConverter
|
||||
|
||||
class ExpressionJwtGrantedAuthoritiesConverterTests {
|
||||
@Test
|
||||
fun convertWhenTokenHasCustomClaimNameExpressionThenCustomClaimNameAttributeIsTranslatedToAuthorities() {
|
||||
// @formatter:off
|
||||
val jwt = TestJwts.jwt()
|
||||
.claim("nested", mapOf("scopes" to listOf("read", "write")))
|
||||
.build()
|
||||
// @formatter:on
|
||||
// tag::spel-expression[]
|
||||
val parser = SpelExpressionParser()
|
||||
val expression = parser.parseExpression("[nested][scopes]")
|
||||
val converter = ExpressionJwtGrantedAuthoritiesConverter(expression)
|
||||
val authorities = converter.convert(jwt)
|
||||
// end::spel-expression[]
|
||||
assertThat(authorities).extracting(GrantedAuthority::getAuthority)
|
||||
.containsExactly(tuple("SCOPE_read"), tuple("SCOPE_write"))
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user