mirror of
https://github.com/spring-projects/spring-security.git
synced 2025-07-12 21:33:30 +00:00
Document new oauth2Login() authority defaults
Issue gh-11887
This commit is contained in:
parent
2063279d89
commit
2a6123a456
@ -2885,6 +2885,196 @@ for (MyEntry entry : entries) {
|
|||||||
|
|
||||||
Please see the reference manual for more information on what xref:features/integrations/cryptography.adoc[encryption mechanisms Spring Security supports].
|
Please see the reference manual for more information on what xref:features/integrations/cryptography.adoc[encryption mechanisms Spring Security supports].
|
||||||
|
|
||||||
|
=== Default authorities for oauth2Login()
|
||||||
|
|
||||||
|
In Spring Security 5, the default `GrantedAuthority` given to a user that authenticates with an OAuth2 or OpenID Connect 1.0 provider (via `oauth2Login()`) is `ROLE_USER`.
|
||||||
|
|
||||||
|
[NOTE]
|
||||||
|
====
|
||||||
|
See xref:servlet/oauth2/login/advanced.adoc#oauth2login-advanced-map-authorities[Mapping User Authorities] for more information.
|
||||||
|
====
|
||||||
|
|
||||||
|
In Spring Security 6, the default authority given to a user authenticating with an OAuth2 provider is `OAUTH2_USER`.
|
||||||
|
The default authority given to a user authenticating with an OpenID Connect 1.0 provider is `OIDC_USER`.
|
||||||
|
These defaults allow clearer distinction of users that have authenticated with an OAuth2 or OpenID Connect 1.0 provider.
|
||||||
|
|
||||||
|
If you are using authorization rules or expressions such as `hasRole("USER")` or `hasAuthority("ROLE_USER")` to authorize users with this specific authority, the new defaults in Spring Security 6 will impact your application.
|
||||||
|
|
||||||
|
To opt into the new Spring Security 6 defaults, the following configuration can be used.
|
||||||
|
|
||||||
|
.Configure oauth2Login() with 6.0 defaults
|
||||||
|
====
|
||||||
|
.Java
|
||||||
|
[source,java,role="primary"]
|
||||||
|
----
|
||||||
|
@Bean
|
||||||
|
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
|
||||||
|
http
|
||||||
|
// ...
|
||||||
|
.oauth2Login((oauth2Login) -> oauth2Login
|
||||||
|
.userInfoEndpoint((userInfo) -> userInfo
|
||||||
|
.userAuthoritiesMapper(grantedAuthoritiesMapper())
|
||||||
|
)
|
||||||
|
);
|
||||||
|
return http.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
private GrantedAuthoritiesMapper grantedAuthoritiesMapper() {
|
||||||
|
return (authorities) -> {
|
||||||
|
Set<GrantedAuthority> mappedAuthorities = new HashSet<>();
|
||||||
|
|
||||||
|
authorities.forEach((authority) -> {
|
||||||
|
GrantedAuthority mappedAuthority;
|
||||||
|
|
||||||
|
if (authority instanceof OidcUserAuthority) {
|
||||||
|
OidcUserAuthority userAuthority = (OidcUserAuthority) authority;
|
||||||
|
mappedAuthority = new OidcUserAuthority(
|
||||||
|
"OIDC_USER", userAuthority.getIdToken(), userAuthority.getUserInfo());
|
||||||
|
} else if (authority instanceof OAuth2UserAuthority) {
|
||||||
|
OAuth2UserAuthority userAuthority = (OAuth2UserAuthority) authority;
|
||||||
|
mappedAuthority = new OAuth2UserAuthority(
|
||||||
|
"OAUTH2_USER", userAuthority.getAttributes());
|
||||||
|
} else {
|
||||||
|
mappedAuthority = authority;
|
||||||
|
}
|
||||||
|
|
||||||
|
mappedAuthorities.add(mappedAuthority);
|
||||||
|
});
|
||||||
|
|
||||||
|
return mappedAuthorities;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
----
|
||||||
|
|
||||||
|
.Kotlin
|
||||||
|
[source,kotlin,role="secondary"]
|
||||||
|
----
|
||||||
|
@Bean
|
||||||
|
fun securityFilterChain(http: HttpSecurity): SecurityFilterChain {
|
||||||
|
http {
|
||||||
|
// ...
|
||||||
|
oauth2Login {
|
||||||
|
userInfoEndpoint {
|
||||||
|
userAuthoritiesMapper = grantedAuthoritiesMapper()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return http.build()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun grantedAuthoritiesMapper(): GrantedAuthoritiesMapper {
|
||||||
|
return GrantedAuthoritiesMapper { authorities ->
|
||||||
|
authorities.map { authority ->
|
||||||
|
when (authority) {
|
||||||
|
is OidcUserAuthority ->
|
||||||
|
OidcUserAuthority("OIDC_USER", authority.idToken, authority.userInfo)
|
||||||
|
is OAuth2UserAuthority ->
|
||||||
|
OAuth2UserAuthority("OAUTH2_USER", authority.attributes)
|
||||||
|
else -> authority
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
----
|
||||||
|
|
||||||
|
.XML
|
||||||
|
[source,xml,role="secondary"]
|
||||||
|
----
|
||||||
|
<http>
|
||||||
|
<oauth2-login user-authorities-mapper-ref="userAuthoritiesMapper" ... />
|
||||||
|
</http>
|
||||||
|
----
|
||||||
|
====
|
||||||
|
|
||||||
|
[[servlet-oauth2-login-authorities-opt-out]]
|
||||||
|
==== Opt-out Steps
|
||||||
|
|
||||||
|
If configuring the new authorities gives you trouble, you can opt out and explicitly use the 5.8 authority of `ROLE_USER` with the following configuration.
|
||||||
|
|
||||||
|
.Configure oauth2Login() with 5.8 defaults
|
||||||
|
====
|
||||||
|
.Java
|
||||||
|
[source,java,role="primary"]
|
||||||
|
----
|
||||||
|
@Bean
|
||||||
|
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
|
||||||
|
http
|
||||||
|
// ...
|
||||||
|
.oauth2Login((oauth2Login) -> oauth2Login
|
||||||
|
.userInfoEndpoint((userInfo) -> userInfo
|
||||||
|
.userAuthoritiesMapper(grantedAuthoritiesMapper())
|
||||||
|
)
|
||||||
|
);
|
||||||
|
return http.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
private GrantedAuthoritiesMapper grantedAuthoritiesMapper() {
|
||||||
|
return (authorities) -> {
|
||||||
|
Set<GrantedAuthority> mappedAuthorities = new HashSet<>();
|
||||||
|
|
||||||
|
authorities.forEach((authority) -> {
|
||||||
|
GrantedAuthority mappedAuthority;
|
||||||
|
|
||||||
|
if (authority instanceof OidcUserAuthority) {
|
||||||
|
OidcUserAuthority userAuthority = (OidcUserAuthority) authority;
|
||||||
|
mappedAuthority = new OidcUserAuthority(
|
||||||
|
"ROLE_USER", userAuthority.getIdToken(), userAuthority.getUserInfo());
|
||||||
|
} else if (authority instanceof OAuth2UserAuthority) {
|
||||||
|
OAuth2UserAuthority userAuthority = (OAuth2UserAuthority) authority;
|
||||||
|
mappedAuthority = new OAuth2UserAuthority(
|
||||||
|
"ROLE_USER", userAuthority.getAttributes());
|
||||||
|
} else {
|
||||||
|
mappedAuthority = authority;
|
||||||
|
}
|
||||||
|
|
||||||
|
mappedAuthorities.add(mappedAuthority);
|
||||||
|
});
|
||||||
|
|
||||||
|
return mappedAuthorities;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
----
|
||||||
|
|
||||||
|
.Kotlin
|
||||||
|
[source,kotlin,role="secondary"]
|
||||||
|
----
|
||||||
|
@Bean
|
||||||
|
fun securityFilterChain(http: HttpSecurity): SecurityFilterChain {
|
||||||
|
http {
|
||||||
|
// ...
|
||||||
|
oauth2Login {
|
||||||
|
userInfoEndpoint {
|
||||||
|
userAuthoritiesMapper = grantedAuthoritiesMapper()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return http.build()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun grantedAuthoritiesMapper(): GrantedAuthoritiesMapper {
|
||||||
|
return GrantedAuthoritiesMapper { authorities ->
|
||||||
|
authorities.map { authority ->
|
||||||
|
when (authority) {
|
||||||
|
is OidcUserAuthority ->
|
||||||
|
OidcUserAuthority("ROLE_USER", authority.idToken, authority.userInfo)
|
||||||
|
is OAuth2UserAuthority ->
|
||||||
|
OAuth2UserAuthority("ROLE_USER", authority.attributes)
|
||||||
|
else -> authority
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
----
|
||||||
|
|
||||||
|
.XML
|
||||||
|
[source,xml,role="secondary"]
|
||||||
|
----
|
||||||
|
<http>
|
||||||
|
<oauth2-login user-authorities-mapper-ref="userAuthoritiesMapper" ... />
|
||||||
|
</http>
|
||||||
|
----
|
||||||
|
====
|
||||||
|
|
||||||
== Reactive
|
== Reactive
|
||||||
|
|
||||||
=== Use `AuthorizationManager` for Method Security
|
=== Use `AuthorizationManager` for Method Security
|
||||||
|
Loading…
x
Reference in New Issue
Block a user