Author: rareddy
Date: 2010-07-26 12:57:39 -0400 (Mon, 26 Jul 2010)
New Revision: 2374
Modified:
trunk/client/src/main/java/org/teiid/jdbc/JDBCURL.java
trunk/client/src/main/java/org/teiid/jdbc/TeiidDataSource.java
trunk/client/src/main/java/org/teiid/net/TeiidURL.java
trunk/client/src/test/java/org/teiid/jdbc/TestTeiidDriver.java
trunk/engine/src/main/java/org/teiid/security/SecurityHelper.java
trunk/jboss-integration/src/main/java/org/teiid/jboss/JBossSecurityHelper.java
trunk/runtime/src/main/java/org/teiid/services/SessionServiceImpl.java
trunk/runtime/src/main/java/org/teiid/services/TeiidLoginContext.java
trunk/runtime/src/main/java/org/teiid/transport/LocalServerConnection.java
trunk/runtime/src/main/resources/org/teiid/runtime/i18n.properties
trunk/runtime/src/test/java/org/teiid/services/TestMembershipServiceImpl.java
trunk/runtime/src/test/java/org/teiid/services/TestSessionServiceImpl.java
Log:
TEIID-1048: adding ability to control the pass though with explicit flag. Also ability to
switch identities on the same connection if the passed in subject does not match with the
original subject.
Modified: trunk/client/src/main/java/org/teiid/jdbc/JDBCURL.java
===================================================================
--- trunk/client/src/main/java/org/teiid/jdbc/JDBCURL.java 2010-07-26 14:17:53 UTC (rev
2373)
+++ trunk/client/src/main/java/org/teiid/jdbc/JDBCURL.java 2010-07-26 16:57:39 UTC (rev
2374)
@@ -71,7 +71,8 @@
BaseDataSource.USER_NAME,
BaseDataSource.PASSWORD,
TeiidURL.CONNECTION.AUTO_FAILOVER,
- TeiidURL.CONNECTION.DISCOVERY_STRATEGY));
+ TeiidURL.CONNECTION.DISCOVERY_STRATEGY,
+ TeiidURL.CONNECTION.PASSTHROUGH_AUTHENTICATION));
props.addAll(EXECUTION_PROPERTIES);
return Collections.unmodifiableSet(props);
}
Modified: trunk/client/src/main/java/org/teiid/jdbc/TeiidDataSource.java
===================================================================
--- trunk/client/src/main/java/org/teiid/jdbc/TeiidDataSource.java 2010-07-26 14:17:53 UTC
(rev 2373)
+++ trunk/client/src/main/java/org/teiid/jdbc/TeiidDataSource.java 2010-07-26 16:57:39 UTC
(rev 2374)
@@ -92,10 +92,13 @@
private String discoveryStrategy;
- /**
- * Constructor for MMDataSource.
- */
- public TeiidDataSource() {
+ /**
+ * when "true", in the "embedded" scenario, authentication is
information is read in pass though manner.
+ */
+ private boolean passthroughAuthentication = false;
+
+
+ public TeiidDataSource() {
}
//
--------------------------------------------------------------------------------------------
@@ -227,6 +230,7 @@
private Properties buildEmbeddedProperties(final String userName, final String password)
{
Properties props = buildProperties(userName, password);
+ props.setProperty(TeiidURL.CONNECTION.PASSTHROUGH_AUTHENTICATION,
Boolean.toString(this.passthroughAuthentication));
return props;
}
@@ -264,7 +268,14 @@
*/
public boolean isSecure() {
return this.secure;
- }
+ }
+ /**
+ * Same as "isSecure". Required by the reflection login in connection pools
to identify the type
+ * @return
+ */
+ public boolean getSecure() {
+ return this.secure;
+ }
/**
* Returns a string containing a comma delimited list of alternate
@@ -475,6 +486,31 @@
public void setDiscoveryStrategy(String discoveryStrategy) {
this.discoveryStrategy = discoveryStrategy;
- }
+ }
+
+ /**
+ * When true, this connection uses the passed in security domain to do the
authentication.
+ * @return
+ */
+ public boolean isPassthroughAuthentication() {
+ return passthroughAuthentication;
+ }
+
+ /**
+ * Same as "isPassthroughAuthentication". Required by the reflection login
in connection pools to identify the type
+ * @return
+ */
+ public boolean getPassthroughAuthentication() {
+ return passthroughAuthentication;
+ }
+
+ /**
+ * When set to true, the connection uses the passed in security domain to do the
authentication.
+ * @since 7.1
+ * @return
+ */
+ public void setPassthroughAuthentication(final boolean passthroughAuthentication) {
+ this.passthroughAuthentication = passthroughAuthentication;
+ }
}
Modified: trunk/client/src/main/java/org/teiid/net/TeiidURL.java
===================================================================
--- trunk/client/src/main/java/org/teiid/net/TeiidURL.java 2010-07-26 14:17:53 UTC (rev
2373)
+++ trunk/client/src/main/java/org/teiid/net/TeiidURL.java 2010-07-26 16:57:39 UTC (rev
2374)
@@ -77,6 +77,8 @@
public static final String PASSWORD = "password"; //$NON-NLS-1$
public static final String ADMIN = "admin"; //$NON-NLS-1$
+
+ public static final String PASSTHROUGH_AUTHENTICATION =
"PassthroughAuthentication"; //$NON-NLS-1$
}
public static final String DOT_DELIMITER = "."; //$NON-NLS-1$
Modified: trunk/client/src/test/java/org/teiid/jdbc/TestTeiidDriver.java
===================================================================
--- trunk/client/src/test/java/org/teiid/jdbc/TestTeiidDriver.java 2010-07-26 14:17:53 UTC
(rev 2373)
+++ trunk/client/src/test/java/org/teiid/jdbc/TestTeiidDriver.java 2010-07-26 16:57:39 UTC
(rev 2374)
@@ -132,7 +132,7 @@
@Test public void testGetPropertyInfo1() throws Exception {
DriverPropertyInfo info[] =
drv.getPropertyInfo("jdbc:metamatrix:vdb@mm://localhost:12345;applicationName=x",
null); //$NON-NLS-1$
- assertEquals(18, info.length);
+ assertEquals(19, info.length);
assertEquals(false, info[0].required);
assertEquals("ApplicationName", info[0].name); //$NON-NLS-1$
assertEquals("x", info[0].value); //$NON-NLS-1$
Modified: trunk/engine/src/main/java/org/teiid/security/SecurityHelper.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/security/SecurityHelper.java 2010-07-26 14:17:53
UTC (rev 2373)
+++ trunk/engine/src/main/java/org/teiid/security/SecurityHelper.java 2010-07-26 16:57:39
UTC (rev 2374)
@@ -37,4 +37,6 @@
Object createSecurityContext(String securityDomain, Principal p, Object credentials,
Subject subject);
Subject getSubjectInContext(String securityDomain);
+
+ boolean sameSubject(String securityDomain, Object context, Subject subject);
}
Modified: trunk/jboss-integration/src/main/java/org/teiid/jboss/JBossSecurityHelper.java
===================================================================
---
trunk/jboss-integration/src/main/java/org/teiid/jboss/JBossSecurityHelper.java 2010-07-26
14:17:53 UTC (rev 2373)
+++
trunk/jboss-integration/src/main/java/org/teiid/jboss/JBossSecurityHelper.java 2010-07-26
16:57:39 UTC (rev 2374)
@@ -29,6 +29,7 @@
import org.jboss.security.SecurityContext;
import org.jboss.security.SubjectInfo;
+import org.teiid.core.util.Assertion;
import org.teiid.security.SecurityHelper;
public class JBossSecurityHelper implements SecurityHelper, Serializable {
@@ -77,5 +78,21 @@
}
return null;
}
+
+ @Override
+ public boolean sameSubject(String securityDomain, Object context, Subject subject) {
+ Assertion.isNotNull(context);
+ SecurityContext previousContext = (SecurityContext)context;
+ Subject previousUser = previousContext.getSubjectInfo().getAuthenticatedSubject();
+
+ SecurityContext currentContext = SecurityActions.getSecurityContext();
+ if (currentContext != null &&
currentContext.getSecurityDomain().equals(securityDomain)) {
+ Subject currentUser = currentContext.getSubjectInfo().getAuthenticatedSubject();
+ if (previousUser.equals(currentUser)) {
+ return true;
+ }
+ }
+ return false;
+ }
}
Modified: trunk/runtime/src/main/java/org/teiid/services/SessionServiceImpl.java
===================================================================
--- trunk/runtime/src/main/java/org/teiid/services/SessionServiceImpl.java 2010-07-26
14:17:53 UTC (rev 2373)
+++ trunk/runtime/src/main/java/org/teiid/services/SessionServiceImpl.java 2010-07-26
16:57:39 UTC (rev 2374)
@@ -150,7 +150,8 @@
if (!domains.isEmpty()) {
// Authenticate user...
// if not authenticated, this method throws exception
- TeiidLoginContext membership = authenticate(userName, credentials,
applicationName, domains, this.securityHelper);
+ boolean onlyAllowPassthrough =
Boolean.valueOf(properties.getProperty(TeiidURL.CONNECTION.PASSTHROUGH_AUTHENTICATION,
"false")); //$NON-NLS-1$
+ TeiidLoginContext membership = authenticate(userName, credentials,
applicationName, domains, this.securityHelper, onlyAllowPassthrough);
loginContext = membership.getLoginContext();
userName = membership.getUserName();
securityDomain = membership.getSecurityDomain();
@@ -204,10 +205,10 @@
return newSession;
}
- protected TeiidLoginContext authenticate(String userName, Credentials credentials,
String applicationName, List<String> domains, SecurityHelper helper)
+ protected TeiidLoginContext authenticate(String userName, Credentials credentials,
String applicationName, List<String> domains, SecurityHelper helper, boolean
onlyallowPassthrough)
throws LoginException {
TeiidLoginContext membership = new TeiidLoginContext(helper);
- membership.authenticateUser(userName, credentials, applicationName, domains);
+ membership.authenticateUser(userName, credentials, applicationName, domains,
onlyallowPassthrough);
return membership;
}
Modified: trunk/runtime/src/main/java/org/teiid/services/TeiidLoginContext.java
===================================================================
--- trunk/runtime/src/main/java/org/teiid/services/TeiidLoginContext.java 2010-07-26
14:17:53 UTC (rev 2373)
+++ trunk/runtime/src/main/java/org/teiid/services/TeiidLoginContext.java 2010-07-26
16:57:39 UTC (rev 2374)
@@ -64,24 +64,32 @@
this.securityHelper = helper;
}
- public void authenticateUser(String username, final Credentials credential, String
applicationName, List<String> domains) throws LoginException {
+ public void authenticateUser(String username, final Credentials credential,
+ String applicationName, List<String> domains, boolean onlyallowPassthrough)
+ throws LoginException {
LogManager.logDetail(LogConstants.CTX_SECURITY, new Object[]
{"authenticateUser", username, applicationName}); //$NON-NLS-1$
final String baseUsername = getBaseUsername(username);
-
+
+ if (onlyallowPassthrough) {
+ for (String domain:getDomainsForUser(domains, username)) {
+ Subject existing = this.securityHelper.getSubjectInContext(domain);
+ if (existing != null) {
+ this.userName = getUserName(existing)+AT+domain;
+ this.securitydomain = domain;
+ this.loginContext = createLoginContext(domain, existing);
+ return;
+ }
+ }
+ throw new
LoginException(RuntimePlugin.Util.getString("no_passthrough_identity_found"));
//$NON-NLS-1$
+ }
+
+
// If username specifies a domain (user@domain) only that domain is authenticated
against.
// If username specifies no domain, then all domains are tried in order.
for (String domain:getDomainsForUser(domains, username)) {
-
- Subject existing = this.securityHelper.getSubjectInContext(domain);
- if (existing != null) {
- this.userName = getUserName(existing)+AT+domain;
- this.securitydomain = domain;
- this.loginContext = createLoginContext(domain, existing);
- return;
- }
-
+
try {
CallbackHandler handler = new CallbackHandler() {
@Override
Modified: trunk/runtime/src/main/java/org/teiid/transport/LocalServerConnection.java
===================================================================
--- trunk/runtime/src/main/java/org/teiid/transport/LocalServerConnection.java 2010-07-26
14:17:53 UTC (rev 2373)
+++ trunk/runtime/src/main/java/org/teiid/transport/LocalServerConnection.java 2010-07-26
16:57:39 UTC (rev 2374)
@@ -46,20 +46,25 @@
import org.teiid.net.ConnectionException;
import org.teiid.net.NetPlugin;
import org.teiid.net.ServerConnection;
+import org.teiid.net.TeiidURL;
public class LocalServerConnection implements ServerConnection {
private static final String TEIID_RUNTIME = "teiid/engine-deployer";
//$NON-NLS-1$
- private final LogonResult result;
+ private LogonResult result;
private boolean shutdown;
private ClientServiceRegistry csr;
private DQPWorkContext workContext = new DQPWorkContext();
+ private Properties connectionProperties;
+ private boolean passthrough;
public LocalServerConnection(Properties connectionProperties) throws
CommunicationException, ConnectionException{
+ this.connectionProperties = connectionProperties;
this.csr = getClientServiceRegistry();
workContext.setSecurityHelper(csr.getSecurityHelper());
- this.result = authenticate(connectionProperties);
+ authenticate(connectionProperties);
+ passthrough =
Boolean.valueOf(connectionProperties.getProperty(TeiidURL.CONNECTION.PASSTHROUGH_AUTHENTICATION,
"false")); //$NON-NLS-1$
}
protected ClientServiceRegistry getClientServiceRegistry() {
@@ -71,10 +76,9 @@
}
}
- public synchronized LogonResult authenticate(Properties connProps) throws
ConnectionException, CommunicationException {
+ public synchronized void authenticate(Properties connProps) throws ConnectionException,
CommunicationException {
try {
- LogonResult logonResult = this.getService(ILogon.class).logon(connProps);
- return logonResult;
+ this.result = this.getService(ILogon.class).logon(connProps);
} catch (LogonException e) {
// Propagate the original message as it contains the message we want
// to give to the user
@@ -95,6 +99,14 @@
throw ExceptionUtil.convertException(arg1, new
TeiidComponentException(NetPlugin.Util.getString("LocalTransportHandler.Transport_shutdown")));
//$NON-NLS-1$
}
try {
+ if (passthrough && !arg1.getDeclaringClass().equals(ILogon.class)) {
+ // check to make sure the current security context same as logged one
+ if
(!csr.getSecurityHelper().sameSubject(workContext.getSession().getSecurityDomain(),
workContext.getSession().getSecurityContext(), workContext.getSubject())) {
+ logoff();
+ authenticate(connectionProperties);
+ }
+ }
+
final T service = csr.getClientService(iface);
return workContext.runInContext(new Callable<Object>() {
public Object call() throws Exception {
@@ -128,19 +140,23 @@
}
if (logoff) {
- try {
- //make a best effort to send the logoff
- Future<?> writeFuture = this.getService(ILogon.class).logoff();
- if (writeFuture != null) {
- writeFuture.get(5000, TimeUnit.MILLISECONDS);
- }
- } catch (Exception e) {
- //ignore
- }
+ logoff();
}
this.shutdown = true;
}
+ private void logoff() {
+ try {
+ //make a best effort to send the logoff
+ Future<?> writeFuture = this.getService(ILogon.class).logoff();
+ if (writeFuture != null) {
+ writeFuture.get(5000, TimeUnit.MILLISECONDS);
+ }
+ } catch (Exception e) {
+ //ignore
+ }
+ }
+
public LogonResult getLogonResult() {
return result;
}
Modified: trunk/runtime/src/main/resources/org/teiid/runtime/i18n.properties
===================================================================
--- trunk/runtime/src/main/resources/org/teiid/runtime/i18n.properties 2010-07-26 14:17:53
UTC (rev 2373)
+++ trunk/runtime/src/main/resources/org/teiid/runtime/i18n.properties 2010-07-26 16:57:39
UTC (rev 2374)
@@ -264,6 +264,7 @@
SessionServiceImpl.The_username_0_and/or_password_are_incorrect=The username
"{0}" and/or password and/or payload token could not be authenticated by any
membership domain.
SessionServiceImpl.terminateSession = Admin [{0}] is terminating this session: {1}.
+no_passthrough_identity_found = Passthrough authentication failed. No authentication
information found.
LogonImpl.Invalid_use_of_credentials_and_token=Conflicting use of both client session
token and credentials.
Modified: trunk/runtime/src/test/java/org/teiid/services/TestMembershipServiceImpl.java
===================================================================
---
trunk/runtime/src/test/java/org/teiid/services/TestMembershipServiceImpl.java 2010-07-26
14:17:53 UTC (rev 2373)
+++
trunk/runtime/src/test/java/org/teiid/services/TestMembershipServiceImpl.java 2010-07-26
16:57:39 UTC (rev 2374)
@@ -81,7 +81,7 @@
TeiidLoginContext ms = createMembershipService();
List<String> domains = new ArrayList<String>();
domains.add("testFile"); //$NON-NLS-1$
- ms.authenticateUser("user1", new
Credentials("pass1".toCharArray()), null, domains); //$NON-NLS-1$ //$NON-NLS-2$
+ ms.authenticateUser("user1", new
Credentials("pass1".toCharArray()), null, domains, false); //$NON-NLS-1$
//$NON-NLS-2$
Mockito.verify(ms.getLoginContext()).login();
@@ -93,7 +93,7 @@
TeiidLoginContext ms = createMembershipService();
List<String> domains = new ArrayList<String>();
domains.add("passthrough"); //$NON-NLS-1$
- ms.authenticateUser("user1", new
Credentials("pass1".toCharArray()), null, domains); //$NON-NLS-1$ //$NON-NLS-2$
+ ms.authenticateUser("user1", new
Credentials("pass1".toCharArray()), null, domains, true); //$NON-NLS-1$
//$NON-NLS-2$
assertEquals("alreadylogged@passthrough", ms.getUserName());
//$NON-NLS-1$
}
Modified: trunk/runtime/src/test/java/org/teiid/services/TestSessionServiceImpl.java
===================================================================
--- trunk/runtime/src/test/java/org/teiid/services/TestSessionServiceImpl.java 2010-07-26
14:17:53 UTC (rev 2373)
+++ trunk/runtime/src/test/java/org/teiid/services/TestSessionServiceImpl.java 2010-07-26
16:57:39 UTC (rev 2374)
@@ -31,9 +31,9 @@
SessionServiceImpl ssi = new SessionServiceImpl() {
@Override
- protected TeiidLoginContext authenticate(String userName, Credentials credentials,
String applicationName, List<String> domains, SecurityHelper helper)
+ protected TeiidLoginContext authenticate(String userName, Credentials credentials,
String applicationName, List<String> domains, SecurityHelper helper, boolean
passthough)
throws LoginException {
- impl.authenticateUser(userName, credentials, applicationName, domains);
+ impl.authenticateUser(userName, credentials, applicationName, domains, passthough);
return impl;
}
};
@@ -49,7 +49,7 @@
SessionMetadata info = ssi.createSession("steve", null, "foo", new
Properties(), false); //$NON-NLS-1$ //$NON-NLS-2$
if (securityEnabled) {
- Mockito.verify(impl).authenticateUser("steve", null, "foo",
domains);
+ Mockito.verify(impl).authenticateUser("steve", null, "foo",
domains, false);
}
String id1 = info.getSessionId();