Security at the Data Source Level

In some use cases, the user might need to pass-in different credentials to their data sources based on the logged in user rather than using the shared credentials for all the logged users. To support this feature, WildFly and Teiid provide multiple different login modules to be used in conjunction with Teiid’s main security domain. See this document for details on configuration. Note that the below directions need to be used in conjunction with this document.

CallerIdentity

If client wants to pass in simple text password or a certificate or a custom serialized object as token credential to the data source, user can configure "CallerIdentity" login module. Using this login module, user can pass-in same credential that user logged into Teiid security domain to the data source. Here is a sample configuration:

standalone-teiid.xml
<subsystem xmlns="urn:jboss:domain:security:1.1">
    <security-domains>
        <security-domain name="my-security-domain">
            <authentication>
                <login-module code="RealmDirect" flag="required">
                    <module-option name="password-stacking" value="useFirstPass"/>
                </login-module>

                <login-module code="org.picketbox.datasource.security.CallerIdentityLoginModule" flag="required">
                    <module-option name="password-stacking" value="useFirstPass"/>
                </login-module>

            </authentication>
        </security-domain>
    </security-domains>
</subsystem>
Note
"applicability" - CallerIdentity Login module is only applicable when logged in subject contains the text based credentials, where this login module retrieves and uses the username and password for the data source authentication purposes. When working with non character based passwords use Passthough Identity defined below.

In the datasource configuration, instead of supplying the userid/pasword you need to add the following element

In JDBC Datasource
<datasource jndi-name="java:/mysql-ds" pool-name="mysql-ds" enabled="true">
    <connection-url>jdbc:mysql://localhost:3306/txns</connection-url>
    <driver>mysql</driver>
     <pool><allow-multiple-users/></pool>
     <security>
          <security-domain>my-security-domain</security-domain>
     </security>
</datasource>
Note
This security domain only should be used as data source security domains, not as generic purpose security domain.
In a connection factory ex:ldap
        <resource-adapter>
            <archive>teiid-connector-ldap.rar</archive>
            <transaction-support>NoTransaction</transaction-support>
            <connection-definitions>
                <connection-definition class-name="org.teiid.resource.adapter.ldap.LDAPManagedConnectionFactory"
                        jndi-name="java:/ldapDS"
                        enabled="true"
                        use-java-context="true"
                        pool-name="ldap-ds">

                  <config-property name="LdapUrl">ldap://ldapServer:389</config-property>
                  <config-property name="LdapAdminUserDN">cn=???,ou=???,dc=???</config-property>
                  <config-property name="LdapAdminUserPassword">pass</config-property>
                  <config-property name="LdapTxnTimeoutInMillis">-1</config-property>

                  <security>
                     <security-domain>my-security-domain</security-domain>
                 </security>
                </connection-definition>
            </connection-definitions>
        </resource-adapter>

In the above configuration example, in the primary login module “UsersRoles” is setup to hold the passwords in the file, and when user logs in with password, the same userid and password will be also set on the logged in Subject after authentication. These credentials can be extracted by the data source by asking for Subject’s private credentials.

Please note that encoding and decoding of this object is strictly up to the user as WildFly and Teiid will only act as a carrier of the information from login module to connection factory. Using this CallerIdentity module, the connection pool for data source is segmented by Subject.

Pass Through Identity

This one is similar to Caller Identity login module, where the calling user’s credentials and roles are passed as is. This is especially useful when dealing with non-text based credentials where you want to pass down the payload as is. The example is when kerberos login is used the logged in subject contains GSSCredential object that contains the GSS token.

standalone-teiid.xml
<subsystem xmlns="urn:jboss:domain:security:1.1">
    <security-domains>
        <security-domain name="passthrough-security">
            <authentication>
                <login-module code="org.teiid.jboss.PassthroughIdentityLoginModule" flag="required" module="org.jboss.teiid">
                    <module-option name="username" value="guest"/>
                    <module-option name="password" value="guest"/>
                </login-module>
            </authentication>
        </security-domain>
    </security-domains>
</subsystem>

In the datasource configuration, instead of supplying the userid/pasword you need to add the following element

In JDBC Datasource
<datasource jndi-name="java:/mysql-ds" pool-name="mysql-ds" enabled="true">
    <connection-url>jdbc:mysql://localhost:3306/txns</connection-url>
    <driver>mysql</driver>
     <pool><allow-multiple-users/></pool>
     <security>
          <security-domain>passthrough-security</security-domain>
     </security>
</datasource>
Note
This security domain only should be used as data source security domains in pass-through scenarios, not as generic purpose security domain.
Tip
When working with Kerberos/GSS security token (GssCredential), some JDBC drivers (MS-SQLServer) upon close of the connection they invalidate the GssCredential security token, to avoid accidental invalidation, add an option to above security-domain’s login-module configuration to wrap the passed in security token by adding below configuration
<module-option name="wrapGSSCredential" value="true"/>

OAuth Authentication

Secured Rest services with OAuth authentication can be used in Teiid, however the data sources need to be configured with OAuth Refresh Token or Json Web Token (JWT) based security domains.

Refresh Token

In order to use OAuth, one need to create application in vendors web service. A connected application is different for different vendors like Google, LinkedIn, SalesForce etc. For details about creating an application consult vendor’s documentation. Once you have created connected application, then run teiid-oauth-util.sh in "<eap>/bin" directory, use client_id, client_pass, and call back from source specific connected application. This script will provide the necessary values to plug-in below CLI script.

create a security-domain by executing CLI

