簡體   English   中英

Spring Security重定向到登錄頁面並在身份驗證成功后終止會話

[英]Spring Security Redirects to login page and kills sessions after authentication success

我正在使用Spring Security 4.2.1對SpringMVC Web應用程序進行身份驗證。 我有一個非常難以捉摸的問題,有時似乎奏效,而被其他人打破(被打破的程度超過其工作范圍)。

問題如下:

  • 嘗試登錄后,AuthenticationProvider會正確驗證用戶身份,並且我在日志中看到Authentication Success(並且Authenticated用戶擁有所需的所有權限,等等,我可以在日志中看到它們)。

  • 然后,該框架似乎為用戶清除了SecurityContextHolder,並且當它嘗試加載登錄頁面時,就好像它們根本沒有經過身份驗證一樣

  • 當然,這會導致重定向回到登錄頁面。

  • 例外是如果我先明確注銷。 如果我轉到注銷地址,那之后我似乎可以登錄。

我已經查看了我的Spring Sec配置,並在其中進行了幾天更改,但仍然得到相同的結果。 我對此失去了理智。

@Override
protected void configure(HttpSecurity http) throws Exception {

    http
        .authorizeRequests()
            .antMatchers(
                "/link/go/*",
                "/pixel/download/*",
                "/favicon.ico",
                "/ping*").permitAll()
            .anyRequest().authenticated()
            .and()
        .formLogin()
            .loginPage("/login")
            .loginProcessingUrl("/j_spring_security_check")
            .defaultSuccessUrl("/")
            .permitAll()
            .authenticationDetailsSource(new CustomAuthenticationDetailsSource())
            .and()
        .logout()
            .permitAll();
}

這是具有以下行為的基本控制器:

@PreAuthorize("isAuthenticated()")
@RequestMapping(value = "/", method = RequestMethod.GET)
public String showIndex() {
    return "pages/index";
}

@RequestMapping(value = "/login", method = RequestMethod.GET)
public String showLogin(HttpServletRequest request, HttpServletResponse response) {
    response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
    return "pages/login";
}

這是我正在使用的基本登錄表單(Thymeleaf):

<form th:action="@{/j_spring_security_check}" method="post" autocomplete="off">
      <div class="group">
        <input type="text" id="username" name="username" autocomplete="off" required="required" /><span class="highlight"></span><span class="bar"></span>
        <label>Username</label>
        <div th:if="${param.error}" class="alert alert-error">    
            Invalid username and password.
        </div>
        <div th:if="${param.logout}" class="alert alert-success"> 
            You have been logged out.
        </div>
      </div>
      <div class="group">
        <input type="password" id="password" name="password" autocomplete="off" required="required" /><span class="highlight"></span><span class="bar"></span>
        <label>Password</label>
      </div>
      <div class="group">
        <input type="text" id="token" name="token" autocomplete="off" required="required" /><span class="highlight"></span><span class="bar"></span>
        <label>Tracker Token</label>
      </div>
      <button type="submit" class="button buttonBlue">Log in
        <div class="ripples buttonRipples"><span class="ripplesCircle"></span></div>
    </button>
</form>

這些是非常相關的日志(成功身份驗證的周期,然后是會話破壞和訪問拒絕)。 我記錄了很多內容,但是我指出了關鍵的部分(帶有*),這樣您就不必太費勁了。

2017-01-24 10:32:25,386 [http-nio-8080-exec-4] DEBUG org.springframework.security.web.FilterChainProxy: /j_spring_security_check at position 1 of 12 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
2017-01-24 10:32:25,386 [http-nio-8080-exec-4] DEBUG org.springframework.security.web.FilterChainProxy: /j_spring_security_check at position 2 of 12 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
2017-01-24 10:32:25,386 [http-nio-8080-exec-4] DEBUG org.springframework.security.web.context.HttpSessionSecurityContextRepository: HttpSession returned null object for SPRING_SECURITY_CONTEXT

*2017-01-24 10:32:25,386 [http-nio-8080-exec-4] DEBUG org.springframework.security.web.context.HttpSessionSecurityContextRepository: No SecurityContext was available from the HttpSession: org.apache.catalina.session.StandardSessionFacade@1ff52ee9. A new one will be created.

