2012-09-21 3 views
0

Spring Roo 환경에서 Spring Security 3.1.RELEASE를 사용하고 있습니다. JSON-Response와 함께 작동하도록 로그인 메커니즘을 변경했습니다. 다음과 같이 그 동안 나는 두 개의 클래스 (스칼라) 즉사용자 정의 필터를 사용한 후 remember-me 인증이 지속되었습니다.

class JsonSuccessHandler extends SimpleUrlAuthenticationSuccessHandler { 
override def onAuthenticationSuccess(request: HttpServletRequest, response: HttpServletResponse, authentication: Authentication) = { 
    val responseWrapper = new HttpServletResponseWrapper(response); 
    val out = responseWrapper.getWriter 
    out.write("{success: true}") 
    out.close 
} 
} 

@Repository class JsonEntryPoint extends AuthenticationEntryPoint { 
def commence(request: HttpServletRequest, response: HttpServletResponse, ae: AuthenticationException) = { 
    response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized") 
} 
} 

응용 프로그램-security.xml의 항목은을 만들었습니다

<http use-expressions="true" entry-point-ref="jsonAuthenticationEntryPoint"> 
    <custom-filter ref="myFilter" position="FORM_LOGIN_FILTER"/> 
    <custom-filter ref="rememberMeFilter" position="REMEMBER_ME_FILTER"/> 

    <logout logout-url="/resources/j_spring_security_logout"/> 

    <intercept-url pattern="/backend/**" access="isAuthenticated()" /> 
    <intercept-url pattern="/resources/**" access="permitAll" /> 
    <intercept-url pattern="/admin/**" access="hasRole('ROLE_ADMIN')" /> 
    <intercept-url pattern="/**" access="permitAll" /> 
</http> 


<beans:bean id="rememberMeFilter" class="org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter"> 
    <beans:property name="rememberMeServices" ref="rememberMeServices"/> 
    <beans:property name="authenticationManager" ref="authenticationManager" /> 
</beans:bean> 

<beans:bean id="rememberMeServices" class="org.springframework.security.web.authentication.rememberme.JdbcTokenBasedRememberMeServices"> 
    <beans:property name="userDetailsService" ref="userServiceDb"/> 
    <beans:property name="tokenRepository" ref="tokenRepository"/> 
    <beans:property name="key" value="reservation" /> 
</beans:bean> 

<beans:bean id="tokenRepository" class="org.springframework.security.web.authentication.rememberme.JdbcTokenRepositoryImpl"> 
<beans:property name="dataSource" ref="dataSource"/> 
</beans:bean> 


<beans:bean id="myFilter" class="org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter"> 
    <beans:property name="authenticationManager" ref="authenticationManager" /> 
    <beans:property name="authenticationSuccessHandler" ref="mySuccessHandler" /> 
    <beans:property name="rememberMeServices" ref="rememberMeServices" /> 
    <beans:property name="usernameParameter" value="email" /> 
    <beans:property name="passwordParameter" value="password" /> 
</beans:bean> 
<beans:bean id="mySuccessHandler" class="JsonSuccessHandler"/> 
<beans:bean id="jsonAuthenticationEntryPoint" class="JsonEntryPoint" /> 
인증 잘 작동, 그래서 성공적으로 로그인 할 수

도 remember-me와 관련하여 데이터는 데이터베이스에 성공적으로 저장됩니다 (테이블 persistent_logins). 하지만 서버를 다시 시작하면 세션이 예상대로 삭제되고 기억 기능이 작업을 수행해야합니다. 죄송 합니다만 다음 로그 데이터와 함께 실패합니다.

