2012-02-15 1 views
3

Spring Security의 3.1.0 remember-me 쿠키에 문제가 있습니다. 최대한 빨리 해결책을 찾아야하며이 문제의 원인을 찾을 수 없습니다. Spring Security 3.1.0 - Remember-me가 예상대로 작동하지 않습니다.

  • 내 응용 프로그램의 URL (예 : http://myapp/app.htm)
  • 나는 로그인 페이지로 리디렉션하고, 그래서
  • 일단 로그인 로그인, 가까운 브라우저로 이동

    이 내가 다음하고있는 단계입니다 및

  • 열기 브라우저를 로그 아웃하지 않고하는 것은 내 응용 프로그램 bypassin를 입력 할 것으로 예상이 시점에서 내 응용 프로그램의 URL

로 이동 g remember-me 쿠키는 여전히 내 브라우저에 있기 때문에 로그인 양식을 사용하십시오. 이 사실에도 불구하고 로그인 페이지가 다시 나타납니다.

  • 나는 일반적으로 로그인 양식을 우회 내 응용 프로그램을 입력 할 수 있습니다, 다시

다시 시도 내 응용 프로그램의 URL로 이동합니다.

이것은 매우 혼란스럽고 지금까지 설명을 찾을 수 없습니다.

나는 모두 시도를 디버깅하기 위해 노력하고 나는 봄 보안의 RememberMeAuthenticationFilter 해고 할 때 다음과 같은 발견 :

시도 1
요청 경로 = /app.htm : request.getCookes()를가() 내 SPRING_SECURITY_REMEMBER_ME_COOKIE가 포함되어 있지 않습니다 따라서를 로그인 페이지로 리디렉션되었습니다. 요청 경로 = /security/login.htm :이 시점에서 request.getCookies() DID에 내 SPRING_SECURITY_REMEMBER_ME_COOKIE이 (가) 허용되었습니다. 어쨌든, 이미 로그인 페이지로 리디렉션되었습니다.

시도 2 ​​
remember-me 쿠키가 이미 허용되었으므로 아무 문제없이 입력 할 수 있습니다.

다음은 스프링 보안 XML 구성과 두 시도의 로그입니다.

이 문제에 대한 도움을 주시면 매우 감사하겠습니다. (운영 체제 및 OSS와 org.springframework.security로 org.springframework 교체) 첫 번째 시도에 대한

<sec:http auto-config="false" use-expressions="true" authentication-manager-ref="authenticationManager"> 
    <sec:custom-filter ref="sessionLocaleResolvingFilter" before="FORM_LOGIN_FILTER"/> 

    <sec:intercept-url pattern="/security/*.htm" requires-channel="https" /> 
    <sec:intercept-url pattern="/retrieve-password/*.htm" requires-channel="https" /> 
    <sec:intercept-url pattern="/messagebroker/*" access="authenticated" requires-channel="http" /> 
    <sec:intercept-url pattern="/platform/*.htm" 
     access="hasRole('limited') or (authenticated and !hasRole('role1') and !hasRole('role2'))" 
     requires-channel="http" /> 
    <sec:intercept-url pattern="/app.htm" access="authenticated" requires-channel="http" /> 
    <sec:intercept-url pattern="/**" requires-channel="http" /> 
    <sec:form-login login-page="/security/login.htm" default-target-url="/app.htm" 
     login-processing-url="/security/process-login.htm" authentication-failure-url="/security/login.htm?error=true" /> 
    <sec:logout logout-url="/security/logout.htm" delete-cookies="JSESSIONID,SPRING_SECURITY_REMEMBER_ME_COOKIE" 
     logout-success-url="/security/logout-success.htm" invalidate-session="true"/> 
    <sec:anonymous/> 
    <sec:remember-me use-secure-cookie="true" key="myAppServices" 
     services-ref="ipTokenBasedRememberMeServicesBean" /> 
    <sec:session-management session-fixation-protection="none"/> 
    <sec:access-denied-handler error-page="/denied-access.htm"/> 
</sec:http> 

<bean id="sessionLocaleResolvingFilter" class="com.myapp.spring.security.SessionLocaleResolvingFilter" /> 
<bean class="com.myapp.spring.security.IPTokenBasedRememberMeServices" 
    id="ipTokenBasedRememberMeServicesBean"> 
    <constructor-arg value="myAppServices"/> 
    <constructor-arg ref="myAppJdbcDaoImpl"/> 
</bean> 
<bean id="myAppPasswordEncoder" class="com.myapp.spring.security.MyAppPasswordEncoder" /> 
<bean id="authenticationManager" 
    class="o.s.s.authentication.ProviderManager"> 
    <property name="providers"> 
     <list> 
      <ref local="daoAuthenticationProvider" /> 
     </list> 
    </property> 
</bean> 
<!-- Other beans... --> 

로그 :


봄 보안 구성 (나는 DaoAuthenticationProvider는 이벤트 리스너에 대한 모든 것을 생략합니다) : 내 두 번째 시도의

o.s.s.web.access.channel.ChannelProcessingFilter:134 - Request: FilterInvocation: URL: /app.htm?lang=en; ConfigAttributes: [REQUIRES_INSECURE_CHANNEL] 
o.s.s.web.context.HttpSessionSecurityContextRepository:127 - No HttpSession currently exists 
o.s.s.web.context.HttpSessionSecurityContextRepository:85 - No SecurityContext was available from the HttpSession: null. A new one will be created. 
o.s.s.web.FilterChainProxy:318 - /app.htm?lang=en at position 9 of 11 in additional filter chain; firing Filter: 'AnonymousAuthenticationFilter' 
o.s.s.web.authentication.AnonymousAuthenticationFilter:102 - Populated SecurityContextHolder with anonymous token: '[email protected]: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: [email protected]: RemoteIpAddress: fe80:0:0:0:ec09:25fb:3df4:323b; SessionId: 057E689401E69589BB7359F3E95B4A18; Granted Authorities: ROLE_ANONYMOUS' 
o.s.s.web.FilterChainProxy:318 - /app.htm?lang=en at position 10 of 11 in additional filter chain; firing Filter: 'ExceptionTranslationFilter' 
o.s.s.web.FilterChainProxy:318 - /app.htm?lang=en at position 11 of 11 in additional filter chain; firing Filter: 'FilterSecurityInterceptor' 
o.s.s.web.util.AntPathRequestMatcher:103 - Checking match of request : '/app.htm'; against '/messagebroker/*' 
o.s.s.web.util.AntPathRequestMatcher:103 - Checking match of request : '/app.htm'; against '/app.htm' 
o.s.s.web.access.intercept.FilterSecurityInterceptor:193 - Secure object: FilterInvocation: URL: /app.htm?lang=en; Attributes: [authenticated] 
o.s.s.web.access.intercept.FilterSecurityInterceptor:298 - Previously Authenticated: [email protected]: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: [email protected]: RemoteIpAddress: fe80:0:0:0:ec09:25fb:3df4:323b; SessionId: 057E689401E69589BB7359F3E95B4A18; Granted Authorities: ROLE_ANONYMOUS 
o.s.s.access.vote.AffirmativeBased:65 - Voter: [email protected], returned: -1 
o.s.s.web.access.ExceptionTranslationFilter:165 - Access is denied (user is anonymous); redirecting to authentication entry point 
o.s.s.access.AccessDeniedException: Access is denied 
    at o.s.s.access.vote.AffirmativeBased.decide(AffirmativeBased.java:83) 
    at o.s.s.access.intercept.AbstractSecurityInterceptor.beforeInvocation(AbstractSecurityInterceptor.java:205) 
    at o.s.s.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:114) 
    at o.s.s.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:83) 
    at o.s.s.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323) 
    at o.s.s.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113) 
    at o.s.s.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323) 
    (X more) 

