Fix CsrfConfigurer default AccessDeniedHandler consistency
Fix when AccessDeniedHandler is specified per RequestMatcher on ExceptionHandlingConfigurer. This introduces evolutions on : - CsrfConfigurer#getDefaultAccessDeniedHandler, to retrieve an AccessDeniedHandler similar to the one used by ExceptionHandlingConfigurer. - OAuth2ResourceServerConfigurer#accessDeniedHandler, to continue to handle CsrfException with the default AccessDeniedHandler implementation Fixes: gh-6511
This commit is contained in:
parent
0aa75e04b7
commit
e85958f65c
|
@ -237,8 +237,8 @@ public final class CsrfConfigurer<H extends HttpSecurityBuilder<H>>
|
|||
|
||||
/**
|
||||
* Gets the default {@link AccessDeniedHandler} from the
|
||||
* {@link ExceptionHandlingConfigurer#getAccessDeniedHandler()} or create a
|
||||
* {@link AccessDeniedHandlerImpl} if not available.
|
||||
* {@link ExceptionHandlingConfigurer#getAccessDeniedHandler(HttpSecurityBuilder)} or
|
||||
* create a {@link AccessDeniedHandlerImpl} if not available.
|
||||
* @param http the {@link HttpSecurityBuilder}
|
||||
* @return the {@link AccessDeniedHandler}
|
||||
*/
|
||||
|
@ -247,7 +247,7 @@ public final class CsrfConfigurer<H extends HttpSecurityBuilder<H>>
|
|||
ExceptionHandlingConfigurer<H> exceptionConfig = http.getConfigurer(ExceptionHandlingConfigurer.class);
|
||||
AccessDeniedHandler handler = null;
|
||||
if (exceptionConfig != null) {
|
||||
handler = exceptionConfig.getAccessDeniedHandler();
|
||||
handler = exceptionConfig.getAccessDeniedHandler(http);
|
||||
}
|
||||
if (handler == null) {
|
||||
handler = new AccessDeniedHandlerImpl();
|
||||
|
|
|
@ -18,6 +18,8 @@ package org.springframework.security.config.annotation.web.configurers.oauth2.se
|
|||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
|
@ -51,6 +53,9 @@ import org.springframework.security.oauth2.server.resource.web.DefaultBearerToke
|
|||
import org.springframework.security.oauth2.server.resource.web.access.BearerTokenAccessDeniedHandler;
|
||||
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.DelegatingAccessDeniedHandler;
|
||||
import org.springframework.security.web.csrf.CsrfException;
|
||||
import org.springframework.security.web.util.matcher.AndRequestMatcher;
|
||||
import org.springframework.security.web.util.matcher.MediaTypeRequestMatcher;
|
||||
import org.springframework.security.web.util.matcher.NegatedRequestMatcher;
|
||||
|
@ -153,7 +158,9 @@ public final class OAuth2ResourceServerConfigurer<H extends HttpSecurityBuilder<
|
|||
|
||||
private OpaqueTokenConfigurer opaqueTokenConfigurer;
|
||||
|
||||
private AccessDeniedHandler accessDeniedHandler = new BearerTokenAccessDeniedHandler();
|
||||
private AccessDeniedHandler accessDeniedHandler = new DelegatingAccessDeniedHandler(
|
||||
new LinkedHashMap<>(Map.of(CsrfException.class, new AccessDeniedHandlerImpl())),
|
||||
new BearerTokenAccessDeniedHandler());
|
||||
|
||||
private AuthenticationEntryPoint authenticationEntryPoint = new BearerTokenAuthenticationEntryPoint();
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2021 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.
|
||||
|
@ -320,6 +320,17 @@ public class CsrfConfigurerTests {
|
|||
any(HttpServletResponse.class), any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getWhenCustomDefaultAccessDeniedHandlerForThenHandlerIsUsed() throws Exception {
|
||||
DefaultAccessDeniedHandlerForConfig.DENIED_HANDLER = mock(AccessDeniedHandler.class);
|
||||
DefaultAccessDeniedHandlerForConfig.MATCHER = mock(RequestMatcher.class);
|
||||
given(DefaultAccessDeniedHandlerForConfig.MATCHER.matches(any())).willReturn(true);
|
||||
this.spring.register(DefaultAccessDeniedHandlerForConfig.class, BasicController.class).autowire();
|
||||
this.mvc.perform(post("/")).andExpect(status().isOk());
|
||||
verify(DefaultAccessDeniedHandlerForConfig.DENIED_HANDLER).handle(any(HttpServletRequest.class),
|
||||
any(HttpServletResponse.class), any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void loginWhenNoCsrfTokenThenRespondsWithForbidden() throws Exception {
|
||||
this.spring.register(FormLoginConfig.class).autowire();
|
||||
|
@ -608,6 +619,24 @@ public class CsrfConfigurerTests {
|
|||
|
||||
}
|
||||
|
||||
@EnableWebSecurity
|
||||
static class DefaultAccessDeniedHandlerForConfig extends WebSecurityConfigurerAdapter {
|
||||
|
||||
static AccessDeniedHandler DENIED_HANDLER;
|
||||
|
||||
static RequestMatcher MATCHER;
|
||||
|
||||
@Override
|
||||
protected void configure(HttpSecurity http) throws Exception {
|
||||
// @formatter:off
|
||||
http
|
||||
.exceptionHandling()
|
||||
.defaultAccessDeniedHandlerFor(DENIED_HANDLER, MATCHER);
|
||||
// @formatter:on
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@EnableWebSecurity
|
||||
static class FormLoginConfig extends WebSecurityConfigurerAdapter {
|
||||
|
||||
|
|
Loading…
Reference in New Issue