]
Marcus Moyses resolved SECURITY-536.
------------------------------------
Resolution: Done
Login module now inserts the Principal in the options map instead of the username.
When using a custom Principal class remember to add it to a group named CallerPrincipal in
getRoleSets so it is the identity seen by EJBs, servlets and Web Services.
Stacked login with subclassed Principal does not work.
------------------------------------------------------
Key: SECURITY-536
URL:
https://jira.jboss.org/browse/SECURITY-536
Project: PicketBox (JBoss Security and Identity Management)
Issue Type: Bug
Security Level: Public(Everyone can see)
Components: JBossSX
Affects Versions: PicketBox_v3_0_CR1
Environment: Windows XP; Jboss 5.1.0.GA;
Reporter: Craig Horrell
Assignee: Marcus Moyses
The Principal is not propagated from login module to login module when using stacked
logins. Instead, a new Principal is created, but only the first one survives. This causes
issued with subclassed SimplePrincipal that adds addition data to the class.
Code references:
1. org.jboss.security.auth.spi.UsernamePasswordLoginModule: Method login():
Object username = sharedState.get("javax.security.auth.login.name");
if (username instanceof Principal) {
identity = (Principal) username;
} else {
String name = username.toString();
try {
identity = createIdentity(name);
} catch (Exception e) {
log.debug("Failed to create principal", e);
throw new LoginException("Failed to create principal: " +
e.getMessage());
}
}
The code above checks to see if the Object stored in the shared state is a Principal.
This code is correct.
2. Later in the same method:
if (getUseFirstPass() == true) { // Add the username and password to the shared
state map
sharedState.put("javax.security.auth.login.name", username);
sharedState.put("javax.security.auth.login.password", credential);
}
This is the bug. It stores the name instead of the Object, which causes the second login
module to create a new Principal per the code above.
3. org.jboss.security.auth.spi.AbstractServerLoginModule: Method: commit():
Principal identity = getIdentity();
principals.add(identity);
'principals' is a Set. The add will not replace an existing identity, so the one
created by the second login module is ignored.
If the second login module got the object from the first, it could update it. As it is
the second login module cannot do anything with the principal, as it is discarded.
Complications: Some thought would have to be given as to what would happen if two
different principal classes were specified in the config. Perhaps disallow that ?
Our specific issue: We have a subclassed SimplePrincipal that holds context based
security information for that user that is checked as part of the authorization in our web
services. We stack a LDAP login module for the user-id and password, then a subclass of
DatabaseServerLoginModule that gets the roles and other context based data from a
database.
Work Around: in the subclassed DatabaseServerLoginModule's getRoleSets() method we
do:
// To overcome stacked login bugs, we must replace the existing principal
// with a new one created here.
Principal pr = this.getIdentity();
log.trace("SlDbServerLoginModule: getRoleSets(): "
+ "Got Principal from parent: user: " + pr.getName());
SlIdentity slId = new SlIdentity(pr.getName());
slId.addClientList(getSlClientList(username, roleSet));
slId.addSiteList(getSlSiteList(username, roleSet));
Set<Principal> prs = this.subject.getPrincipals();
prs.remove(pr);
prs.add(slId);
log.trace("SlDbServerLoginModule: getRoleSets(): "
+ "Replaced Principal with SlIdentity: user: " + slId.getName());
return roleSets;
Thanks,
Craig.
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: