SAML Based Security For OData

By default the OData access to a Virtual Database (VDB) in WildFly is restricted to authentication using the HTTP Basic. However, it possible with below instructions one can configure OData access to participate in a Single-Sign-On (SSO) based security using SAML2. The below instructions are based on JBoss EAP platform using Picketlink security framework.

In SAML based authentication there are Identity Providers (IDP) who provide authentication services and Service Providers (SP), a end user service like odata and user (you). It is expected that you already have IDP, configured and working with security domain of your choice like LDAP or Kerberoes etc. The SP in this case is the OData WAR file that is supplied with Teiid distribution along with Picketlink based framework. Picketlink framework does not explicitly mention the interoperability with other third party external vendors supplied IDP, but Teiid team has tested successfully with

  • Shibboleth

  • Picketlink IDP

  • Salesforce IDP (this is documented on Picketlink, not verified)

  • Social Logins with Picketlink IDP (like, google, facebook etc. This has been mentioned in Picketlink documentation but not verified)

Note
Since SAML2 is standard, we believe any standards complaint IDP vendor will work with Picketlink SP.

requisites

  • Collect the certificate for authentication that is used by IDP to sign the SAML messages.

  • Gather the SSO POST based URL for your IDP, that your SP can use to redirect for authentication call.

Note
"DNS Names" - Do not try to use IP address or localhost except for the testing scenarios. Configure proper DNS names for both IDP and SP servers and make sure both can access each other using the URLs configured.

Configure for SAML based authentication the OData

In security-domains add following login module using the following CLI

/subsystem=security/security-domain=teiid-security/authentication=classic/login-module=RealmDirect:write-attribute(name=flag, value=sufficient)
/subsystem=security/security-domain=teiid-security/authentication=classic/login-module=saml2:add(code=org.picketlink.identity.federation.bindings.jboss.auth.SAML2LoginModule, flag=sufficient)
reload

the above commands will result in XML in standalone.xml or domain.xml file similar to:

"Security-Domain for SAML Authentication"
	<security-domain name="teiid-security">
        <authentication>
            <login-module code="org.picketlink.identity.federation.bindings.jboss.auth.SAML2LoginModule" flag="sufficient"/>
            <login-module code="RealmDirect" flag="sufficient">
               <module-option name="password-stacking" value="useFirstPass"/>
            </login-module>
        </authentication>
    </security-domain>

Modify the OData WAR File to use SAML based authentication

  • Extract the "teiid-olingo-odata4.war" file from "modules/system/base/dv/org/jboss/teiid/main/deployments" to another location. The WAR file is simple ZIP file so you can "jar -x teiid-olingo-odata4.war /modified"

  • Edit "WEB-INF/jboss-web.xml" file, and it should look like

"jboss-web.xml"
<?xml version="1.0" encoding="UTF-8"?>
<jboss-web>
    <context-root>odata4</context-root>
    <security-domain>teiid-security</security-domain>
    <valve>
       <class-name>org.picketlink.identity.federation.bindings.tomcat.sp.ServiceProviderAuthenticator</class-name>
       <param>
      <param-name>configProvider</param-name>
      <param-value>org.picketlink.identity.federation.web.config.SPPostMetadataConfigurationProvider</param-value>
    </param>
    </valve>
</jboss-web>
  • Edit "web.xml" file and remove the section below

"web.xml"
<login-config>
    <auth-method>BASIC</auth-method>
    <realm-name>yourdomain.com</realm-name>
</login-config>
  • Add the certificate keystore from your IDP to the classes directory. This is {KEYSTORE-FILE} in below configuration. or you can add to a existing keystore using following command

keytool -import -file idp_cert.cer -keystore {KEYSTORE-FILE} -alias {CERTIFICATE-ALIAS}
  • Add "picketlink.xml" file to WEB-INF directory with following content

"picketlink.xml"
<PicketLink xmlns="urn:picketlink:identity-federation:config:2.1">
    <PicketLinkSP xmlns="urn:picketlink:identity-federation:config:2.1"
        ServerEnvironment="tomcat" BindingType="POST" SupportsSignatures="true">
        <KeyProvider
            ClassName="org.picketlink.identity.federation.core.impl.KeyStoreKeyManager">
            <Auth Key="KeyStoreURL" Value="{KEYSTORE-FILE}" />
            <Auth Key="KeyStorePass" Value="{KEYSTORE-PASSWORD}" />
            <Auth Key="SigningKeyAlias" Value="{CERTIFICATE-ALIAS}" />
                        <Auth Key="SigningKeyPass" Value="{CERTIFICATE-PASSWORD}" />
            <ValidatingAlias Key="localhost" Value="{CERTIFICATE-ALIAS}" />
            <ValidatingAlias Key="127.0.0.1" Value="{CERTIFICATE-ALIAS}" />
        </KeyProvider>
    </PicketLinkSP>
    <Handlers xmlns="urn:picketlink:identity-federation:handler:config:2.1">
        <Handler class="org.picketlink.identity.federation.web.handlers.saml2.SAML2LogOutHandler" />
        <Handler class="org.picketlink.identity.federation.web.handlers.saml2.SAML2AuthenticationHandler" />
        <Handler class="org.picketlink.identity.federation.web.handlers.saml2.RolesGenerationHandler" />
        <Handler class="org.picketlink.identity.federation.web.handlers.saml2.SAML2SignatureGenerationHandler" />
        <Handler class="org.picketlink.identity.federation.web.handlers.saml2.SAML2SignatureValidationHandler" />
    </Handlers>
