@@ -629,65 +629,42 @@ However, there are a number of circumstances where this default is insufficient.
629629For example, some authorization servers don't use the `scope` attribute, but instead have their own custom attribute.
630630Or, at other times, the resource server may need to adapt the attribute or a composition of attributes into internalized authorities.
631631
632- To this end, the DSL exposes `jwtAuthenticationConverter()`:
632+ To this end, the DSL exposes `jwtAuthenticationConverter()`, which is responsible for converting a `Jwt` into an `Authentication`.
633633
634- .Authorities Extractor Configuration
634+ As part of its configuration, we can supply a subsidiary converter to go from `Jwt` to a `Collection` of granted authorities.
635+ Let's say that that your authorization server communicates authorities in a custom claim called `authorities`.
636+ In that case, you can configure the claim that `JwtAuthenticationConverter` should inspect, like so:
637+
638+ .Authorities Claim Configuration
635639====
636640.Java
637641[source,java,role="primary"]
638642----
639643@EnableWebSecurity
640- public class DirectlyConfiguredJwkSetUri extends WebSecurityConfigurerAdapter {
644+ public class CustomAuthoritiesClaimName extends WebSecurityConfigurerAdapter {
641645 protected void configure(HttpSecurity http) {
642646 http
643647 .authorizeRequests(authorize -> authorize
644648 .anyRequest().authenticated()
645649 )
646650 .oauth2ResourceServer(oauth2 -> oauth2
647651 .jwt(jwt -> jwt
648- .jwtAuthenticationConverter(grantedAuthoritiesExtractor ())
652+ .jwtAuthenticationConverter(jwtAuthenticationConverter ())
649653 )
650654 );
651655 }
652656}
653657
654- Converter<Jwt, AbstractAuthenticationToken> grantedAuthoritiesExtractor() {
655- JwtAuthenticationConverter jwtAuthenticationConverter =
656- new JwtAuthenticationConverter();
657-
658- jwtAuthenticationConverter.setJwtGrantedAuthoritiesConverter
659- (new GrantedAuthoritiesExtractor());
658+ JwtAuthenticationConverter jwtAuthenticationConverter() {
659+ JwtGrantedAuthoritiesConverter grantedAuthoritiesConverter = new JwtGrantedAuthoritiesConverter();
660+ grantedAuthoritiesConverter.setAuthoritiesClaimName("authorities");
660661
662+ JwtAuthenticationConverter authenticationConverter = new JwtAuthenticationConverter();
663+ jwtAuthenticationConverter.setJwtGrantedAuthoritiesConverter(authoritiesConverter);
661664 return jwtAuthenticationConverter;
662665}
663666----
664667
665- .Kotlin
666- [source,kotlin,role="secondary"]
667- ----
668- @EnableWebSecurity
669- class DirectlyConfiguredJwkSetUri : WebSecurityConfigurerAdapter() {
670- override fun configure(http: HttpSecurity) {
671- http {
672- authorizeRequests {
673- authorize(anyRequest, authenticated)
674- }
675- oauth2ResourceServer {
676- jwt {
677- jwtAuthenticationConverter = grantedAuthoritiesExtractor()
678- }
679- }
680- }
681- }
682-
683- private fun grantedAuthoritiesExtractor(): JwtAuthenticationConverter {
684- val jwtAuthenticationConverter = JwtAuthenticationConverter()
685- jwtAuthenticationConverter.setJwtGrantedAuthoritiesConverter(GrantedAuthoritiesExtractor())
686- return jwtAuthenticationConverter
687- }
688- }
689- ----
690-
691668.Xml
692669[source,xml,role="secondary"]
693670----
@@ -696,40 +673,65 @@ class DirectlyConfiguredJwkSetUri : WebSecurityConfigurerAdapter() {
696673 <intercept-uri pattern="/messages/**" access="hasAuthority('SCOPE_messages')"/>
697674 <oauth2-resource-server>
698675 <jwt jwk-set-uri="https://idp.example.org/.well-known/jwks.json"
699- jwt-authentication-converter-ref="grantedAuthoritiesExtractor "/>
676+ jwt-authentication-converter-ref="jwtAuthenticationConverter "/>
700677 </oauth2-resource-server>
701678</http>
702679
703- <bean id="grantedAuthoritiesExtractor "
680+ <bean id="jwtAuthenticationConverter "
704681 class="org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationConverter">
705- <property name="jwtGrantedAuthoritiesConverter">
706- <bean class="my.custom.GrantedAuthoritiesConverter"/>
707- </property>
682+ <property name="jwtGrantedAuthoritiesConverter" ref="jwtGrantedAuthoritiesConverter"/>
683+ </bean>
684+
685+ <bean id="jwtGrantedAuthoritiesConverter"
686+ class="org.springframework.security.oauth2.server.resource.authentication.JwtGrantedAuthoritiesConverter">
687+ <property name="authoritiesClaimName" value="authorities"/>
708688</bean>
709689----
710690====
711691
712- which is responsible for converting a `Jwt` into an `Authentication` .
713- As part of its configuration, we can supply a subsidiary converter to go from `Jwt` to a `Collection` of granted authorities.
692+ You can also configure the authority prefix to be different as well .
693+ Instead of prefixing each authority with `SCOPE_`, you can change it to `ROLE_` like so:
714694
715- That final converter might be something like `GrantedAuthoritiesExtractor` below:
695+ .Authorities Prefix Configuration
696+ ====
697+ .Java
698+ [source,java,role="primary"]
699+ ----
700+ JwtAuthenticationConverter jwtAuthenticationConverter() {
701+ JwtGrantedAuthoritiesConverter grantedAuthoritiesConverter = new JwtGrantedAuthoritiesConverter();
702+ grantedAuthoritiesConverter.setAuthorityPrefix("ROLE_");
716703
717- [source,java]
704+ JwtAuthenticationConverter authenticationConverter = new JwtAuthenticationConverter();
705+ jwtAuthenticationConverter.setJwtGrantedAuthoritiesConverter(authoritiesConverter);
706+ return jwtAuthenticationConverter;
707+ }
718708----
719- static class GrantedAuthoritiesExtractor
720- implements Converter<Jwt, Collection<GrantedAuthority>> {
721709
722- public Collection<GrantedAuthority> convert(Jwt jwt) {
723- Collection<?> authorities = (Collection<?>)
724- jwt.getClaims().getOrDefault("mycustomclaim", Collections.emptyList());
710+ .Xml
711+ [source,xml,role="secondary"]
712+ ----
713+ <http>
714+ <intercept-uri pattern="/contacts/**" access="hasAuthority('SCOPE_contacts')"/>
715+ <intercept-uri pattern="/messages/**" access="hasAuthority('SCOPE_messages')"/>
716+ <oauth2-resource-server>
717+ <jwt jwk-set-uri="https://idp.example.org/.well-known/jwks.json"
718+ jwt-authentication-converter-ref="jwtAuthenticationConverter"/>
719+ </oauth2-resource-server>
720+ </http>
725721
726- return authorities.stream()
727- .map(Object::toString)
728- .map(SimpleGrantedAuthority::new)
729- .collect(Collectors.toList());
730- }
731- }
722+ <bean id="jwtAuthenticationConverter"
723+ class="org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationConverter">
724+ <property name="jwtGrantedAuthoritiesConverter" ref="jwtGrantedAuthoritiesConverter"/>
725+ </bean>
726+
727+ <bean id="jwtGrantedAuthoritiesConverter"
728+ class="org.springframework.security.oauth2.server.resource.authentication.JwtGrantedAuthoritiesConverter">
729+ <property name="authorityPrefix" value="ROLE_"/>
730+ </bean>
732731----
732+ ====
733+
734+ Or, you can remove the prefix altogether by calling `JwtGrantedAuthoritiesConverter#setAuthorityPrefix("")`.
733735
734736For more flexibility, the DSL supports entirely replacing the converter with any class that implements `Converter<Jwt, AbstractAuthenticationToken>`:
735737
0 commit comments