Thursday, December 14, 2017

Cloudera SSO/SAML /X.509 Login Handler/Shibboleth IDP/Configuration/Part3

In my Previous post i showed shibboleth installation and Cloudera SAML configuration. in this post i am going to show to how to configure shibboleth idp configuration for cloudera cm/hue/nav and release the attributes in the SAML assertion.

Update the following files

cat /app/shibboleth-idp/conf/ldap.properties|grep -v "^#"|sed "/^$/d"

idp.authn.LDAP.authenticator                   = adAuthenticator
idp.authn.LDAP.ldapURL                          = ldap://ad.tanu.com
idp.authn.LDAP.useStartTLS                     = false
idp.authn.LDAP.useSSL                          = true
idp.authn.LDAP.sslConfig                       = certificateTrust
idp.authn.LDAP.trustCertificates                = /app/apache-tomcat-7.0.65/ssl/ca_certificate.pem
idp.authn.LDAP.returnAttributes                 = cn,mail,company
idp.authn.LDAP.baseDN                           = OU=Users,DC=tanu,DC=com
idp.authn.LDAP.subtreeSearch                   = true
idp.authn.LDAP.userFilter                       = (cn={0})
idp.authn.LDAP.bindDN                           = aduser@TANU
idp.authn.LDAP.bindDNCredential                 = tanu123
idp.authn.LDAP.dnFormat                         = %s@TANU
idp.attribute.resolver.LDAP.ldapURL             = %{idp.authn.LDAP.ldapURL}
idp.attribute.resolver.LDAP.connectTimeout      = %{idp.authn.LDAP.connectTimeout:PT3S}
idp.attribute.resolver.LDAP.responseTimeout     = %{idp.authn.LDAP.responseTimeout:PT3S}
idp.attribute.resolver.LDAP.baseDN              = %{idp.authn.LDAP.baseDN:undefined}
idp.attribute.resolver.LDAP.bindDN              = %{idp.authn.LDAP.bindDN:undefined}
idp.attribute.resolver.LDAP.bindDNCredential    = %{idp.authn.LDAP.bindDNCredential:undefined}
idp.attribute.resolver.LDAP.useStartTLS         = %{idp.authn.LDAP.useStartTLS:true}
idp.attribute.resolver.LDAP.trustCertificates   = %{idp.authn.LDAP.trustCertificates:undefined}

idp.attribute.resolver.LDAP.searchFilter        = (cn=$resolutionContext.principal)

We need to update the ldap.properties file to get the users attributes like mail/ou..etc  to include in saml assertion post authentication.

cat /app/shibboleth-idp/conf/idp.properties |grep -v "^#"|sed "/^$/d"

idp.additionalProperties= /conf/ldap.properties, /conf/saml-nameid.properties, /conf/services.properties, /conf/authn/duo.properties
idp.entityID= https://idp.tanu.com:8443/idp/shibboleth
idp.scope= am.hedani.net
idp.sealer.storeResource= %{idp.home}/credentials/sealer.jks
idp.sealer.versionResource= %{idp.home}/credentials/sealer.kver
idp.sealer.storePassword= tanu123
idp.sealer.keyPassword= tanu123
idp.signing.key= %{idp.home}/credentials/idp-signing.key
idp.signing.cert= %{idp.home}/credentials/idp-signing.crt
idp.encryption.key= %{idp.home}/credentials/idp-encryption.key
idp.encryption.cert= %{idp.home}/credentials/idp-encryption.crt
idp.encryption.optional = false
idp.authn.flows= X509
idp.ui.fallbackLanguages= en,fr,de


Note that important property line idp.authn.flows =  X509. Since i am going to use ssl mutual authentication handler, i have updated X509. Shibboleth also support many authentication handler

    cat /app/shibboleth-idp/conf/authn/general-authn.xml  |grep 'authn/'

        <bean id="authn/IPAddress" parent="shibboleth.AuthenticationFlow"
        <bean id="authn/SPNEGO" parent="shibboleth.AuthenticationFlow"
        <bean id="authn/External" parent="shibboleth.AuthenticationFlow"
        <bean id="authn/RemoteUser" parent="shibboleth.AuthenticationFlow"
        <bean id="authn/RemoteUserInternal" parent="shibboleth.AuthenticationFlow" />
        <bean id="authn/X509" parent="shibboleth.AuthenticationFlow"
        <bean id="authn/X509Internal" parent="shibboleth.AuthenticationFlow">
        <bean id="authn/Password" parent="shibboleth.AuthenticationFlow"
        <bean id="authn/Duo" parent="shibboleth.AuthenticationFlow"
        <bean id="authn/MFA" parent="shibboleth.AuthenticationFlow"

We can also use multi factor authentication by updating like below, if user can't able to login with username and password credential it will redirect to another  authentication handler
idp.authn.flows= Password|X509

And also change the idp.authn.LDAP.userFilter based on your ldap and authentication handler. In my poc environment post authentication  employee id will be returned to session and my active directory configured with cn="employee id". but shibboleth default filter will be sAMAccountName.

Update the  /app/shibboleth-idp/conf/c14n/x500-subject-c14n-config.xml file 


    <util:list id="shibboleth.c14n.x500.Transforms">
        <bean parent="shibboleth.Pair" p:first="^(.*) \((.+)\)$" p:second="$2" />
    </util:list>

Above  marked regular expression is for extract the employee id from the certificate.

After successfully authenticated shibboleth will extract the common name from the client certificate. in our environment all employees common name(CN) would be cn=tanu sathish (12345).

So using above expression i am replacing shibboleth resolutionContext.principal  session variable with  only employee id instead of whole common name,. 

Update the /app/shibboleth-idp/conf/metadata-providers.xml file 

    <MetadataProvider id="clouderaManager"
                      xsi:type="FileBackedHTTPMetadataProvider"
                      backingFile="%{idp.home}/metadata/cm-metadata.xml"
                      metadataURL="https://cm.tanu.com:7183/saml/metadata">
       <!-- <MetadataFilter xsi:type="RequiredValidUntil" maxValidityInterval="P14D"/> -->
       <MetadataFilter xsi:type="EntityRoleWhiteList">
          <RetainedRole>md:SPSSODescriptor</RetainedRole>
       </MetadataFilter>
    </MetadataProvider>


    <MetadataProvider id="hueserver1"
                      xsi:type="FileBackedHTTPMetadataProvider"
                      backingFile="%{idp.home}/metadata/HuelocalCopyFromXYZHTTP.xml"
                      metadataURL="http://hue.tanu.com:8888/saml2/metadata">
       <!-- <MetadataFilter xsi:type="RequiredValidUntil" maxValidityInterval="P14D"/> -->
       <MetadataFilter xsi:type="EntityRoleWhiteList">
          <RetainedRole>md:SPSSODescriptor</RetainedRole>
       </MetadataFilter>
    </MetadataProvider>

             <MetadataProvider id="clouderaNavigator"
                      xsi:type="FileBackedHTTPMetadataProvider"
                      backingFile="%{idp.home}/metadata/clouderaNavigatorlocalCopyFromXYZHTTP.xml"
                      metadataURL="http://nav.tanu.com:7187/saml/metadata">
       <!-- <MetadataFilter xsi:type="RequiredValidUntil" maxValidityInterval="P14D"/> -->
       <MetadataFilter xsi:type="EntityRoleWhiteList">
          <RetainedRole>md:SPSSODescriptor</RetainedRole>
       </MetadataFilter>
    </MetadataProvider>