</PicketLink>
Note
{CERTIFICATE-ALIAS} is typically something like "idp.example.com" for which the certificate is created for
  • Add the certificate received from IDP vendor to "WEB-INF/classes" directory. Note this must be same name as {CERTIFICATE-FILE-NAME} used in "Configuring the Picketlink Subsystem"

  • Add "sp-metadata.xml" to the classes directory. Note that your "sp-metadata.xml" contents will entirely dependent upon your Identity Provider settings. The below sample ONLY provided as an example

"sp-metadata.xml"
<?xml version="1.0" encoding="UTF-8"?>
<EntitiesDescriptor Name="urn:mace:shibboleth:testshib:two"
    xmlns:shibmd="urn:mace:shibboleth:metadata:1.0" xmlns="urn:oasis:names:tc:SAML:2.0:metadata"
    xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <EntityDescriptor entityID="http://localhost:8080/idp-metadata/">
        <IDPSSODescriptor
            protocolSupportEnumeration="urn:oasis:names:tc:SAML:1.1:protocol urn:oasis:names:tc:SAML:2.0:protocol">
            <NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:transient
            </NameIDFormat>
            <SingleSignOnService Binding="urn:mace:shibboleth:1.0:profiles:AuthnRequest"
                Location="http://localhost:8080/idp-metadata/" />
            <SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
                Location="http://localhost:8080/idp-metadata/" />
            <SingleSignOnService
                Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
                Location="http://localhost:8080/idp-metadata/" />
            <SingleLogoutService
                Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
                Location="http://localhost:8080/idp-metadata/?GLO=true" />
            <SingleLogoutService
                Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
                Location="http://localhost:8080/idp-metadata/SLO" />
        </IDPSSODescriptor>
        <Organization>
            <OrganizationName xmlns="urn:oasis:names:tc:SAML:2.0:metadata"
                xml:lang="en">JBoss</OrganizationName>
            <OrganizationDisplayName xmlns="urn:oasis:names:tc:SAML:2.0:metadata"
                xml:lang="en">JBoss by Red Hat</OrganizationDisplayName>
            <OrganizationURL xmlns="urn:oasis:names:tc:SAML:2.0:metadata"
                xml:lang="en">http://www.jboss.org</OrganizationURL>
        </Organization>
        <ContactPerson contactType="technical">
            <GivenName>The</GivenName>
            <SurName>Admin</SurName>
            <EmailAddress>admin@mycompany.com</EmailAddress>
        </ContactPerson>
    </EntityDescriptor>
    <EntityDescriptor entityID="http://localhost:8080/odata4/">
        <SPSSODescriptor
            protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol urn:oasis:names:tc:SAML:1.1:protocol http://schemas.xmlsoap.org/ws/2003/07/secext">
            <NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:transient
            </NameIDFormat>
            <AssertionConsumerService
                Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="http://localhost:8080/odata4/"
                index="1" isDefault="true" />
        </SPSSODescriptor>
        <Organization>
            <OrganizationName xmlns="urn:oasis:names:tc:SAML:2.0:metadata"
                xml:lang="en">JBoss</OrganizationName>
            <OrganizationDisplayName xmlns="urn:oasis:names:tc:SAML:2.0:metadata"
                xml:lang="en">JBoss by Red Hat</OrganizationDisplayName>
            <OrganizationURL xmlns="urn:oasis:names:tc:SAML:2.0:metadata"
                xml:lang="en">http://localhost:8080/odata4/</OrganizationURL>
        </Organization>
        <ContactPerson contactType="technical">
            <GivenName>The</GivenName>
            <SurName>Admin</SurName>
            <EmailAddress>admin@mycompany.com</EmailAddress>
        </ContactPerson>
    </EntityDescriptor>
</EntitiesDescriptor>
deployment-overlay add --name=myOverlay --content=/WEB-INF/web.xml=/modified/web.xml,/WEB-INF/jboss-web.xml=/modified/jboss-web.xml --deployments=teiid-odata-odata4.war --redeploy-affected

results matching ""

    No results matching ""