by David Damo & Brian Peng
Many security architects have the false impression that configuring two-way SSL is sufficient to verify the client and restrict access to only trusted clients. This is actually not the case. In fact, many people set up two-way SSL with Verisign and nothing else, despite the fact that Verisign is designed only for trust—not for authentication or any other type of application access restriction, for that matter.
In this how-to you will learn how to create a custom user name mapper class that maps various certificate attributes to a user in your security realm that you can then authenticate and use to restrict or allow access to your application. It will also cover how to configure your Oracle WebLogic application server to be used to authenticate the certificate passed to the server from the client to restrict client access to your application.
We have been in countless meetings where the customer will suggest using two-way SSL to verify the client's identity and to use it to restrict access to the application. In almost every case, the customer wants to use a trusted third party to verify the identity of the certificate. This makes complete sense because you want a trusted third party to verify the identity of the certificate, but setting up two-way SSL without any certificate authentication—at least in Oracle WebLogic Server—will all allow clients with a valid Verisign certificate to connect to your server. This is usually not what the customer wants, especially in most cases where customers are using two-way SSL.
It is important to remember SSL is import for data encryption since the data you are sending is encrypted, and having two-way SSL means two ends of the connection establish trust using the X509 certificate type. However, certificate-based authentication is used to authenticate a user to the WebLogic server based on a digital certificate, and many types of certificates/tokens can be used including X509, X501, and CSlv2. For the purpose of this article only the X509 certificate type will be discussed.
When we suggest that setting up two-way SSL will not enable certificate-based authentication for connecting applications without some changes, most clients propose to make the changes on the firewall or use connection filters on WebLogic to protect their application instead of implementing certificate-based authentication. Both ideas are good ones, but they should complement the certificate-based authentication process for maximum security. We all know that spoofing IPs is quite possible, so setting up as many barriers as possible to only allow trusted clients to connect to your applications is critical.
In the example described here we implement the Custom User Name Mapper option of the default identity assertor as we could find no examples of how to develop this class. WebLogic does come with the default user name mapper, which can do simple mappings of various X509, X501, and CSlv2 certificate attributes to users. The custom user name mapper option originally was created for more custom user name mappings outside the basics that the default user name mapper offers. In our example, the custom user name mapper maps the CN attribute of an X509 certificate to a valid user.
You can download a zip containing the custom user name mapper class that maps the CN to a user in the Weblogic security realm here. You can easily update the class to map any X509 certificate attribute to a valid user in the security realm, or customize it using the class as a template. For the purpose of our example, we will assume you have already set up two-way SSL.
We compiled the class as in the screen shot below and then added the class to a JAR file, which we later added to all the classpaths of the servers within our domain.
You will add the custom user name mapper class to the default identity assertor. In order for your application to access the default identity assertor, add the following into your web.xml.
<login-config> <auth-method>CLIENT-CERT</auth-method> </login-config>
When you have your custom user name mapper added to the classpath, login into your admin console and under Security Realms->myrealm->Providers select the Default Identity Assertor. Ensure you are under the common tab which you should be by default and under ActiveTypes confirm that X.509 is selected as an option.
Now select the provider-specific tab of the default identity assertor. Confirm you have the following values set as below. In our example we also did not enable the default user name mapper.
Add the appropriate User Name Mapper Class to the User Name Mapper Class Name field. In our example the class is com.security.userNameMapper.CustomUserNameMapperImpl.
After making this change you should restart the server to ensure you have configured your custom user name mapper properly. Before you do this you may want to do two things.
First, enable debugging to ensure that your default identity assertor is being triggered and initialized properly. You can do this by adding the switch (if you know it) to the Java arguments of the server. If you don't know it, enable it under the debug options of the server: select WebLogic->Security->Atn and enable the DebugSecutityAtn.
Second, you may want to delete the cache before restarting the server. For some reason we had to delete the cache for the server to pick the custom user name mapper. You can delete the cache my removing the tmp directory to clear the cache under the WebLogic server directory, which can be found under WL_HOME/servers/ServerName.
To ensure the Custom User Name Mapper is configured properly check the output log for the output below:
<Jul 14, 2008 5:18:57 PM EDT> <Notice> <Stdout> <000000> <Creating Custom User Name Mapper Implementation with Subject DN of CN and delimiter of>
If you want to trace the full identity assertor calls, confirm that you have enabled DebugSecurityAtn in the Server Debug tab as instructed earlier and you will be able to view the identity assertor in action and debug any issues.
After you have confirmed your custom user name mapper has been deployed properly, you will have to configure your application and a role, group, and users in the admin console to restrict your application to allow only certain certificates to access your application.
We suggest that the application be set up such that it references a role not defined in the applications deployment descriptor (externally defined role). This allows you to not have to change the code every time you want to add a new certificate attribute as a user; you only need to add the new certificate attribute to a group and that group is a part of a role defined in your application.
The code we have created here has externally referenced the Certificate role so you need to create a global role in the admin console called Certificate.
Once you have added the role create a group. For example, we created a group called AcceptedCertificates.
Go back under the role and add the group to the role as a condition. Thus all users (certificate attributes) who will be added to the group will be part of the role you just created.
Then create the CN of the certificates as users that you want to have access to your application and add them to the group you created earlier.
Assuming you have completed the steps above, you will need only restart the server or redeploy the application for all future CN user group additions.
The developer will need to set up their application to use the role you defined above. The certificate CN is being authenticated as if it were a user so the application is set up as per standard Web application security best practices.
In the weblogic.xml add the tag shown in blue below:
<?xml version='1.0' encoding='ISO-8859-1'?> <weblogic-web-app xmlns="http://www.bea.com/ns/weblogic/90" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <context-root>TestService</context-root>
<security-role-assignment> <role-name>Certificate</role-name> <externally-defined/> </security-role-assignment>
This externally-defined tag tells WebLogic that the role and its users are defined in the admin console in our case and not in the deployment descriptor.
To the web.xml add the section shown in blue, below:
<?xml version='1.0' encoding='ISO-8859-1'?> <web-app xmlns="http://bit.ly/nC7jFS" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <display-name>TestServiceWebApp</display-name> <servlet> <servlet-name>TestServiceServlethttp</servlet-name> <servlet-class>com.test.TestServiceImpl</servlet-class> <load-on-startup>0</load-on-startup> </servlet> <servlet-mapping> <servlet-name>TestServiceServlethttp</servlet-name> <url-pattern>/TestServiceImpl</url-pattern> </servlet-mapping>
<security-constraint> <web-resource-collection> <web-resource-name>SecurePages</web-resource-name> <description>Security constraint for resources in the secure directory</description> <url-pattern>/*</url-pattern> <http-method>POST</http-method> <http-method>GET</http-method> </web-resource-collection> <auth-constraint> <description>only let the system user login</description> <role-name>Certificate</role-name> </auth-constraint> <user-data-constraint> <description>For SSL</description> <transport-guarantee>CONFIDENTIAL</transport-guarantee> </user-data-constraint> </security-constraint> <login-config> <auth-method>CLIENT-CERT</auth-method> </login-config> <security-role> <description>The Secure ROLE</description> <role-name>Certificate</role-name> </security-role>
Now that you have completed this configuration, you will be able to associate the desired X509 certificates attributes to a user who can be authenticated as a valid principal. Then, using Web application security standards and best practices, your application can be set up to allow only certain certificates to access your application.
David Damo and Brian Peng work as Senior Engineers for a major Canadian bank. They have extensive experience with middleware infrastructure deployment, design, development, security, and integration. While they specialize in middleware, they do enjoy keeping on top of system administration tasks and technology.