1
0
mirror of synced 2026-05-22 21:33:16 +00:00

Add GrantedAuthorities.FACTOR_*_AUTHORITY

Closes gh-17952
This commit is contained in:
Rob Winch
2025-09-24 08:42:43 -05:00
parent 28aad8855c
commit b2d76dfe66
57 changed files with 227 additions and 81 deletions
@@ -21,6 +21,7 @@ import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.HttpSecurityBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.core.GrantedAuthorities;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.authentication.ForwardAuthenticationFailureHandler;
import org.springframework.security.web.authentication.ForwardAuthenticationSuccessHandler;
@@ -236,7 +237,7 @@ public final class FormLoginConfigurer<H extends HttpSecurityBuilder<H>> extends
AuthenticationEntryPoint entryPoint = getAuthenticationEntryPoint();
RequestMatcher requestMatcher = getAuthenticationEntryPointMatcher(http);
exceptions.defaultDeniedHandlerForMissingAuthority((ep) -> ep.addEntryPointFor(entryPoint, requestMatcher),
"FACTOR_PASSWORD");
GrantedAuthorities.FACTOR_PASSWORD_AUTHORITY);
}
}
@@ -28,6 +28,7 @@ import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.HttpSecurityBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.core.GrantedAuthorities;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.authentication.DelegatingAuthenticationEntryPoint;
import org.springframework.security.web.authentication.HttpStatusEntryPoint;
@@ -195,7 +196,8 @@ public final class HttpBasicConfigurer<B extends HttpSecurityBuilder<B>>
AuthenticationEntryPoint entryPoint = postProcess(this.authenticationEntryPoint);
exceptionHandling.defaultAuthenticationEntryPointFor(entryPoint, preferredMatcher);
exceptionHandling.defaultDeniedHandlerForMissingAuthority(
(ep) -> ep.addEntryPointFor(entryPoint, preferredMatcher), "FACTOR_PASSWORD");
(ep) -> ep.addEntryPointFor(entryPoint, preferredMatcher),
GrantedAuthorities.FACTOR_PASSWORD_AUTHORITY);
}
private void registerDefaultLogoutSuccessHandler(B http, RequestMatcher preferredMatcher) {
@@ -26,6 +26,7 @@ import org.springframework.context.ApplicationContext;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.security.authentication.ProviderManager;
import org.springframework.security.config.annotation.web.HttpSecurityBuilder;
import org.springframework.security.core.GrantedAuthorities;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.access.intercept.AuthorizationFilter;
@@ -159,7 +160,8 @@ public class WebAuthnConfigurer<H extends HttpSecurityBuilder<H>>
if (exceptions != null) {
AuthenticationEntryPoint entryPoint = new LoginUrlAuthenticationEntryPoint("/login");
exceptions.defaultDeniedHandlerForMissingAuthority(
(ep) -> ep.addEntryPointFor(entryPoint, AnyRequestMatcher.INSTANCE), "FACTOR_WEBAUTHN");
(ep) -> ep.addEntryPointFor(entryPoint, AnyRequestMatcher.INSTANCE),
GrantedAuthorities.FACTOR_WEBAUTHN_AUTHORITY);
}
}
@@ -25,6 +25,7 @@ import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.HttpSecurityBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthorities;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.AuthenticationUserDetailsService;
import org.springframework.security.core.userdetails.UserDetailsByNameServiceWrapper;
@@ -179,14 +180,16 @@ public final class X509Configurer<H extends HttpSecurityBuilder<H>>
public void init(H http) {
PreAuthenticatedAuthenticationProvider authenticationProvider = new PreAuthenticatedAuthenticationProvider();
authenticationProvider.setPreAuthenticatedUserDetailsService(getAuthenticationUserDetailsService(http));
authenticationProvider.setGrantedAuthoritySupplier(() -> AuthorityUtils.createAuthorityList("FACTOR_X509"));
authenticationProvider.setGrantedAuthoritySupplier(
() -> AuthorityUtils.createAuthorityList(GrantedAuthorities.FACTOR_X509_AUTHORITY));
http.authenticationProvider(authenticationProvider)
.setSharedObject(AuthenticationEntryPoint.class, new Http403ForbiddenEntryPoint());
ExceptionHandlingConfigurer<H> exceptions = http.getConfigurer(ExceptionHandlingConfigurer.class);
if (exceptions != null) {
AuthenticationEntryPoint forbidden = new Http403ForbiddenEntryPoint();
exceptions.defaultDeniedHandlerForMissingAuthority(
(ep) -> ep.addEntryPointFor(forbidden, AnyRequestMatcher.INSTANCE), "FACTOR_X509");
(ep) -> ep.addEntryPointFor(forbidden, AnyRequestMatcher.INSTANCE),
GrantedAuthorities.FACTOR_X509_AUTHORITY);
}
}
@@ -45,6 +45,7 @@ import org.springframework.security.config.annotation.web.configurers.SessionMan
import org.springframework.security.context.DelegatingApplicationListener;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthorities;
import org.springframework.security.core.authority.mapping.GrantedAuthoritiesMapper;
import org.springframework.security.core.session.AbstractSessionEvent;
import org.springframework.security.core.session.SessionDestroyedEvent;
@@ -566,7 +567,8 @@ public final class OAuth2LoginConfigurer<B extends HttpSecurityBuilder<B>>
if (exceptions != null) {
RequestMatcher requestMatcher = getAuthenticationEntryPointMatcher(http);
exceptions.defaultDeniedHandlerForMissingAuthority(
(ep) -> ep.addEntryPointFor(loginEntryPoint, requestMatcher), "FACTOR_AUTHORIZATION_CODE");
(ep) -> ep.addEntryPointFor(loginEntryPoint, requestMatcher),
GrantedAuthorities.FACTOR_AUTHORIZATION_CODE_AUTHORITY);
}
return loginEntryPoint;
}
@@ -38,6 +38,7 @@ import org.springframework.security.config.annotation.web.configurers.CsrfConfig
import org.springframework.security.config.annotation.web.configurers.ExceptionHandlingConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthorities;
import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
import org.springframework.security.oauth2.jwt.Jwt;
import org.springframework.security.oauth2.jwt.JwtDecoder;
@@ -328,7 +329,8 @@ public final class OAuth2ResourceServerConfigurer<H extends HttpSecurityBuilder<
Arrays.asList(this.requestMatcher, X_REQUESTED_WITH, restNotHtmlMatcher, allMatcher));
exceptionHandling.defaultAuthenticationEntryPointFor(this.authenticationEntryPoint, preferredMatcher);
exceptionHandling.defaultDeniedHandlerForMissingAuthority(
(ep) -> ep.addEntryPointFor(this.authenticationEntryPoint, preferredMatcher), "FACTOR_BEARER");
(ep) -> ep.addEntryPointFor(this.authenticationEntryPoint, preferredMatcher),
GrantedAuthorities.FACTOR_BEARER_AUTHORITY);
}
}
@@ -37,6 +37,7 @@ import org.springframework.security.config.annotation.web.configurers.AbstractAu
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.config.annotation.web.configurers.ExceptionHandlingConfigurer;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthorities;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.authentication.AuthenticationConverter;
@@ -141,7 +142,7 @@ public final class OneTimeTokenLoginConfigurer<H extends HttpSecurityBuilder<H>>
AuthenticationEntryPoint entryPoint = getAuthenticationEntryPoint();
RequestMatcher requestMatcher = getAuthenticationEntryPointMatcher(http);
exceptions.defaultDeniedHandlerForMissingAuthority((ep) -> ep.addEntryPointFor(entryPoint, requestMatcher),
"FACTOR_OTT");
GrantedAuthorities.FACTOR_OTT_AUTHORITY);
}
}
@@ -35,6 +35,7 @@ import org.springframework.security.config.annotation.web.configurers.AbstractHt
import org.springframework.security.config.annotation.web.configurers.CsrfConfigurer;
import org.springframework.security.config.annotation.web.configurers.ExceptionHandlingConfigurer;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthorities;
import org.springframework.security.saml2.provider.service.authentication.AbstractSaml2AuthenticationRequest;
import org.springframework.security.saml2.provider.service.authentication.OpenSaml5AuthenticationProvider;
import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistration;
@@ -353,7 +354,8 @@ public final class Saml2LoginConfigurer<B extends HttpSecurityBuilder<B>>
if (exceptions != null) {
RequestMatcher requestMatcher = getAuthenticationEntryPointMatcher(http);
exceptions.defaultDeniedHandlerForMissingAuthority(
(ep) -> ep.addEntryPointFor(loginEntryPoint, requestMatcher), "FACTOR_SAML_RESPONSE");
(ep) -> ep.addEntryPointFor(loginEntryPoint, requestMatcher),
GrantedAuthorities.FACTOR_SAML_RESPONSE_AUTHORITY);
}
return loginEntryPoint;
}
@@ -40,6 +40,7 @@ import org.springframework.security.config.annotation.web.configuration.WebSecur
import org.springframework.security.config.test.SpringTestContext;
import org.springframework.security.config.test.SpringTestContextExtension;
import org.springframework.security.config.users.AuthenticationTestConfiguration;
import org.springframework.security.core.GrantedAuthorities;
import org.springframework.security.core.context.SecurityContextChangedListener;
import org.springframework.security.core.context.SecurityContextHolderStrategy;
import org.springframework.security.core.userdetails.PasswordEncodedUser;
@@ -415,16 +416,21 @@ public class FormLoginConfigurerTests {
.with(SecurityMockMvcRequestPostProcessors.csrf()))
.andExpect(status().is3xxRedirection())
.andExpect(redirectedUrl("/"));
user = PasswordEncodedUser.withUserDetails(user).authorities("profile:read", "FACTOR_OTT").build();
user = PasswordEncodedUser.withUserDetails(user)
.authorities("profile:read", GrantedAuthorities.FACTOR_OTT_AUTHORITY)
.build();
this.mockMvc.perform(get("/profile").with(user(user)))
.andExpect(status().is3xxRedirection())
.andExpect(redirectedUrl("http://localhost/login?factor=password"));
user = PasswordEncodedUser.withUserDetails(user).authorities("profile:read", "FACTOR_PASSWORD").build();
user = PasswordEncodedUser.withUserDetails(user)
.authorities("profile:read", GrantedAuthorities.FACTOR_PASSWORD_AUTHORITY)
.build();
this.mockMvc.perform(get("/profile").with(user(user)))
.andExpect(status().is3xxRedirection())
.andExpect(redirectedUrl("http://localhost/login?factor=ott"));
user = PasswordEncodedUser.withUserDetails(user)
.authorities("profile:read", "FACTOR_PASSWORD", "FACTOR_OTT")
.authorities("profile:read", GrantedAuthorities.FACTOR_PASSWORD_AUTHORITY,
GrantedAuthorities.FACTOR_OTT_AUTHORITY)
.build();
this.mockMvc.perform(get("/profile").with(user(user))).andExpect(status().isNotFound());
}
@@ -447,7 +453,8 @@ public class FormLoginConfigurerTests {
.andExpect(status().is3xxRedirection())
.andExpect(redirectedUrl("/"));
UserDetails authorized = PasswordEncodedUser.withUsername("rod")
.authorities("profile:read", "FACTOR_X509", "FACTOR_PASSWORD")
.authorities("profile:read", GrantedAuthorities.FACTOR_X509_AUTHORITY,
GrantedAuthorities.FACTOR_PASSWORD_AUTHORITY)
.build();
this.mockMvc.perform(get("/profile").with(user(authorized))).andExpect(status().isOk());
}
@@ -814,7 +821,8 @@ public class FormLoginConfigurerTests {
@Bean
AuthorizationManagerFactory<?> authz() {
return new AuthorizationManagerFactory<>("FACTOR_PASSWORD", "FACTOR_OTT");
return new AuthorizationManagerFactory<>(GrantedAuthorities.FACTOR_PASSWORD_AUTHORITY,
GrantedAuthorities.FACTOR_OTT_AUTHORITY);
}
}
@@ -840,7 +848,8 @@ public class FormLoginConfigurerTests {
@Bean
AuthorizationManagerFactory<?> authz() {
return new AuthorizationManagerFactory<>("FACTOR_X509", "FACTOR_PASSWORD");
return new AuthorizationManagerFactory<>(GrantedAuthorities.FACTOR_X509_AUTHORITY,
GrantedAuthorities.FACTOR_PASSWORD_AUTHORITY);
}
}