Reputation: 610
I'm using spring mvc and spring security (version 3.1). The web application gives users the option to register using there google/gmail accounts for login. This works fine on my development environment but when deployed to a production server, the registration process is failing as a Bad Credentials exception is shown event when correct google credentials are provided. Here's the openid config in my spring-security.xml config:
<openid-login
login-processing-url="/j_spring_openid_security_check"
default-target-url="/home"
user-service-ref="userOpenIdDetailsService"
authentication-failure-handler-ref="openIdAuthFailureHandler"/>
<logout logout-success-url="/login?rc=2" />
<beans:bean id="userOpenIdDetailsService" class="com.xxx.service.OpenIdUserDetailsServiceImpl"/>
<beans:bean id="openIdAuthFailureHandler" class="com.xxx.controllers.OpenIDAuthenticationFailureHandler">
<beans:property name="defaultFailureUrl" value="/login?rc=6"/>
</beans:bean>
I've implemented an authentication failure handler to handle the registration process, when an openid identity is returned but not registered in my database:
public class OpenIDAuthenticationFailureHandler extends
SimpleUrlAuthenticationFailureHandler {
private static Logger logger = Logger.getLogger(OpenIDAuthenticationFailureHandler.class);
@Override
public void onAuthenticationFailure(HttpServletRequest request,
HttpServletResponse response, org.springframework.security.core.AuthenticationException exception)
throws IOException, ServletException {
if(exception instanceof UsernameNotFoundException
&& exception.getAuthentication() instanceof OpenIDAuthenticationToken
&& ((OpenIDAuthenticationToken)exception.getAuthentication()).
getStatus().equals(OpenIDAuthenticationStatus.SUCCESS)) {
DefaultRedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
OpenIDAuthenticationToken token = (OpenIDAuthenticationToken)exception.getAuthentication();
String url = token.getIdentityUrl();
request.getSession(true).setAttribute("USER_OPENID_CREDENTIAL", url);
String inviteId = (String)request.getSession().getAttribute("INVITE_ID");
if (inviteId != null) {
redirectStrategy.sendRedirect(request, response, "/setup/invite/" + inviteId + "/complete");
} else {
//redirect to create account page
redirectStrategy.sendRedirect(request, response, "/setup/openid/complete");
}
} else {
OpenIDAuthenticationToken token = (OpenIDAuthenticationToken)exception.getAuthentication();
logger.debug("Token Identity: " + token.getIdentityUrl());
logger.debug("Open ID authentication failure: " + exception.getMessage());
logger.debug("Auth Exception: " + exception.toString());
super.onAuthenticationFailure(request, response, exception);
}
}
}
So I'm expecting a UsernameNotFoundException which is handled in the above handler for registration but I'm getting a org.springframework.security.authentication.BadCredentialsException. From the logs:
Log --> 10:19:17 DEBUG org.springframework.security.openid.OpenIDAuthenticationFilter - Supplied OpenID identity is https://www.google.com/accounts/o8/id?id=open-id-token-here
Log --> 10:19:17 DEBUG org.springframework.security.openid.OpenIDAuthenticationFilter - Authentication request failed: org.springframework.security.authentication.BadCredentialsException: Log in failed - identity could not be verified
Log --> 10:19:17 DEBUG org.springframework.security.openid.OpenIDAuthenticationFilter - Updated SecurityContextHolder to contain null Authentication
Log --> 10:19:17 DEBUG org.springframework.security.openid.OpenIDAuthenticationFilter - Delegating to authentication failure handlercom.xxx.controllers.OpenIDAuthenticationFailureHandler@435fef7d
Log --> 10:19:17 DEBUG com.xxx.controllers.OpenIDAuthenticationFailureHandler - Token Identity: Unknown
Log --> 10:19:17 DEBUG com.xxx.controllers.OpenIDAuthenticationFailureHandler - Open ID authentication failure: Log in failed - identity could not be verified
Log --> 10:19:17 DEBUG com.xxx.controllers.OpenIDAuthenticationFailureHandler - Auth Exception: org.springframework.security.authentication.BadCredentialsException: Log in failed - identity could not be verified
Upvotes: 2
Views: 978
Reputation: 467
It turns out the clock on the production server can get out of synch with the internet time used to validate the OpenId request. In my case, my server had been running for 177 days without a reboot. The server clock was off by one minute. A reboot solves the problem. Otherwise, synching the server clock with the internet time server fixes the problem too.
Upvotes: 1