Question

I'm using Spring-Security 3.1.RELEASE within a Spring Roo environment. I've changed the login mechanism so that it works with JSON-Response. For that I've created two classes (scala) namely

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")
 }
}

The entries in application-security.xml are as follows:

<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" />

Authentication is working fine, so I can successfully login and also concerning remember-me the data is stored successfully into the database (table persistent_logins). But when I restart the server the Session is as expected deleted and the remember me functionality should do its work. Unfortunately it fails with following log data:

[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 'physio1@physio-termin.at', 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.springframework.security.authentication.RememberMeAuthenticationToken@2fb6ff6b: Principal: org.springframework.security.core.userdetails.User@d45302c2: Username: physio1@physio-termin.at; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_PHYSIOTHERAPEUT; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@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]

What am I missing? I dont't understand why the ProviderNotFoundException is thrown.

Was it helpful?

Solution

You're almost done, authentication works OK, you forgot to add RememberMeAuthenticationProvider. If you use security namespace to create AuthenticationManager, just add separate <authentication-provider> like here:

<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>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top