-
1. Re: Can client authentication be configured for Embedded Teiid?
rareddy Feb 23, 2015 6:55 PM (in response to btkibler)1 of 1 people found this helpfulQuestion is how are configuring any security domains in the embedded scenario? In the JBoss EAP based deployment Teiid uses JAAS Login Modules supplied by the JBoss EAP platform and Teiid hooks into that for Kerberos negotiation. So, you need to configure a security domain. Take look at EmbeddedConfiguration.getSecurityHelper() and EmbeddedConfiguration.getSecurityDomain() methods. These give you option to inject the security domain and manage it. The client side you use same configuration as Teiid documented for JBoss EAP based deployment. If everything configured correctly then you should see call into your security domain module from Teiid.
Ramesh..
-
2. Re: Re: Can client authentication be configured for Embedded Teiid?
btkibler Mar 5, 2015 8:59 AM (in response to rareddy)Thanks Ramesh, that helped, and got me started on the right track. I have Kerberos working now (using the Postgres JDBC driver, from a Java client), but I still think I'm missing something...
Steps I took:
- Extended SessionServiceImpl, overriding/implementing the negotiateGssLogin() method, to call LoginContext.acceptSecContext() and validate the client's Kerberos token. (source code attached)
- Created a basic KerberosSecurityHelper and KerberosSecurityContext to store the authenticated state in thread-local variables.
However, it wasn't clear how the logic in ODBCServerRemoteImpl expected to handle the GSSResult.isAuthenticated() state returned from negotiateGssLogin(). The Postgres client driver expects the following token handshake sequence (from the Postgres driver debug logs):
1. 08:16:28.101 (1) FE=> StartupPacket(user=MYUSERID@MYDOMAIN.COM, database=test, client_encoding=UTF8, DateStyle=ISO, TimeZone=America/New_York, extra_float_digits=2)
2. 08:16:28.143 (1) Using JSSE GSSAPI, gssapi requested by server and gsslib=sspi not forced
3. 08:16:28.144 (1) <=BE AuthenticationReqGSS
4. 08:16:28.449 (1) FE=> Password(GSS Authentication Token)
5. 08:16:28.495 (1) <=BE AuthenticationGSSContinue
6. 08:16:28.514 (1) <=BE AuthenticationOk
In the log above, step 3 is the response from the server requesting GSS auth, step 4 is the client token sent to the server, step 5 is the peer response from the server (used by the client to validate the server's SPN), and step 6 is a final ACK from the server telling the client it's ready to start processing queries.
However, the ODBCServerRemoteImpl class (as implemented) would only send an AuthenticationGSSContinue OR an AuthenticationOK response. If my GSSResult.isAuthenticated() response returns TRUE, the code returns an AuthenticationOK, and the client throws an exception because it never got the server's GSSContinue response token for mutual auth. If I send GSSResult.isAuthenticated = FALSE, the server code just sends an AuthenticationGSSContinue, and the client blocks and waits on an AuthenticationOK message, which never arrives. Neither approach seems correct, because the client is expecting BOTH messages (GSSContinue and OK).
I made the following modifications to ODBCServerRemoteImpl class:
else if (authType.equals(AuthenticationType.GSS)) { byte[] serviceToken = data.readServiceToken(); LogonResult result = this.logon.neogitiateGssLogin(this.props, serviceToken, false); serviceToken = (byte[])result.getProperty(ILogon.KRB5TOKEN); //REMOVE if (Boolean.TRUE.equals(result.getProperty(ILogon.KRB5_ESTABLISHED))) { info.put(ILogon.KRB5TOKEN, serviceToken); // if delegation is in progress, participate in it. if (result.getProperty(GSSCredential.class.getName()) != null) { info.put(GSSCredential.class.getName(), result.getProperty(GSSCredential.class.getName())); } //REMOVE } //REMOVE else { this.client.authenticationGSSContinue(serviceToken); //REMOVE return; //REMOVE} } else { throw new AssertionError("Unsupported Authentication Type"); //$NON-NLS-1$ }
These modifications got it working, but I wonder if I'm doing something wrong, or missing a while (!isAuthenticated()) loop somewhere that should be processing the handshake.
Any suggestions are welcome, and I can attach more of my sample code if needed.
-Ben
-
KerbSessionServiceImpl.java 3.0 KB
-
TeiidDemoServer.java 2.8 KB
-
TeiidDemoClient.java 1.5 KB
-
KerbEmbeddedServer.java 339 bytes
-
demo-server-login.conf.zip 337 bytes
-
3. Re: Re: Can client authentication be configured for Embedded Teiid?
shawkins Mar 5, 2015 5:33 PM (in response to btkibler)1 of 1 people found this helpfulI don't think you are missing something. My guess would be we had different expectations from our kerberos/client setups. From http://www.postgresql.org/docs/9.1/static/protocol-flow.html what you have would certainly seem to be a valid flow. I think we should test on our end with a similar change to verify.
Thanks,
Steve
-
4. Re: Re: Re: Can client authentication be configured for Embedded Teiid?
rareddy Mar 5, 2015 8:14 PM (in response to btkibler)What I remember seeing is, some times the negotiation take more one trip between client and server, thus the way it is. Re-reading the link provided by Steve, I think the code should read as
else if (authType.equals(AuthenticationType.GSS)) { byte[] serviceToken = data.readServiceToken(); LogonResult result = this.logon.neogitiateGssLogin(this.props, serviceToken, false); serviceToken = (byte[])result.getProperty(ILogon.KRB5TOKEN); if (Boolean.TRUE.equals(result.getProperty(ILogon.KRB5_ESTABLISHED))) { info.put(ILogon.KRB5TOKEN, serviceToken); // if delegation is in progress, participate in it. if (result.getProperty(GSSCredential.class.getName()) != null) { info.put(GSSCredential.class.getName(), result.getProperty(GSSCredential.class.getName())); } this.client.authenticationGSSContinue(serviceToken); // NEW LINE ADDED } else { this.client.authenticationGSSContinue(serviceToken); return; } } else { throw new AssertionError("Unsupported Authentication Type"); //$NON-NLS-1$ }
You can open a JIRA, I will apply the fix.
Ramesh..
-
5. Re: Re: Re: Can client authentication be configured for Embedded Teiid?
btkibler Mar 6, 2015 12:20 PM (in response to rareddy)Thanks Ramesh! I applied those changes and it works in our environment, both from a standalone Java JDBC client, and from SQLWorkbench/J, using the Postgres 9.4-1201 JDBC driver. I'll create a JIRA to request a fix.
-
6. Re: Re: Re: Can client authentication be configured for Embedded Teiid?
rareddy Mar 6, 2015 12:57 PM (in response to btkibler)Ben,
Very nice. Would you be willing to write some kind of blog about your usecase, that will be superb. I am really interested to know how/why you are embedding the Teiid. There are few community members developing using embedded Teiid, it would great if we can develop some reference architecture docs/samples etc to share with others.
Thanks
Ramesh..
-
7. Re: Re: Re: Re: Can client authentication be configured for Embedded Teiid?
btkibler Mar 6, 2015 1:31 PM (in response to rareddy)This particular scenario is to provide Kerberos authentication for Amazon AWS-managed cloud databases that don't natively support LDAP or Kerberos for integrated authentication. AWS probably doesn't have much customer demand for LDAP or Kerberos integration, because typically end-users connect to a web application with SSO credentials, and then the web app server connects to the back-end database using a single database-provided local credential. However in enterprise/legacy use cases, and some operational support use cases, we have 2-tier client/server applications that require end users to connect directly to the database, bypassing the application tier. Rather than maintaining individual userids and passwords for every user in each of those back-end databases, we can easily pop up a small Teiid instance which proxies the user connection, authenticating the client against Kerberos, and then proxy-connect to the back-end database using a "service account" with the appropriate permissions. All of our client desktops are Kerberos-aware and integrated with Active Directory, and the Postgres client natively supports Kerberos, so Teiid seemed like an great fit.
We're not a "JBoss shop", and generally prefer lightweight J2SE containers over large/complex J2EE servers, so Teiid Embedded was much more attractive than running a JBoss container. I found the embedded version easy to debug, extend via code, and unit test with minimal effort. This use case doesn't have complex connection pooling, XA, or distributed transaction management requirements, since we're basically mapping each client connection to a single back-end DB connection, and if either end of the connection fails, the client can simply reconnect.
Unfortunately I'm not permitted to blog or mention my employer, but you're welcome to blog about the general use case of adding Kerberos auth to non-Kerberos databases.
Our primary use case for Teiid Embedded is probably more traditional: if an application needs to join between two disparate databases or data sources, we encourage them to embed Teiid within their application, and use the VDB model to join the data, rather than writing complex joins (hashmaps, lookups, etc.) in Java code. This use case doesn't need Kerberos, and for most simple use cases, the configuration is done entirely in code, with no need for vdb.xml files. The attached code is what I share with developers as an example of joining two disparate databases (or even processing small text files using SQL constructs) within Java code.
-
TeiidFederationDemo.java 4.6 KB
-
DerbyProvider.java 2.4 KB
-
-
8. Re: Re: Re: Re: Can client authentication be configured for Embedded Teiid?
rareddy Mar 6, 2015 2:00 PM (in response to btkibler)Thanks for sharing, that is really cool. I have never seen somebody using Teiid for just the authentication unification before. We do say one place to manage all the user permissions for enterprise.
-
9. Re: Re: Re: Re: Can client authentication be configured for Embedded Teiid?
shawkins Mar 23, 2015 9:46 AM (in response to rareddy)Also there is now [TEIID-3380] Simplify Kerberos configuration with Embedded - JBoss Issue Tracker
That will be a breaking change from an API perspective, but should better encapsulate the implementation.
-
10. Re: Re: Re: Re: Can client authentication be configured for Embedded Teiid?
rareddy Mar 23, 2015 10:37 AM (in response to shawkins)Also short blog at teiid: Authenticating datasources with LDAP or Kerberos in Amazon AWS