In this usecase, I have a SOAP web service that is secured through Kerberos. Now, I need to access this web service from Teiid.
I will show how to this when Teiid is already secured using Kerberos and the authentication is delegated via a Kerberos token to the back end SOAP web-service. For a non-SSO re-authentication see How to implement Kerberos authentication to a SOAP Web Service using Teiid
Basic knowledge of Teiid and JBoss EAP is assumed throughout this article.
Step 1: Create a SOAP Web Service
In this article, How to implement a SOAP Web Service with Kerberos authentication in JBoss EAP I showed an sample to create SOAP web-service. Please follow this article and create a sample web service, and test to make sure it works!
If you are working with a third party web-service then gather the WSDL file for it, and make sure the service is operational and accessible.
Step 2: Create VDB
Now we need to create a VDB and required data sources to be consumed by the VDB. For my sample I used the following VDB (See Note about using Designer based VDB at the end of the article)
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <vdb name="kerberos" version="1"> <property name="security-domain" value="EXAMPLE.COM" /> <property name="authentication-type" value="GSS" /> <description>Shows how to call SOAP Web with Kerberos Auth</description> <property name="cache-metadata" value="true"/> <model name="web"> <source name="web" translator-name="ws" connection-jndi-name="java:/wsDS"/> </model> </vdb>
Step 3: Create Data Source
Add the following xml fragment to resource-adapters subsystem in standalone-teiid.xml file. Note that the below configuration is setup for sample service from step (1) when deployed in the same JBoss EAP. If your service is remote and/or different adjust the properties accordingly.
<resource-adapter id="KerberosService"> <module slot="main" id="org.jboss.teiid.resource-adapter.webservice"/> <transaction-support>NoTransaction</transaction-support> <connection-definitions> <connection-definition class-name="org.teiid.resource.adapter.ws.WSManagedConnectionFactory" jndi-name="java:/wsDS" enabled="true" use-java-context="true" pool-name="teiid-ws-ds"> <config-property name="NamespaceUri"> http://webservices.samples.jboss.org/ </config-property> <config-property name="ConfigFile"> /path/to/alice-cxf.xml </config-property> <config-property name="ServiceName"> HelloWorldService </config-property> <config-property name="Wsdl"> http://localhost:8080/kerberos/HelloWorld?wsdl </config-property> <config-property name="ConfigName"> HelloWorldPort </config-property> <config-property name="SecurityType"> WSSecurity </config-property> <config-property name="EndPoint"> http://localhost:8080/kerberos/HelloWorld </config-property> <security> <security-domain>passthrough-security</security-domain> </security> </connection-definition> </connection-definitions> </resource-adapter>
Also add following to the "security-domains" subsystem. If you need to add additional "ws-security" properties like "ws-security.encryption.properties" (see ws-security properties here https://git-wip-us.apache.org/repos/asf?p=cxf.git;a=blob;f=rt/ws/security/src/main/java/org/apache/cxf/ws/security/Secur… and sample uses of it here http://anonsvn.jboss.org/repos/jbossws/stack/cxf/trunk/modules/testsuite/cxf-spring-tests/src/test/java/org/jboss/test/w…) add them as "module-option" properties then Teiid's web-service resource adapter will retrieve these properties and will set them correctly on the SOAP web service's CXF Endpoint configuration.
<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>
and we also need alice-cxf.xml file above, the contents look like. Note that the context name and service name must match to that of your service. In this example, I used the same context and service names for both Teiid and as well as the SOAP service. However typically this is never the case in real world scenarios.
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:http="http://cxf.apache.org/transports/http/configuration" xmlns:jaxws="http://cxf.apache.org/jaxws" xmlns:cxf="http://cxf.apache.org/core" xmlns:p="http://cxf.apache.org/policy" xmlns:sec="http://cxf.apache.org/configuration/security" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd http://cxf.apache.org/transports/http/configuration http://cxf.apache.org/schemas/configuration/http-conf.xsd http://cxf.apache.org/configuration/security http://cxf.apache.org/schemas/configuration/security.xsd http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd http://cxf.apache.org/policy http://cxf.apache.org/schemas/policy.xsd"> <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"/> <cxf:bus> <cxf:features> <p:policies/> <cxf:logging/> </cxf:features> </cxf:bus> <jaxws:client name="{http://webservices.samples.jboss.org/}HelloWorldPort" createdFromAPI="true"> <jaxws:properties> <entry key="ws-security.kerberos.client"> <bean class="org.teiid.resource.adapter.ws.DelegateKerberosClient"> <constructor-arg ref="cxf"/> <property name="contextName" value="host"/> <property name="serviceName" value="bob@service.example.com"/> </bean> </entry> </jaxws:properties> </jaxws:client> </beans>
Step 4: Configure JDBC
Now configure a Teiid JDBC client by following the document defined here How to implement Kerberos authentication with Teiid over JDBC
Using a JDBC client issue a query like ( you need to execute using java client as procedure, you can even write view then you can simply issue a select * from view from any jdbc client)
{?=call PM3.sayHello(XMLPARSE(DOCUMENT '<web:sayHello xmlns:web=\"http://webservices.samples.jboss.org/\"><arg0>hi</arg0></web:sayHello>'))}
You will see out put like
<?xml version='1.0' encoding='UTF-8'?><return>Hello = hi From User = alice@EXAMPLE.COM</return>
That is data from the web service created in the Step 1, also shows the connected user. JDBC client gets authenticated to Teiid, then "pass-through" security domain passes the subject to the web service resource adapter. The resource adapter takes the delegated credential in the subject and authenticates with KDC for given service principle.
Hopefully this showed you how to configure Teiid to issue kerberos based SOAP call. This is tested with Teiid 8.9
Note: If you designed your VDB using the WSDL importer the above may not work as is, as Designer as of 8.7 version uses "invoke" method for executing the web service. If you want to use Designer, design the the VDB using WSDL importer, then use Teiid Connection importer and supply WSDL name and import the metadata from "ws" translator. Then switch the ws source model to this newly created model. Then edit all the transformations and edit them and replace "invoke" method with actual procedure name from source models. Note that the request XML is same in both. So, trim the verbose parameters and it should be good. Added [TEIIDDES-2371] WSDL Based procedure metadata needs to be used - JBoss Issue Tracker to fix the issue.
Ramesh..
Comments