Jer
Jer

Reputation: 610

Spring security with openid for google not working in production environment

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

Answers (1)

Dean Peterson
Dean Peterson

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

Related Questions