/subsystem=security/security-domain=oauth2-security:add(cache-type=default)
/subsystem=security/security-domain=oauth2-security/authentication=classic:add
/subsystem=security/security-domain=oauth2-security/authentication=classic/login-module=oauth:add(code=org.teiid.jboss.oauth.OAuth20LoginModule, flag=required, module=org.jboss.teiid.security,
   module-options=[client-id=xxxx, client-secret=xxxx, refresh-token=xxxx,
   access-token-uri=https://login.salesforce.com/services/oauth2/token])
reload

this will generate following XML in the standalone.xml or domain.xml (this can also be directly added to the standalone.xml or domain.xml files instead of executing the CLI)

standalone.xml
<security-domain name="oauth2-security">
    <authentication>
        <login-module code="org.teiid.jboss.oauth.OAuth20LoginModule" flag="required" module="org.jboss.teiid.security">
            <module-option name="client-id" value="xxxx"/>
            <module-option name="client-secret" value="xxxx"/>
            <module-option name="refresh-token" value="xxxx"/>
            <module-option name="access-token-uri" value="https://login.salesforce.com/services/oauth2/token"/>
        </login-module>
    </authentication>
</security-domain>

JSON Web Token (JWT)

In order to use OAuth, one need to create application in vendors web service. A connected application is different for different vendors like Google, LinkedIn, SalesForce etc. For details about creating an application consult vendor’s documentation. Once you have created connected application that uses the JWT, gather the below information client-id, client-secret, access-token-uri, jwt-audience,jwt-subject,keystore-type,keystore-password, keystore-url,certificate-alias,signature-algorithm-name and provide in the below CLI. (only tested with SalesForce)

/subsystem=security/security-domain=oauth2-jwt-security:add(cache-type=default)
/subsystem=security/security-domain=oauth2-jwt-security/authentication=classic:add
/subsystem=security/security-domain=oauth2-jwt-security/authentication=classic/login-module=oauth:add(code=org.teiid.jboss.oauth.OAuth20LoginModule, flag=required, module=org.jboss.teiid.security,
   module-options=[client-id=xxxx, client-secret=xxxx, access-token-uri=https://login.salesforce.com/services/oauth2/token, jwt-audience=https://login.salesforce.com, jwt-subject=your@sf-login.com,
    keystore-type=JKS, keystore-password=changeme, keystore-url=${jboss.server.config.dir}/salesforce.jks, certificate-alias=teiidtest, signature-algorithm-name=SHA256withRSA])
reload

this will generate following XML in the standalone.xml or domain.xml (this can also be directly added to the standalone.xml or domain.xml files instead of executing the CLI)

standalone.xml
<security-domain name="oauth2-jwt-security">
    <authentication>
        <login-module code="org.teiid.jboss.oauth.JWTBearerTokenLoginModule" flag="required" module="org.jboss.teiid.security">
            <module-option name="client-id" value="xxxxx"/>
            <module-option name="client-secret" value="xxxx"/>
            <module-option name="access-token-uri" value="https://login.salesforce.com/services/oauth2/token"/>
            <module-option name="jwt-audience" value="https://login.salesforce.com"/>
            <module-option name="jwt-subject" value="your@sf-login.com"/>

            <module-option name="keystore-type" value="JKS"/>
            <module-option name="keystore-password" value="changeme"/>
            <module-option name="keystore-url" value="${jboss.server.config.dir}/salesforce.jks"/>
            <module-option name="certificate-alias" value="teiidtest"/>
            <module-option name="signature-algorithm-name" value="SHA256withRSA"/>
        </login-module>
    </authentication>
</security-domain>

Kerberos

Kerberos can also used as data source security. The below configuration is to configure a static Kerberos ticket at data source. Please note that Kerberos can be used with RDBMS, REST web services.

/subsystem=security/security-domain=host:add(cache-type=default)
/subsystem=security/security-domain=host/authentication=classic:add
/subsystem=security/security-domain=host/authentication=classic/login-module=Kerberos:add(code=Kerberos, flag=required,
   module-options=[storeKey=true, refreshKrb5Config=true, useKeyTab=true,
   principal=host/testserver@MY_REALM, keyTab=/path/to/service.keytab, doNotPrompt=true, debug=false])
reload

The above command will generate resulting XML in the standalone.xml file or domain.xml file.

standalone.xml
<security-domain name="host">
   <authentication>
      <login-module code="Kerberos" flag="required">
         <module-option name="storeKey" value="true"/>
         <module-option name="useKeyTab" value="true"/>
         <module-option name="principal" value="host/testserver@MY_REALM"/>
         <module-option name="keyTab" value="/path/to/service.keytab"/>
         <module-option name="doNotPrompt" value="true"/>
         <module-option name="debug" value="false"/>
         <module-option name="refreshKrb5Config" value = "true"/>
      </login-module>
   </authentication>
</security-domain>

Kerberos passthrough

For using the same kerberos token at Teiid and as well as at the data source level, the token negotiated at the Teiid engine can be passed into data source. Data source explicitly needs to provide this support. Major database vendors like Oracle, MS-SQLServer, DB2, HIVE, Impala support kerberos. Some also support pass through mode. To Make pass-through work, follow the directions here to setup the Kerberos at Teiid engine level [Kerberos support through GSSAPI] then for data source level create the [#Pass Through Identity]

Translator Customization

Teiid’s extensible Translator framework also provides hooks for securing access at the DataSource level. The ExecutionFactory.getConnection may be overridden to initialize the source connection in any number of ways, such as re-authentication, based upon the Teiid Subject, execution payload, session variables, and any of the other relevant information accessible via the ExecutionContext and the CommandContext. You may even also modify the generated source SQL in any way that is seen fit in the relevant Execution.

results matching ""

    No results matching ""