[INFO] Started Jetty Server 
17:19:15.867 [qtp1943091306-38] DEBUG o.s.security.web.FilterChainProxy -/at position 1 of 10 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter' 
17:19:15.875 [qtp1943091306-38] DEBUG o.s.s.w.c.HttpSessionSecurityContextRepository - No HttpSession currently exists 
17:19:15.875 [qtp1943091306-38] DEBUG o.s.s.w.c.HttpSessionSecurityContextRepository - No SecurityContext was available from the HttpSession: null. A new one will be created. 
17:19:15.877 [qtp1943091306-38] DEBUG o.s.security.web.FilterChainProxy -/at position 2 of 10 in additional filter chain; firing Filter: 'LogoutFilter' 
17:19:15.878 [qtp1943091306-38] DEBUG o.s.security.web.FilterChainProxy -/at position 3 of 10 in additional filter chain; firing Filter: 'UsernamePasswordAuthenticationFilter' 
17:19:15.878 [qtp1943091306-38] DEBUG o.s.security.web.FilterChainProxy -/at position 4 of 10 in additional filter chain; firing Filter: 'RequestCacheAwareFilter' 
17:19:15.878 [qtp1943091306-38] DEBUG o.s.security.web.FilterChainProxy -/at position 5 of 10 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter' 
17:19:15.879 [qtp1943091306-38] DEBUG o.s.security.web.FilterChainProxy -/at position 6 of 10 in additional filter chain; firing Filter: 'RememberMeAuthenticationFilter' 
17:19:15.879 [qtp1943091306-38] DEBUG o.s.s.w.a.r.PersistentTokenBasedRememberMeServices - Remember-me cookie detected 
17:19:15.895 [qtp1943091306-38] DEBUG o.s.jdbc.core.JdbcTemplate - Executing prepared SQL query 
17:19:15.895 [qtp1943091306-38] DEBUG o.s.jdbc.core.JdbcTemplate - Executing prepared SQL statement [select username,series,token,last_used from persistent_logins where series = ?] 
17:19:15.896 [qtp1943091306-38] DEBUG o.s.jdbc.datasource.DataSourceUtils - Fetching JDBC Connection from DataSource 
17:19:15.922 [qtp1943091306-38] DEBUG o.s.jdbc.datasource.DataSourceUtils - Returning JDBC Connection to DataSource 
17:19:15.938 [qtp1943091306-38] DEBUG o.s.s.w.a.r.PersistentTokenBasedRememberMeServices - Refreshing persistent login token for user '[email protected]', series 'oLmZMQbnFsfyTziANriMKw==' 
17:19:15.939 [qtp1943091306-38] DEBUG o.s.jdbc.core.JdbcTemplate - Executing prepared SQL update 
17:19:15.944 [qtp1943091306-38] DEBUG o.s.jdbc.core.JdbcTemplate - Executing prepared SQL statement [update persistent_logins set token = ?, last_used = ? where series = ?] 
17:19:15.944 [qtp1943091306-38] DEBUG o.s.jdbc.datasource.DataSourceUtils - Fetching JDBC Connection from DataSource 
17:19:15.984 [qtp1943091306-38] DEBUG o.s.jdbc.core.JdbcTemplate - SQL update affected 1 rows 
17:19:15.992 [qtp1943091306-38] DEBUG o.s.jdbc.datasource.DataSourceUtils - Returning JDBC Connection to DataSource 
17:19:15.996 [qtp1943091306-38] DEBUG o.s.jdbc.core.JdbcTemplate - Executing prepared SQL query 
17:19:15.996 [qtp1943091306-38] DEBUG o.s.jdbc.core.JdbcTemplate - Executing prepared SQL statement [select email username, password, isactive enabled from principal where email = ?] 
17:19:15.996 [qtp1943091306-38] DEBUG o.s.jdbc.datasource.DataSourceUtils - Fetching JDBC Connection from DataSource 
17:19:16.001 [qtp1943091306-38] DEBUG o.s.jdbc.datasource.DataSourceUtils - Returning JDBC Connection to DataSource 
17:19:16.013 [qtp1943091306-38] DEBUG o.s.jdbc.core.JdbcTemplate - Executing prepared SQL query 
17:19:16.013 [qtp1943091306-38] DEBUG o.s.jdbc.core.JdbcTemplate - Executing prepared SQL statement [select p.email username, a.authority from principal p inner join principal_authority apa on p.id = apa.principal_id inner join authority a on a.id = apa.authorities_id where p.email = ?] 
17:19:16.013 [qtp1943091306-38] DEBUG o.s.jdbc.datasource.DataSourceUtils - Fetching JDBC Connection from DataSource 
17:19:16.015 [qtp1943091306-38] DEBUG o.s.jdbc.datasource.DataSourceUtils - Returning JDBC Connection to DataSource 
17:19:16.021 [qtp1943091306-38] DEBUG o.s.s.w.a.r.PersistentTokenBasedRememberMeServices - Remember-me cookie accepted 
17:19:16.036 [qtp1943091306-38] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Returning cached instance of singleton bean 'org.springframework.context.annotation.internalScheduledAnnotationProcessor' 
17:19:16.042 [qtp1943091306-38] DEBUG o.s.s.w.a.r.RememberMeAuthenticationFilter - SecurityContextHolder not populated with remember-me token, as AuthenticationManager rejected Authentication returned by RememberMeServices: 'org.spring[email protected]2fb6ff6b: Principal: [email protected]: Username: [email protected]; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_PHYSIOTHERAPEUT; Credentials: [PROTECTED]; Authenticated: true; Details: org.sprin[email protected]957e: RemoteIpAddress: 127.0.0.1; SessionId: null; Granted Authorities: ROLE_PHYSIOTHERAPEUT'; invalidating remember-me token 
org.springframework.security.authentication.ProviderNotFoundException: No AuthenticationProvider found for org.springframework.security.authentication.RememberMeAuthenticationToken 
    at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:196) ~[spring-security-core-3.1.0.RELEASE.jar:3.1.0.RELEASE] 
    at org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter.doFilter(RememberMeAuthenticationFilter.java:102) ~[spring-security-web-3.1.0.RELEASE.jar:3.1.0.RELEASE] 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323) [spring-security-web-3.1.0.RELEASE.jar:3.1.0.RELEASE] 

