@@ -629,65 +629,42 @@ However, there are a number of circumstances where this default is insufficient.
629
629
For example, some authorization servers don't use the `scope` attribute, but instead have their own custom attribute.
630
630
Or, at other times, the resource server may need to adapt the attribute or a composition of attributes into internalized authorities.
631
631
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`.
633
633
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
635
639
====
636
640
.Java
637
641
[source,java,role="primary"]
638
642
----
639
643
@EnableWebSecurity
640
- public class DirectlyConfiguredJwkSetUri extends WebSecurityConfigurerAdapter {
644
+ public class CustomAuthoritiesClaimName extends WebSecurityConfigurerAdapter {
641
645
protected void configure(HttpSecurity http) {
642
646
http
643
647
.authorizeRequests(authorize -> authorize
644
648
.anyRequest().authenticated()
645
649
)
646
650
.oauth2ResourceServer(oauth2 -> oauth2
647
651
.jwt(jwt -> jwt
648
- .jwtAuthenticationConverter(grantedAuthoritiesExtractor ())
652
+ .jwtAuthenticationConverter(jwtAuthenticationConverter ())
649
653
)
650
654
);
651
655
}
652
656
}
653
657
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");
660
661
662
+ JwtAuthenticationConverter authenticationConverter = new JwtAuthenticationConverter();
663
+ jwtAuthenticationConverter.setJwtGrantedAuthoritiesConverter(authoritiesConverter);
661
664
return jwtAuthenticationConverter;
662
665
}
663
666
----
664
667
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
-
691
668
.Xml
692
669
[source,xml,role="secondary"]
693
670
----
@@ -696,40 +673,65 @@ class DirectlyConfiguredJwkSetUri : WebSecurityConfigurerAdapter() {
696
673
<intercept-uri pattern="/messages/**" access="hasAuthority('SCOPE_messages')"/>
697
674
<oauth2-resource-server>
698
675
<jwt jwk-set-uri="https://idp.example.org/.well-known/jwks.json"
699
- jwt-authentication-converter-ref="grantedAuthoritiesExtractor "/>
676
+ jwt-authentication-converter-ref="jwtAuthenticationConverter "/>
700
677
</oauth2-resource-server>
701
678
</http>
702
679
703
- <bean id="grantedAuthoritiesExtractor "
680
+ <bean id="jwtAuthenticationConverter "
704
681
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"/>
708
688
</bean>
709
689
----
710
690
====
711
691
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:
714
694
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_");
716
703
717
- [source,java]
704
+ JwtAuthenticationConverter authenticationConverter = new JwtAuthenticationConverter();
705
+ jwtAuthenticationConverter.setJwtGrantedAuthoritiesConverter(authoritiesConverter);
706
+ return jwtAuthenticationConverter;
707
+ }
718
708
----
719
- static class GrantedAuthoritiesExtractor
720
- implements Converter<Jwt, Collection<GrantedAuthority>> {
721
709
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>
725
721
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>
732
731
----
732
+ ====
733
+
734
+ Or, you can remove the prefix altogether by calling `JwtGrantedAuthoritiesConverter#setAuthorityPrefix("")`.
733
735
734
736
For more flexibility, the DSL supports entirely replacing the converter with any class that implements `Converter<Jwt, AbstractAuthenticationToken>`:
735
737
0 commit comments