Covering J2EE Security and WebLogic Topics

Mutual Authentication in Action

This post is a continuation of the Fifteen Minute Guide to Mutual Authentication. In that post, I walked you through configuring WebLogic for two-way SSL, or mutual authentication. It was a whirlwind tour whose purpose was to drive home the essentials of PKI theory while emerging with a simple working implementation.

This post picks up where the other left off by having the user’s certificate suffice for web application authentication. In other words, with mutual authentication the user does not have to log in with a username and password. Instead, the user’s certificate is his ticket to ride.

Here’s what we’ll do in this post:

  • Create a user
  • Configure identity assertion in WebLogic
  • Configure a web application to use CLIENT-CERT authentication
  • Configure role-to-principal mapping in weblogic.xml

The pre-requisite of this post is a browser that will accept the server’s certificate and a server that will accept the browser’s client certificate. If you don’t already have that set up, refer to the Fifteen Minute Guide to Mutual Authentication and follow the steps there. You can also use certificates issued by other Certificate Authorities (CAs) but you must be able to connect the browser to the server as described in the guide. If not, the steps in this post will not work for you until the basic problem is resolved.

Enough introductory babble. Let’s get to it.

Create a User

When we’re done with configuration, client certificates will map to known users in the WebLogic security realm. I’m assuming here that you are using the DefaultAuthenticator which stores users and group information in WebLogic’s embedded LDAP.

You need to add a user via WebLogic Console. Note that the steps given here are for WebLogic 8.1.4 but they are approximately the same for WebLogic 9.x. To add a user, navigate to the Security->Realms->myrealm->Users node in the applet.

On the right-hand side, click on Configure a new User. In the General tab, enter the user ID in the Name field. If you used the example from the Mutual Authentication Guide, enter "Spongebob". Otherwise, enter the value of the Common Name (CN) of your test certificate. Enter and confirm a password. The password won’t be used for mutual authentication, but make it a strong password anyway.

Click Apply and then select the Groups tab. Add the user to the Administrators group by moving "Administrators" to the Current Groups box. Click Apply.

You now have a new user in the Administrators group. The user ID for this user matches the CN of the client certificate you’ve loaded in your browser.

Configure Identity Assertion

Next up is identity assertion configuration. Identity assertion is the process by which a token from the request is mapped to a known user.

You need to configure WebLogic to use an X.509 certificate as the authentication token. Furthermore, you’ll configure a username mapper to map the certificate’s Distinguished Name (DN) to a user ID. The username mapper is part of the identity asserter.

These steps assume you are using the DefaultIdentityAsserter. To configure it, navigate to the Security->Realms->myrealm->Providers->Authentication->DefaultIdentityAsserter node in the applet.

On the General tab, the User Name Mapper Class Name and Trusted Client Principals fields can remain blank. For Types, however, move X.509 to the Chosen side and remove AuthenticatedUser. An identity asserter can only support one type at a time. Click Apply.

Click the Details tab to configure username mapping. Check the Use Default User Name Mapper field. Select CN for the Default User Name Mapper Attribute Type. Leave Default User Name Mapper Attribute Delimiter and Base64DecodingRequired set to "@" and selected, respectively. Click Apply and then restart WebLogic for the changes to take effect.

What you’ve done is told WebLogic to use its default username mapper to map the certificate to the user. It does this by pulling the CN value from the DN of the certificate. The default usernmame mapper can handle these basic functions. If you have more complicated mapping requirements, you can write a custom username mapper and specify it on the General tab in the User Name Mapper Class Name field.

Regardless, given a valid client certificate, if the username mapper emits a user ID that can be found in the security realm, the user will be authenticated.

Configure a Web Application

At this point, you’ve defined a user whose username matches the CN of the client certificate. You’ve also told WebLogic how to map client certificates to users.

You now need to configure your web application to use what you’ve configured. You only need to do three things:

  1. Apply a security constraint to a resource in web.xml
  2. Set the authentication method to CLIENT-CERT in web.xml
  3. Configure role-to-principal mapping in weblogic.xml

All three of these changes are made in the web application’s deployment descriptors. I’ve provided a sample web application for you that can be deployed without changes if you want to skip the editing. The application also shows how to pull the user’s certificate from the request if you need to (although you usually don’t).

You must protect a resource with a security constraint for the security framework to kick in. Here’s an example security constraint from web.xml:

  <security-constraint>
      <display-name>Example Security Constraint</display-name>
      <web-resource-collection>
         <web-resource-name>Protected Area</web-resource-name>
         <url-pattern>/protected/*</url-pattern>
             <http-method>DELETE</http-method>
             <http-method>GET</http-method>
             <http-method>POST</http-method>
	     <http-method>PUT</http-method>
      </web-resource-collection>
      <auth-constraint>
         <role-name>Admin</role-name>
      </auth-constraint>
  </security-constraint>

With a security constraint in place, you need to tell WebLogic how you want it to handle authentication. You’re probably most familiar with the FORM authentication type for doing username/password authentication. However, we want to extract the certificate from the two-way SSL session that’s already been established. To do this, we use the CLIENT-CERT authentication type. (You can find more information on the various authentication types here.) Here’s the pertinent snippet from web.xml:

 <login-config>
   <auth-method>CLIENT-CERT</auth-method>
   <realm-name>ArbitraryName</realm-name>
 </login-config>

With this web.xml file in place, we’ve told WebLogic what we want to protect and how users should be authenticated. When the user requests a protected resource, WebLogic will notice and the security framework will spring into action. Before a user can be authorized to access the protected resource, WebLogic first has to determine who the user is. Since we told it to use the certificate from the SSL connection, WebLogic will extract the certificate and hand it to the identity asserter. The identity asserter will attempt to map the certificate to a known user using a username mapper class. If it finds a match, the user is authenticated.

After authentication, authorization checks kick in and the request will be processed if the user is allowed access.

The last thing to do is to map the "Admin" security role defined in web.xml to one or more principals. This mapping is done in weblogic.xml. We’ll map the "Admin" role to the "Administrators" group so that any user in the Administrators group will have the Admin role and will thus be granted access. Here’s the relevant snippet from weblogic.xml:

  <security-role-assignment>
    <role-name>Admin</role-name>
    <principal-name>Administrators</principal-name>
  </security-role-assignment>

At this point, deploy your application (or use the sample) and see if you can log in with the certificate.

If it doesn’t work, troubleshooting is straight-forward. Since you already have two-way SSL working properly, there should be no problem with the server, client, or CA certificates. Here’s what could be wrong:

  • Incorrect security constraint
  • Incorrect role to principal mapping in weblogic.xml
  • Not requesting a web page with a security constraint
  • Not using https
  • Incorrect username mapper configuration
  • Non-existent user (given the username mapping)
  • User is not in the appropriate group for the security constraint

Once everything is correctly configured, you should be able to log in with only the client certificate.

Summary

You now have a web application that uses private/public keys for a very strong form of authentication. In the implementation shown here, the user’s public certificate does not exist on the server side. Rather, the user’s certificate is trusted because the server trusts the certificate’s issuer. Assuming the certificate is trusted, WebLogic then maps the certificate to a known user which can have the normal group memberships as any user.

Finally, thanks to the J2EE specification, your application does not have to deal with any of the mutual authentication machinery other than specifying in web.xml that you want it.