Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ public final class DefaultLoginPageConfigurer<H extends HttpSecurityBuilder<H>>

@Override
public void init(H http) {
this.loginPageGeneratingFilter.setSecurityContextHolderStrategy(getSecurityContextHolderStrategy());
this.loginPageGeneratingFilter.setResolveHiddenInputs(DefaultLoginPageConfigurer.this::hiddenInputs);
this.logoutPageGeneratingFilter.setResolveHiddenInputs(DefaultLoginPageConfigurer.this::hiddenInputs);
http.setSharedObject(DefaultLoginPageGeneratingFilter.class, this.loginPageGeneratingFilter);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,18 @@
package org.springframework.security.config.annotation.web.configurers;

import java.util.LinkedHashMap;
import java.util.function.Consumer;

import org.jspecify.annotations.Nullable;

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.GrantedAuthority;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.access.AccessDeniedHandler;
import org.springframework.security.web.access.AccessDeniedHandlerImpl;
import org.springframework.security.web.access.DelegatingMissingAuthorityAccessDeniedHandler;
import org.springframework.security.web.access.ExceptionTranslationFilter;
import org.springframework.security.web.access.RequestMatcherDelegatingAccessDeniedHandler;
import org.springframework.security.web.authentication.DelegatingAuthenticationEntryPoint;
Expand Down Expand Up @@ -77,6 +80,8 @@ public final class ExceptionHandlingConfigurer<H extends HttpSecurityBuilder<H>>

private LinkedHashMap<RequestMatcher, AccessDeniedHandler> defaultDeniedHandlerMappings = new LinkedHashMap<>();

private DelegatingMissingAuthorityAccessDeniedHandler.@Nullable Builder missingAuthoritiesHandlerBuilder;

/**
* Creates a new instance
* @see HttpSecurity#exceptionHandling(Customizer)
Expand Down Expand Up @@ -127,6 +132,43 @@ public ExceptionHandlingConfigurer<H> defaultAccessDeniedHandlerFor(AccessDenied
return this;
}

/**
* Sets a default {@link AuthenticationEntryPoint} to be used which prefers being
* invoked for the provided missing {@link GrantedAuthority}.
* @param entryPoint the {@link AuthenticationEntryPoint} to use for the given
* {@code authority}
* @param authority the authority
* @return the {@link ExceptionHandlingConfigurer} for further customizations
* @since 7.0
*/
public ExceptionHandlingConfigurer<H> defaultDeniedHandlerForMissingAuthority(AuthenticationEntryPoint entryPoint,
String authority) {
if (this.missingAuthoritiesHandlerBuilder == null) {
this.missingAuthoritiesHandlerBuilder = DelegatingMissingAuthorityAccessDeniedHandler.builder();
}
this.missingAuthoritiesHandlerBuilder.addEntryPointFor(entryPoint, authority);
return this;
}

/**
* Sets a default {@link AuthenticationEntryPoint} to be used which prefers being
* invoked for the provided missing {@link GrantedAuthority}.
* @param entryPoint a consumer of a
* {@link DelegatingAuthenticationEntryPoint.Builder} to use for the given
* {@code authority}
* @param authority the authority
* @return the {@link ExceptionHandlingConfigurer} for further customizations
* @since 7.0
*/
public ExceptionHandlingConfigurer<H> defaultDeniedHandlerForMissingAuthority(
Consumer<DelegatingAuthenticationEntryPoint.Builder> entryPoint, String authority) {
if (this.missingAuthoritiesHandlerBuilder == null) {
this.missingAuthoritiesHandlerBuilder = DelegatingMissingAuthorityAccessDeniedHandler.builder();
}
this.missingAuthoritiesHandlerBuilder.addEntryPointFor(entryPoint, authority);
return this;
}

/**
* Sets the {@link AuthenticationEntryPoint} to be used.
*
Expand Down Expand Up @@ -229,6 +271,17 @@ AuthenticationEntryPoint getAuthenticationEntryPoint(H http) {
}

private AccessDeniedHandler createDefaultDeniedHandler(H http) {
AccessDeniedHandler defaults = createDefaultAccessDeniedHandler(http);
if (this.missingAuthoritiesHandlerBuilder == null) {
return defaults;
}
DelegatingMissingAuthorityAccessDeniedHandler deniedHandler = this.missingAuthoritiesHandlerBuilder.build();
deniedHandler.setRequestCache(getRequestCache(http));
deniedHandler.setDefaultAccessDeniedHandler(defaults);
return deniedHandler;
}

private AccessDeniedHandler createDefaultAccessDeniedHandler(H http) {
if (this.defaultDeniedHandlerMappings.isEmpty()) {
return new AccessDeniedHandlerImpl();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,13 @@ public FormLoginConfigurer<H> successForwardUrl(String forwardUrl) {
public void init(H http) throws Exception {
super.init(http);
initDefaultLoginFilter(http);
ExceptionHandlingConfigurer<H> exceptions = http.getConfigurer(ExceptionHandlingConfigurer.class);
if (exceptions != null) {
AuthenticationEntryPoint entryPoint = getAuthenticationEntryPoint();
RequestMatcher requestMatcher = getAuthenticationEntryPointMatcher(http);
exceptions.defaultDeniedHandlerForMissingAuthority((ep) -> ep.addEntryPointFor(entryPoint, requestMatcher),
"FACTOR_PASSWORD");
}
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -192,8 +192,10 @@ private void registerDefaultEntryPoint(B http, RequestMatcher preferredMatcher)
if (exceptionHandling == null) {
return;
}
exceptionHandling.defaultAuthenticationEntryPointFor(postProcess(this.authenticationEntryPoint),
preferredMatcher);
AuthenticationEntryPoint entryPoint = postProcess(this.authenticationEntryPoint);
exceptionHandling.defaultAuthenticationEntryPointFor(entryPoint, preferredMatcher);
exceptionHandling.defaultDeniedHandlerForMissingAuthority(
(ep) -> ep.addEntryPointFor(entryPoint, preferredMatcher), "FACTOR_PASSWORD");
}

private void registerDefaultLogoutSuccessHandler(B http, RequestMatcher preferredMatcher) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,14 @@
import org.springframework.security.authentication.ProviderManager;
import org.springframework.security.config.annotation.web.HttpSecurityBuilder;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.access.intercept.AuthorizationFilter;
import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint;
import org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter;
import org.springframework.security.web.authentication.ui.DefaultResourcesFilter;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
import org.springframework.security.web.csrf.CsrfToken;
import org.springframework.security.web.util.matcher.AnyRequestMatcher;
import org.springframework.security.web.webauthn.api.PublicKeyCredentialRpEntity;
import org.springframework.security.web.webauthn.authentication.PublicKeyCredentialRequestOptionsFilter;
import org.springframework.security.web.webauthn.authentication.WebAuthnAuthenticationFilter;
Expand Down Expand Up @@ -150,6 +153,16 @@ public WebAuthnConfigurer<H> creationOptionsRepository(
return this;
}

@Override
public void init(H http) throws Exception {
ExceptionHandlingConfigurer<H> exceptions = http.getConfigurer(ExceptionHandlingConfigurer.class);
if (exceptions != null) {
AuthenticationEntryPoint entryPoint = new LoginUrlAuthenticationEntryPoint("/login");
exceptions.defaultDeniedHandlerForMissingAuthority(
(ep) -> ep.addEntryPointFor(entryPoint, AnyRequestMatcher.INSTANCE), "FACTOR_WEBAUTHN");
}
}

@Override
public void configure(H http) throws Exception {
UserDetailsService userDetailsService = getSharedOrBean(http, UserDetailsService.class)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,10 @@ public void init(H http) {
.setSharedObject(AuthenticationEntryPoint.class, new Http403ForbiddenEntryPoint());
ExceptionHandlingConfigurer<H> exceptions = http.getConfigurer(ExceptionHandlingConfigurer.class);
if (exceptions != null) {
exceptions.defaultAuthenticationEntryPointFor(new Http403ForbiddenEntryPoint(), AnyRequestMatcher.INSTANCE);
AuthenticationEntryPoint forbidden = new Http403ForbiddenEntryPoint();
exceptions.defaultAuthenticationEntryPointFor(forbidden, AnyRequestMatcher.INSTANCE);
exceptions.defaultDeniedHandlerForMissingAuthority(
(ep) -> ep.addEntryPointFor(forbidden, AnyRequestMatcher.INSTANCE), "FACTOR_X509");
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractAuthenticationFilterConfigurer;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.config.annotation.web.configurers.ExceptionHandlingConfigurer;
import org.springframework.security.config.annotation.web.configurers.SessionManagementConfigurer;
import org.springframework.security.context.DelegatingApplicationListener;
import org.springframework.security.core.Authentication;
Expand Down Expand Up @@ -556,11 +557,18 @@ private AuthenticationEntryPoint getLoginEntryPoint(B http, String providerLogin
RequestMatcher loginUrlMatcher = new AndRequestMatcher(notXRequestedWith,
new NegatedRequestMatcher(defaultLoginPageMatcher), formLoginNotEnabled);
// @formatter:off
return DelegatingAuthenticationEntryPoint.builder()
AuthenticationEntryPoint loginEntryPoint = DelegatingAuthenticationEntryPoint.builder()
.addEntryPointFor(loginUrlEntryPoint, loginUrlMatcher)
.defaultEntryPoint(getAuthenticationEntryPoint())
.build();
// @formatter:on
ExceptionHandlingConfigurer<B> exceptions = http.getConfigurer(ExceptionHandlingConfigurer.class);
if (exceptions != null) {
RequestMatcher requestMatcher = getAuthenticationEntryPointMatcher(http);
exceptions.defaultDeniedHandlerForMissingAuthority(
(ep) -> ep.addEntryPointFor(loginEntryPoint, requestMatcher), "FACTOR_AUTHORIZATION_CODE");
}
return loginEntryPoint;
}

private RequestMatcher getFormLoginNotEnabledRequestMatcher(B http) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,8 @@ private void registerDefaultEntryPoint(H http) {
RequestMatcher preferredMatcher = new OrRequestMatcher(
Arrays.asList(this.requestMatcher, X_REQUESTED_WITH, restNotHtmlMatcher, allMatcher));
exceptionHandling.defaultAuthenticationEntryPointFor(this.authenticationEntryPoint, preferredMatcher);
exceptionHandling.defaultDeniedHandlerForMissingAuthority(
(ep) -> ep.addEntryPointFor(this.authenticationEntryPoint, preferredMatcher), "FACTOR_BEARER");
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,10 @@
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractAuthenticationFilterConfigurer;
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.userdetails.UserDetailsService;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.authentication.AuthenticationConverter;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
Expand Down Expand Up @@ -134,6 +136,13 @@ public void init(H http) throws Exception {
AuthenticationProvider authenticationProvider = getAuthenticationProvider();
http.authenticationProvider(postProcess(authenticationProvider));
intiDefaultLoginFilter(http);
ExceptionHandlingConfigurer<H> exceptions = http.getConfigurer(ExceptionHandlingConfigurer.class);
if (exceptions != null) {
AuthenticationEntryPoint entryPoint = getAuthenticationEntryPoint();
RequestMatcher requestMatcher = getAuthenticationEntryPointMatcher(http);
exceptions.defaultDeniedHandlerForMissingAuthority((ep) -> ep.addEntryPointFor(entryPoint, requestMatcher),
"FACTOR_OTT");
}
}

private void intiDefaultLoginFilter(H http) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import org.springframework.security.config.annotation.web.configurers.AbstractAuthenticationFilterConfigurer;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
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.saml2.provider.service.authentication.AbstractSaml2AuthenticationRequest;
import org.springframework.security.saml2.provider.service.authentication.OpenSaml5AuthenticationProvider;
Expand Down Expand Up @@ -343,11 +344,18 @@ private AuthenticationEntryPoint getLoginEntryPoint(B http, String providerLogin
RequestMatcher loginUrlMatcher = new AndRequestMatcher(notXRequestedWith,
new NegatedRequestMatcher(defaultLoginPageMatcher));
// @formatter:off
return DelegatingAuthenticationEntryPoint.builder()
AuthenticationEntryPoint loginEntryPoint = DelegatingAuthenticationEntryPoint.builder()
.addEntryPointFor(loginUrlEntryPoint, loginUrlMatcher)
.defaultEntryPoint(getAuthenticationEntryPoint())
.build();
// @formatter:on
ExceptionHandlingConfigurer<B> exceptions = http.getConfigurer(ExceptionHandlingConfigurer.class);
if (exceptions != null) {
RequestMatcher requestMatcher = getAuthenticationEntryPointMatcher(http);
exceptions.defaultDeniedHandlerForMissingAuthority(
(ep) -> ep.addEntryPointFor(loginEntryPoint, requestMatcher), "FACTOR_SAML_RESPONSE");
}
return loginEntryPoint;
}

private void setAuthenticationRequestRepository(B http,
Expand Down
Loading