簡體   English   中英

Spring Security登錄/注銷問題

[英]Spring Security login/logout problems

我正在使用Spring 4.3.3,並且正在嘗試為我的應用程序實現登錄/注銷功能。 我遇到的問題是,如果我登錄並再次注銷后,所有工作都可以按預期進行。 我被帶到URL:login?logout的登錄頁面,並在登錄框中輸入了成功注銷的消息。 但是,如果我登錄並導航到另一個頁面然后注銷,則我將再次正確進入帶登錄框的成功注銷消息的登錄頁面,但是當我單擊“登錄”時,我卻沒有登錄。使用URL:無消息登錄,我需要再次單擊登錄才能登錄。以下是我正在使用的一些代碼

security.xml文件

<http pattern="/resources/**" security="none"/>
<http pattern="/forgot**" security="none"/>
<http pattern="/reset**" security="none" />
<!-- enable use-expressions -->
<security:http 
    auto-config="false" 
    use-expressions="true">
    <headers><cache-control/></headers>
    <security:intercept-url pattern="/resources**" access="permitAll" />
    <security:intercept-url pattern="/login**" access="permitAll" />
    <security:intercept-url pattern="/users**" access="hasAnyRole('ROLE_USER','ROLE_ADMIN')" />
    <security:intercept-url pattern="/suppliers**" access="hasAnyRole('ROLE_USER','ROLE_ADMIN')" />
    <security:intercept-url pattern="/reports**" access="hasAnyRole('ROLE_USER','ROLE_ADMIN')" />
    <security:intercept-url pattern="/games**" access="hasAnyRole('ROLE_USER','ROLE_ADMIN')" />
    <security:intercept-url pattern="/clients**" access="hasAnyRole('ROLE_USER','ROLE_ADMIN')" />
    <security:intercept-url pattern="/servers**" access="hasAnyRole('ROLE_USER','ROLE_ADMIN')" />
    <security:intercept-url pattern="/**" access="hasAnyRole('ROLE_USER','ROLE_ADMIN')"/>
    <security:intercept-url pattern="/logs**" access="hasAnyRole('ROLE_USER','ROLE_ADMIN')"/>

<!-- access denied page -->
    <access-denied-handler error-page="/403" />
    <security:form-login 
        login-page="/login" 
        authentication-failure-url="/login?error" 

        username-parameter="username"
        password-parameter="password" 
        login-processing-url="/auth/login_check" />

    <security:logout 
        invalidate-session="true"
        logout-success-url="/login"
        logout-url="/login?logout"
        delete-cookies="JSESSIONID"/>
    <!-- enable csrf protection -->
    <csrf/>
    <!-- Default lifeTime 2 weeks can be configured -->
    <!--<remember-me key="uniqueAndSecret"/>-->
</security:http>

控制器方式

@RequestMapping(value = "/login", method = RequestMethod.GET)
public @ResponseBody ModelAndView login( @RequestParam(value = "error", required = false) String error, @RequestParam(value = "logout", required = false) String logout, HttpServletResponse response, HttpServletRequest request, SessionStatus sessionStatus) throws IOException {

    ModelAndView model = new ModelAndView();

    if (error != null) {
        model.addObject("error", getErrorMessage(request, "SPRING_SECURITY_LAST_EXCEPTION"));
    }

    if (logout != null) {

        HttpSession session= request.getSession(false);

        SecurityContextHolder.clearContext();
        session= request.getSession(false);

        if(session != null) {
            session.invalidate();
        }

        for(Cookie cookie : request.getCookies()) {
                cookie.setMaxAge(0);
        }

        //sessionStatus.setComplete();
        //request.getSession(false).invalidate();

        model.addObject("msg", "You've been logged out successfully.");
    }
    model.setViewName("login");
    return model;

}

login.jsp的

<form name='loginForm' action="<c:url value='/auth/login_check?targetUrl=${targetUrl}' />" method='POST'>
        <div class="form-group">
            <div id="emailError" class="alert alert-danger" style="display:none;"></div> 
            <label for="email">Email
                <input  class="form-control" id="email" type="email" name="username" placeholder="Email">
            </label> 
        </div>
        <div class="form-group">
            <label for="password">Password
                <input class="form-control" id="password" type="password" name="password" placeholder="Password">
            </label>
        </div>
            Remember Me: <input type="checkbox" name="remember-me" />
            <input id="login"class="btn btn-primary" name="submit" type="submit" value="Login">
            <div><a id="forgotPass">forgot password</a></div>
        <input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" />
    </form>

從您的安全配置來看,我不確定您是否正在使用CookieCsrfTokenRepository 我看到您在注銷時手動使所有cookie過期:

 for(Cookie cookie : request.getCookies()) {
     cookie.setMaxAge(0);
 }

除非您在應用程序中手動設置了其他cookie,否則默認情況下會刪除會話cookie,因為您已將其配置為:

<security:logout 
    ...
    delete-cookies="JSESSIONID"/>

我的猜測是,您還要清除CSRF令牌Cookie,因此無需令牌即可呈現的登錄頁面。 由於CSRF的不匹配,提交表單可能會在無提示的情況下失敗,從而使您返回登錄頁面。 這次,將再次設置CSRF值,並且隨后的登錄嘗試成功。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM