Skip to content

Commit

Permalink
TEIID-3913: Adding the supporting infrastructure to support OAuth sec…
Browse files Browse the repository at this point in the history
…urity on the OData REST interface
  • Loading branch information
rareddy committed Jan 19, 2016
1 parent d6b1f01 commit 0d1c66c
Show file tree
Hide file tree
Showing 8 changed files with 82 additions and 1 deletion.
40 changes: 40 additions & 0 deletions api/src/main/java/org/teiid/OAuthCredentialContext.java
@@ -0,0 +1,40 @@
/*
* JBoss, Home of Professional Open Source.
* See the COPYRIGHT.txt file distributed with this work for information
* regarding copyright ownership. Some portions may be licensed
* to Red Hat, Inc. under one or more contributor license agreements.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA.
*/
package org.teiid;


public class OAuthCredentialContext {
private static ThreadLocal<OAuthCredential> CREDENTIAL = new ThreadLocal<OAuthCredential>() {
@Override
protected OAuthCredential initialValue() {
return null;
}
};

public static OAuthCredential getCredential() {
return CREDENTIAL.get();
}

public static void setCredential(OAuthCredential credential) {
CREDENTIAL.set(credential);
}
}
Expand Up @@ -9,6 +9,7 @@
</resources>

<dependencies>
<module name="javax.api"/>
<module name="javax.servlet.api"/>
<module name="org.apache.olingo" />
<module name="org.jboss.teiid.common-core" />
Expand Down
Expand Up @@ -38,6 +38,8 @@
import org.jboss.security.vault.SecurityVaultException;
import org.jboss.security.vault.SecurityVaultUtil;
import org.picketbox.datasource.security.AbstractPasswordCredentialLoginModule;
import org.teiid.OAuthCredential;
import org.teiid.OAuthCredentialContext;