o.s.s.web.DefaultRedirectStrategy:36 - Redirecting to 'http://arbad67464/services/security/login.htm' 
o.s.s.web.context.HttpSessionSecurityContextRepository:269 - SecurityContext is empty or contents are anonymous - context will not be stored in HttpSession. 
o.s.s.web.context.SecurityContextPersistenceFilter:97 - SecurityContextHolder now cleared, as request processing completed 

o.s.s.web.access.channel.RetryWithHttpsEntryPoint:55 - Redirecting to: https://arbad67464/services/security/login.htm 
o.s.s.web.DefaultRedirectStrategy:36 - Redirecting to 'https://arbad67464/services/security/login.htm' 

o.s.s.web.access.channel.ChannelProcessingFilter:134 - Request: FilterInvocation: URL: /security/login.htm; ConfigAttributes: [REQUIRES_SECURE_CHANNEL] 
o.s.s.web.FilterChainProxy:318 - /security/login.htm at position 2 of 11 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter' 
o.s.s.web.context.HttpSessionSecurityContextRepository:139 - HttpSession returned null object for SPRING_SECURITY_CONTEXT 
o.s.s.web.context.HttpSessionSecurityContextRepository:85 - No SecurityContext was available from the HttpSession: [email protected] A new one will be created. 
o.s.s.web.FilterChainProxy:318 - /security/login.htm at position 3 of 11 in additional filter chain; firing Filter: 'LogoutFilter' 
o.s.s.web.FilterChainProxy:318 - /security/login.htm at position 4 of 11 in additional filter chain; firing Filter: 'SessionLocaleResolvingFilter' 
o.s.s.web.FilterChainProxy:318 - /security/login.htm at position 5 of 11 in additional filter chain; firing Filter: 'UsernamePasswordAuthenticationFilter' 
o.s.s.web.FilterChainProxy:318 - /security/login.htm at position 6 of 11 in additional filter chain; firing Filter: 'RequestCacheAwareFilter' 

