Response to Additional Feedback
- Moved request attribute to WebAttributes - Renamed ExceptionHandlingConfigurer methods - Removed varargs from DelegatingMissingAuthorityAccessDeniedHandler Issue gh-17901 Issue gh-17934
This commit is contained in:
parent
50ebd467c3
commit
d757e6e44e
|
@ -80,8 +80,7 @@ public final class ExceptionHandlingConfigurer<H extends HttpSecurityBuilder<H>>
|
||||||
|
|
||||||
private LinkedHashMap<RequestMatcher, AccessDeniedHandler> defaultDeniedHandlerMappings = new LinkedHashMap<>();
|
private LinkedHashMap<RequestMatcher, AccessDeniedHandler> defaultDeniedHandlerMappings = new LinkedHashMap<>();
|
||||||
|
|
||||||
private final DelegatingMissingAuthorityAccessDeniedHandler.Builder missingAuthoritiesHandlerBuilder = DelegatingMissingAuthorityAccessDeniedHandler
|
private DelegatingMissingAuthorityAccessDeniedHandler.@Nullable Builder missingAuthoritiesHandlerBuilder;
|
||||||
.builder();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new instance
|
* Creates a new instance
|
||||||
|
@ -142,8 +141,11 @@ public final class ExceptionHandlingConfigurer<H extends HttpSecurityBuilder<H>>
|
||||||
* @return the {@link ExceptionHandlingConfigurer} for further customizations
|
* @return the {@link ExceptionHandlingConfigurer} for further customizations
|
||||||
* @since 7.0
|
* @since 7.0
|
||||||
*/
|
*/
|
||||||
public ExceptionHandlingConfigurer<H> defaultAuthenticationEntryPointFor(AuthenticationEntryPoint entryPoint,
|
public ExceptionHandlingConfigurer<H> defaultDeniedHandlerForMissingAuthority(AuthenticationEntryPoint entryPoint,
|
||||||
String authority) {
|
String authority) {
|
||||||
|
if (this.missingAuthoritiesHandlerBuilder == null) {
|
||||||
|
this.missingAuthoritiesHandlerBuilder = DelegatingMissingAuthorityAccessDeniedHandler.builder();
|
||||||
|
}
|
||||||
this.missingAuthoritiesHandlerBuilder.addEntryPointFor(entryPoint, authority);
|
this.missingAuthoritiesHandlerBuilder.addEntryPointFor(entryPoint, authority);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -158,8 +160,11 @@ public final class ExceptionHandlingConfigurer<H extends HttpSecurityBuilder<H>>
|
||||||
* @return the {@link ExceptionHandlingConfigurer} for further customizations
|
* @return the {@link ExceptionHandlingConfigurer} for further customizations
|
||||||
* @since 7.0
|
* @since 7.0
|
||||||
*/
|
*/
|
||||||
public ExceptionHandlingConfigurer<H> defaultAuthenticationEntryPointFor(
|
public ExceptionHandlingConfigurer<H> defaultDeniedHandlerForMissingAuthority(
|
||||||
Consumer<DelegatingAuthenticationEntryPoint.Builder> entryPoint, String authority) {
|
Consumer<DelegatingAuthenticationEntryPoint.Builder> entryPoint, String authority) {
|
||||||
|
if (this.missingAuthoritiesHandlerBuilder == null) {
|
||||||
|
this.missingAuthoritiesHandlerBuilder = DelegatingMissingAuthorityAccessDeniedHandler.builder();
|
||||||
|
}
|
||||||
this.missingAuthoritiesHandlerBuilder.addEntryPointFor(entryPoint, authority);
|
this.missingAuthoritiesHandlerBuilder.addEntryPointFor(entryPoint, authority);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -267,6 +272,9 @@ public final class ExceptionHandlingConfigurer<H extends HttpSecurityBuilder<H>>
|
||||||
|
|
||||||
private AccessDeniedHandler createDefaultDeniedHandler(H http) {
|
private AccessDeniedHandler createDefaultDeniedHandler(H http) {
|
||||||
AccessDeniedHandler defaults = createDefaultAccessDeniedHandler(http);
|
AccessDeniedHandler defaults = createDefaultAccessDeniedHandler(http);
|
||||||
|
if (this.missingAuthoritiesHandlerBuilder == null) {
|
||||||
|
return defaults;
|
||||||
|
}
|
||||||
DelegatingMissingAuthorityAccessDeniedHandler deniedHandler = this.missingAuthoritiesHandlerBuilder.build();
|
DelegatingMissingAuthorityAccessDeniedHandler deniedHandler = this.missingAuthoritiesHandlerBuilder.build();
|
||||||
deniedHandler.setRequestCache(getRequestCache(http));
|
deniedHandler.setRequestCache(getRequestCache(http));
|
||||||
deniedHandler.setDefaultAccessDeniedHandler(defaults);
|
deniedHandler.setDefaultAccessDeniedHandler(defaults);
|
||||||
|
|
|
@ -235,7 +235,7 @@ public final class FormLoginConfigurer<H extends HttpSecurityBuilder<H>> extends
|
||||||
if (exceptions != null) {
|
if (exceptions != null) {
|
||||||
AuthenticationEntryPoint entryPoint = getAuthenticationEntryPoint();
|
AuthenticationEntryPoint entryPoint = getAuthenticationEntryPoint();
|
||||||
RequestMatcher requestMatcher = getAuthenticationEntryPointMatcher(http);
|
RequestMatcher requestMatcher = getAuthenticationEntryPointMatcher(http);
|
||||||
exceptions.defaultAuthenticationEntryPointFor((ep) -> ep.addEntryPointFor(entryPoint, requestMatcher),
|
exceptions.defaultDeniedHandlerForMissingAuthority((ep) -> ep.addEntryPointFor(entryPoint, requestMatcher),
|
||||||
"FACTOR_PASSWORD");
|
"FACTOR_PASSWORD");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -194,8 +194,8 @@ public final class HttpBasicConfigurer<B extends HttpSecurityBuilder<B>>
|
||||||
}
|
}
|
||||||
AuthenticationEntryPoint entryPoint = postProcess(this.authenticationEntryPoint);
|
AuthenticationEntryPoint entryPoint = postProcess(this.authenticationEntryPoint);
|
||||||
exceptionHandling.defaultAuthenticationEntryPointFor(entryPoint, preferredMatcher);
|
exceptionHandling.defaultAuthenticationEntryPointFor(entryPoint, preferredMatcher);
|
||||||
exceptionHandling.defaultAuthenticationEntryPointFor((ep) -> ep.addEntryPointFor(entryPoint, preferredMatcher),
|
exceptionHandling.defaultDeniedHandlerForMissingAuthority(
|
||||||
"FACTOR_PASSWORD");
|
(ep) -> ep.addEntryPointFor(entryPoint, preferredMatcher), "FACTOR_PASSWORD");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void registerDefaultLogoutSuccessHandler(B http, RequestMatcher preferredMatcher) {
|
private void registerDefaultLogoutSuccessHandler(B http, RequestMatcher preferredMatcher) {
|
||||||
|
|
|
@ -158,7 +158,7 @@ public class WebAuthnConfigurer<H extends HttpSecurityBuilder<H>>
|
||||||
ExceptionHandlingConfigurer<H> exceptions = http.getConfigurer(ExceptionHandlingConfigurer.class);
|
ExceptionHandlingConfigurer<H> exceptions = http.getConfigurer(ExceptionHandlingConfigurer.class);
|
||||||
if (exceptions != null) {
|
if (exceptions != null) {
|
||||||
AuthenticationEntryPoint entryPoint = new LoginUrlAuthenticationEntryPoint("/login");
|
AuthenticationEntryPoint entryPoint = new LoginUrlAuthenticationEntryPoint("/login");
|
||||||
exceptions.defaultAuthenticationEntryPointFor(
|
exceptions.defaultDeniedHandlerForMissingAuthority(
|
||||||
(ep) -> ep.addEntryPointFor(entryPoint, AnyRequestMatcher.INSTANCE), "FACTOR_WEBAUTHN");
|
(ep) -> ep.addEntryPointFor(entryPoint, AnyRequestMatcher.INSTANCE), "FACTOR_WEBAUTHN");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -185,7 +185,7 @@ public final class X509Configurer<H extends HttpSecurityBuilder<H>>
|
||||||
ExceptionHandlingConfigurer<H> exceptions = http.getConfigurer(ExceptionHandlingConfigurer.class);
|
ExceptionHandlingConfigurer<H> exceptions = http.getConfigurer(ExceptionHandlingConfigurer.class);
|
||||||
if (exceptions != null) {
|
if (exceptions != null) {
|
||||||
AuthenticationEntryPoint forbidden = new Http403ForbiddenEntryPoint();
|
AuthenticationEntryPoint forbidden = new Http403ForbiddenEntryPoint();
|
||||||
exceptions.defaultAuthenticationEntryPointFor(
|
exceptions.defaultDeniedHandlerForMissingAuthority(
|
||||||
(ep) -> ep.addEntryPointFor(forbidden, AnyRequestMatcher.INSTANCE), "FACTOR_X509");
|
(ep) -> ep.addEntryPointFor(forbidden, AnyRequestMatcher.INSTANCE), "FACTOR_X509");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -565,8 +565,8 @@ public final class OAuth2LoginConfigurer<B extends HttpSecurityBuilder<B>>
|
||||||
ExceptionHandlingConfigurer<B> exceptions = http.getConfigurer(ExceptionHandlingConfigurer.class);
|
ExceptionHandlingConfigurer<B> exceptions = http.getConfigurer(ExceptionHandlingConfigurer.class);
|
||||||
if (exceptions != null) {
|
if (exceptions != null) {
|
||||||
RequestMatcher requestMatcher = getAuthenticationEntryPointMatcher(http);
|
RequestMatcher requestMatcher = getAuthenticationEntryPointMatcher(http);
|
||||||
exceptions.defaultAuthenticationEntryPointFor((ep) -> ep.addEntryPointFor(loginEntryPoint, requestMatcher),
|
exceptions.defaultDeniedHandlerForMissingAuthority(
|
||||||
"FACTOR_AUTHORIZATION_CODE");
|
(ep) -> ep.addEntryPointFor(loginEntryPoint, requestMatcher), "FACTOR_AUTHORIZATION_CODE");
|
||||||
}
|
}
|
||||||
return loginEntryPoint;
|
return loginEntryPoint;
|
||||||
}
|
}
|
||||||
|
|
|
@ -327,7 +327,7 @@ public final class OAuth2ResourceServerConfigurer<H extends HttpSecurityBuilder<
|
||||||
RequestMatcher preferredMatcher = new OrRequestMatcher(
|
RequestMatcher preferredMatcher = new OrRequestMatcher(
|
||||||
Arrays.asList(this.requestMatcher, X_REQUESTED_WITH, restNotHtmlMatcher, allMatcher));
|
Arrays.asList(this.requestMatcher, X_REQUESTED_WITH, restNotHtmlMatcher, allMatcher));
|
||||||
exceptionHandling.defaultAuthenticationEntryPointFor(this.authenticationEntryPoint, preferredMatcher);
|
exceptionHandling.defaultAuthenticationEntryPointFor(this.authenticationEntryPoint, preferredMatcher);
|
||||||
exceptionHandling.defaultAuthenticationEntryPointFor(
|
exceptionHandling.defaultDeniedHandlerForMissingAuthority(
|
||||||
(ep) -> ep.addEntryPointFor(this.authenticationEntryPoint, preferredMatcher), "FACTOR_BEARER");
|
(ep) -> ep.addEntryPointFor(this.authenticationEntryPoint, preferredMatcher), "FACTOR_BEARER");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -140,7 +140,7 @@ public final class OneTimeTokenLoginConfigurer<H extends HttpSecurityBuilder<H>>
|
||||||
if (exceptions != null) {
|
if (exceptions != null) {
|
||||||
AuthenticationEntryPoint entryPoint = getAuthenticationEntryPoint();
|
AuthenticationEntryPoint entryPoint = getAuthenticationEntryPoint();
|
||||||
RequestMatcher requestMatcher = getAuthenticationEntryPointMatcher(http);
|
RequestMatcher requestMatcher = getAuthenticationEntryPointMatcher(http);
|
||||||
exceptions.defaultAuthenticationEntryPointFor((ep) -> ep.addEntryPointFor(entryPoint, requestMatcher),
|
exceptions.defaultDeniedHandlerForMissingAuthority((ep) -> ep.addEntryPointFor(entryPoint, requestMatcher),
|
||||||
"FACTOR_OTT");
|
"FACTOR_OTT");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -352,8 +352,8 @@ public final class Saml2LoginConfigurer<B extends HttpSecurityBuilder<B>>
|
||||||
ExceptionHandlingConfigurer<B> exceptions = http.getConfigurer(ExceptionHandlingConfigurer.class);
|
ExceptionHandlingConfigurer<B> exceptions = http.getConfigurer(ExceptionHandlingConfigurer.class);
|
||||||
if (exceptions != null) {
|
if (exceptions != null) {
|
||||||
RequestMatcher requestMatcher = getAuthenticationEntryPointMatcher(http);
|
RequestMatcher requestMatcher = getAuthenticationEntryPointMatcher(http);
|
||||||
exceptions.defaultAuthenticationEntryPointFor((ep) -> ep.addEntryPointFor(loginEntryPoint, requestMatcher),
|
exceptions.defaultDeniedHandlerForMissingAuthority(
|
||||||
"FACTOR_SAML_RESPONSE");
|
(ep) -> ep.addEntryPointFor(loginEntryPoint, requestMatcher), "FACTOR_SAML_RESPONSE");
|
||||||
}
|
}
|
||||||
return loginEntryPoint;
|
return loginEntryPoint;
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,8 +31,6 @@ import org.springframework.security.authorization.AuthorizationManager;
|
||||||
*/
|
*/
|
||||||
public interface GrantedAuthority extends Serializable {
|
public interface GrantedAuthority extends Serializable {
|
||||||
|
|
||||||
String MISSING_AUTHORITIES_ATTRIBUTE = GrantedAuthority.class + ".missingAuthorities";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If the <code>GrantedAuthority</code> can be represented as a <code>String</code>
|
* If the <code>GrantedAuthority</code> can be represented as a <code>String</code>
|
||||||
* and that <code>String</code> is sufficient in precision to be relied upon for an
|
* and that <code>String</code> is sufficient in precision to be relied upon for an
|
||||||
|
|
|
@ -16,6 +16,9 @@
|
||||||
|
|
||||||
package org.springframework.security.web;
|
package org.springframework.security.web;
|
||||||
|
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
|
import org.springframework.security.core.GrantedAuthority;
|
||||||
import org.springframework.security.web.access.WebInvocationPrivilegeEvaluator;
|
import org.springframework.security.web.access.WebInvocationPrivilegeEvaluator;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -52,6 +55,17 @@ public final class WebAttributes {
|
||||||
public static final String WEB_INVOCATION_PRIVILEGE_EVALUATOR_ATTRIBUTE = WebAttributes.class.getName()
|
public static final String WEB_INVOCATION_PRIVILEGE_EVALUATOR_ATTRIBUTE = WebAttributes.class.getName()
|
||||||
+ ".WEB_INVOCATION_PRIVILEGE_EVALUATOR_ATTRIBUTE";
|
+ ".WEB_INVOCATION_PRIVILEGE_EVALUATOR_ATTRIBUTE";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to set a {@code Collection} of {@link GrantedAuthority} instances into the
|
||||||
|
* {@link HttpServletRequest}.
|
||||||
|
* <p>
|
||||||
|
* Represents what authorities are missing to be authorized for the current request
|
||||||
|
*
|
||||||
|
* @since 7.0
|
||||||
|
* @see org.springframework.security.web.access.DelegatingMissingAuthorityAccessDeniedHandler
|
||||||
|
*/
|
||||||
|
public static final String MISSING_AUTHORITIES = WebAttributes.class + ".MISSING_AUTHORITIES";
|
||||||
|
|
||||||
private WebAttributes() {
|
private WebAttributes() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,11 +35,13 @@ import org.springframework.security.authorization.AuthorizationDeniedException;
|
||||||
import org.springframework.security.core.AuthenticationException;
|
import org.springframework.security.core.AuthenticationException;
|
||||||
import org.springframework.security.core.GrantedAuthority;
|
import org.springframework.security.core.GrantedAuthority;
|
||||||
import org.springframework.security.web.AuthenticationEntryPoint;
|
import org.springframework.security.web.AuthenticationEntryPoint;
|
||||||
|
import org.springframework.security.web.WebAttributes;
|
||||||
import org.springframework.security.web.authentication.DelegatingAuthenticationEntryPoint;
|
import org.springframework.security.web.authentication.DelegatingAuthenticationEntryPoint;
|
||||||
import org.springframework.security.web.savedrequest.NullRequestCache;
|
import org.springframework.security.web.savedrequest.NullRequestCache;
|
||||||
import org.springframework.security.web.savedrequest.RequestCache;
|
import org.springframework.security.web.savedrequest.RequestCache;
|
||||||
import org.springframework.security.web.util.ThrowableAnalyzer;
|
import org.springframework.security.web.util.ThrowableAnalyzer;
|
||||||
import org.springframework.security.web.util.matcher.AnyRequestMatcher;
|
import org.springframework.security.web.util.matcher.AnyRequestMatcher;
|
||||||
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An {@link AccessDeniedHandler} that adapts {@link AuthenticationEntryPoint}s based on
|
* An {@link AccessDeniedHandler} that adapts {@link AuthenticationEntryPoint}s based on
|
||||||
|
@ -62,8 +64,8 @@ import org.springframework.security.web.util.matcher.AnyRequestMatcher;
|
||||||
*
|
*
|
||||||
* <code>
|
* <code>
|
||||||
* AccessDeniedHandler handler = DelegatingMissingAuthorityAccessDeniedHandler.builder()
|
* AccessDeniedHandler handler = DelegatingMissingAuthorityAccessDeniedHandler.builder()
|
||||||
* .authorities("FACTOR_OTT").commence(new LoginUrlAuthenticationEntryPoint("/login"))
|
* .addEntryPointFor(new LoginUrlAuthenticationEntryPoint("/login"), "FACTOR_OTT")
|
||||||
* .authorities("FACTOR_PASSWORD")...
|
* .addEntryPointFor(new MyCustomEntryPoint(), "FACTOR_PASSWORD")
|
||||||
* .build();
|
* .build();
|
||||||
* </code>
|
* </code>
|
||||||
*
|
*
|
||||||
|
@ -84,6 +86,7 @@ public final class DelegatingMissingAuthorityAccessDeniedHandler implements Acce
|
||||||
private AccessDeniedHandler defaultAccessDeniedHandler = new AccessDeniedHandlerImpl();
|
private AccessDeniedHandler defaultAccessDeniedHandler = new AccessDeniedHandlerImpl();
|
||||||
|
|
||||||
private DelegatingMissingAuthorityAccessDeniedHandler(Map<String, AuthenticationEntryPoint> entryPoints) {
|
private DelegatingMissingAuthorityAccessDeniedHandler(Map<String, AuthenticationEntryPoint> entryPoints) {
|
||||||
|
Assert.notEmpty(entryPoints, "entryPoints cannot be empty");
|
||||||
this.entryPoints = entryPoints;
|
this.entryPoints = entryPoints;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,7 +100,7 @@ public final class DelegatingMissingAuthorityAccessDeniedHandler implements Acce
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
this.requestCache.saveRequest(request, response);
|
this.requestCache.saveRequest(request, response);
|
||||||
request.setAttribute(GrantedAuthority.MISSING_AUTHORITIES_ATTRIBUTE, List.of(needed));
|
request.setAttribute(WebAttributes.MISSING_AUTHORITIES, List.of(needed));
|
||||||
String message = String.format("Missing Authorities %s", List.of(needed));
|
String message = String.format("Missing Authorities %s", List.of(needed));
|
||||||
AuthenticationException ex = new InsufficientAuthenticationException(message, denied);
|
AuthenticationException ex = new InsufficientAuthenticationException(message, denied);
|
||||||
entryPoint.commence(request, response, ex);
|
entryPoint.commence(request, response, ex);
|
||||||
|
@ -112,6 +115,7 @@ public final class DelegatingMissingAuthorityAccessDeniedHandler implements Acce
|
||||||
* @param defaultAccessDeniedHandler the default {@link AccessDeniedHandler} to use
|
* @param defaultAccessDeniedHandler the default {@link AccessDeniedHandler} to use
|
||||||
*/
|
*/
|
||||||
public void setDefaultAccessDeniedHandler(AccessDeniedHandler defaultAccessDeniedHandler) {
|
public void setDefaultAccessDeniedHandler(AccessDeniedHandler defaultAccessDeniedHandler) {
|
||||||
|
Assert.notNull(defaultAccessDeniedHandler, "defaultAccessDeniedHandler cannot be null");
|
||||||
this.defaultAccessDeniedHandler = defaultAccessDeniedHandler;
|
this.defaultAccessDeniedHandler = defaultAccessDeniedHandler;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -123,6 +127,7 @@ public final class DelegatingMissingAuthorityAccessDeniedHandler implements Acce
|
||||||
* @param requestCache the {@link RequestCache} to use
|
* @param requestCache the {@link RequestCache} to use
|
||||||
*/
|
*/
|
||||||
public void setRequestCache(RequestCache requestCache) {
|
public void setRequestCache(RequestCache requestCache) {
|
||||||
|
Assert.notNull(requestCache, "requestCachgrantedaue cannot be null");
|
||||||
this.requestCache = requestCache;
|
this.requestCache = requestCache;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -158,57 +163,44 @@ public final class DelegatingMissingAuthorityAccessDeniedHandler implements Acce
|
||||||
*/
|
*/
|
||||||
public static final class Builder {
|
public static final class Builder {
|
||||||
|
|
||||||
private final Map<String, DelegatingAuthenticationEntryPoint.Builder> entryPointByRequestMatcherByAuthority = new LinkedHashMap<>();
|
private final Map<String, DelegatingAuthenticationEntryPoint.Builder> entryPointBuilderByAuthority = new LinkedHashMap<>();
|
||||||
|
|
||||||
private Builder() {
|
private Builder() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DelegatingAuthenticationEntryPoint.Builder entryPointBuilder(String authority) {
|
|
||||||
return this.entryPointByRequestMatcherByAuthority.computeIfAbsent(authority,
|
|
||||||
(k) -> DelegatingAuthenticationEntryPoint.builder());
|
|
||||||
}
|
|
||||||
|
|
||||||
void entryPoint(String authority, AuthenticationEntryPoint entryPoint) {
|
|
||||||
DelegatingAuthenticationEntryPoint.Builder builder = DelegatingAuthenticationEntryPoint.builder()
|
|
||||||
.addEntryPointFor(entryPoint, AnyRequestMatcher.INSTANCE);
|
|
||||||
this.entryPointByRequestMatcherByAuthority.put(authority, builder);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Bind these authorities to the given {@link AuthenticationEntryPoint}
|
* Use this {@link AuthenticationEntryPoint} when the given
|
||||||
* @param entryPoint the {@link AuthenticationEntryPoint} for the given
|
* {@code missingAuthority} is missing from the authenticated user
|
||||||
* authorities
|
* @param entryPoint the {@link AuthenticationEntryPoint} for the given authority
|
||||||
* @param authorities the authorities
|
* @param missingAuthority the authority
|
||||||
* @return the {@link Builder} for further configurations
|
* @return the {@link Builder} for further configurations
|
||||||
*/
|
*/
|
||||||
public Builder addEntryPointFor(AuthenticationEntryPoint entryPoint, String... authorities) {
|
public Builder addEntryPointFor(AuthenticationEntryPoint entryPoint, String missingAuthority) {
|
||||||
for (String authority : authorities) {
|
DelegatingAuthenticationEntryPoint.Builder builder = DelegatingAuthenticationEntryPoint.builder()
|
||||||
Builder.this.entryPoint(authority, entryPoint);
|
.addEntryPointFor(entryPoint, AnyRequestMatcher.INSTANCE);
|
||||||
}
|
this.entryPointBuilderByAuthority.put(missingAuthority, builder);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Bind these authorities to the given {@link AuthenticationEntryPoint}
|
* Use this {@link AuthenticationEntryPoint} when the given
|
||||||
|
* {@code missingAuthority} is missing from the authenticated user
|
||||||
* @param entryPoint a consumer to configure the underlying
|
* @param entryPoint a consumer to configure the underlying
|
||||||
* {@link DelegatingAuthenticationEntryPoint}
|
* {@link DelegatingAuthenticationEntryPoint}
|
||||||
* @param authorities the authorities
|
* @param missingAuthority the authority
|
||||||
* @return the {@link Builder} for further configurations
|
* @return the {@link Builder} for further configurations
|
||||||
*/
|
*/
|
||||||
public Builder addEntryPointFor(Consumer<DelegatingAuthenticationEntryPoint.Builder> entryPoint,
|
public Builder addEntryPointFor(Consumer<DelegatingAuthenticationEntryPoint.Builder> entryPoint,
|
||||||
String... authorities) {
|
String missingAuthority) {
|
||||||
for (String authority : authorities) {
|
entryPoint.accept(this.entryPointBuilderByAuthority.computeIfAbsent(missingAuthority,
|
||||||
entryPoint.accept(Builder.this.entryPointBuilder(authority));
|
(k) -> DelegatingAuthenticationEntryPoint.builder()));
|
||||||
}
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DelegatingMissingAuthorityAccessDeniedHandler build() {
|
public DelegatingMissingAuthorityAccessDeniedHandler build() {
|
||||||
Map<String, AuthenticationEntryPoint> entryPointByAuthority = new LinkedHashMap<>();
|
Map<String, AuthenticationEntryPoint> entryPointByAuthority = new LinkedHashMap<>();
|
||||||
for (String authority : this.entryPointByRequestMatcherByAuthority.keySet()) {
|
this.entryPointBuilderByAuthority.forEach((key, value) -> entryPointByAuthority.put(key, value.build()));
|
||||||
entryPointByAuthority.put(authority, this.entryPointByRequestMatcherByAuthority.get(authority).build());
|
|
||||||
}
|
|
||||||
return new DelegatingMissingAuthorityAccessDeniedHandler(entryPointByAuthority);
|
return new DelegatingMissingAuthorityAccessDeniedHandler(entryPointByAuthority);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,6 +38,7 @@ import org.springframework.security.web.DefaultRedirectStrategy;
|
||||||
import org.springframework.security.web.PortMapper;
|
import org.springframework.security.web.PortMapper;
|
||||||
import org.springframework.security.web.PortMapperImpl;
|
import org.springframework.security.web.PortMapperImpl;
|
||||||
import org.springframework.security.web.RedirectStrategy;
|
import org.springframework.security.web.RedirectStrategy;
|
||||||
|
import org.springframework.security.web.WebAttributes;
|
||||||
import org.springframework.security.web.access.ExceptionTranslationFilter;
|
import org.springframework.security.web.access.ExceptionTranslationFilter;
|
||||||
import org.springframework.security.web.util.RedirectUrlBuilder;
|
import org.springframework.security.web.util.RedirectUrlBuilder;
|
||||||
import org.springframework.security.web.util.UrlUtils;
|
import org.springframework.security.web.util.UrlUtils;
|
||||||
|
@ -117,7 +118,7 @@ public class LoginUrlAuthenticationEntryPoint implements AuthenticationEntryPoin
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
protected String determineUrlToUseForThisRequest(HttpServletRequest request, HttpServletResponse response,
|
protected String determineUrlToUseForThisRequest(HttpServletRequest request, HttpServletResponse response,
|
||||||
AuthenticationException exception) {
|
AuthenticationException exception) {
|
||||||
Collection<GrantedAuthority> authorities = getAttribute(request, GrantedAuthority.MISSING_AUTHORITIES_ATTRIBUTE,
|
Collection<GrantedAuthority> authorities = getAttribute(request, WebAttributes.MISSING_AUTHORITIES,
|
||||||
Collection.class);
|
Collection.class);
|
||||||
if (CollectionUtils.isEmpty(authorities)) {
|
if (CollectionUtils.isEmpty(authorities)) {
|
||||||
return getLoginFormUrl();
|
return getLoginFormUrl();
|
||||||
|
@ -130,7 +131,7 @@ public class LoginUrlAuthenticationEntryPoint implements AuthenticationEntryPoin
|
||||||
}
|
}
|
||||||
|
|
||||||
private static <T> @Nullable T getAttribute(HttpServletRequest request, String name, Class<T> clazz) {
|
private static <T> @Nullable T getAttribute(HttpServletRequest request, String name, Class<T> clazz) {
|
||||||
Object value = request.getAttribute(GrantedAuthority.MISSING_AUTHORITIES_ATTRIBUTE);
|
Object value = request.getAttribute(name);
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue