<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
<!ENTITY % CustomDTD SYSTEM "../../../../../../docbook/custom.dtd">
%CustomDTD;
]>
<chapter id="custom_security">
	<title>Teiid Security</title>
	<para>The Teiid system provides a range of built-in and extensible security features to enable the
		secure access of data.</para>
	<section>
		<title>Authentication</title>
		<para>JDBC clients may use simple passwords to authenticate a user.</para>

		<para>Typically a user name is required, however user names may be considered optional if the
			identity of the user can be discerned by the password credential alone.  In
			any case it is up to the configured security domain to determine whether a user can be
			authenticated. If you need authentication, the administrator must configure a LoginModule to be used with Teiid. 
            See below for more information on how configure the Login module in JBoss AS.</para>
			
			<note><para>By default, access to Teiid is NOT secure. The default login modules are only 
	        backed by file based authentication, which has a well known user 
	        name and password.
	        The same is true for making connections to the Admin Console application. 
	        We DO NOT recommend leaving the default security profile as defined when you 
	        are exposing sensitive data.</para></note>
            <section>
                <title>Pass-through Authentication</title>
                <para>If your client application (web application or Web service) resides in the same JBoss AS instance as Teiid and 
                the client application uses a security-domain, then you can configure Teiid to use the 
                same security-domain and not force the user to re-authenticate. In this case Teiid looks for an authenticated 
                subject in the calling thread context and uses it for sessioning and authorization. To configure Teiid for
                pass-through authentication, change the Teiid security-domain name to the same name as your 
                application's security domain name in the "standalone-teiid.xml" file in the "transport" section. 
                Please note that for this to work, the security-domain 
                must be a JAAS based Login Module and your client application MUST obtain its Teiid connection 
                using a <emphasis>local/embedded</emphasis> connection with the<emphasis>PassthroughAuthentication=true</emphasis> connection flag set.</para>
            </section>
	</section>
	<section>
		<title>Authorization</title>
		<para>Authorization covers both administrative activities and data
			roles.  A data role is a collection of permissions (also referred to as entitlements) and a
			collection of entitled principals or groups. With the deployment of a VDB
			the deployer can choose which principals and groups have which data roles.</para>
	</section>
	<section>
		<title>Encryption</title>

		<para>At a transport level Teiid provides built-in support for JDBC
			over SSL or just sensitive message encryption when SSL is not in use.
		</para>
		<para>
			Passwords in configuration files however are by default stored in
			plain text. If you need these values to be encrypted, please see
			<ulink
				url="http://community.jboss.org/wiki/maskingpasswordsinjbossasxmlconfiguration">encrypting passwords</ulink>
			for instructions on encryption facilities provided by the container.
		</para>
	</section>
	<section>
		<title>LoginModules</title>

		<para>
			LoginModules are an essential part of the JAAS security
			framework and provide Teiid customizable user authentication and the
			ability to reuse existing LoginModules defined for JBossAS. See
			<ulink
				url="http://docs.jboss.org/jbossas/admindevel326/html/ch8.chapter.html">JBossAS Security</ulink>
			for general information on configuring security in JBossAS.</para>
		<para>
			Teiid can be configured with multiple named application policies
			that group together relevant LoginModules. Each of these application
			policy (or domain) names can be used to fully qualify user names to
 			authenticate only against that domain.  The format for a qualified
			name is username@domainname.  The security-domain attribute under the transport/authentication element in the &jboss-beans; file should be used set 
			the comma separated list of desired domains.  The securityDomains property defaults to a single domain named teiid-security.
		</para>
		<para>If a user name is not fully qualified, then the installed
			domains will be consulted in order until a domain
			successfully or unsuccessfully authenticates the
			user.
		</para>

		<para>If no domain can authenticate the user, the login
			attempt will fail.
			Details of the failed attempt including invalid users, which
			domains were consulted, etc. will be in the server log with appropriate
			levels of severity.</para>
        <note>
            <para>The security-domain defined for each transport type is can be different. The JDBC connection .
                The default name of JDBC connection's security-domain is "teiid-security". In existing installations 
                an appropriate security domain may already be configured for use by administrative clients (typically "admin-console").
		        If the admin connections (CLI and adminshell) are not secured, it is recommended that you secure that that interface
                by executing one of scripts in the "bin/scripts" directory.</para>
        </note>    
			
		<section>
			<title>Built-in LoginModules</title>
			<para>JBossAS provides several LoginModules for common authentication needs, such as authenticating from a <xref linkend="text-login"/> or a <xref linkend="ldap-login"/>.</para>

			<para>You can install multiple login modules as part of single security domain configuration and configure them 
                to part of login process. For example, for "teiid-security" domain, you can configure a file based and also LDAP based login modules, 
                and have your user authenticated with either or both login modules.  If you want to write your own custom login module, refer to the Developer's Guide for instructions.  
	        </para>

		<section id="text-login">
			<title>Text Based LoginModule</title>
			<para>The UsersRolesLoginModule utilizes simple text files to authenticate users and to define their groups.  
            The below XML fragment under "security" subsystem shows a Text based login module. Also see standalone-teiid.xml 
            configuration file contains an example of how to use UsersRolesLoginModule.  
            <programlisting><![CDATA[        
         <subsystem xmlns="urn:jboss:domain:security:1.1">
            <security-domains>
                <security-domain name="teiid-security" cache-type="default">
                    <authentication>
                        <login-module code="UsersRoles" flag="required">
                            <module-option name="usersProperties" value="teiid-security-users.properties"/>
                            <module-option name="rolesProperties" value="teiid-security-roles.properties"/>
                        </login-module>
                    </authentication>
                </security-domain>
            </security-domains>
        </subsystem>]]></programlisting>            
            <note><para>The UsersRolesLoginModule is not recommended for production use and is strongly recommended 
            that you replace this login module.</para></note>
			</para>

			<para>User names and passwords are stored in the 
            &lt;jboss-as&gt;/modules/org/jboss/teiid/main/conf/teiid-security-users.properties file. 
            These files must be available on classpath
            <example>
            <title>Example user.properties file</title>
            <programlisting><![CDATA[# A users.properties file for use with the UsersRolesLoginModule
# username=password

fred=password
george=password
...]]></programlisting>
            </example>