/**
* A simple login module passes the principal making the connection request
Expand Down Expand Up @@ -122,6 +124,11 @@ public boolean commit() throws LoginException {
makeCopy(this.callerSubject, this.subject);
}
addPrivateCredential(this.subject, this.properties);

// if oauth credential available in calling context then add the OAuthCredential.
if (OAuthCredentialContext.getCredential() != null) {
addPrivateCredential(this.subject, OAuthCredentialContext.getCredential());
}
return true;
}

Expand Down
Expand Up @@ -35,6 +35,7 @@
import org.jboss.security.SecurityContextAssociation;
import org.picketbox.datasource.security.AbstractPasswordCredentialLoginModule;
import org.teiid.OAuthCredential;
import org.teiid.OAuthCredentialContext;

/**
* Login module to capture OAuth 2.0 profile credential for web service resource-adapter.
Expand Down Expand Up @@ -145,7 +146,10 @@ public Subject run() {
}

public OAuthCredential getCredential() {
return credential;
if (this.credential != null) {
return this.credential;
}
return OAuthCredentialContext.getCredential();
}

public void setCredential(OAuthCredential credential) {
Expand Down
1 change: 1 addition & 0 deletions olingo/src/main/java/org/teiid/olingo/ODataPlugin.java
Expand Up @@ -83,6 +83,7 @@ public static enum Event implements BundleUtil.Event {
TEIID16041,
TEIID16042,
TEIID16043,
TEIID16044,
TEIID16045
}
}
20 changes: 20 additions & 0 deletions olingo/src/main/java/org/teiid/olingo/web/ODataFilter.java
Expand Up @@ -39,12 +39,15 @@
import javax.servlet.http.HttpServletRequest;

import org.apache.olingo.server.api.ODataHttpHandler;
import org.teiid.OAuthCredential;
import org.teiid.OAuthCredentialContext;
import org.teiid.core.util.LRUCache;
import org.teiid.deployers.CompositeVDB;
import org.teiid.deployers.VDBLifeCycleListener;
import org.teiid.jdbc.ConnectionImpl;
import org.teiid.logging.LogConstants;
import org.teiid.logging.LogManager;
import org.teiid.net.TeiidURL;
import org.teiid.odata.api.Client;
import org.teiid.olingo.ODataPlugin;
import org.teiid.olingo.service.LocalClient;
Expand Down Expand Up @@ -100,6 +103,12 @@ public void doFilter(ServletRequest request, ServletResponse response,

String uri = ((HttpServletRequest) request).getRequestURL().toString();
int idx = uri.indexOf("/odata4/"); //$NON-NLS-1$

if (idx != -1 && (uri.endsWith("auth") || uri.endsWith("token"))){
chain.doFilter(httpRequest, response);
return;
}

if (idx != -1) {
String contextPath = httpRequest.getContextPath();
if (contextPath == null) {
Expand Down Expand Up @@ -143,6 +152,12 @@ public void doFilter(ServletRequest request, ServletResponse response,
this.initProperties.getProperty("vdb-version") == null) { //$NON-NLS-1$ //$NON-NLS-2$
throw new ServletException(ODataPlugin.Util.gs(ODataPlugin.Event.TEIID16018));
}

if (uri.endsWith("auth") || uri.endsWith("token")){
chain.doFilter(httpRequest, response);
return;
}

vdbName = this.initProperties.getProperty("vdb-name"); //$NON-NLS-1$
version = Integer.parseInt(this.initProperties.getProperty("vdb-version")); //$NON-NLS-1$
int modelIdx = uri.indexOf('/', uri.indexOf('/'));
Expand All @@ -169,6 +184,11 @@ public void doFilter(ServletRequest request, ServletResponse response,
this.contextMap.put(key, ref);
}

// send the access token using jdbc protocol
if (OAuthCredentialContext.getCredential() != null) {
this.initProperties.setProperty(TeiidURL.CONNECTION.PASSTHROUGH_AUTHENTICATION, "false");
}

Client client = buildClient(vdbName, version, this.initProperties);
try {
Connection connection = client.open();
Expand Down
6 changes: 6 additions & 0 deletions olingo/src/main/java/org/teiid/olingo/web/ODataServlet.java
Expand Up @@ -29,6 +29,7 @@

import org.apache.olingo.server.api.ODataHttpHandler;
import org.teiid.odata.api.Client;
import org.teiid.olingo.ODataPlugin;
import org.teiid.olingo.service.TeiidServiceHandler;

@SuppressWarnings("serial")
Expand All @@ -39,6 +40,11 @@ public void service(HttpServletRequest request, HttpServletResponse response)
ODataHttpHandler handler = (ODataHttpHandler) request.getAttribute(ODataHttpHandler.class.getName());
Client client = (Client) request.getAttribute(Client.class.getName());

String uri = request.getRequestURI();
if (uri.endsWith("auth") || uri.endsWith("token")) {
throw new IOException(ODataPlugin.Util.gs(ODataPlugin.Event.TEIID16044));
}

try {
TeiidServiceHandler.setClient(client);
handler.process(request, response);
Expand Down
2 changes: 2 additions & 0 deletions olingo/src/main/resources/org/teiid/olingo/i18n.properties
Expand Up @@ -63,3 +63,5 @@ TEIID16040=$it used but supplied resource must be an array or entity.
TEIID16041=in $expand system option nested $skip, $top, $count and $levels options are not currently supported
TEIID16042=Multiple $expand nodes are not supported, for ex: /customer?$expand=orders,accounts
TEIID16045=Expected Edm.String, but value is {0}
TEIID16043=Wrong query expecting $root
TEIID16044=Invalid query, "auth" and "token" end points apply only for oauth based security. Typically the authentication URL will look like http://<host>:8080/odata4/auth, note there is no VDB name after the "odata4" in the URL. The OData URL looks like http://<host>:8080/odata4/<vdbname>.<version>/schema/entityName

0 comments on commit 0d1c66c

Please sign in to comment.