package org.picketlink.identity.federation.bindings.jboss.auth;
import java.security.Principal;
import java.security.acl.Group;
import java.util.Enumeration;
import java.util.Map;
import javax.security.auth.Subject;
import org.picketlink.identity.federation.PicketLinkLogger;
import org.picketlink.identity.federation.PicketLinkLoggerFactory;
import org.picketlink.identity.federation.core.wstrust.plugins.saml.SAML20TokenAttributeProvider;
import org.picketlink.identity.federation.saml.v2.assertion.AttributeStatementType;
import org.picketlink.identity.federation.saml.v2.assertion.AttributeStatementType.ASTChoiceType;
import org.picketlink.identity.federation.saml.v2.assertion.AttributeType;
/**
* <p>
* An implementation of the SAML20TokenAttributeProvider for JBoss which looks at the authenticated Subject and creates an
* Attribute containing the user's roles.
* </p>
*
* <h3>Configuration</h3>
*
* <pre>
* {@code
* <TokenProviders>
* <TokenProvider ProviderClass="org.picketlink.identity.federation.core.wstrust.plugins.saml.SAML20TokenProvider"
* TokenType="http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV2.0"
* TokenElement="Assertion"
* TokenElementNS="urn:oasis:names:tc:SAML:2.0:assertion">
* <Property Key="AttributeProvider" Value="org.picketlink.identity.federation.bindings.jboss.auth.SAML20TokenRoleAttributeProvider"/>
* <Property Key="org.picketlink.identity.federation.bindings.jboss.auth.SAML20TokenRoleAttributeProvider.tokenRoleAttributeName" Value="role"/>
* </TokenProvider>
* </TokenProviders>
* }
* </pre>
*
* When configured, this attribute provider will be called by the {@code SAML20TokenProvider} to return an
* {@code AttributeStatement} from the STS token and supply them for insertion into the JAAS Subject. This returns a
* multi-valued Attribute to be included in the Assertion, where each value of the attribute is a JBoss user role. The name of
* this attribute defaults to {@code DEFAULT_TOKEN_ROLE_ATTRIBUTE_NAME} but may be set to any value through an optional property
* as shown above.
*
* @author <a href="mailto:Babak@redhat.com">Babak Mozaffari</a>
*/
public abstract class SAML20CommonTokenRoleAttributeProvider implements SAML20TokenAttributeProvider {
private static final PicketLinkLogger logger = PicketLinkLoggerFactory.getLogger();
/**
* The name of the principal in JBoss that is expected to include user roles
*/
public static final String JBOSS_ROLE_PRINCIPAL_NAME = "Roles";
/**
* The default attribute name in the SAML Token that will carry the user's roles, if not configured otherwise
*/
public static final String DEFAULT_TOKEN_ROLE_ATTRIBUTE_NAME = "role";
/**
* The name of the attribute in the SAML Token that will carry the user's roles
*/
private String tokenRoleAttributeName;
public void setProperties(Map<String, String> properties) {
String roleAttrKey = this.getClass().getName() + ".tokenRoleAttributeName";
tokenRoleAttributeName = properties.get(roleAttrKey);
if (tokenRoleAttributeName == null) {
tokenRoleAttributeName = DEFAULT_TOKEN_ROLE_ATTRIBUTE_NAME;
}
}
public AttributeStatementType getAttributeStatement() {
Subject subject = SecurityActions.getSecurityContext().getSubjectInfo().getAuthenticatedSubject();
if (subject == null) {
logger.trace("No authentication Subject found, cannot provide any user roles!");
return null;
} else {
AttributeStatementType attributeStatement = new AttributeStatementType();
AttributeType rolesAttribute = new AttributeType(tokenRoleAttributeName);
attributeStatement.addAttribute(new ASTChoiceType(rolesAttribute));
// List<Object> roles = rolesAttribute.getAttributeValue();
for (Principal rolePrincipal : subject.getPrincipals()) {
if (JBOSS_ROLE_PRINCIPAL_NAME.equalsIgnoreCase(rolePrincipal.getName())) {
Group simpleGroup = (Group) rolePrincipal;
Enumeration<? extends Principal> members = simpleGroup.members();
while (members.hasMoreElements()) {
Principal role = members.nextElement();
rolesAttribute.addAttributeValue(role.getName());
// roles.add( role.getName() );
}
}
}
logger.trace("Returning an AttributeStatement with a [" + tokenRoleAttributeName + "] attribute containing: " + rolesAttribute.getAttributeValue().toString());
return attributeStatement;
}
}
}