Update the /app/shibboleth-idp/conf/attribute-resolver.xml file to retrieve the attributes from ldap/active directory

    <AttributeDefinition id="eduPersonPrincipalName" xsi:type="Scoped" scope="%{idp.scope}" sourceAttributeID="uid">
        <Dependency ref="uid" />
        <AttributeEncoder xsi:type="SAML1ScopedString" name="urn:mace:dir:attribute-def:eduPersonPrincipalName" encodeType="false" />
        <AttributeEncoder xsi:type="SAML2ScopedString" name="urn:oid:1.3.6.1.4.1.5923.1.1.1.6" friendlyName="eduPersonPrincipalName" encodeType="false" />
    </AttributeDefinition>

    <AttributeDefinition id="uid" xsi:type="PrincipalName">
        <AttributeEncoder xsi:type="SAML1String" name="urn:mace:dir:attribute-def:uid" encodeType="false" />
        <AttributeEncoder xsi:type="SAML2String" name="urn:oid:0.9.2342.19200300.100.1.1" friendlyName="uid" encodeType="false" />
    </AttributeDefinition>

    <AttributeDefinition id="mail" xsi:type="Simple" sourceAttributeID="mail">
        <Dependency ref="myLDAP" />
        <AttributeEncoder xsi:type="SAML1String" name="urn:mace:dir:attribute-def:mail" encodeType="false" />
        <AttributeEncoder xsi:type="SAML2String" name="urn:oid:0.9.2342.19200300.100.1.3" friendlyName="mail" encodeType="false" />
    </AttributeDefinition>

    <AttributeDefinition xsi:type="Simple" id="role" sourceAttributeID="role">
        <Dependency ref="statiConnector" />
        <AttributeEncoder xsi:type="SAML1String" name="urn:mace:dir:attribute-def:ou" encodeType="false" />
        <AttributeEncoder xsi:type="SAML2String" name="urn:oid:2.5.4.11" friendlyName="role" encodeType="false" />
    </AttributeDefinition>

    <DataConnector id="myLDAP" xsi:type="LDAPDirectory"
        ldapURL="%{idp.attribute.resolver.LDAP.ldapURL}"
        baseDN="%{idp.attribute.resolver.LDAP.baseDN}"
        principal="%{idp.attribute.resolver.LDAP.bindDN}"
        principalCredential="%{idp.attribute.resolver.LDAP.bindDNCredential}"
        useStartTLS="%{idp.attribute.resolver.LDAP.useStartTLS:true}"
        connectTimeout="%{idp.attribute.resolver.LDAP.connectTimeout}"
        trustFile="%{idp.attribute.resolver.LDAP.trustCertificates}"
        responseTimeout="%{idp.attribute.resolver.LDAP.responseTimeout}">
        <FilterTemplate>
            <![CDATA[
                %{idp.attribute.resolver.LDAP.searchFilter}
            ]]>
        </FilterTemplate>
        <ConnectionPool
            minPoolSize="%{idp.pool.LDAP.minSize:3}"
            maxPoolSize="%{idp.pool.LDAP.maxSize:10}"
            blockWaitTime="%{idp.pool.LDAP.blockWaitTime:PT3S}"
            validatePeriodically="%{idp.pool.LDAP.validatePeriodically:true}"
            validateTimerPeriod="%{idp.pool.LDAP.validatePeriod:PT5M}"
            expirationTime="%{idp.pool.LDAP.idleTime:PT10M}"
            failFastInitialize="%{idp.pool.LDAP.failFastInitialize:false}" />
    </DataConnector>

    <DataConnector id="statiConnector" xsi:type="Static">
        <Attribute id="role">
            <Value>user</Value>
        </Attribute>
    </DataConnector>


Note that i use static connector for attribute role which mean role attribute will be always user to all the authenticated users.

Update the /app/shibboleth-idp/conf/attribute-filter.xml file to release the attribute the respective SP entity.

    <AttributeFilterPolicy id="example1">
        <PolicyRequirementRule xsi:type="Requester" value="clouderaManager" />

        <AttributeRule attributeID="uid">
            <PermitValueRule xsi:type="ANY" />
        </AttributeRule>
        <AttributeRule attributeID="mail">
            <PermitValueRule xsi:type="ANY" />
        </AttributeRule>
       <AttributeRule attributeID="role">
            <PermitValueRule xsi:type="ANY" />
        </AttributeRule>
    </AttributeFilterPolicy>


    <AttributeFilterPolicy id="example2">
        <PolicyRequirementRule xsi:type="Requester" value="hueserver1" />

        <AttributeRule attributeID="uid">
            <PermitValueRule xsi:type="ANY" />
        </AttributeRule>
       <AttributeRule attributeID="mail">
            <PermitValueRule xsi:type="ANY" />
        </AttributeRule>
    </AttributeFilterPolicy>

    <AttributeFilterPolicy id="example3">
        <PolicyRequirementRule xsi:type="Requester" value="clouderaNavigator" />

        <AttributeRule attributeID="uid">
            <PermitValueRule xsi:type="ANY" />
        </AttributeRule>
        <AttributeRule attributeID="mail">
            <PermitValueRule xsi:type="ANY" />
        </AttributeRule>
       <AttributeRule attributeID="role">
            <PermitValueRule xsi:type="ANY" />
        </AttributeRule>
    </AttributeFilterPolicy>







No comments:

Post a Comment