o.s.s.web.FilterChainProxy:318 - /security/login.htm at position 7 of 11 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter' 
o.s.s.web.FilterChainProxy:318 - /security/login.htm at position 8 of 11 in additional filter chain; firing Filter: 'RememberMeAuthenticationFilter' 
com.myapp.spring.security.IPTokenBasedRememberMeServices:103 - Remember-me cookie detected 
com.myapp.spring.security.IPTokenBasedRememberMeServices:118 - Remember-me cookie accepted 
o.s.s.authentication.ProviderManager:152 - Authentication attempt using o.s.s.authentication.RememberMeAuthenticationProvider 

로그 :

o.s.s.web.access.channel.ChannelProcessingFilter:134 - Request: FilterInvocation: URL: /app.htm?lang=en; ConfigAttributes: [REQUIRES_INSECURE_CHANNEL] 
o.s.s.web.context.HttpSessionSecurityContextRepository:158 - Obtained a valid SecurityContext from SPRING_SECURITY_CONTEXT: '[email protected]: Authentication: [email protected]: Principal: [email protected]: Username: [email protected]; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: limited,premium,special; Credentials: [PROTECTED]; Authenticated: true; Details: [email protected]: RemoteIpAddress: fe80:0:0:0:ec09:25fb:3df4:323b; SessionId: 057E689401E69589BB7359F3E95B4A18; Granted Authorities: limited, premium, special' 
o.s.s.web.FilterChainProxy:318 - /app.htm?lang=en at position 8 of 11 in additional filter chain; firing Filter: 'RememberMeAuthenticationFilter' 
o.s.s.web.authentication.rememberme.RememberMeAuthenticationFilter:142 - SecurityContextHolder not populated with remember-me token, as it already contained: '[email protected]: Principal: [email protected]: Username: [email protected]; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: limited,premium,special; Credentials: [PROTECTED]; Authenticated: true; Details: [email protected]: RemoteIpAddress: fe80:0:0:0:ec09:25fb:3df4:323b; SessionId: 057E689401E69589BB7359F3E95B4A18; Granted Authorities: limited, premium, special' 
o.s.s.web.FilterChainProxy:318 - /app.htm?lang=en at position 9 of 11 in additional filter chain; firing Filter: 'AnonymousAuthenticationFilter' 
o.s.s.web.authentication.AnonymousAuthenticationFilter:107 - SecurityContextHolder not populated with anonymous token, as it already contained: '[email protected]: Principal: [email protected]: Username: [email protected]; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: limited,premium,special; Credentials: [PROTECTED]; Authenticated: true; Details: [email protected]: RemoteIpAddress: fe80:0:0:0:ec09:25fb:3df4:323b; SessionId: 057E689401E69589BB7359F3E95B4A18; Granted Authorities: limited, premium, special' 
o.s.s.web.access.intercept.FilterSecurityInterceptor:193 - Secure object: FilterInvocation: URL: /app.htm?lang=en; Attributes: [authenticated] 
o.s.s.web.access.intercept.FilterSecurityInterceptor:298 - Previously Authenticated: [email protected]: Principal: [email protected]: Username: [email protected]; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: limited,premium,special; Credentials: [PROTECTED]; Authenticated: true; Details: [email protected]: RemoteIpAddress: fe80:0:0:0:ec09:25fb:3df4:323b; SessionId: 057E689401E69589BB7359F3E95B4A18; Granted Authorities: limited, premium, special 
o.s.s.access.vote.AffirmativeBased:65 - Voter: [email protected], returned: 1 
o.s.s.web.access.intercept.FilterSecurityInterceptor:214 - Authorization successful 
+0

