Covering J2EE Security and WebLogic Topics

Common Problems with Authentication Provider Configuration

I haunt the BEA security forum and often see people struggling with common authenticator configuration issues. One of two things usually happens:

  • The server won’t boot
  • A user can’t authenticate or authorize

I’ll show you how to fix these problems after a brief explanation of what authenticators do. This will give you context for understanding the solutions and handling future troubleshooting sessions.

What Authenticators Do

Authenticators are responsible for authenticating users as part of the WebLogic security framework. I know you want to throw your monitor at me for making such an obvious statement. Even my cat smacked me when I wrote it. However, what’s not so obvious is that authenticators have a supporting role in the authorization process.

Authenticators deal with principals. In WebLogic, principals are users and groups. Thus, an authenticator can tell the security framework that a user successfully authenticated or not but it can also say to which groups a user belongs. It does this by creating a Subject object and populating it with the username and group names for which the user is a member. This information is used by the role mapping providers which in turn feed the authorization providers. The authorization providers make a decision based on the security policy of the requested resource and the information provided by the other security providers. This is how an authenticator can cause authorization problems. We’ll see more on that in a bit.

Out of the box, users are stored in WebLogic’s embedded LDAP. This means all “normal” users as well as the WebLogic administrative user typically named “weblogic” or “admin” are stored there. Additionally, groups are also stored in embedded LDAP. Users and groups are stored there because the embedded LDAP serves as the DefaultAuthenticator’s data store. Remove the DefaultAuthenticator and the users and groups in embedded LDAP will not be used. Or, you could add another authenticator which would have its own user/group storage. Now, the users and groups known to WebLogic encompass both data stores.

There’s one more critical piece about authenticators and that’s the Control Flag. Each authenticator has a Control Flag that can be set to REQUIRED, REQUISITE, SUFFICIENT, or OPTIONAL. Each flag indicates how the authenticator will be treated by the security framework and whether or not that authenticator has to be able to successfully authenticate the user or not. You can find an explanation of these flags here.

With the authenticator explanations out of the way, let’s move on to the problems and their solutions.

Getting the Server to Start

Starting WebLogic requires authorization. The boot identity (the main WebLogic administrative user) is used to do it. Just like any other protected resource, authentication and authorization is delegated to the security framework. With the normal security configuration, the DefaultAuthenticator will find the boot user, authenticate it, populate the Subject with the groups, and start-up will continue assuming the authorizers are pleased.

You must have at least one authenticator in a security realm. One of those authenticators must be able to find and authenticate the boot user. If not, the server won’t start and you’ll get the following error message:

Authentication denied: Boot identity not valid

When this happens, check the following:

  1. That the boot identity (normally “weblogic”) is stored in a data store managed by an active authenticator
  2. That the boot identity is in the “Admin” group
  3. Authenticator order matters — check the control flags of all active authenticators. Forgetting to change the DefaultAuthenticator to OPTIONAL or SUFFICIENT in multiple authenticator configurations is the leading cause of authentication issues
  4. That boot.properties contains the correct username/password (or you’re typing in the correct username/password when you’re not using boot.properties)

Essentially, getting the server to start requires that a user be authenticated and authorized. This sounds an awful lot like…

Authenticating Users for an Application

That’s right. The same principles apply to “normal” authentication and authorization in J2EE applications. A common problem is trying to login to a web application only to get the login page again. As mentioned above, you don’t really know if the failure to access the page is from an incorrect username/password or the simple fact that the user (while properly authenticated) is not authorized for access.

Check the following when you can’t log in to your application:

  1. That the user is located in a data store managed by an active authenticator
  2. That the role mentioned in the security constraint in web.xml maps to a principal (usually a group) in weblogic.xml (For WebLogic 9.x, you can read WebLogic 9.1 Authorization Gotcha for a painful lesson I learned)
  3. Authenticator order matters — check the control flags of all active authenticators. Forgetting to change the DefaultAuthenticator to OPTIONAL or SUFFICIENT in multiple authenticator configurations is the leading cause of authentication issues.

This checklist is essentially the same as the first list because the two problem areas are actually the same type of problem. Starting the server is just a special case due to the mechanics of specifying the boot identity (such as via boot.properties).

The tips given above should have you well on your way to solving your authentication/authorization problems.

Identity Assertion

If your user authenticates with a perimeter token such as a client certificate, most of the tips above still apply. The difference is that 1) there’s an identity asserter provider for the token type in question; and 2) that token has to be mapped to an existing user in the realm.

The first difference is fairly obvious. It’s the second one that can cause some problems. Regardless of the token type, somehow its contents must map to a user known to WebLogic. For example, if you configure an identity asserter to handle X.509 certificates, you might indicate that the user name is the email address within the certificate. In that case, your user data store must contain that email address just like the data store must contain the username and password for username/password authentication. By the same token (yes, the pun was definitely intended), the user must be in the appropriate group for authorization purposes, just like in all of the scenarios above.

For more information on X.509 identity assertion, see Mutual Authentication in Action.

Multiple Security Realms

Up until now, I never mentioned a domain with multiple security realms. The reason I didn’t mention it is that there can only be one realm active at a time. Inactive ones are not used at all. Referencing an inactive realm in web.xml has no effect. In fact, the realm name in web.xml is totally arbitrary and regardless of what you specify, the active realm will be used. See WebLogic Security Framework Overview for more information.

Even so, WebLogic’s functionality in this regard can cause you grief if you configured an authenticator in an inactive realm. The fix, of course, is to either make your new realm the active one or add the extra authenticator to the active realm.

Summary

This post described the authentication and authorization process. When troubleshooting authentication and authorization problems, consider the following:

  • Is the username and password correct?
  • Is the security constraint mapped to the role you think it is?
  • Is the role mapped to the proper group?
  • Is the user actually in that group?
  • Is an authenticator properly configured to point to the data store containing the user and group?
  • For multiple authenticators, are the control flags and authenticator order appropriate?
  • If you have multiple security realms, realize that only one is active at a time

In my next post, I’ll show you some troubleshooting techniques that quickly make the cause of the problem jump up and bite you on the nose.

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.

 

Bookmark this page on del.icio.us