JBoss 5 Security Context Being Destroyed
jslowry May 13, 2011 12:44 PMHi,
I'm currently working with JBoss 5.1 and using a custom login module that also extends the ClientLoginModule. The user presents a certificate and JBoss authenticates the user based off their information. Sometimes, during authentication, the JBoss code will update the cache with the user's credentials, and when doing so, it completely destroys the security context. I'm left with a Security Context has not been set exception. Here's what's happening in the code:
JBossWebRealm:
public Principal authenticate(X509Certificate[] certs)
192 {
193 Principal principal = null;
194
195 try
196 {
197 // Get the JBoss security manager from the ENC context
198 SubjectSecurityManager securityMgr = getSubjectSecurityManager("authenticate(X509Certificate[] certs)");
199 if(securityMgr == null)
200 return null;
201
202 Subject subject = new Subject();
203 principal = certMapping.toPrinicipal(certs);
204 if (securityMgr.isValid(principal, certs, subject))
205 {
206 if (trace)
207 {
208 log.trace("User: " + principal + " is authenticated");
209 }
210 securityDomain = securityMgr.getSecurityDomain();
211 SecurityAssociationActions.setPrincipalInfo(principal, certs, subject);
When the securityMgr.isValid call is made, it calls the JaasSecurityManagerBase's authenticate method (in some cases, when it can't validate the user against the cache). The authenticate method ultimately calls an updateCache method that does this:
synchronized( domainCache)
{
if (domainCache.peek(principal) != null)
domainCache.remove(principal);
domainCache.insert(principal, info);
}
return info.subject
When it does a domainCache.remove(principal), the code actually ends up setting the security context to null. So, then in the JBossWebRealm class, when it tries to do the SecurityAssociationActions.setPrincipalInfo, I end up seeing the Security Context has not been set exception. In order to work around this, I've added the following code to JBossWebRealm:
public Principal authenticate(X509Certificate[] certs)
192 {
193 Principal principal = null;
194
195 try
196 {
197 // Get the JBoss security manager from the ENC context
198 SubjectSecurityManager securityMgr = getSubjectSecurityManager("authenticate(X509Certificate[] certs)");
199 if(securityMgr == null)
200 return null;
// New code starts here
SecurityContext sc = SecurityAssociationActions.getSecurityContext();
if (sc == null)
{
try
{
sc = SecurityAssociationActions.createSecurityContext(securityDomain);
}
catch (Exception e)
{
throw new RuntimeException(e);
}
SecurityAssociationActions.setSecurityContext(sc);
}
Is this a viable solution? Right now, I get past the security context exceptions, but I'm just wondering if there's something else I should do in JaasSecurityManagerBase or in my custom login module.
Thanks in advance for the help!