Spring MVC의 Ajax 요청에서 세션 시간 초과 탐지
세션이 시간 초과되었을 때 Ajax 요청에서 일부 데이터를 다시 보내는 방법에 대한 좋은 예/답변을 찾을 수 없습니다.그것은 로그인 페이지 HTML을 다시 보내고 나는 json을 보내거나 내가 가로챌 수 있는 코드를 보내고 싶습니다.
가장 간단한 방법은 AJAX 요청의 URL에 필터를 사용하는 것입니다.
아래 예제에서는 세션 시간 초과를 나타내는 응답 본문과 함께 HTTP 500 응답 코드를 보내고 있지만, 응답 코드와 본문을 사용자의 경우에 더 적합한 것으로 쉽게 설정할 수 있습니다.
package com.myapp.security.authentication;
import org.springframework.web.filter.GenericFilterBean;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class ExpiredSessionFilter extends GenericFilterBean {
static final String FILTER_APPLIED = "__spring_security_expired_session_filter_applied";
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
if (request.getAttribute(FILTER_APPLIED) != null) {
chain.doFilter(request, response);
return;
}
request.setAttribute(FILTER_APPLIED, Boolean.TRUE);
if (request.getRequestedSessionId() != null && !request.isRequestedSessionIdValid()) {
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "SESSION_TIMED_OUT");
return;
}
chain.doFilter(request, response);
}
}
여기 제가 생각하기에 아주 간단한 접근법이 있습니다.이것은 제가 이 사이트에서 관찰한 접근 방식의 조합입니다.저는 그것에 대해 블로그 포스트를 썼습니다: http://yoyar.com/blog/2012/06/dealing-with-the-spring-security-ajax-session-timeout-problem/
기본 아이디어는 위에서 제안한 대로 인증 진입점과 함께 api url 접두사(즉, /api/secured)를 사용하는 것입니다.간단하고 효과적입니다.
인증 진입점은 다음과 같습니다.
package com.yoyar.yaya.config;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint;
import javax.servlet.ServletException;
import javax.servlet.http.*;
import java.io.IOException;
public class AjaxAwareAuthenticationEntryPoint
extends LoginUrlAuthenticationEntryPoint {
public AjaxAwareAuthenticationEntryPoint(String loginUrl) {
super(loginUrl);
}
@Override
public void commence(
HttpServletRequest request,
HttpServletResponse response,
AuthenticationException authException)
throws IOException, ServletException {
boolean isAjax
= request.getRequestURI().startsWith("/api/secured");
if (isAjax) {
response.sendError(403, "Forbidden");
} else {
super.commence(request, response, authException);
}
}
}
다음은 스프링 컨텍스트 xml에 포함된 내용입니다.
<bean id="authenticationEntryPoint"
class="com.yoyar.yaya.config.AjaxAwareAuthenticationEntryPoint">
<constructor-arg name="loginUrl" value="/login"/>
</bean>
<security:http auto-config="true"
use-expressions="true"
entry-point-ref="authenticationEntryPoint">
<security:intercept-url pattern="/api/secured/**" access="hasRole('ROLE_USER')"/>
<security:intercept-url pattern="/login" access="permitAll"/>
<security:intercept-url pattern="/logout" access="permitAll"/>
<security:intercept-url pattern="/denied" access="hasRole('ROLE_USER')"/>
<security:intercept-url pattern="/" access="permitAll"/>
<security:form-login login-page="/login"
authentication-failure-url="/loginfailed"
default-target-url="/login/success"/>
<security:access-denied-handler error-page="/denied"/>
<security:logout invalidate-session="true"
logout-success-url="/logout/success"
logout-url="/logout"/>
</security:http>
백엔드에서 @Matt와 동일한 솔루션을 사용합니다.프론트 엔드에서 angularJs를 사용하는 경우 아래 가로채기를 angular$http에 추가하여 브라우저가 실제로 로그인 페이지로 리디렉션할 수 있도록 합니다.
var HttpInterceptorModule = angular.module('httpInterceptor', [])
.config(function ($httpProvider) {
$httpProvider.interceptors.push('myInterceptor');
$httpProvider.defaults.headers.common["X-Requested-With"] = 'XMLHttpRequest';
})
.factory('myInterceptor', function ($q) {
return {
'responseError': function(rejection) {
// do something on error
if(rejection.status == 403 || rejection.status == 401) window.location = "login";
return $q.reject(rejection);
}
};
});
아래 줄은 버전 1.1.1(각형) 이후에 AngularJs를 사용하는 경우에만 필요합니다.JS는 해당 버전에서 "X-Requested-With" 헤더를 제거했습니다.)
$httpProvider.defaults.headers.common["X-Requested-With"] = 'XMLHttpRequest';
현재의 답변은 모두 몇 년이 지났기 때문에 현재 Spring Boot REST 애플리케이션에서 작업 중인 솔루션을 공유하겠습니다.
@Configuration
@EnableWebSecurity
public class UISecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
...
http.exceptionHandling.authenticationEntryPoint(authenticationEntryPoint());
...
}
private AuthenticationEntryPoint authenticationEntryPoint() {
// As a REST service there is no 'authentication entry point' like MVC which can redirect to a login page
// Instead just reply with 401 - Unauthorized
return (request, response, authException) -> response.sendError(HttpServletResponse.SC_UNAUTHORIZED, authException.getMessage());
}
}
여기서 기본 전제는 기본적으로 존재하지 않는 로그인 페이지로 리디렉션하는 인증 진입점을 재정의한다는 것입니다.이제 401을 전송하여 응답합니다.또한 Spring은 표준 오류 응답 JSON 개체를 암시적으로 생성하여 반환합니다.
언급URL : https://stackoverflow.com/questions/4964145/detect-session-timeout-in-ajax-request-in-spring-mvc
'source' 카테고리의 다른 글
| C에서 구조물에 메모리 할당 (0) | 2023.08.27 |
|---|---|
| MySQL의 쿼리에서 반환된 각 행에 대한 쿼리 호출 (0) | 2023.08.27 |
| 그리드 보기 행 명령에서 데이터 키 값 가져오기 (0) | 2023.08.27 |
| Ajax 내부의 Javascript 변수에 액세스 성공 (0) | 2023.08.27 |
| url 매개 변수를 javascript/jquery로 대체하는 방법은 무엇입니까? (0) | 2023.08.27 |