더 쉽게 소화 무언가로이 내려 트림하시기 바랍니다. 지금은 사람들이 시간을 들여 보지 않아도되도록하는 벽/텍스트/코드 일뿐입니다. 또한 모든 코드와 로그를 그냥 버리면 실제로 발생한 * 문제를 찾아 내려고 여기에 * 도움을 요청하는 데 최소한의 노력을 나타냅니다. – casperOne

+1

좋아, 나는 그것을 압도적 인일지도 모른다 이해한다, 그래서 나는 그것을 아래로 정정하는 것을 시도 할 것이다. 그러나 내 기록을 버렸을 때 도움이 될 수있는 사람들에게 유용한 추가 정보를 제공하기로했다는 것을 이해하십시오. 그 자체로 최소한의 노력을 나타내는 지표는 아닙니다. 로그를 신중하게 읽고 앱을 디버깅하고 게시하기 전에 여러 곳에서 솔루션을 찾으려고했습니다. 또한, 모든 XML 코드만을 덤프하지 않았습니다. 내가하지 않으면, 어떻게 누군가가 도울 수 있겠습니까? 어쨌든, 귀하의 의견에 감사드립니다. – nomusicnolife

답변

3

나는 HTTPS를 사용하도록 구성된 일부 URL이 있다는 사실과 관련이 있다고 생각합니다.

remember-me 쿠키는 안전한 것으로 표시됩니다 (브라우저에서 수신 한 set-cookie 헤더 및 브라우저 쿠키 캐시에서도 확인할 수 있음). /app에 대한 요청이 HTTP를 통해 이루어지기 때문에 쿠키가 전송되지 않습니다. 그러나 로그인 페이지에 대한 요청은 쿠키가 전송되는 HTTPS로 리디렉션됩니다.

실제로 HTTPS를 사용해야합니다. 구성하기가 더 쉽고 앱이 그렇지 않은 경우에는 안전하지 않습니다. 그러나 remember-me namespace element에는 use-secure-cookie 옵션이 있으며, false로 설정하면 기본 동작을 무시할 수 있습니다.

+0

네, 그게 문제였습니다. 어쨌든 HTTPS를 강제하지 않기 위해' '엘리먼트에서'requires-channel' 애트리뷰트를 모두 지우려고했는데 첫 번째 시도에서 remember-me 쿠키가 감지되었습니다. 완전히 안전한 것은 아니지만 실제로 XML에서 HTTPS를 구성하라는 요청을 받았지만 이러한 쿠키가 제대로 작동하도록 전체 세션을 통해 사용해야 할 수도 있습니다. 채널 구성을 조정하려고합니다. 내가 그 일을 끝내면 결과를 게시 할 것입니다. 감사합니다. 루크! – nomusicnolife

+0

차가움. 앞서 말했듯이, 쿠키가 안전하지 않은 것으로 표시되어 쿠키가 HTTP와 HTTPS 모두에서 전송되도록 할 수도 있습니다. –

+0

이것은 실제로 허용 된 대답이어야합니다. – Ajax

5

스프링 보안에서는 rememberMe 서비스를 사용하는 두 가지 방법을 제공합니다.

  1. rememberMeService 정의에서 alwaysRememberMe 속성이 true로 설정됩니다. 이 경우 처음으로 사용자가 보안 URL에 액세스하려고 시도 할 때마다 페이지에 로그인해야합니다. 사용자가 올바른 사용자 이름과 암호로 로그인하면 이후에 로그 아웃 할 때까지 에 로그인하라는 메시지가 표시되지 않습니다.

  2. 로그인 페이지에서 "_spring_security_remember_me"이름이 이고 값이 "true"인 나를 기억 확인란을 추가하십시오. 이 경우 사용자가 나 기억하기 확인란을 선택하면 로그 아웃 할 때까지 로그인 페이지없이 보안 URL에 액세스 할 수 있습니다. 나를 위해 일하는

그 ..