From 1ebb73856b070706efae25d9043634c33850bab0 Mon Sep 17 00:00:00 2001 From: Josh Cummings Date: Tue, 24 Mar 2020 14:38:12 -0600 Subject: [PATCH] Document JwtGrantedAuthoritiesConverter Features Fixes gh-8176 --- .../servlet/oauth2/oauth2-resourceserver.adoc | 116 +++++++++--------- 1 file changed, 59 insertions(+), 57 deletions(-) diff --git a/docs/manual/src/docs/asciidoc/_includes/servlet/oauth2/oauth2-resourceserver.adoc b/docs/manual/src/docs/asciidoc/_includes/servlet/oauth2/oauth2-resourceserver.adoc index ae338e60e0..3db8fbdbf1 100644 --- a/docs/manual/src/docs/asciidoc/_includes/servlet/oauth2/oauth2-resourceserver.adoc +++ b/docs/manual/src/docs/asciidoc/_includes/servlet/oauth2/oauth2-resourceserver.adoc @@ -629,15 +629,19 @@ However, there are a number of circumstances where this default is insufficient. For example, some authorization servers don't use the `scope` attribute, but instead have their own custom attribute. Or, at other times, the resource server may need to adapt the attribute or a composition of attributes into internalized authorities. -To this end, the DSL exposes `jwtAuthenticationConverter()`: +To this end, the DSL exposes `jwtAuthenticationConverter()`, which is responsible for converting a `Jwt` into an `Authentication`. -.Authorities Extractor Configuration +As part of its configuration, we can supply a subsidiary converter to go from `Jwt` to a `Collection` of granted authorities. +Let's say that that your authorization server communicates authorities in a custom claim called `authorities`. +In that case, you can configure the claim that `JwtAuthenticationConverter` should inspect, like so: + +.Authorities Claim Configuration ==== .Java [source,java,role="primary"] ---- @EnableWebSecurity -public class DirectlyConfiguredJwkSetUri extends WebSecurityConfigurerAdapter { +public class CustomAuthoritiesClaimName extends WebSecurityConfigurerAdapter { protected void configure(HttpSecurity http) { http .authorizeRequests(authorize -> authorize @@ -645,49 +649,22 @@ public class DirectlyConfiguredJwkSetUri extends WebSecurityConfigurerAdapter { ) .oauth2ResourceServer(oauth2 -> oauth2 .jwt(jwt -> jwt - .jwtAuthenticationConverter(grantedAuthoritiesExtractor()) + .jwtAuthenticationConverter(jwtAuthenticationConverter()) ) ); } } -Converter grantedAuthoritiesExtractor() { - JwtAuthenticationConverter jwtAuthenticationConverter = - new JwtAuthenticationConverter(); - - jwtAuthenticationConverter.setJwtGrantedAuthoritiesConverter - (new GrantedAuthoritiesExtractor()); +JwtAuthenticationConverter jwtAuthenticationConverter() { + JwtGrantedAuthoritiesConverter grantedAuthoritiesConverter = new JwtGrantedAuthoritiesConverter(); + grantedAuthoritiesConverter.setAuthoritiesClaimName("authorities"); + JwtAuthenticationConverter authenticationConverter = new JwtAuthenticationConverter(); + jwtAuthenticationConverter.setJwtGrantedAuthoritiesConverter(authoritiesConverter); return jwtAuthenticationConverter; } ---- -.Kotlin -[source,kotlin,role="secondary"] ----- -@EnableWebSecurity -class DirectlyConfiguredJwkSetUri : WebSecurityConfigurerAdapter() { - override fun configure(http: HttpSecurity) { - http { - authorizeRequests { - authorize(anyRequest, authenticated) - } - oauth2ResourceServer { - jwt { - jwtAuthenticationConverter = grantedAuthoritiesExtractor() - } - } - } - } - - private fun grantedAuthoritiesExtractor(): JwtAuthenticationConverter { - val jwtAuthenticationConverter = JwtAuthenticationConverter() - jwtAuthenticationConverter.setJwtGrantedAuthoritiesConverter(GrantedAuthoritiesExtractor()) - return jwtAuthenticationConverter - } -} ----- - .Xml [source,xml,role="secondary"] ---- @@ -696,41 +673,66 @@ class DirectlyConfiguredJwkSetUri : WebSecurityConfigurerAdapter() { + jwt-authentication-converter-ref="jwtAuthenticationConverter"/> - - - - + + + + + ---- ==== -which is responsible for converting a `Jwt` into an `Authentication`. -As part of its configuration, we can supply a subsidiary converter to go from `Jwt` to a `Collection` of granted authorities. +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: -That final converter might be something like `GrantedAuthoritiesExtractor` below: - -[source,java] +.Authorities Prefix Configuration +==== +.Java +[source,java,role="primary"] ---- -static class GrantedAuthoritiesExtractor - implements Converter> { +JwtAuthenticationConverter jwtAuthenticationConverter() { + JwtGrantedAuthoritiesConverter grantedAuthoritiesConverter = new JwtGrantedAuthoritiesConverter(); + grantedAuthoritiesConverter.setAuthorityPrefix("ROLE_"); - public Collection convert(Jwt jwt) { - Collection authorities = (Collection) - jwt.getClaims().getOrDefault("mycustomclaim", Collections.emptyList()); - - return authorities.stream() - .map(Object::toString) - .map(SimpleGrantedAuthority::new) - .collect(Collectors.toList()); - } + JwtAuthenticationConverter authenticationConverter = new JwtAuthenticationConverter(); + jwtAuthenticationConverter.setJwtGrantedAuthoritiesConverter(authoritiesConverter); + return jwtAuthenticationConverter; } ---- +.Xml +[source,xml,role="secondary"] +---- + + + + + + + + + + + + + + + +---- +==== + +Or, you can remove the prefix altogether by calling `JwtGrantedAuthoritiesConverter#setAuthorityPrefix("")`. + For more flexibility, the DSL supports entirely replacing the converter with any class that implements `Converter`: [source,java]