JAAS role assignments are stored in the &lt;jboss-as&gt;/modules/org/jboss/teiid/main/conf/teiid-security-roles.properties file.
<example><title>Example user.properties file</title>
<programlisting><![CDATA[# A roles.properties file for use with the UsersRolesLoginModule
# username=role1,role2,...

data_role_1=fred,sally
data_role_2=george
]]></programlisting></example>

User and role names are entirely up to the needs of the given deployment.  For example each application team can set their own security constraints for their VDBs, by mapping their VDB data roles to application specific JAAS roles, e.g. app_role_1=user1,user2,user3.
<note><para>Teiid data roles names are independent of JAAS roles.  VDB creators can choose whatever name they want for their data roles, which are then mapped at deployment time to JAAS roles.</para></note>
</para>
		</section>

			<section id="ldap-login">
				<title>LDAP Based LoginModule</title>
				<para>See <ulink url="http://community.jboss.org/docs/DOC-11253">LDAP LoginModule configuration</ulink> for the AS community guide.  The following are streamlined installation instruction.
					<orderedlist>
						<listitem><para>If using SSL to the LDAP server, ensure that the Corporate CA Certificate is added to the JRE trust store.</para>
						</listitem>
	
						<listitem><para>Include LDAP LoginModule in the JAAS Configuration</para>
						<para>Configure LDAP authentication by editing standalone-teiid.xml under security subdomain.  If you wish to configure specifically for teiid, then the security domain teiid-security will need to be created/altered.
						You could do one of the following for Teiid:
						<itemizedlist>
						 	<listitem>
						 	<para>Reuse the admin-console (or whatever name you choose) security domain for Teiid by changing the teiid configuration &jboss-beans; to point to admin-console.
						 	</para>
						 	</listitem>

						 	<listitem>
						 	<para>Follow the same steps to configure an LDAP security domain named teiid-security.
						 	</para>
						 	</listitem>
						</itemizedlist>
						</para></listitem>

						<listitem><para>Obscure the LDAP Password</para><para>Finally, protect the password following <ulink url="http://docs.redhat.com/docs/en-US/JBoss_Enterprise_Application_Platform/5/html/Security_Guide/Using_LdapExtLoginModule_with_JaasSecurityDomain.html">these instructions.</ulink>
						Note that the salt must be 8 chars and see also http://community.jboss.org/message/137756#137756 for more on securing passwords.
						</para></listitem>
					</orderedlist>
				</para>
			</section>
		</section>
        
        <section>

            <title>Kerberos support through GSSAPI</title>
            <para>Teiid supports kerberos authentication using GSSAPI, to be used with single sign-on applications.
            This service ticket negotiation based authentication is supported through remote JDBC and ODBC drivers and LocalConnections. 
            Client configuration is different for based on connection you are using</para>
            
            <section>
                <title>LocalConnection</title>
                <para>Set the JDBC URL property <emphasis>PassthroughAuthentication</emphasis> 
                as true and use <ulink url="http://community.jboss.org/docs/DOC-10680">JBoss Negotiation</ulink> for 
                authentication of your web-application with kerberos. When the web application authenticates with the provided
                kerberos token, the same subject authenticated will be used in Teiid. For details about configuration, check the 
                JBoss Negotiation documentation.</para>

            </section>
            
            <section>
                <title>Remote Connections</title>
                <para>On the server, edit the &jboss-beans; under teiid subsystem on "transport" definition, add follows:
                <programlisting><![CDATA[
<transport name="jdbc" protocol="teiid" socket-binding="teiid-jdbc"/>
        <authentication security-domain="teiid-security" krb5-domain="krb5-domain"/>
</transport>
]]></programlisting>                    
                Now we need to define a security domain context for kerberos with the name mentioned (kbr5-domain)in above.
                Since kerberos authorization cannot define authorization roles, we'll define them using another login context. 
                Given below is a sample configuration to define roles using a UserRolesLoginModule. 
                <note><para>This configuration replaces the default Teiid login configuration, and you should change the principal 
                and key tab locations accordingly.</para></note>
                <programlisting><![CDATA[<!--login module that negotiates the login conext for kerberos --> 
         <subsystem xmlns="urn:jboss:domain:security:1.1">
            <security-domains>
                <security-domain name="krb5-domain" cache-type="default">
                    <authentication>
                        <login-module code="Kerberos" flag="required">
                            <module-option name="storeKey">true</module-option>
                            <module-option name="useKeyTab">true</module-option>
                            <module-option  name="principal">demo@EXAMPLE.COM</module-option>
                            <module-option  name="keyTab">path/to/krb5.keytab</module-option>
                            <module-option name="doNotPrompt">true</module-option>
                            <module-option name="debug">false</module-option>
                        </login-module>         
                    </authentication>        
                </security-domain>
                <!-- teiid's default security domain, replace this with your own if needs to be any other JAAS domain  -->
                <security-domain name="teiid-security" cache-type="default">
                    <authentication>
                        <login-module code="UsersRoles" flag="required">
                            <module-option name="usersProperties" value="teiid-security-users.properties"/>
                            <module-option name="rolesProperties" value="teiid-security-roles.properties"/>
                        </login-module>
                    </authentication>
                </security-domain>
            </security-domains>
        </subsystem>]]></programlisting>
               Edit the "standalone.conf" file in the "${jboss-as}/bin" directory 
               and add the following JVM options (changing the realm and KDC settings according to your environment)
               <programlisting><![CDATA[JAVA_OPTS = "$JAVA_OPTS -Djava.security.krb5.realm=EXAMPLE.COM -Djava.security.krb5.kdc=kerberos.example.com -Djavax.security.auth.useSubjectCredsOnly=false"]]></programlisting>                                          
            This finishes the configuration on the server side, restart the server and make sure that there were no errors during startup. 
            </para>
            
            <section>
				<title>JDBC Client Configuration</title>                        
	            <para>In you client VM the JAAS 
	            configuration for kerberos authentication needs to be written. A sample configuration file (client.conf) is show below
	            
	           <programlisting><![CDATA[Client {
    com.sun.security.auth.module.Krb5LoginModule required
    useTicketCache=true
    storeKey=true
    useKeyTab=true 
    keyTab="/path/to/krb5.keytab" 
    doNotPrompt=false 
    debug=false
    principal="demo@EXAMPLE.COM";
};]]></programlisting>                                          
	            
	            Add the following JVM options to your client's startup script - change Realm and KDC settings according to 
	            your environment
	           <programlisting><![CDATA[-Djava.security.krb5.realm=EXAMPLE.COM
-Djava.security.krb5.kdc=kerberos.example.com
-Djavax.security.auth.useSubjectCredsOnly=false
-Dsun.security.krb5.debug=false
-Djava.security.auth.login.config=/path/to/client.conf]]></programlisting>              
	            
	            Add the following URL connection properties to Teiid JDBC connection string
	            <programlisting><![CDATA[authenticationType=KRB5;jaasName=Client;kerberosServicePrincipleName=demo@EXAMPLE.COM]]></programlisting>
	            There is no need to provide the user name and password. When the application makes a JDBC connection, it
	            will authenticate locally and use the same user credentials to negotiate a service token with server and grant the
	            connection. See Client Developer's guide for information on connection properties and how to configure data sources.
	            </para>

	            </section>
	
	        </section>        
        </section>
        
        <section>
        	<title>ODBC Client Configuration</title>
        	<para>Consult the PostgreSQL ODBC client documentation.</para>
        </section>
		
        <section>

            <title>Security at Data Source level</title>
            <para>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, JBoss AS and Teiid provide multiple different 
            login modules to be used in conjunction with Teiid's main security domain. See this 
            <ulink url="http://community.jboss.org/docs/DOC-9350">document</ulink> for details on configuration. Note that the below 
            directions need to be used in conjunction with this document.</para>
            
            <section>
                <title>CallerIdentity and Trusted Payload</title>
                <para>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, this needs to be configured in "standalone-teiid.xml" file.
                </para>
                
            <programlisting><![CDATA[<subsystem xmlns="urn:jboss:domain:security:1.1">
            <security-domains>
                <security-domain name="my-security-domain" cache-type="default">
                    <authentication>
                        <login-module code="UsersRoles" flag="required">
                            <module-option name = "password-stacking">useFirstPass</module-option>
                            <module-option name="usersProperties">props/teiid-security-users.properties</module-option>
                            <module-option name="rolesProperties">props/teiid-security-roles.properties</module-option>
                        </login-module>
                        
                        <login-module code="org.jboss.resource.security.CallerIdentityLoginModule" flag="required">
                            <module-option name = "password-stacking">useFirstPass</module-option>
                            <module-option name = "managedConnectionFactoryName">jboss.jca:service=LocalTxCM,name=DefaultDS</module-option>
                        </login-module>
                    
                    </authentication>
                </security-domain>
                </security-domains>
                ]]></programlisting>
            
            <para>In the datasource defined as the "managedConnectionFactoryName" in the above configuration, 
            you need to add the following element</para>
            
            <programlisting><![CDATA[<security-domain>teiid-security</security-domain>]]></programlisting>
            
            <para>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 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.</para>
            
            <para>To use a certificate or serialized object instead of plain password as the token, replace the simple text password
                with Base64 encoded contents of the serialized object. Please note that encoding and decoding of this object 
                is strictly up to the user as JBoss AS 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.</para>
            </section>
        <section>

            <title>Role Based Credential Map</title>
            <para>In some use cases, the users are divided by their functionality and they have varied levels of security access to 
            data sources. These types of users are identified by their roles as to what they have access to. In the above "CallerIdentity" 
            login scenario, that may be too fine-grained security at data sources, that can lead resource exhaustion as every user has 
            their own separate connection. 
            Using Role based security gives a balance, where the users with same role are treated equally 
            for authentication purposes at the data source. Teiid provides a login module called "RoleBasedCredentialMap" 
            for this purposes, where administrator can define a role-based authentication module, where given the role of the user
            from the primary login module, this module will hold a credential to that role. So, it is the container of credentials that
            maps to different roles. If a user has multiple roles, the first role that has the credential will be chosen.
            Below find the sample configuration.</para>
            
            <programlisting><![CDATA[<subsystem xmlns="urn:jboss:domain:security:1.1">
            <security-domains>
                <security-domain name="my-security-domain" cache-type="default">
                    <authentication>
        
                        <login-module code="UsersRoles" flag="required">
                            <module-option name = "password-stacking">useFirstPass</module-option>
                            <module-option name="usersProperties">teiid-security-users.properties</module-option>
                            <module-option name="rolesProperties">teiid-security-roles.properties</module-option>
                        </login-module>
                        
                        <login-module code="org.teiid.jboss.RoleBasedCredentialMapIdentityLoginModule" flag="required">
                            <module-option name = "password-stacking">useFirstPass</module-option>
                            <module-option name="credentialMap">teiid-credentialmap.properties</module-option>
                            <module-option name = "managedConnectionFactoryName">jboss.jca:service=LocalTxCM,name=DefaultDS</module-option>
                        </login-module>            
                    
                    </authentication>
                </security-domain>
             </security-domains>]]></programlisting>
                      
            <para>In the datasource that is defined as the "managedConnectionFactoryName" in the above configuration, 
            you need to add the following element</para>
            
            <programlisting><![CDATA[<security-domain>teiid-security</security-domain>]]></programlisting>
            
            <para>In the above configuration example, in the primary login module "UsersRolesLoginModule" is set up for logging in
            the primary user and assign some roles. The "RoleBasedCredentialMap" login module is configured to hold 
            role to password information in the file defined by "credentialMap" property. When user logs in, the role information 
            from the primary login module is taken, and extracts the role's passsword and attaches as 
            a private credential to the Subject. If you want use this for role based trusted token, you can configure the Base64 based
            endcoding/decoded object as defined above.</para>
            
            <para>You can also encrypt the password instead of plain text password using this module. Just include the encrypted
             password in the file defined by the "credentialMap" property, and define following properties in 
             the "RoleBasedCredentialMap" login module.</para>
             
            <programlisting><![CDATA[<login-module code="org.teiid.jboss.RoleBasedCredentialMapIdentityLoginModule" flag="required">
    <module-option name = "password-stacking">useFirstPass</module-option>
    <module-option name="credentialMap">props/teiid-credentialmap.properties</module-option>
    <module-option name = "managedConnectionFactoryName">jboss.jca:service=LocalTxCM,name=DefaultDS</module-option>
    
   <!-- below properties are only required when passwords are encrypted -->
   <module-option name = "pbealgo">PBEWithMD5AndDES</module-option>
   <module-option name = "pbepass">testPBEIdentityLoginModule</module-option>
   <module-option name = "salt">abcdefgh</module-option>
   <module-option name = "iterationCount">19</module-option>
</login-module>]]></programlisting>         
             
            <para>For full details about encryption of the password, please follow this 
            <ulink url="http://community.jboss.org/docs/DOC-9703">document</ulink>'s 
            "A KeyStore based login module for encrypting a datasource password" section. Be sure to give the same configuration elements
            in the above configuration, as they are used to encrypt the password.</para>             
            </section>            
        </section>
	  </section>
	
	<section id="ssl_config">
        <title>Configuring SSL</title>
        <para>The Teiid's configuration file(s) 
        <code>standalone-teiid.xml/domain-teiid.xml</code>, contain transports defined for access to Teiid, and transport  
        contain the properties to configure SSL for socket per transport.</para>

        <itemizedlist>
        	<para>There are two types of transports, each with it's own SSL configuration:</para>
            <listitem><para>"teiid" - Default configuration to only encrypt login traffic, none of the other properties are used.</para></listitem>
            <listitem><para>"pg" type - Defaults to no SSL.</para></listitem>
        </itemizedlist>
        <example><title>Example Configuration</title>
	    <programlisting><![CDATA[<ssl mode="login" authentication-mode="1-way" ssl-protocol="SSLv3" keymanagement-algorithm="algo"
         enabled-cipher-suites="SSL_RSA_WITH_RC4_128_MD5,SSL_RSA_WITH_RC4_128_SHA">
            <keystore name="cert.keystore" password="passwd" type="JKS"/>
            <truststore name="cert.truststore" password="passwd"/>
        </ssl>]]></programlisting>       
