복붙노트

[SPRING] Spring Security로 자동으로 로그 아웃하는 방법

SPRING

Spring Security로 자동으로 로그 아웃하는 방법

스프링 웹 애플리케이션이 있고 스프링 보안을 사용하여 사용자 인증을했습니다.

모든 것이 잘 작동합니다. 로그인하고 로그 아웃하면 완벽하게 작동합니다!

이제 자동으로 로그 아웃하기 위해 구현하고 싶습니다. 예를 들어 사용자가 약 30 분 동안 창이 열렸고 아무 것도하지 않으면 (예 : 세션 만료) 시스템이 자동으로 로그 아웃해야합니다. 어떻게 구현할 수 있습니까?

클라이언트 측에서 구현할 수 있습니다 (1 분마다 요청을 보내고 세션이 종료되었는지 확인). 하지만 스프링에서 자동으로이 작업을 수행 할 수 없습니까?

나는이 설정을 가지고있다 :

<http auto-config="true" use-expressions="true">


        <intercept-url pattern="/admin**" />
        <access-denied-handler error-page="/403" />

        <form-login login-page="/login" 
            default-target-url="/admin"
            authentication-failure-url="/login?error" 
            username-parameter="NAME"
            password-parameter="PASSWORD"  />

        <logout invalidate-session="true" 
             logout-success-url="/login?logout"/>

    </http>

및 web.xml

<session-config>
  <session-timeout>1</session-timeout>
</session-config>

1 분 후에 그 세션이 파괴 된 것을 봅니다. 1 분 후에 세션을 종료하십시오. 하지만 페이지가 / login으로 리디렉션되지 않았습니까? logout

