Search code examples
javaauthenticationtomcat8openid-connectgoogle-oauth

How to implement Tomcat 8.0 container level authentication with Google OAuth2?


I have a Java web application deployed on AWS, which uses basic Tomcat authentication -

<login-config>
    <auth-method>BASIC</auth-method>
</login-config>

The application itself does not perform any authentication. All of that is handled by the container. I've been trying to do the same with Google OAuth2, where the application does not handle any authentication, but the container does, i.e., login with a Google or GSuite account. Is this possible?

OpenID Connect Authenticator for Tomcat looked promising but when I logged in with it, it kept redirecting me to the login error page.

I followed these steps while trying to implement this on my localhost -

  1. I downloaded and placed their jar file in /tomcat-8/lib/.
  2. I created a Client ID with Authorized JavaScript origins as https://localhost:8443 and Authorized redirect URIs as https://localhost:8443/myapp/j_security_check.
  3. I setup localhost to use https on port 8443, since hostBaseURI requires it.
  4. In my application's web.xml, I setup -

    <security-constraint> <web-resource-collection> <web-resource-name>All</web-resource-name> <url-pattern>*.html</url-pattern> <url-pattern>/myapp/*</url-pattern> </web-resource-collection> <auth-constraint> <role-name>*</role-name> </auth-constraint> </security-constraint>

    <login-config> <auth-method>FORM</auth-method> <realm-name>authTestWeb</realm-name> <form-login-config> <form-login-page>/WEB-INF/public/login.html</form-login-page> <form-error-page>/WEB-INF/public/login-error.html</form-error-page> </form-login-config> </login-config>

  5. In context.xml, I setup the Valve property as <Valve className="org.bsworks.catalina.authenticator.oidc.OpenIDConnectAuthenticator" discoveryDocumentURL="https://accounts.google.com/.well-known/openid-configuration" clientId="xxxx" clientSecret="xxxx"/>.

  6. Placed the Google Sign-In script in login.html.

When I access https://localhost:8443/myapp, it prompts me for a Google username and password. When I login though, it briefly shows me a Check Cookie message and redirects to login-error.html.

What am I doing wrong here?

I've also thought about using Philip Green II's module for Google OAuth 2 but it looks like this is only available for Tomcat 8.5 and above. Unfortunately, AWS Elastic Beanstalk only has Tomcat 8.0 as the latest version.

So, how can I achieve Tomcat 8.0 container level authentication with Google OAuth2?


Solution

  • Turns out that while Google OAuth2 is doing the authentication, authorization is still being handled by Tomcat, for which I had to create a role myrole and add a user to that, where the username and password is the same, i.e., both the username and password will be email@example.com -

    <user username="email@example.com" password="email@example.com" roles="myrole"/>

    Excerpt from their documentation - "For the purpose of the OpenID Connect authenticator, the realm needs to be configured in such a way, that the password is always the same as the username (we still need the password due to limitations in the Tomcat API)."

    Additionally, I had to specify the role myrole in <auth-constraint> and <security-role> -

    <security-constraint>
        ...
        <auth-constraint>
            <role-name>myrole</role-name>
        </auth-constraint>
    </security-constraint>
    <security-role>
        <role-name>myrole</role-name>
    </security-role>