diff --git a/config/src/test/java/org/springframework/security/config/annotation/web/configurers/oauth2/client/OAuth2LoginConfigurerTests.java b/config/src/test/java/org/springframework/security/config/annotation/web/configurers/oauth2/client/OAuth2LoginConfigurerTests.java index 25f2b04b2f..1facc1f7eb 100644 --- a/config/src/test/java/org/springframework/security/config/annotation/web/configurers/oauth2/client/OAuth2LoginConfigurerTests.java +++ b/config/src/test/java/org/springframework/security/config/annotation/web/configurers/oauth2/client/OAuth2LoginConfigurerTests.java @@ -193,7 +193,7 @@ public class OAuth2LoginConfigurerTests { .loadContext(new HttpRequestResponseHolder(this.request, this.response)).getAuthentication(); assertThat(authentication.getAuthorities()).hasSize(1); assertThat(authentication.getAuthorities()).first().isInstanceOf(OAuth2UserAuthority.class) - .hasToString("ROLE_USER"); + .hasToString("OAUTH2_USER"); } @Test @@ -208,7 +208,7 @@ public class OAuth2LoginConfigurerTests { .loadContext(new HttpRequestResponseHolder(this.request, this.response)).getAuthentication(); assertThat(authentication.getAuthorities()).hasSize(1); assertThat(authentication.getAuthorities()).first().isInstanceOf(OAuth2UserAuthority.class) - .hasToString("ROLE_USER"); + .hasToString("OAUTH2_USER"); } // gh-6009 @@ -246,7 +246,7 @@ public class OAuth2LoginConfigurerTests { Authentication authentication = this.securityContextRepository .loadContext(new HttpRequestResponseHolder(this.request, this.response)).getAuthentication(); assertThat(authentication.getAuthorities()).hasSize(2); - assertThat(authentication.getAuthorities()).first().hasToString("ROLE_USER"); + assertThat(authentication.getAuthorities()).first().hasToString("OAUTH2_USER"); assertThat(authentication.getAuthorities()).last().hasToString("ROLE_OAUTH2_USER"); } @@ -266,7 +266,7 @@ public class OAuth2LoginConfigurerTests { Authentication authentication = this.securityContextRepository .loadContext(new HttpRequestResponseHolder(this.request, this.response)).getAuthentication(); assertThat(authentication.getAuthorities()).hasSize(2); - assertThat(authentication.getAuthorities()).first().hasToString("ROLE_USER"); + assertThat(authentication.getAuthorities()).first().hasToString("OAUTH2_USER"); assertThat(authentication.getAuthorities()).last().hasToString("ROLE_OAUTH2_USER"); } @@ -286,7 +286,7 @@ public class OAuth2LoginConfigurerTests { Authentication authentication = this.securityContextRepository .loadContext(new HttpRequestResponseHolder(this.request, this.response)).getAuthentication(); assertThat(authentication.getAuthorities()).hasSize(2); - assertThat(authentication.getAuthorities()).first().hasToString("ROLE_USER"); + assertThat(authentication.getAuthorities()).first().hasToString("OAUTH2_USER"); assertThat(authentication.getAuthorities()).last().hasToString("ROLE_OAUTH2_USER"); } @@ -309,7 +309,7 @@ public class OAuth2LoginConfigurerTests { .loadContext(new HttpRequestResponseHolder(this.request, this.response)).getAuthentication(); assertThat(authentication.getAuthorities()).hasSize(1); assertThat(authentication.getAuthorities()).first().isInstanceOf(OAuth2UserAuthority.class) - .hasToString("ROLE_USER"); + .hasToString("OAUTH2_USER"); } // gh-5521 @@ -518,7 +518,7 @@ public class OAuth2LoginConfigurerTests { .loadContext(new HttpRequestResponseHolder(this.request, this.response)).getAuthentication(); assertThat(authentication.getAuthorities()).hasSize(1); assertThat(authentication.getAuthorities()).first().isInstanceOf(OidcUserAuthority.class) - .hasToString("ROLE_USER"); + .hasToString("OIDC_USER"); } @Test @@ -538,7 +538,7 @@ public class OAuth2LoginConfigurerTests { .loadContext(new HttpRequestResponseHolder(this.request, this.response)).getAuthentication(); assertThat(authentication.getAuthorities()).hasSize(1); assertThat(authentication.getAuthorities()).first().isInstanceOf(OidcUserAuthority.class) - .hasToString("ROLE_USER"); + .hasToString("OIDC_USER"); } @Test @@ -557,7 +557,7 @@ public class OAuth2LoginConfigurerTests { Authentication authentication = this.securityContextRepository .loadContext(new HttpRequestResponseHolder(this.request, this.response)).getAuthentication(); assertThat(authentication.getAuthorities()).hasSize(2); - assertThat(authentication.getAuthorities()).first().hasToString("ROLE_USER"); + assertThat(authentication.getAuthorities()).first().hasToString("OIDC_USER"); assertThat(authentication.getAuthorities()).last().hasToString("ROLE_OIDC_USER"); } @@ -577,7 +577,7 @@ public class OAuth2LoginConfigurerTests { Authentication authentication = this.securityContextRepository .loadContext(new HttpRequestResponseHolder(this.request, this.response)).getAuthentication(); assertThat(authentication.getAuthorities()).hasSize(2); - assertThat(authentication.getAuthorities()).first().hasToString("ROLE_USER"); + assertThat(authentication.getAuthorities()).first().hasToString("OIDC_USER"); assertThat(authentication.getAuthorities()).last().hasToString("ROLE_OIDC_USER"); } diff --git a/docs/modules/ROOT/pages/reactive/oauth2/login/advanced.adoc b/docs/modules/ROOT/pages/reactive/oauth2/login/advanced.adoc index 71f902cb91..e137091580 100644 --- a/docs/modules/ROOT/pages/reactive/oauth2/login/advanced.adoc +++ b/docs/modules/ROOT/pages/reactive/oauth2/login/advanced.adoc @@ -302,7 +302,8 @@ The UserInfo Endpoint includes a number of configuration options, as described i [[webflux-oauth2-login-advanced-map-authorities]] === Mapping User Authorities -After the user successfully authenticates with the OAuth 2.0 Provider, the `OAuth2User.getAuthorities()` (or `OidcUser.getAuthorities()`) may be mapped to a new set of `GrantedAuthority` instances, which will be supplied to `OAuth2AuthenticationToken` when completing the authentication. +After the user successfully authenticates with the OAuth 2.0 Provider, the `OAuth2User.getAuthorities()` (or `OidcUser.getAuthorities()`) contains a list of granted authorities populated from `OAuth2UserRequest.getAccessToken().getScopes()` and prefixed with `SCOPE_`. +These granted authorities may be mapped to a new set of `GrantedAuthority` instances, which will be supplied to `OAuth2AuthenticationToken` when completing the authentication. [TIP] `OAuth2AuthenticationToken.getAuthorities()` is used for authorizing requests, such as in `hasRole('USER')` or `hasRole('ADMIN')`. @@ -316,6 +317,8 @@ There are a couple of options to choose from when mapping user authorities: [[webflux-oauth2-login-advanced-map-authorities-grantedauthoritiesmapper]] ==== Using a GrantedAuthoritiesMapper +The `GrantedAuthoritiesMapper` is given a list of granted authorities which contains a special authority of type `OAuth2UserAuthority` and the authority string `OAUTH2_USER` (or `OidcUserAuthority` and the authority string `OIDC_USER`). + Register a `GrantedAuthoritiesMapper` `@Bean` to have it automatically applied to the configuration, as shown in the following example: .Granted Authorities Mapper Configuration diff --git a/docs/modules/ROOT/pages/servlet/oauth2/login/advanced.adoc b/docs/modules/ROOT/pages/servlet/oauth2/login/advanced.adoc index 14daff74de..61afc9153c 100644 --- a/docs/modules/ROOT/pages/servlet/oauth2/login/advanced.adoc +++ b/docs/modules/ROOT/pages/servlet/oauth2/login/advanced.adoc @@ -425,7 +425,8 @@ The UserInfo Endpoint includes a number of configuration options, as described i [[oauth2login-advanced-map-authorities]] === Mapping User Authorities -After the user successfully authenticates with the OAuth 2.0 Provider, the `OAuth2User.getAuthorities()` (or `OidcUser.getAuthorities()`) can be mapped to a new set of `GrantedAuthority` instances, which are supplied to `OAuth2AuthenticationToken` when completing the authentication. +After the user successfully authenticates with the OAuth 2.0 Provider, the `OAuth2User.getAuthorities()` (or `OidcUser.getAuthorities()`) contains a list of granted authorities populated from `OAuth2UserRequest.getAccessToken().getScopes()` and prefixed with `SCOPE_`. +These granted authorities can be mapped to a new set of `GrantedAuthority` instances, which are supplied to `OAuth2AuthenticationToken` when completing the authentication. [TIP] `OAuth2AuthenticationToken.getAuthorities()` is used for authorizing requests, such as in `hasRole('USER')` or `hasRole('ADMIN')`. @@ -439,6 +440,8 @@ There are a couple of options to choose from when mapping user authorities: [[oauth2login-advanced-map-authorities-grantedauthoritiesmapper]] ==== Using a GrantedAuthoritiesMapper +The `GrantedAuthoritiesMapper` is given a list of granted authorities which contains a special authority of type `OAuth2UserAuthority` and the authority string `OAUTH2_USER` (or `OidcUserAuthority` and the authority string `OIDC_USER`). + Provide an implementation of `GrantedAuthoritiesMapper` and configure it, as follows: .Granted Authorities Mapper Configuration diff --git a/oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/oidc/userinfo/OidcReactiveOAuth2UserServiceTests.java b/oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/oidc/userinfo/OidcReactiveOAuth2UserServiceTests.java index 5ed86f86ba..90859bda89 100644 --- a/oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/oidc/userinfo/OidcReactiveOAuth2UserServiceTests.java +++ b/oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/oidc/userinfo/OidcReactiveOAuth2UserServiceTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2022 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. @@ -198,6 +198,9 @@ public class OidcReactiveOAuth2UserServiceTests { assertThat(user.getAuthorities()).hasSize(1); Iterator authorities = user.getAuthorities().iterator(); assertThat(authorities.next()).isInstanceOf(OAuth2UserAuthority.class); + OAuth2UserAuthority userAuthority = (OAuth2UserAuthority) user.getAuthorities().iterator().next(); + assertThat(userAuthority.getAuthority()).isEqualTo("OIDC_USER"); + assertThat(userAuthority.getAttributes()).isEqualTo(user.getAttributes()); } private OidcUserRequest userRequest() { diff --git a/oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/oidc/userinfo/OidcUserServiceTests.java b/oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/oidc/userinfo/OidcUserServiceTests.java index 152f77295a..f06c5cc821 100644 --- a/oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/oidc/userinfo/OidcUserServiceTests.java +++ b/oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/oidc/userinfo/OidcUserServiceTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2022 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. @@ -246,7 +246,7 @@ public class OidcUserServiceTests { assertThat(user.getAuthorities().size()).isEqualTo(3); assertThat(user.getAuthorities().iterator().next()).isInstanceOf(OidcUserAuthority.class); OidcUserAuthority userAuthority = (OidcUserAuthority) user.getAuthorities().iterator().next(); - assertThat(userAuthority.getAuthority()).isEqualTo("ROLE_USER"); + assertThat(userAuthority.getAuthority()).isEqualTo("OIDC_USER"); assertThat(userAuthority.getIdToken()).isEqualTo(user.getIdToken()); assertThat(userAuthority.getUserInfo()).isEqualTo(user.getUserInfo()); } diff --git a/oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/userinfo/DefaultOAuth2UserServiceTests.java b/oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/userinfo/DefaultOAuth2UserServiceTests.java index 49e2a3c5c7..f8e29740ab 100644 --- a/oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/userinfo/DefaultOAuth2UserServiceTests.java +++ b/oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/userinfo/DefaultOAuth2UserServiceTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2022 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. @@ -154,7 +154,7 @@ public class DefaultOAuth2UserServiceTests { assertThat(user.getAuthorities().size()).isEqualTo(1); assertThat(user.getAuthorities().iterator().next()).isInstanceOf(OAuth2UserAuthority.class); OAuth2UserAuthority userAuthority = (OAuth2UserAuthority) user.getAuthorities().iterator().next(); - assertThat(userAuthority.getAuthority()).isEqualTo("ROLE_USER"); + assertThat(userAuthority.getAuthority()).isEqualTo("OAUTH2_USER"); assertThat(userAuthority.getAttributes()).isEqualTo(user.getAttributes()); } diff --git a/oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/userinfo/DefaultReactiveOAuth2UserServiceTests.java b/oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/userinfo/DefaultReactiveOAuth2UserServiceTests.java index 1a215ca8b6..f8cfb57028 100644 --- a/oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/userinfo/DefaultReactiveOAuth2UserServiceTests.java +++ b/oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/userinfo/DefaultReactiveOAuth2UserServiceTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2021 the original author or authors. + * Copyright 2002-2022 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. @@ -141,7 +141,7 @@ public class DefaultReactiveOAuth2UserServiceTests { assertThat(user.getAuthorities().size()).isEqualTo(1); assertThat(user.getAuthorities().iterator().next()).isInstanceOf(OAuth2UserAuthority.class); OAuth2UserAuthority userAuthority = (OAuth2UserAuthority) user.getAuthorities().iterator().next(); - assertThat(userAuthority.getAuthority()).isEqualTo("ROLE_USER"); + assertThat(userAuthority.getAuthority()).isEqualTo("OAUTH2_USER"); assertThat(userAuthority.getAttributes()).isEqualTo(user.getAttributes()); } diff --git a/oauth2/oauth2-core/src/main/java/org/springframework/security/oauth2/core/oidc/user/OidcUserAuthority.java b/oauth2/oauth2-core/src/main/java/org/springframework/security/oauth2/core/oidc/user/OidcUserAuthority.java index 73bcdf624d..31920772c7 100644 --- a/oauth2/oauth2-core/src/main/java/org/springframework/security/oauth2/core/oidc/user/OidcUserAuthority.java +++ b/oauth2/oauth2-core/src/main/java/org/springframework/security/oauth2/core/oidc/user/OidcUserAuthority.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2022 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. @@ -48,13 +48,13 @@ public class OidcUserAuthority extends OAuth2UserAuthority { /** * Constructs a {@code OidcUserAuthority} using the provided parameters and defaults - * {@link #getAuthority()} to {@code ROLE_USER}. + * {@link #getAuthority()} to {@code OIDC_USER}. * @param idToken the {@link OidcIdToken ID Token} containing claims about the user * @param userInfo the {@link OidcUserInfo UserInfo} containing claims about the user, * may be {@code null} */ public OidcUserAuthority(OidcIdToken idToken, OidcUserInfo userInfo) { - this("ROLE_USER", idToken, userInfo); + this("OIDC_USER", idToken, userInfo); } /** diff --git a/oauth2/oauth2-core/src/main/java/org/springframework/security/oauth2/core/user/OAuth2UserAuthority.java b/oauth2/oauth2-core/src/main/java/org/springframework/security/oauth2/core/user/OAuth2UserAuthority.java index 425e17e1f7..0182a72e31 100644 --- a/oauth2/oauth2-core/src/main/java/org/springframework/security/oauth2/core/user/OAuth2UserAuthority.java +++ b/oauth2/oauth2-core/src/main/java/org/springframework/security/oauth2/core/user/OAuth2UserAuthority.java @@ -43,11 +43,11 @@ public class OAuth2UserAuthority implements GrantedAuthority { /** * Constructs a {@code OAuth2UserAuthority} using the provided parameters and defaults - * {@link #getAuthority()} to {@code ROLE_USER}. + * {@link #getAuthority()} to {@code OAUTH2_USER}. * @param attributes the attributes about the user */ public OAuth2UserAuthority(Map attributes) { - this("ROLE_USER", attributes); + this("OAUTH2_USER", attributes); } /**