</example>
           <itemizedlist>
           	<title>Properties</title>

            <listitem><para>mode - diabled|login|enabled, disabled = no transport or message level security will be used.  
            login = only the login traffic will be encrypted at a message level using 128 bit AES with an ephemerial DH key exchange. No other config values are needed in this mode.
            enabled = traffic will be secured using the other configuration properties.</para></listitem>
            <listitem><para>ssl-protocol- Type of SSL protocol to be used. Default is TLSv1</para></listitem>
            <listitem><para>keystore/type - Keystore type created by the keytool. Default "JKS" is used.</para></listitem>
            <listitem><para>authentication-mode - anonymous|1-way|2-way,  Type of <link linkend="ssl_auth">SSL Authentication Mode</link>.</para></listitem>
            <listitem><para>keymanagement-algorithm - Type of key algorithm used. Default 
            is based upon the VM, e.g. "SunX509"</para></listitem>
            <listitem><para>keystore/name - The file name of the keystore, which contains the 
            private key of the Server. The file name can be relative resource path available to the Teiid deployer classloader or an absolute file system path.  
            A typical installation would place the keystore file in the conf directory of the profile where Teiid is deployed with a file name relative to the conf path.</para></listitem>
            <listitem><para>keystorePassword - password for the keystore.</para></listitem>
            <listitem><para>truststore/name - if "authenticationMode" is chosen 
            as "2-way", then this property must be provided. This is the truststore that contains the 
            public key for the client. Depending upon how you created the keystore and truststores, 
            this may be same file as defined under  "keystoreFilename" property.</para></listitem>
            <listitem><para>truststore/password - password for the truststore. </para></listitem>
            <listitem><para>enabled-cipher-suites - A comma separated list of cipher suites allowed for encryption between server and client.  The values must be valid supported cipher suites otherwise SSL connections will fail.</para></listitem>
           </itemizedlist>  
      	<section id="ssl_auth">

      		<title>SSL Authentication Modes</title>
      		<para>SSL supports multiple authentication modes.  In most secure intranet environments, anonymous is suitable to just bulk encrypt traffic without the need
      		to setup SSL certificates. 
      		</para>
      		<itemizedlist>
      			<listitem><para><emphasis>anonymous</emphasis> - no certificates are exchanged, settings are not needed for the keystore and truststore properties.  
      			Client must have <code>org.teiid.ssl.allowAnon</code> set to true (the default) to connect to an anonymous server.
      			</para></listitem>
      			<listitem><para><emphasis>1-way</emphasis> - the server will present a certificate, which is obtained from the keystore related properties.  
      			The client should have a truststore configured to accept the server certificate. 
      			</para></listitem>

      			<listitem><para><emphasis>2-way</emphasis> - the server will present a certificate, which is obtained from the keystore related properties.
      			The client should have a truststore configured to accept the server certificate.  The client is also expected to present a certificate, which is obtained from its
      			keystore.  The client certificate should be accepted by the trust store configured by the truststore related properties.
      			</para></listitem>
      		</itemizedlist>
      	</section>
      	<section id="encryption_strength">
      		<title>Encryption Strength</title>
      		<para>Both anonymous SSL and login only encryption are configured to use 128 bit AES encryption by default.  By default,
      		1-way and 2-way SSL allow for cipher suite negotiation based upon the default cipher suites supported by the respective Java platforms of the client and server.
            User can restrict the cipher suites used for encryption by specifying the <emphasis>enabledCipherSuites</emphasis> property above in ssl configuration.     		
      		</para>

      	</section> 
    </section>
</chapter>