해결법

  1. ==============================

    1.보안 설정을 사용하는 방법. ?? 나는 config 아래 희망 : 작동합니다. applicationContext.xml

    보안 설정을 사용하는 방법. ?? 나는 config 아래 희망 : 작동합니다. applicationContext.xml

     --namespace-> xmlns:security="http://www.springframework.org/schema/security"
    
            <security:logout invalidate-session="true"
                            success-handler-ref="Logout"
                            logout-url="/logout.html" />
            </security:http>
    

    을 포함한다.

     <session-config>
            <session-timeout>
                30
            </session-timeout>
        </session-config>
    

    그리고 success-handler-ref = "Logout"은 로그 아웃을위한 커스텀 핸들러이기 때문에 그들 스스로 작성해야합니다 : 로그 아웃 @구성 요소

    public class Logout extends SimpleUrlLogoutSuccessHandler {
    
        @Override
        public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response,
                Authentication authentication) throws IOException, ServletException {
    
            if (authentication != null) {
                // do something 
            }
    
            setDefaultTargetUrl("/login");
            super.onLogoutSuccess(request, response, authentication);       
        }
    }
    
  2. ==============================

    2.이 값을 web.xml에 넣으면 전역 시간 초과 값을 사용할 수 있습니다.

    이 값을 web.xml에 넣으면 전역 시간 초과 값을 사용할 수 있습니다.

    <session-config>
      <session-timeout>30</session-timeout>
    </session-config>
    
  3. ==============================

    3.다음은 내가 사용한 튜토리얼입니다. 자바 스크립트와 서버 측 코드가 있습니다. 서버는 세션이 만료 될 때를 계산하여이를 쿠키로 다시 보냅니다. 그런 다음 java 스크립트는 만료 된 경우 10 초마다 검사하고, 그렇다면 window.close ()를 점검합니다. http://www.javaworld.com/article/2073234/tracking-session-expiration-in-browser.html

    다음은 내가 사용한 튜토리얼입니다. 자바 스크립트와 서버 측 코드가 있습니다. 서버는 세션이 만료 될 때를 계산하여이를 쿠키로 다시 보냅니다. 그런 다음 java 스크립트는 만료 된 경우 10 초마다 검사하고, 그렇다면 window.close ()를 점검합니다. http://www.javaworld.com/article/2073234/tracking-session-expiration-in-browser.html

    여기 어떻게 구현 했는가?

    SessionTimeout.js

    /**
     * Monitor the session timeout cookie from Apache and log the user out when expired
     */
    "use strict";
    
    var jQuery = require("jquery").noConflict();
    var jsCookie = require("js-cookie");
    
    module.exports.registerListener = function() {
        calcOffset();
        checkSession();
    };
    
    /**
     * We can't assume the server time and client time are the same
     * so lets calcuate the difference
     */
    function calcOffset() {
        var serverTime = jsCookie.get('serverTime');
        serverTime = serverTime==null ? null : Math.abs(serverTime);
        var clientTimeOffset = (new Date()).getTime() - serverTime;
        jsCookie.set('clientTimeOffset', clientTimeOffset);
    }
    
    /**
     * Check the sessionExpiry cookie and see if we should send the user to /
     */
    function checkSession() {
        var sessionExpiry = Math.abs(jsCookie.get('sessionExpiry'));
        var timeOffset = Math.abs(jsCookie.get('clientTimeOffset'));
        var localTime = (new Date()).getTime();
        if(!sessionExpiry){
            window.console.log("Unknown session sessionExpiry");
            return;
        }
        if (localTime - timeOffset > (sessionExpiry+15000)) { // 15 extra seconds to make sure
            window.location = "/login";
            jsCookie.remove('sessionExpiry');
        } else {
            setTimeout('checkSession()', 10000);
        }
        window.console.log("Session expires in " + ((sessionExpiry+15000) - localTime - timeOffset) + "ms");
    }
    
    window.checkSession = checkSession; //Used for recalling via setTimeout
    

    SessionTimeoutCookieFilter.java

    public class SessionTimeoutCookieFilter implements Filter {
    
        private static final Logger LOG = LoggerFactory.getLogger(SessionTimeoutCookieFilter.class);
    
        @Override
        public void init(FilterConfig config) throws ServletException {
            LOG.info("Initialization SessionTimeoutCookieFilter");
        }
    
        @Override
        public void doFilter(ServletRequest req, ServletResponse resp, FilterChain filterChain) throws IOException, ServletException {
            HttpServletResponse httpResp = (HttpServletResponse) resp;
            HttpServletRequest httpReq = (HttpServletRequest) req;
    
            long currTime = System.currentTimeMillis();
            String expiryTime = Long.toString(currTime + httpReq.getSession().getMaxInactiveInterval() * 1000);
            Cookie cookie = new Cookie("serverTime", Long.toString(currTime));
            cookie.setPath("/");
            httpResp.addCookie(cookie);
            if (httpReq.getRemoteUser() != null) {
                cookie = new Cookie("sessionExpiry", expiryTime);
            }
            cookie.setPath("/");
            httpResp.addCookie(cookie);
    
            filterChain.doFilter(req, resp);
        }
    

    필터 추가

    public class ApplicationInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
    ...
        @Override
        protected Filter[] getServletFilters() {
            return new Filter[]{new SessionTimeoutCookieFilter()};
        }
    }
    
  4. ==============================

    4.세션 만료 후 로그인 페이지로 리디렉션하려면 보안 컨텍스트에서 "세션 관리"bean에 "invalid-session-url"태그를 추가하십시오.

    세션 만료 후 로그인 페이지로 리디렉션하려면 보안 컨텍스트에서 "세션 관리"bean에 "invalid-session-url"태그를 추가하십시오.

    <session-management invalid-session-url="/error-login">
        ....
    </session-management>
    

    제 경우에는 오류 메시지가 표시되고 다시 로그인 할 수있는 오류 로그인 페이지로 리디렉션됩니다. 세션 만료시 자동으로 리디렉션되지 않습니다. 페이지의 아무 부분이나 클릭해야하는데 리디렉션이 시작됩니다.

  5. from https://stackoverflow.com/questions/27775651/how-to-log-out-automatically-with-spring-security by cc-by-sa and MIT license