2017-01-24 10:32:25,386 [http-nio-8080-exec-4] DEBUG org.springframework.security.web.FilterChainProxy: /j_spring_security_check at position 3 of 12 in additional filter chain; firing Filter: 'HeaderWriterFilter'
2017-01-24 10:32:25,386 [http-nio-8080-exec-4] DEBUG org.springframework.security.web.header.writers.HstsHeaderWriter: Not injecting HSTS header since it did not match the requestMatcher org.springframework.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher@362f8994
2017-01-24 10:32:25,386 [http-nio-8080-exec-4] DEBUG org.springframework.security.web.FilterChainProxy: /j_spring_security_check at position 4 of 12 in additional filter chain; firing Filter: 'CsrfFilter'
2017-01-24 10:32:25,387 [http-nio-8080-exec-4] DEBUG org.springframework.security.web.FilterChainProxy: /j_spring_security_check at position 5 of 12 in additional filter chain; firing Filter: 'LogoutFilter'
2017-01-24 10:32:25,387 [http-nio-8080-exec-4] DEBUG org.springframework.security.web.util.matcher.AntPathRequestMatcher: Checking match of request : '/j_spring_security_check'; against '/logout'
2017-01-24 10:32:25,387 [http-nio-8080-exec-4] DEBUG org.springframework.security.web.FilterChainProxy: /j_spring_security_check at position 6 of 12 in additional filter chain; firing Filter: 'UsernamePasswordAuthenticationFilter'

*2017-01-24 10:32:25,387 [http-nio-8080-exec-4] DEBUG org.springframework.security.web.util.matcher.AntPathRequestMatcher: Checking match of request : '/j_spring_security_check'; against '/j_spring_security_check'
*2017-01-24 10:32:25,387 [http-nio-8080-exec-4] DEBUG org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter: Request is to process authentication
*2017-01-24 10:32:25,388 [http-nio-8080-exec-4] DEBUG org.springframework.security.authentication.ProviderManager: Authentication attempt using com.company.project.tracker.config.security.CustomAuthenticationProvider

2017-01-24 10:32:25,729 [http-nio-8080-exec-4] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory: Returning cached instance of singleton bean 'delegatingApplicationListener'
2017-01-24 10:32:25,729 [http-nio-8080-exec-4] DEBUG org.springframework.security.web.authentication.session.CompositeSessionAuthenticationStrategy: Delegating to org.springframework.security.web.authentication.session.ChangeSessionIdAuthenticationStrategy@473f5bae
2017-01-24 10:32:25,729 [http-nio-8080-exec-4] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory: Returning cached instance of singleton bean 'delegatingApplicationListener'
2017-01-24 10:32:25,729 [http-nio-8080-exec-4] DEBUG org.springframework.security.web.authentication.session.CompositeSessionAuthenticationStrategy: Delegating to org.springframework.security.web.csrf.CsrfAuthenticationStrategy@213137f3

*2017-01-24 10:32:25,730 [http-nio-8080-exec-4] DEBUG org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter: Authentication success. Updating SecurityContextHolder to contain: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@d7d972f2: Principal: com.company.project.tracker.config.security.Principal@50525059; Credentials: [PROTECTED]; Authenticated: true; Details: com.company.project.tracker.config.security.CustomAuthenticationDetailsSource$CustomAuthenticationDetails@b364: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: BFDA41C5C1883560BACC75BB353001CA; Granted Authorities: com.company.project.tracker.config.security.UserAuthority@78746e0b

2017-01-24 10:32:25,730 [http-nio-8080-exec-4] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory: Returning cached instance of singleton bean 'delegatingApplicationListener'

