Please give details about which login modules you are using. If you are using a custom login module, please show how you set your custom principal.
Configuration for custom login module configured in login-config.xml:
<login-module code="core.rbac.jboss.LDAPCertificateLoginModule" flag="required"> <module-option name="securityDomain">java:/jaas/CoreApplication</module-option> <module-option name="principalClass">core.rbac.BasicPrincipal</module-option> <module-option name="verifier">core.rbac.jboss.CertificateVerifier</module-option> </login-module>
The custom login module is a subclass of BaseCertLoginModule that obtains user roles from LDAP. In the login module the identity is instance of BasicPrincipal. The user roles are propagated to the web application, for example, calling request.isUserInRole("someRole") correctly returns true or false based on user role assignment. However request.getUserPrincipal() returns an instance of SimplePrincipal and not BasicPrincipal.
Please inform me if you need other code or configuration snapshots.
This was an interesting hunt for me as I have not used client certs before. I think you have two options.
1.) Follow JBossSX Subject usage package in your custom login module and add a java.security.acl.Group with name "CallerPrincipal" to the authenticated Subject's principal set. In that group, add your custom Principal class.
2.) Have your custom principal extend org.jboss.security.CertificatePrincipal and set this as the "certificatePrincipal" attribute in Tomcat's server.xml file for JBossSecurityMgrRealm config.
if you need more details or if you have problems, let us know. cgriffith
I am actually struggling with this issue in 4.0.5GA. What is interesting is that the wiki article for using custom principals doesn't say that the custom principal will be used as the caller principal if you simply supply the class name via the module-option.
I have stepped through a login session using UserRolesLoginModule with the principalClass option set, and I see that the createIdentity() calls create Principals of the custom type. What is interesting is that no where a custom principal type get assigned to a group named CallerPrincipal like the login module example in the wiki article does.
I created a login module much like the code example in the wiki, and it worked as I expected - I call request.getUserPrincipal().getClass() in a jsp and it gives me the custom principal class name.
Why would you allow customization of the principal class (via the module option), but not use a principal of that type for the caller principal? I can't tell if I am looking at a bug or if I am just misunderstanding the intent of the option.
I think I have found where the caller principal is being populated: org.jboss.security.plugins.JaasSecurityManager.updateCache(...). It appears what occurs is that once a user authenticates, a DomainInfo object is created and stored in the login domain's cache. The DomainInfo object is assigned the Subject for the authenticated user which is a copy of the Subject created by the authentication process.
The caller Principal is then manually assigned to the DomainInfo object by searching the original Subject for a Group called "CallerPrincipal" and if found taking the first Principal object in the Group. If no such Group is found and the Principal can't be reused from the cache, the first non-Group Principle found in the Subject's set of Principals is assigned to the DomainInfo object.
It seems (with the code from 4.0.5 GA at least), that unless you add the CallerPrincipal Group in your module(s), it doesn't matter if you specify the custom class in your login config... despite using instances of your Principal class in the login modules, the code that calls the JaasSecurityManager.isValid() authentication code from the web container passes in an instance of SimplePrincipal org.jboss.web.tomcat.security.JBossSecurityMgrRealm(line 491). At JaasSecurityManager.updateCache() (line 778) the manager has a non-null principal so the test fails and the subject is not scanned for the principal as previously described (if it did it would yield the custom principal), instead, it uses the SimplePrincipal passed in from the web container.
So, to make a long story short... make sure you include a Group named "CustomPrincipal" with the custom principal added to it. Otherwise, you'll always get the SimplePrincipal passed in from the tomcat side.