무엇이 누락 되었습니까? ProviderNotFoundException이 Throw되는 이유를 모르겠다.

+0

(라인'log4j.logger.org.springframework.security = DEBUG' log4j.properties를 추가)에 디버그를 설정하십시오 출력을 게시 : 당신의 AuthenticationManager를 만들 보안 네임 스페이스를 사용하는 경우, 여기처럼 별도의 <authentication-provider>를 추가 (기억하지 못하는) 기억 - 나는 당신의 질문에 여기에서 요청합니다. – Xaerxess

+0

이제 로그 출력이 게시됩니다. – rainerhahnekamp

+0

디버그 메시지에 'UsernamePasswordAuthenticationToken'이 발견되어서 remember-me가 사용되지 않았기 때문에 remember-me에 문제가없는 것으로 보입니다. 일반 로그인, 세션 만료 및 remember-me 로그인 시도로 시작하여 전체 ** 디버그 출력을 게시 할 수 있습니까? 또한 "인증은 정상적으로 작동하지만 remember-me 기능은 전혀 작동하지 않는다"는 의미를 정확히 정의하십시오. – Xaerxess

답변

2

거의 완료되었습니다. 인증이 작동합니다. RememberMeAuthenticationProvider을 잊어 버렸습니다.

<authentication-manager> 
    <authentication-provider ref="yourRegularAuthenticationProvider" /> 
    <authentication-provider ref="rememberMeAuthenticationProvider" /> 
</authentication-manager> 

<beans:bean id="rememberMeAuthenticationProvider" class="org.springframework.security.authentication.RememberMeAuthenticationProvider"> 
    <beans:property name="key" value="reservation" /> 
</beans:bean> 
+0

감사합니다. 누락 된 링크였습니다. 그냥 마지막 질문입니다. 이것은 어딘가에 문서화 되었습니까? 아니면 소스 코드를 조사하여 찾아야합니까? – rainerhahnekamp

+1

[여기 Remeber-Me 장] (http://static.springsource.org/spring-security/site/docs/3.1.x/reference/springsecurity-single.html#remember-me-impls) 및 [ 여기'AuthenticationProvider's에 대한 장 (http://static.springsource.org/spring-security/site/docs/3.1.x/reference/springsecurity-single.html#core-services-authentication-manager)에서 각각의 공급자는 인증을 시도하거나 단순히 null을 반환하여 인증을 건너 뛸 수 있습니다. 모든 구현이 null를 돌려주는 경우,'ProviderManager'는'ProviderNotFoundException'_ – Xaerxess