*2017-01-24 10:32:25,730 [http-nio-8080-exec-4] DEBUG org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler: Redirecting to DefaultSavedRequest Url: http://localhost:8080/tracker
*2017-01-24 10:32:25,730 [http-nio-8080-exec-4] DEBUG org.springframework.security.web.DefaultRedirectStrategy: Redirecting to 'http://localhost:8080/tracker'
*2017-01-24 10:32:25,730 [http-nio-8080-exec-4] DEBUG org.springframework.security.web.context.HttpSessionSecurityContextRepository: SecurityContext 'org.springframework.security.core.context.SecurityContextImpl@d7d972f2: Authentication: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@d7d972f2: Principal: com.company.project.tracker.config.security.Principal@50525059; Credentials: [PROTECTED]; Authenticated: true; Details: com.company.project.tracker.config.security.CustomAuthenticationDetailsSource$CustomAuthenticationDetails@b364: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: BFDA41C5C1883560BACC75BB353001CA; Granted Authorities: com.company.project.tracker.config.security.UserAuthority@78746e0b' stored to HttpSession: 'org.apache.catalina.session.StandardSessionFacade@1ff52ee9
*2017-01-24 10:32:25,730 [http-nio-8080-exec-4] DEBUG org.springframework.security.web.context.SecurityContextPersistenceFilter: SecurityContextHolder now cleared, as request processing completed

我認為這是開始處理經過身份驗證的請求的起點(即所有出錯的地方)。

2017-01-24 10:32:25,733 [http-nio-8080-exec-5] DEBUG org.springframework.security.web.FilterChainProxy:  at position 1 of 12 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
2017-01-24 10:32:25,734 [http-nio-8080-exec-5] DEBUG org.springframework.security.web.FilterChainProxy:  at position 2 of 12 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'

*2017-01-24 10:32:25,734 [http-nio-8080-exec-5] DEBUG org.springframework.security.web.context.HttpSessionSecurityContextRepository: No HttpSession currently exists
*2017-01-24 10:32:25,734 [http-nio-8080-exec-5] DEBUG org.springframework.security.web.context.HttpSessionSecurityContextRepository: No SecurityContext was available from the HttpSession: null. A new one will be created.

2017-01-24 10:32:25,734 [http-nio-8080-exec-5] DEBUG org.springframework.security.web.FilterChainProxy:  at position 3 of 12 in additional filter chain; firing Filter: 'HeaderWriterFilter'
2017-01-24 10:32:25,734 [http-nio-8080-exec-5] DEBUG org.springframework.security.web.header.writers.HstsHeaderWriter: Not injecting HSTS header since it did not match the requestMatcher org.springframework.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher@362f8994
2017-01-24 10:32:25,734 [http-nio-8080-exec-5] DEBUG org.springframework.security.web.FilterChainProxy:  at position 4 of 12 in additional filter chain; firing Filter: 'CsrfFilter'
2017-01-24 10:32:25,734 [http-nio-8080-exec-5] DEBUG org.springframework.security.web.FilterChainProxy:  at position 5 of 12 in additional filter chain; firing Filter: 'LogoutFilter'
2017-01-24 10:32:25,734 [http-nio-8080-exec-5] DEBUG org.springframework.security.web.util.matcher.AntPathRequestMatcher: Request 'GET ' doesn't match 'POST /logout
2017-01-24 10:32:25,734 [http-nio-8080-exec-5] DEBUG org.springframework.security.web.FilterChainProxy:  at position 6 of 12 in additional filter chain; firing Filter: 'UsernamePasswordAuthenticationFilter'
2017-01-24 10:32:25,734 [http-nio-8080-exec-5] DEBUG org.springframework.security.web.util.matcher.AntPathRequestMatcher: Request 'GET ' doesn't match 'POST /j_spring_security_check
2017-01-24 10:32:25,734 [http-nio-8080-exec-5] DEBUG org.springframework.security.web.FilterChainProxy:  at position 7 of 12 in additional filter chain; firing Filter: 'RequestCacheAwareFilter'
2017-01-24 10:32:25,734 [http-nio-8080-exec-5] DEBUG org.springframework.security.web.FilterChainProxy:  at position 8 of 12 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter'
2017-01-24 10:32:25,734 [http-nio-8080-exec-5] DEBUG org.springframework.security.web.FilterChainProxy:  at position 9 of 12 in additional filter chain; firing Filter: 'AnonymousAuthenticationFilter'

