[SPRING] Spring Security와의 CSRF 통합시 Session timeout으로 인해 Spring MVC에서 Access Denied가 발생합니다.
SPRINGSpring Security와의 CSRF 통합시 Session timeout으로 인해 Spring MVC에서 Access Denied가 발생합니다.
Spring MVC 프로젝트에서 Spring Security와 통합 된 CSRF 토큰을 가지고있다. 모든 것이 CSRF 토큰으로 제대로 작동하며 토큰은 클라이언트 측에서 서버 측으로 전송됩니다.
CSRF 토큰을 보내고 POST 메서드를 제대로 작동하도록 로그 아웃 프로세스를 변경했습니다.
세션 시간 제한이 발생할 때 얼굴 문제가 있습니다. 스프링 기본 로그 아웃 URL로 리디렉션되어야하지만 해당 URL에서 액세스 거부가 발생합니다.
이 동작을 재정의하는 방법.
나는 보안 설정 파일에 아래 라인을 포함시켰다.
<http>
//Other config parameters
<csrf/>
</http>
누구든지 더 많은 정보가 필요하면 알려주십시오.
해결법
-
==============================
1.질문은 조금 오래되었지만 대답은 항상 유용합니다.
질문은 조금 오래되었지만 대답은 항상 유용합니다.
첫째, 이것은 CSRF Caveats - Timeouts 문서에 설명 된대로 세션 지원 CSRF 토큰에 대한 알려진 문제입니다.
이를 해결하기 위해 몇 가지 자바 스크립트를 사용하여 임박한 시간 초과를 감지하거나 세션 독립적 인 CSRF 토큰 리포지토리를 사용하거나 사용자 정의 AccessDeniedHandler 라우트를 만듭니다. 나는 후자를 선택했다 :
구성 XML :
<http> <!-- ... --> <access-denied-handler ref="myAccessDeniedHandler"/> </http> <bean id="myAccessDeniedHandler" class="package.MyAccessDeniedHandler"> <!-- <constructor-arg ref="myInvalidSessionStrategy" /> --> </bean>
AccessDeniedHandler :
public class MyAccessDeniedHandler implements AccessDeniedHandler { /* ... */ @Override public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException exception) throws IOException, ServletException { if (exception instanceof MissingCsrfTokenException) { /* Handle as a session timeout (redirect, etc). Even better if you inject the InvalidSessionStrategy used by your SessionManagementFilter, like this: invalidSessionStrategy.onInvalidSessionDetected(request, response); */ } else { /* Redirect to a error page, send HTTP 403, etc. */ } } }
또는 사용자 지정 처리기를 DelegatingAccessDeniedHandler로 정의 할 수 있습니다.
<bean id="myAccessDeniedHandler" class="org.springframework.security.web.access.DelegatingAccessDeniedHandler"> <constructor-arg name="handlers"> <map> <entry key="org.springframework.security.web.csrf.MissingCsrfTokenException"> <bean class="org.springframework.security.web.session.InvalidSessionAccessDeniedHandler"> <constructor-arg name="invalidSessionStrategy" ref="myInvalidSessionStrategy" /> </bean> </entry> </map> </constructor-arg> <constructor-arg name="defaultHandler"> <bean class="org.springframework.security.web.access.AccessDeniedHandlerImpl"> <property name="errorPage" value="/my_error_page"/> </bean> </constructor-arg> </bean>
-
==============================
2.mdrg가 제공 한 답은 바로 다음과 같습니다. 또한 사용자가 고려할 수 있도록 사용자 정의 AccessDeniedHandler를 구현했습니다.
mdrg가 제공 한 답은 바로 다음과 같습니다. 또한 사용자가 고려할 수 있도록 사용자 정의 AccessDeniedHandler를 구현했습니다.
import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import org.springframework.security.access.AccessDeniedException; import org.springframework.security.web.access.AccessDeniedHandlerImpl; import org.springframework.security.web.csrf.MissingCsrfTokenException; import org.springframework.security.web.savedrequest.HttpSessionRequestCache; import org.springframework.security.web.savedrequest.RequestCache; /** * Intended to fix the CSRF Timeout Caveat * (https://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/#csrf-timeouts). * When the session expires and a request requiring CSRF is received (POST), the * missing token exception is handled by caching the current request and * redirecting the user to the login page after which their original request will * complete. The intended result is that no loss of data due to the timeout will * occur. */ public class MissingCsrfTokenAccessDeniedHandler extends AccessDeniedHandlerImpl { private RequestCache requestCache = new HttpSessionRequestCache(); private String loginPage = "/login"; @Override public void handle(HttpServletRequest req, HttpServletResponse res, AccessDeniedException exception) throws IOException, ServletException { if (exception instanceof MissingCsrfTokenException && isSessionInvalid(req)) { requestCache.saveRequest(req, res); res.sendRedirect(req.getContextPath() + loginPage); } super.handle(req, res, exception); } private boolean isSessionInvalid(HttpServletRequest req) { try { HttpSession session = req.getSession(false); return session == null || !req.isRequestedSessionIdValid(); } catch (IllegalStateException ex) { return true; } } public void setRequestCache(RequestCache requestCache) { this.requestCache = requestCache; } public void setLoginPage(String loginPage) { this.loginPage = loginPage; } }
자바 설정을 통해 유선 :
@EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { ... http.exceptionHandling().accessDeniedHandler(getAccessDeniedHandler()); ... } public AccessDeniedHandler getAccessDeniedHandler() { return new MissingCsrfTokenAccessDeniedHandler(); } }
from https://stackoverflow.com/questions/27654206/session-timeout-leads-to-access-denied-in-spring-mvc-when-csrf-integration-with by cc-by-sa and MIT license
'SPRING' 카테고리의 다른 글
[SPRING] 봄과 Guice 함께 또는 그냥 봄 (0) | 2019.04.06 |
---|---|
[SPRING] SPRING MVC에서의 URL 패턴 제한 (0) | 2019.04.06 |
[SPRING] Spring MVC가 ArrayList를 컨트롤러로 전달 (0) | 2019.04.06 |
[SPRING] spring-security-oauth2 2.0.7 새로 고침 토큰 UserDetailsService 구성 - UserDetailsService가 필요합니다. (0) | 2019.04.06 |
[SPRING] 스프링 빈을 JSF 변환기에 삽입하는 법 [duplicate] (0) | 2019.04.06 |