Add Reference Docs for DelegatingJwtGrantedAuthoritiesConverter

Issue gh-18300

Signed-off-by: Josh Cummings <3627351+jzheaux@users.noreply.github.com>
This commit is contained in:
Josh Cummings 2026-03-27 12:13:49 -06:00
parent d5d466b0eb
commit de14d9684f
No known key found for this signature in database
GPG Key ID: 869B37A20E876129
3 changed files with 115 additions and 0 deletions

View File

@ -1189,6 +1189,13 @@ include-code::./ExpressionJwtGrantedAuthoritiesConverterTests[tag=spel-expressio
The SpEL expression result should be a `Collection`.
[[jwt-granted-authorities-composite]]
==== Reading from Multiple Locations
When you are collecting authorities from more than one claim, you can use `DelegatingJwtGrantedAuthoritiesConverter` and provide multiple converter instances like so:
include-code::./DelegatingJwtGrantedAuthoritiesConverterTests[tag=two-locations,indent=0]
[[oauth2resourceserver-jwt-validation]]
== Configuring Validation

View File

@ -0,0 +1,57 @@
/*
* Copyright 2004-present the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.docs.servlet.oauth2.resourceserver.jwtgrantedauthoritiescomposite;
import java.util.Arrays;
import java.util.Collection;
import org.junit.jupiter.api.Test;
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.DelegatingJwtGrantedAuthoritiesConverter;
import org.springframework.security.oauth2.server.resource.authentication.JwtGrantedAuthoritiesConverter;
import static org.assertj.core.api.Assertions.assertThat;
class DelegatingJwtGrantedAuthoritiesConverterTests {
@Test
public void convertWhenTokenHasMultipleClaimsThenAuthoritiesFromBothClaims() {
// @formatter:off
Jwt jwt = TestJwts.jwt()
.claim("scp", Arrays.asList("read", "write"))
.claim("roles", Arrays.asList("admin"))
.build();
// @formatter:on
// tag::two-locations[]
JwtGrantedAuthoritiesConverter scopesConverter = new JwtGrantedAuthoritiesConverter();
JwtGrantedAuthoritiesConverter rolesConverter = new JwtGrantedAuthoritiesConverter();
rolesConverter.setAuthoritiesClaimName("roles");
rolesConverter.setAuthorityPrefix("ROLE_");
DelegatingJwtGrantedAuthoritiesConverter converter =
new DelegatingJwtGrantedAuthoritiesConverter(scopesConverter, rolesConverter);
Collection<GrantedAuthority> authorities = converter.convert(jwt);
// end::two-locations[]
assertThat(authorities).extracting(GrantedAuthority::getAuthority)
.containsExactlyInAnyOrder("SCOPE_read", "SCOPE_write", "ROLE_admin");
}
}

View File

@ -0,0 +1,51 @@
/*
* Copyright 2004-present the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.kt.docs.servlet.oauth2.resourceserver.jwtgrantedauthoritiescomposite
import org.assertj.core.api.Assertions.assertThat
import org.assertj.core.api.Assertions.tuple
import org.junit.jupiter.api.Test
import org.springframework.security.core.GrantedAuthority
import org.springframework.security.oauth2.jwt.TestJwts
import org.springframework.security.oauth2.server.resource.authentication.DelegatingJwtGrantedAuthoritiesConverter
import org.springframework.security.oauth2.server.resource.authentication.JwtGrantedAuthoritiesConverter
class DelegatingJwtGrantedAuthoritiesConverterTests {
@Test
fun convertWhenTokenHasMultipleClaimsThenAuthoritiesFromBothClaims() {
// @formatter:off
val jwt = TestJwts.jwt()
.claim("scp", listOf("read", "write"))
.claim("roles", listOf("admin"))
.build()
// @formatter:on
// tag::two-locations[]
val scopesConverter = JwtGrantedAuthoritiesConverter()
val rolesConverter = JwtGrantedAuthoritiesConverter()
rolesConverter.setAuthoritiesClaimName("roles")
rolesConverter.setAuthorityPrefix("ROLE_")
val converter = DelegatingJwtGrantedAuthoritiesConverter(scopesConverter, rolesConverter)
val authorities = converter.convert(jwt)
// end::two-locations[]
assertThat(authorities).extracting(GrantedAuthority::getAuthority)
.containsExactlyInAnyOrder(tuple("SCOPE_read"), tuple("SCOPE_write"), tuple("ROLE_admin"))
}
}