*2017-01-24 10:32:25,734 [http-nio-8080-exec-5] DEBUG org.springframework.security.web.authentication.AnonymousAuthenticationFilter: Populated SecurityContextHolder with anonymous token: 'org.springframework.security.authentication.AnonymousAuthenticationToken@9055c2bc: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@b364: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: null; Granted Authorities: ROLE_ANONYMOUS'

2017-01-24 10:32:25,734 [http-nio-8080-exec-5] DEBUG org.springframework.security.web.FilterChainProxy:  at position 10 of 12 in additional filter chain; firing Filter: 'SessionManagementFilter'
2017-01-24 10:32:25,734 [http-nio-8080-exec-5] DEBUG org.springframework.security.web.FilterChainProxy:  at position 11 of 12 in additional filter chain; firing Filter: 'ExceptionTranslationFilter'
2017-01-24 10:32:25,734 [http-nio-8080-exec-5] DEBUG org.springframework.security.web.FilterChainProxy:  at position 12 of 12 in additional filter chain; firing Filter: 'FilterSecurityInterceptor'
2017-01-24 10:32:25,734 [http-nio-8080-exec-5] DEBUG org.springframework.security.web.util.matcher.AntPathRequestMatcher: Request 'GET ' doesn't match 'POST /logout
2017-01-24 10:32:25,734 [http-nio-8080-exec-5] DEBUG org.springframework.security.web.util.matcher.AntPathRequestMatcher: Checking match of request : ''; against '/link/go/*'
2017-01-24 10:32:25,734 [http-nio-8080-exec-5] DEBUG org.springframework.security.web.util.matcher.AntPathRequestMatcher: Checking match of request : ''; against '/pixel/download/*'
2017-01-24 10:32:25,734 [http-nio-8080-exec-5] DEBUG org.springframework.security.web.util.matcher.AntPathRequestMatcher: Checking match of request : ''; against '/favicon.ico'
2017-01-24 10:32:25,734 [http-nio-8080-exec-5] DEBUG org.springframework.security.web.util.matcher.AntPathRequestMatcher: Checking match of request : ''; against '/ping*'
2017-01-24 10:32:25,734 [http-nio-8080-exec-5] DEBUG org.springframework.security.web.access.intercept.FilterSecurityInterceptor: Secure object: FilterInvocation: URL: ; Attributes: [authenticated]

*2017-01-24 10:32:25,734 [http-nio-8080-exec-5] DEBUG org.springframework.security.web.access.intercept.FilterSecurityInterceptor: Previously Authenticated: org.springframework.security.authentication.AnonymousAuthenticationToken@9055c2bc: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@b364: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: null; Granted Authorities: ROLE_ANONYMOUS
*2017-01-24 10:32:25,734 [http-nio-8080-exec-5] DEBUG org.springframework.security.access.vote.AffirmativeBased: Voter: org.springframework.security.web.access.expression.WebExpressionVoter@2cca1b0b, returned: -1
*2017-01-24 10:32:25,734 [http-nio-8080-exec-5] DEBUG org.springframework.security.web.access.ExceptionTranslationFilter: Access is denied (user is anonymous); redirecting to authentication entry point
org.springframework.security.access.AccessDeniedException: Access is denied

因此,您可以看到,當它返回到“ /”地址時,該會話消失了,並且該會話中存儲的原始正確對象被匿名身份驗證對象替換,該身份驗證對象顯然無權訪問'/'。 我還包括了相應的響應和請求標頭(通過chrome),它們來自與上述日志相同的請求周期:

所有三個請求

任何幫助將不勝感激。 我確定我在做一些愚蠢的事情。 我已經使用了這個框架很多年,甚至編寫了大量的自定義組件,但是這個框架讓我徹底迷住了(1d +的實驗)。 我可以提供其他任何文件或示例,如果它們有助於深入了解它。

謝謝。

TRy添加http.csrf()。disable(); 您的代碼。 可能是CSRF過濾器攔截了您的請求。

我在您提供的日志中看到過濾器調用。

暫無
暫無

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

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