Package org.picketlink.identity.federation.bindings.jboss.auth.mapping

Source Code of org.picketlink.identity.federation.bindings.jboss.auth.mapping.STSGroupMappingProvider

package org.picketlink.identity.federation.bindings.jboss.auth.mapping;

import java.util.List;
import java.util.Map;
import java.util.Set;

import org.jboss.security.identity.RoleGroup;
import org.jboss.security.identity.plugins.SimpleRole;
import org.jboss.security.identity.plugins.SimpleRoleGroup;
import org.jboss.security.mapping.MappingProvider;
import org.jboss.security.mapping.MappingResult;
import org.picketlink.identity.federation.PicketLinkLogger;
import org.picketlink.identity.federation.PicketLinkLoggerFactory;
import org.picketlink.identity.federation.bindings.jboss.auth.SAML20CommonTokenRoleAttributeProvider;
import org.picketlink.identity.federation.core.wstrust.auth.AbstractSTSLoginModule;
import org.picketlink.identity.federation.core.wstrust.plugins.saml.SAMLUtil;
import org.picketlink.identity.federation.saml.v2.assertion.AssertionType;
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;
import org.picketlink.identity.federation.saml.v2.assertion.StatementAbstractType;
import org.w3c.dom.Element;

/**
* <p>
* This mapping provider looks at the role attributes in the Assertion and returns corresponding JBoss RoleGroup objects for
* insertion into the Subject.
* </p>
*
* <h3>Configuration</h3>
*
* <pre>
* {@code
* <application-policy name="saml-issue-token">
*   <authentication>
*     <login-module code="org.picketlink.identity.federation.core.wstrust.auth.STSIssuingLoginModule" flag="required">
*       <module-option name="configFile">/sts-client.properties</module-option>
*       <module-option name="password-stacking">useFirstPass</module-option>
*     </login-module>
*   </authentication>
*   <mapping>
*     <mapping-module code="org.picketlink.identity.federation.bindings.jboss.auth.mapping.STSPrincipalMappingProvider" type="principal"/>
*     <mapping-module code="org.picketlink.identity.federation.bindings.jboss.auth.mapping.STSGroupMappingProvider" type="role">
*       <module-option name="token-role-attribute-name">role</module-option>
*     </mapping-module>
*   </mapping>
* </application-policy>
* }
* </pre>
*
* As demonstrated above, this mapping provider is typically configured for an STS Login Module to extract user roles from the
* STS token and supply them for insertion into the JAAS Subject.
*
* This mapping provider looks for a multi-valued Attribute in the Assertion, where each value is a user role. The name of this
* attribute defaults to {@code SAML20TokenRoleAttributeProvider.DEFAULT_TOKEN_ROLE_ATTRIBUTE_NAME} but may be set to any value
* through the "token-role-attribute-name" module option.
* <p/>
*
*
* @author <a href="mailto:Babak@redhat.com">Babak Mozaffari</a>
*/
public class STSGroupMappingProvider implements MappingProvider<RoleGroup> {

    private static final PicketLinkLogger logger = PicketLinkLoggerFactory.getLogger();
   
    private MappingResult<RoleGroup> result;

    private String tokenRoleAttributeName;

    public void init(Map<String, Object> contextMap) {
        Object tokenRoleAttributeObject = contextMap.get("token-role-attribute-name");
        if (tokenRoleAttributeObject != null) {
            tokenRoleAttributeName = (String) tokenRoleAttributeObject;
        } else {
            tokenRoleAttributeName = SAML20CommonTokenRoleAttributeProvider.DEFAULT_TOKEN_ROLE_ATTRIBUTE_NAME;
        }

        // No initialization needed

        logger.trace("Initialized with " + contextMap);
    }

    public void performMapping(Map<String, Object> contextMap, RoleGroup Group) {
        logger.debug("performMapping with map as " + contextMap);

        if (contextMap == null) {
            logger.mappingContextNull();
        }

        Object tokenObject = contextMap.get(AbstractSTSLoginModule.SHARED_TOKEN);
        if (!(tokenObject instanceof Element)) {
            // With Tomcat SSO Valves, mapping providers DO get called automatically, so there may be no tokens and errors
            // should be expected and handled
            logger.debug("Did not find a token " + Element.class.getName() + " under " + AbstractSTSLoginModule.SHARED_TOKEN + " in the map");
        }

        try {
            Element tokenElement = (Element) tokenObject;
            AssertionType assertion = SAMLUtil.fromElement(tokenElement);

            // check the assertion statements and look for role attributes.
            AttributeStatementType attributeStatement = this.getAttributeStatement(assertion);
            if (attributeStatement != null) {
                RoleGroup rolesGroup = new SimpleRoleGroup(SAML20CommonTokenRoleAttributeProvider.JBOSS_ROLE_PRINCIPAL_NAME);
                List<ASTChoiceType> attributeList = attributeStatement.getAttributes();
                for (ASTChoiceType obj : attributeList) {
                    AttributeType attribute = obj.getAttribute();
                    if (attribute != null) {
                        // if this is a role attribute, get its values and add them to the role set.
                        if (tokenRoleAttributeName.equals(attribute.getName())) {
                            for (Object value : attribute.getAttributeValue()) {
                                rolesGroup.addRole(new SimpleRole((String) value));
                            }
                        }
                    }
                }
                result.setMappedObject(rolesGroup);

                logger.trace("Mapped roles to " + rolesGroup);
            }
        } catch (Exception e) {
            logger.authFailedToParseSAMLAssertion(e);
        }
    }

    public void setMappingResult(MappingResult<RoleGroup> mappingResult) {
        this.result = mappingResult;
    }

    /**
     * @see MappingProvider#supports(Class)
     */
    public boolean supports(Class<?> p) {
        if (RoleGroup.class.isAssignableFrom(p))
            return true;

        return false;
    }

    /**
     * <p>
     * Checks if the specified SAML assertion contains a {@code AttributeStatementType} and returns this type when it is
     * available.
     * </p>
     *
     * @param assertion a reference to the {@code AssertionType} that may contain an {@code AttributeStatementType}.
     * @return the assertion's {@code AttributeStatementType}, or {@code null} if no such type can be found in the SAML
     *         assertion.
     */
    private AttributeStatementType getAttributeStatement(AssertionType assertion) {
        Set<StatementAbstractType> statementList = assertion.getStatements();
        if (statementList.size() != 0) {
            for (StatementAbstractType statement : statementList) {
                if (statement instanceof AttributeStatementType)
                    return (AttributeStatementType) statement;
            }
        }
        return null;
    }
}
TOP

Related Classes of org.picketlink.identity.federation.bindings.jboss.auth.mapping.STSGroupMappingProvider

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.