Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAngel Avila2015-12-21 22:01:14 +0000
committerRyan D. Brooks2015-12-21 22:01:14 +0000
commitd7c359722bf1a6fd3ee5bd202657b273b3373409 (patch)
tree3f1e41663ba980d3b25c9f179ea72daf288988ec /plugins/org.eclipse.osee.jaxrs.server
parentbf73e2f0b898bcf54aca7ee1fe76c3edeb0b8c76 (diff)
downloadorg.eclipse.osee-d7c359722bf1a6fd3ee5bd202657b273b3373409.tar.gz
org.eclipse.osee-d7c359722bf1a6fd3ee5bd202657b273b3373409.tar.xz
org.eclipse.osee-d7c359722bf1a6fd3ee5bd202657b273b3373409.zip
bug: Enable OAuth to work with multiple servers through proxy
Change-Id: Ibb25c2ded9502745b9f91beb6e09fd53f2e10123 Conflicts: plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/security/oauth2/provider/adapters/OAuthEncryption.java
Diffstat (limited to 'plugins/org.eclipse.osee.jaxrs.server')
-rw-r--r--plugins/org.eclipse.osee.jaxrs.server/META-INF/MANIFEST.MF4
-rw-r--r--plugins/org.eclipse.osee.jaxrs.server/OSGI-INF/jaxrs.security.oauth2.provider.server.xml2
-rw-r--r--plugins/org.eclipse.osee.jaxrs.server/OSGI-INF/session.provider.xml9
-rw-r--r--plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/database/AbstractDatabaseStorage.java208
-rw-r--r--plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/security/oauth2/OAuthUtil.java17
-rw-r--r--plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/security/oauth2/provider/OAuth2Configuration.java26
-rw-r--r--plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/security/oauth2/provider/OAuth2DataProvider.java12
-rw-r--r--plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/security/oauth2/provider/OAuth2RequestFilter.java9
-rw-r--r--plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/security/oauth2/provider/OAuth2ServerProvider.java14
-rw-r--r--plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/security/oauth2/provider/SubjectProvider.java5
-rw-r--r--plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/security/oauth2/provider/adapters/OAuthEncryption.java71
-rw-r--r--plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/security/oauth2/provider/adapters/SubjectProviderImpl.java152
-rw-r--r--plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/security/oauth2/provider/endpoints/ImplicitGrantEndpoint.java60
-rw-r--r--plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/security/JaxRsSessionProvider.java16
-rw-r--r--plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/session/AuthenticitySessionStorage.java71
-rw-r--r--plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/session/AuthenticityToken.java39
-rw-r--r--plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/session/JaxRsSessionProviderImpl.java116
-rw-r--r--plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/session/SessionData.java116
-rw-r--r--plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/session/SessionStorage.java75
19 files changed, 973 insertions, 49 deletions
diff --git a/plugins/org.eclipse.osee.jaxrs.server/META-INF/MANIFEST.MF b/plugins/org.eclipse.osee.jaxrs.server/META-INF/MANIFEST.MF
index cccb166c8bd..5401227518e 100644
--- a/plugins/org.eclipse.osee.jaxrs.server/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.osee.jaxrs.server/META-INF/MANIFEST.MF
@@ -68,10 +68,12 @@ Import-Package: com.google.common.cache;version="15.0.0",
org.eclipse.osee.jaxrs,
org.eclipse.osee.jaxrs.client,
org.eclipse.osee.jaxrs.mvc,
+ org.eclipse.osee.jdbc,
org.eclipse.osee.logger,
org.eclipse.osgi.util,
org.osgi.framework,
org.osgi.service.http
Bundle-Vendor: Eclipse Open System Engineering Environment
-Export-Package: org.eclipse.osee.jaxrs.server.security
+Export-Package: org.eclipse.osee.jaxrs.server.database,
+ org.eclipse.osee.jaxrs.server.security
Bundle-ActivationPolicy: lazy
diff --git a/plugins/org.eclipse.osee.jaxrs.server/OSGI-INF/jaxrs.security.oauth2.provider.server.xml b/plugins/org.eclipse.osee.jaxrs.server/OSGI-INF/jaxrs.security.oauth2.provider.server.xml
index 3668840f6f2..122351ebeda 100644
--- a/plugins/org.eclipse.osee.jaxrs.server/OSGI-INF/jaxrs.security.oauth2.provider.server.xml
+++ b/plugins/org.eclipse.osee.jaxrs.server/OSGI-INF/jaxrs.security.oauth2.provider.server.xml
@@ -6,5 +6,5 @@
<reference bind="setJaxRsResourceManager" cardinality="1..1" interface="org.eclipse.osee.jaxrs.server.internal.JaxRsResourceManager" name="JaxRsResourceManager" policy="static"/>
<reference bind="setJaxRsAuthenticator" cardinality="1..1" interface="org.eclipse.osee.jaxrs.server.security.JaxRsAuthenticator" name="JaxRsAuthenticator" policy="static"/>
<reference bind="setJaxRsOAuthStorage" cardinality="1..1" interface="org.eclipse.osee.jaxrs.server.security.JaxRsOAuthStorage" name="JaxRsOAuthStorage" policy="static"/>
- <reference bind="setJaxRsSessionProvider" cardinality="0..1" interface="org.eclipse.osee.jaxrs.server.security.JaxRsSessionProvider" name="JaxRsSessionProvider" policy="static"/>
+ <reference bind="setJaxRsSessionProvider" cardinality="1..1" interface="org.eclipse.osee.jaxrs.server.security.JaxRsSessionProvider" name="JaxRsSessionProvider" policy="static"/>
</scr:component>
diff --git a/plugins/org.eclipse.osee.jaxrs.server/OSGI-INF/session.provider.xml b/plugins/org.eclipse.osee.jaxrs.server/OSGI-INF/session.provider.xml
new file mode 100644
index 00000000000..6513435ec9a
--- /dev/null
+++ b/plugins/org.eclipse.osee.jaxrs.server/OSGI-INF/session.provider.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" activate="start">
+ <implementation class="org.eclipse.osee.jaxrs.server.session.JaxRsSessionProviderImpl"/>
+ <service>
+ <provide interface="org.eclipse.osee.jaxrs.server.security.JaxRsSessionProvider"/>
+ </service>
+ <reference bind="setLogger" cardinality="1..1" interface="org.eclipse.osee.logger.Log" name="Log" policy="static"/>
+ <reference bind="setJdbcService" cardinality="1..1" interface="org.eclipse.osee.jdbc.JdbcService" name="JdbcService" policy="static" target="(osgi.binding=oauth.jdbc.service)"/>
+</scr:component>
diff --git a/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/database/AbstractDatabaseStorage.java b/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/database/AbstractDatabaseStorage.java
new file mode 100644
index 00000000000..871198b53fa
--- /dev/null
+++ b/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/database/AbstractDatabaseStorage.java
@@ -0,0 +1,208 @@
+/*******************************************************************************
+ * Copyright (c) 2014 Boeing.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Boeing - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.osee.jaxrs.server.database;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.concurrent.Callable;
+import org.eclipse.osee.framework.jdk.core.type.OseeCoreException;
+import org.eclipse.osee.framework.jdk.core.type.ResultSet;
+import org.eclipse.osee.framework.jdk.core.type.ResultSets;
+import org.eclipse.osee.framework.jdk.core.util.Lib;
+import org.eclipse.osee.jdbc.JdbcClient;
+import org.eclipse.osee.jdbc.JdbcStatement;
+import org.eclipse.osee.jdbc.SQL3DataType;
+import org.eclipse.osee.logger.Log;
+
+/**
+ * @author Roberto E. Escobar
+ */
+public abstract class AbstractDatabaseStorage<T> {
+
+ private final Log logger;
+ private final JdbcClient jdbcClient;
+
+ public AbstractDatabaseStorage(Log logger, JdbcClient jdbcClient) {
+ super();
+ this.logger = logger;
+ this.jdbcClient = jdbcClient;
+ }
+
+ protected Object asVarcharOrNull(String value) {
+ return value != null ? value : SQL3DataType.VARCHAR;
+ }
+
+ protected abstract Object[] asInsert(T item);
+
+ protected abstract Object[] asUpdate(T item);
+
+ protected abstract Object[] asDelete(T item);
+
+ protected abstract T readData(JdbcStatement chStmt);
+
+ protected <R> R execute(Callable<R> callable) {
+ try {
+ return callable.call();
+ } catch (Exception ex) {
+ throw OseeCoreException.wrap(ex);
+ }
+ }
+
+ protected T selectOneOrNull(final String query, final Object... data) {
+ return execute(select(query, data)).getOneOrNull();
+ }
+
+ protected ResultSet<T> selectItems(final String query, final Object... data) {
+ return execute(select(query, data));
+ }
+
+ protected void insertItems(final String insertSql, final T... items) {
+ insertItems(insertSql, Arrays.asList(items));
+ }
+
+ protected void insertItems(final String insertSql, final Iterable<T> items) {
+ execute(insert(insertSql, items));
+ }
+
+ protected void deleteItems(final String deleteSql, final T... items) {
+ deleteItems(deleteSql, Arrays.asList(items));
+ }
+
+ protected void deleteItems(final String deleteSql, final Iterable<T> items) {
+ execute(delete(deleteSql, items));
+ }
+
+ protected void updateItems(final String insertSql, final T... items) {
+ updateItems(insertSql, Arrays.asList(items));
+ }
+
+ protected void updateItems(final String updateSql, final Iterable<T> items) {
+ execute(update(updateSql, items));
+ }
+
+ protected long countItems(final String countSql, final Object... data) {
+ return execute(count(countSql, data));
+ }
+
+ private Callable<ResultSet<T>> select(final String query, final Object... data) {
+ return new AbstractCallable<Object[], ResultSet<T>>(query, data) {
+
+ @Override
+ protected ResultSet<T> innerCall() throws Exception {
+ List<T> list = new LinkedList<>();
+ JdbcStatement chStmt = jdbcClient.getStatement();
+ try {
+ chStmt.runPreparedQuery(query, data);
+ while (chStmt.next()) {
+ T data = readData(chStmt);
+ list.add(data);
+ }
+ } finally {
+ chStmt.close();
+ }
+ return ResultSets.newResultSet(list);
+ }
+ };
+ }
+
+ private Callable<Long> count(final String query, final Object... data) {
+ return new AbstractCallable<Object[], Long>(query, data) {
+
+ @Override
+ protected Long innerCall() throws Exception {
+ return jdbcClient.runPreparedQueryFetchObject(-1L, query, data);
+ }
+ };
+ }
+
+ private Callable<Integer> insert(final String insertSql, final Iterable<T> items) {
+ return new AbstractCallable<Iterable<T>, Integer>(insertSql, items) {
+
+ @Override
+ protected Integer innerCall() throws Exception {
+ List<Object[]> data = new ArrayList<>();
+ for (T item : items) {
+ data.add(asInsert(item));
+ }
+ return jdbcClient.runBatchUpdate(insertSql, data);
+ }
+ };
+ }
+
+ private Callable<Integer> delete(final String deleteSql, final Iterable<T> items) {
+ return new AbstractCallable<Iterable<T>, Integer>(deleteSql, items) {
+
+ @Override
+ protected Integer innerCall() throws Exception {
+ List<Object[]> data = new ArrayList<>();
+ for (T item : items) {
+ data.add(asDelete(item));
+ }
+ return jdbcClient.runBatchUpdate(deleteSql, data);
+ }
+ };
+ }
+
+ private Callable<Integer> update(final String updateSql, final Iterable<T> items) {
+ return new AbstractCallable<Iterable<T>, Integer>(updateSql, items) {
+
+ @Override
+ protected Integer innerCall() throws Exception {
+ List<Object[]> data = new ArrayList<>();
+ for (T item : items) {
+ data.add(asUpdate(item));
+ }
+ return jdbcClient.runBatchUpdate(updateSql, data);
+ }
+ };
+ }
+
+ protected abstract class AbstractCallable<I, O> implements Callable<O> {
+
+ protected final String query;
+ protected final I data;
+
+ public AbstractCallable(String query, I data) {
+ super();
+ this.query = query;
+ this.data = data;
+ }
+
+ protected JdbcClient getJdbcClient() {
+ return jdbcClient;
+ }
+
+ @Override
+ public final O call() throws Exception {
+ long startTime = System.currentTimeMillis();
+ long endTime = startTime;
+ O result = null;
+ try {
+ if (logger.isTraceEnabled()) {
+ logger.trace("%s [start] - [%s] [%s]", getClass().getSimpleName(), query, data);
+ }
+ result = innerCall();
+ } finally {
+ endTime = System.currentTimeMillis() - startTime;
+ }
+ if (logger.isTraceEnabled()) {
+ logger.trace("%s [finished] - [%s] [%s] [%s]", getClass().getSimpleName(), Lib.asTimeString(endTime), query,
+ data);
+ }
+ return result;
+ }
+
+ protected abstract O innerCall() throws Exception;
+ }
+
+} \ No newline at end of file
diff --git a/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/security/oauth2/OAuthUtil.java b/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/security/oauth2/OAuthUtil.java
index 776cde53e06..398f760d93b 100644
--- a/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/security/oauth2/OAuthUtil.java
+++ b/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/security/oauth2/OAuthUtil.java
@@ -130,11 +130,16 @@ public final class OAuthUtil {
return finalRedirectURI;
}
- public static Response newAuthorizationRequiredResponse(URI redirectURI, boolean ignoreBasePath, String realmName, Message m, ContainerRequestContext context) {
+ public static Response newAuthorizationRequiredResponse(Exception ex, URI redirectURI, boolean ignoreBasePath, String realmName, Message m, ContainerRequestContext context) {
HttpHeaders headers = new HttpHeadersImpl(m);
if (redirectURI != null && JaxRsUtils.isHtmlSupported(headers.getAcceptableMediaTypes())) {
URI finalRedirectURI = computeRedirectUri(redirectURI, ignoreBasePath, m, context);
- return Response.temporaryRedirect(finalRedirectURI).build();
+ ResponseBuilder toReturn = Response.temporaryRedirect(finalRedirectURI);
+
+ if (ex != null) {
+ toReturn.entity("Incorrect Username/Password");
+ }
+ return toReturn.build();
} else {
ResponseBuilder builder = Response.status(Response.Status.UNAUTHORIZED);
StringBuilder sb = new StringBuilder();
@@ -206,12 +211,18 @@ public final class OAuthUtil {
}
UserSubject data = new UserSubject();
data.setId(String.valueOf(subject.getGuid()));
- data.setLogin(subject.getUserName());
+ String userName = subject.getUserName();
+ if (Strings.isValid(userName)) {
+ data.setLogin(subject.getUserName());
+ } else {
+ data.setLogin(subject.getLogin());
+ }
data.setRoles(roles);
Map<String, String> properties = new HashMap<>();
properties.put(SUBJECT_USERNAME, subject.getUserName());
String displayName = subject.getDisplayName();
+
if (displayName.contains(",")) {
String[] names = displayName.split(",");
displayName = String.format("%s %s", names[1].trim(), names[0].trim());
diff --git a/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/security/oauth2/provider/OAuth2Configuration.java b/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/security/oauth2/provider/OAuth2Configuration.java
index c92fcd77d00..f1733a36d5d 100644
--- a/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/security/oauth2/provider/OAuth2Configuration.java
+++ b/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/security/oauth2/provider/OAuth2Configuration.java
@@ -34,8 +34,10 @@ public class OAuth2Configuration {
public static final String OAUTH2_PROVIDER__ACCESS_TOKEN_EXPIRATION = qualify("access.token.expiration");
public static final String OAUTH2_PROVIDER__CODE_GRANT_EXPIRATION = qualify("code.grant.expiration");
public static final String OAUTH2_PROVIDER__REFRESH_TOKEN_EXPIRATION = qualify("refresh.token.expiration");
+ public static final String OAUTH2_PROVIDER__SESSION_TOKEN_EXPIRATION = qualify("session.token.expiration");
public static final String OAUTH2_PROVIDER__NONCE_ALLOWED_WINDOW = qualify("nonce.allowed.window");
public static final String OAUTH2_PROVIDER__LOGIN_REDIRECT_URI = qualify("login.redirect.uri");
+ public static final String OAUTH2_PROVIDER__LOGIN_REDIRECT_ERROR_URI = qualify("login.redirect.error.uri");
public static final String OAUTH2_PROVIDER__IGNORE_LOGIN_REDIRECT_BASE_PATH = qualify("ignore.login.redirect.base.path");
public static final String OAUTH2_PROVIDER__REALM = qualify("realm");
public static final String OAUTH2_PROVIDER__AUDIENCE_IS_ENDPOINT_ADDRESS = qualify("audience.is.endpoint.address");
@@ -60,9 +62,12 @@ public class OAuth2Configuration {
public static final long DEFAULT_OAUTH2_PROVIDER__ACCESS_TOKEN_EXPIRATION = 10L * 60L * 1000L;
public static final long DEFAULT_OAUTH2_PROVIDER__CODE_GRANT_EXPIRATION = 1L * 60L * 1000L;
public static final long DEFAULT_OAUTH2_PROVIDER__REFRESH_TOKEN_EXPIRATION = 30L * 60L * 1000L;
+ public static final long DEFAULT_OAUTH2_PROVIDER__SESSION_TOKEN_EXPIRATION = 60L;
public static final long DEFAULT_OAUTH2_PROVIDER__NONCE_ALLOWED_WINDOW = 2000L;
public static final URI DEFAULT_OAUTH2_PROVIDER__LOGIN_REDIRECT_URI = null;
public static final boolean DEFAULT_OAUTH2_PROVIDER__IGNORE_LOGIN_REDIRECT_BASE_PATH = false;
+ public static final URI DEFAULT_OAUTH2_PROVIDER__LOGIN_ERROR_REDIRECT_URI = null;
+ public static final boolean DEFAULT_OAUTH2_PROVIDER__IGNORE_LOGIN_ERROR_REDIRECT_BASE_PATH = false;
public static final String DEFAULT_OAUTH2_PROVIDER__REALM = "OAuth2-OSEE";
public static final boolean DEFAULT_OAUTH2_PROVIDER__AUDIENCE_IS_ENDPOINT_ADDRESS = false;
public static final boolean DEFAULT_OAUTH2_PROVIDER__BLOCK_UNSECURED_REQUESTS = false;
@@ -99,6 +104,11 @@ public class OAuth2Configuration {
return getBoolean(props, OAUTH2_PROVIDER__SERVICE_ENABLED, DEFAULT_OAUTH2_PROVIDER__SERVICE_ENABLED);
}
+ public long getSessionTokenExpiration() {
+ return JaxRsUtils.getLong(props, OAUTH2_PROVIDER__SESSION_TOKEN_EXPIRATION,
+ DEFAULT_OAUTH2_PROVIDER__SESSION_TOKEN_EXPIRATION);
+ }
+
public long getAccessTokenExpiration() {
return JaxRsUtils.getLong(props, OAUTH2_PROVIDER__ACCESS_TOKEN_EXPIRATION,
DEFAULT_OAUTH2_PROVIDER__ACCESS_TOKEN_EXPIRATION);
@@ -132,6 +142,19 @@ public class OAuth2Configuration {
return loginRedirectURI;
}
+ public URI getLoginRedirectErrorURI() {
+ URI loginRedirectErrorURI = DEFAULT_OAUTH2_PROVIDER__LOGIN_ERROR_REDIRECT_URI;
+ String value = get(props, OAUTH2_PROVIDER__LOGIN_REDIRECT_ERROR_URI, null);
+ if (Strings.isValid(value)) {
+ try {
+ loginRedirectErrorURI = new URI(value);
+ } catch (URISyntaxException ex) {
+ // do nothing;
+ }
+ }
+ return loginRedirectErrorURI;
+ }
+
public boolean isIgnoreLoginRedirectBasePath() {
return getBoolean(props, OAUTH2_PROVIDER__IGNORE_LOGIN_REDIRECT_BASE_PATH,
DEFAULT_OAUTH2_PROVIDER__IGNORE_LOGIN_REDIRECT_BASE_PATH);
@@ -171,7 +194,8 @@ public class OAuth2Configuration {
}
public boolean isRefreshTokenAllowed() {
- return getBoolean(props, OAUTH2_PROVIDER__REFRESH_TOKENS_ALLOWED, DEFAULT_OAUTH2_PROVIDER__REFRESH_TOKENS_ALLOWED);
+ return getBoolean(props, OAUTH2_PROVIDER__REFRESH_TOKENS_ALLOWED,
+ DEFAULT_OAUTH2_PROVIDER__REFRESH_TOKENS_ALLOWED);
}
public boolean isReportClientId() {
diff --git a/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/security/oauth2/provider/OAuth2DataProvider.java b/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/security/oauth2/provider/OAuth2DataProvider.java
index 3c836068176..d6feaebe3e0 100644
--- a/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/security/oauth2/provider/OAuth2DataProvider.java
+++ b/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/security/oauth2/provider/OAuth2DataProvider.java
@@ -35,6 +35,7 @@ import org.eclipse.osee.jaxrs.server.security.JaxRsOAuthStorage;
import org.eclipse.osee.jaxrs.server.security.OAuthCodeGrant;
import org.eclipse.osee.jaxrs.server.security.OAuthToken;
import org.eclipse.osee.jaxrs.server.security.OAuthTokenType;
+import org.eclipse.osee.jaxrs.server.session.SessionData;
/**
* @author Roberto E. Escobar
@@ -211,6 +212,10 @@ public class OAuth2DataProvider implements AuthorizationCodeDataProvider {
return accessToken;
}
+ public String createSessionToken(SessionData session) {
+ return serializer.encryptSessionToken(session, getSecretKey());
+ }
+
@Override
public ServerAccessToken getAccessToken(String accessToken) {
return serializer.decryptAccessToken(this, accessToken, getSecretKey());
@@ -292,8 +297,8 @@ public class OAuth2DataProvider implements AuthorizationCodeDataProvider {
@Override
public ServerAccessToken getPreauthorizedToken(Client client, List<String> requestedScopes, UserSubject subject, String grantType) {
- // This is an optimization useful in cases where a client requests an authorization code:
- // if a user has already provided a given client with a pre-authorized token then challenging
+ // This is an optimization useful in cases where a client requests an authorization code:
+ // if a user has already provided a given client with a pre-authorized token then challenging
// a user with yet another form asking for the authorization is redundant
long clientId = getClientId(client);
long subjectId = getSubjectId(subject);
@@ -313,6 +318,8 @@ public class OAuth2DataProvider implements AuthorizationCodeDataProvider {
if (!isExpired && entry.getGrantType().equals(grantType)) {
token = serializer.decryptAccessToken(this, entry.getTokenKey(), getSecretKey());
+ } else if (isExpired) {
+ revokeToken(client, entry.getTokenKey(), entry.getTokenType());
}
break;
}
@@ -366,5 +373,4 @@ public class OAuth2DataProvider implements AuthorizationCodeDataProvider {
private List<String> getApprovedScopes(List<String> requestedScopes, List<String> approvedScopes) {
return approvedScopes.isEmpty() ? requestedScopes : approvedScopes;
}
-
} \ No newline at end of file
diff --git a/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/security/oauth2/provider/OAuth2RequestFilter.java b/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/security/oauth2/provider/OAuth2RequestFilter.java
index e034d62c5b7..db25a0c72a5 100644
--- a/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/security/oauth2/provider/OAuth2RequestFilter.java
+++ b/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/security/oauth2/provider/OAuth2RequestFilter.java
@@ -48,6 +48,7 @@ public class OAuth2RequestFilter extends OAuthRequestFilter {
private volatile boolean useUserSubject;
private volatile URI redirectURI;
+ private volatile URI redirectErrorURI;
private volatile boolean ignoreBasePath;
public OAuth2RequestFilter(Log logger, JaxRsResourceManager resourceManager, SubjectProvider subjectProvider) {
@@ -63,6 +64,10 @@ public class OAuth2RequestFilter extends OAuthRequestFilter {
this.useUserSubject = useUserSubject;
}
+ public void setRedirectErrorURI(URI redirectErrorURI) {
+ this.redirectErrorURI = redirectErrorURI;
+ }
+
public void setRedirectURI(URI redirectURI) {
this.redirectURI = redirectURI;
}
@@ -133,12 +138,12 @@ public class OAuth2RequestFilter extends OAuthRequestFilter {
private Response getAuthorizationRequired(Message msg, ContainerRequestContext context) {
logger.debug("authorizationRequiredResponse called");
- return newAuthorizationRequiredResponse(redirectURI, ignoreBasePath, realm, msg, context);
+ return newAuthorizationRequiredResponse(null, redirectURI, ignoreBasePath, realm, msg, context);
}
private Response getAuthenticationException(Exception ex, Message msg, ContainerRequestContext context) {
logger.error(ex, "Authorization error [%s]", msg.toString());
- return newAuthorizationRequiredResponse(redirectURI, ignoreBasePath, realm, msg, context);
+ return newAuthorizationRequiredResponse(ex, redirectErrorURI, ignoreBasePath, realm, msg, context);
}
private void doBasicAuthentication(MessageContext mc, String header) {
diff --git a/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/security/oauth2/provider/OAuth2ServerProvider.java b/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/security/oauth2/provider/OAuth2ServerProvider.java
index 926ccb0db78..8e4aa04b368 100644
--- a/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/security/oauth2/provider/OAuth2ServerProvider.java
+++ b/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/security/oauth2/provider/OAuth2ServerProvider.java
@@ -89,6 +89,7 @@ public class OAuth2ServerProvider {
private JaxRsAuthenticator authenticator;
private JaxRsSessionProvider sessionProvider;
private JaxRsOAuthStorage storage;
+ private SubjectProvider subjectProvider;
private final AtomicBoolean wasRegistered = new AtomicBoolean();
@@ -143,12 +144,12 @@ public class OAuth2ServerProvider {
}
private void initialize(OAuth2Configuration config) {
- SubjectProvider subjectProvider = new SubjectProviderImpl(logger, sessionProvider, authenticator);
+ OAuthEncryption serializer = new OAuthEncryption();
+ subjectProvider = new SubjectProviderImpl(logger, sessionProvider, authenticator, serializer);
ClientProvider clientProvider = new ClientProviderImpl(subjectProvider, storage);
audiences = Collections.emptyList();
- OAuthEncryption serializer = new OAuthEncryption();
dataProvider = new OAuth2DataProvider(clientProvider, subjectProvider, serializer, storage);
filter = new OAuth2RequestFilter(logger, resourceManager, subjectProvider);
@@ -230,6 +231,7 @@ public class OAuth2ServerProvider {
private void configure(OAuth2Configuration config) {
configure(config, filter);
+ configure(config, subjectProvider);
configure(config, dataProvider);
configure(config, nonceVerifier);
@@ -256,6 +258,12 @@ public class OAuth2ServerProvider {
configureObject(config, provider);
}
+ private void configure(OAuth2Configuration config, SubjectProvider provider) {
+ provider.setSessionTokenExpiration(config.getSessionTokenExpiration());
+ provider.setSecretKeyAlgorithm(config.getSecretKeyAlgorithm());
+ provider.setSecretKeyEncoded(config.getEncodedSecretKey());
+ }
+
private void configure(OAuth2Configuration config, NonceVerifier object) {
if (object instanceof NonceVerifierImpl) {
NonceVerifierImpl nonceVerifier = (NonceVerifierImpl) object;
@@ -271,6 +279,8 @@ public class OAuth2ServerProvider {
filter.setRealm(config.getRealm());
filter.setRedirectURI(config.getLoginRedirectURI());
+ filter.setRedirectErrorURI(config.getLoginRedirectErrorURI());
+
filter.setIgnoreBasePath(config.isIgnoreLoginRedirectBasePath());
filter.setRealm(config.getRealm());
configureObject(config, filter);
diff --git a/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/security/oauth2/provider/SubjectProvider.java b/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/security/oauth2/provider/SubjectProvider.java
index eb121eab4c4..8ef5fa76cb2 100644
--- a/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/security/oauth2/provider/SubjectProvider.java
+++ b/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/security/oauth2/provider/SubjectProvider.java
@@ -31,4 +31,9 @@ public interface SubjectProvider extends SessionAuthenticityTokenProvider, Subje
UserSubject getSubjectById(long subjectId);
+ void setSecretKeyAlgorithm(String secretKeyAlgorithm);
+
+ void setSecretKeyEncoded(String encodedSecretKey);
+
+ void setSessionTokenExpiration(long accessTokenExpiration);
} \ No newline at end of file
diff --git a/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/security/oauth2/provider/adapters/OAuthEncryption.java b/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/security/oauth2/provider/adapters/OAuthEncryption.java
index 9808899936a..7ead0316a80 100644
--- a/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/security/oauth2/provider/adapters/OAuthEncryption.java
+++ b/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/security/oauth2/provider/adapters/OAuthEncryption.java
@@ -27,6 +27,7 @@ import org.apache.cxf.rs.security.oauth2.tokens.refresh.RefreshToken;
import org.apache.cxf.rs.security.oauth2.utils.crypto.CryptoUtils;
import org.apache.cxf.rs.security.oauth2.utils.crypto.KeyProperties;
import org.eclipse.osee.framework.jdk.core.util.Strings;
+import org.eclipse.osee.jaxrs.server.session.SessionData;
/**
* @author Roberto E. Escobar
@@ -86,6 +87,15 @@ public class OAuthEncryption {
return state.toString();
}
+ public String encryptSessionToken(SessionData session, SecretKey secretKey) {
+ return encryptSessionToken(session, secretKey, null);
+ }
+
+ private String encryptSessionToken(SessionData session, SecretKey secretKey, KeyProperties props) {
+ String tokenSequence = tokenizeSessionToken(session);
+ return CryptoUtils.encryptSequence(tokenSequence, secretKey, props);
+ }
+
public String encryptAccessToken(AccessToken token, SecretKey secretKey) {
return encryptAccessToken(token, secretKey, null);
}
@@ -120,9 +130,8 @@ public class OAuthEncryption {
private static ServerAuthorizationCodeGrant recreateCodeGrantInternal(OAuthDataProvider provider, String sequence) {
String[] parts = getParts(sequence);
- ServerAuthorizationCodeGrant grant =
- new ServerAuthorizationCodeGrant(provider.getClient(parts[0]), parts[1], Long.valueOf(parts[2]),
- Long.valueOf(parts[3]));
+ ServerAuthorizationCodeGrant grant = new ServerAuthorizationCodeGrant(provider.getClient(parts[0]), parts[1],
+ Long.valueOf(parts[2]), Long.valueOf(parts[3]));
grant.setRedirectUri(getStringPart(parts[4]));
grant.setAudience(getStringPart(parts[5]));
grant.setClientCodeVerifier(getStringPart(parts[6]));
@@ -174,6 +183,25 @@ public class OAuthEncryption {
return sequence.split("\\" + SEP);
}
+ public SessionData decryptSessionToken(String token, SecretKey secretKey) {
+ String decryptedSequence = CryptoUtils.decryptSequence(token, secretKey, null);
+ String[] parts = getParts(decryptedSequence);
+
+ UserSubject recreateUserSubject = recreateUserSubject(parts[9]);
+
+ SessionData toReturn = new SessionData(parts[0]);
+ toReturn.setAccountActive(Boolean.getBoolean(parts[1]));
+ toReturn.setExpiresIn(Long.valueOf(parts[2]));
+ toReturn.setIssuedAt(Long.valueOf(parts[3]));
+ toReturn.setAccountDisplayName(parts[4]);
+ toReturn.setAccountEmail(parts[5]);
+ toReturn.setAccountName(parts[6]);
+ toReturn.setAccountUsername(parts[7]);
+ toReturn.setAccountId(Long.valueOf(parts[8]));
+ toReturn.setSubject(recreateUserSubject);
+ return toReturn;
+ }
+
public ServerAccessToken decryptAccessToken(OAuthDataProvider provider, String token, SecretKey secretKey) {
ServerAccessToken accessToken = decryptAccessToken(provider, token, secretKey, null);
return accessToken;
@@ -246,6 +274,41 @@ public class OAuthEncryption {
return seq + SEP + token.getAccessTokens().toString();
}
+ private static String tokenizeSessionToken(SessionData session) {
+ StringBuilder state = new StringBuilder();
+ // 0: key
+ state.append(tokenizeString(session.getGuid()));
+ // 1: active
+ state.append(SEP);
+ state.append(session.getAccountActive());
+ // 2: expiresIn
+ state.append(SEP);
+ state.append(session.getExpiresIn());
+ // 3: issuedAt
+ state.append(SEP);
+ state.append(session.getIssuedAt());
+ // 4: display name
+ state.append(SEP);
+ state.append(tokenizeString(session.getAccountDisplayName()));
+ // 5: email
+ state.append(SEP);
+ state.append(tokenizeString(session.getAccountEmail()));
+ // 6: name
+ state.append(SEP);
+ state.append(tokenizeString(session.getAccountName()));
+ // 7: username
+ state.append(SEP);
+ state.append(tokenizeString(session.getAccountUsername()));
+ // 8: id
+ state.append(SEP);
+ state.append(session.getAccountId());
+ // 9: user subject
+ state.append(SEP);
+ tokenizeUserSubject(state, session.getSubject());
+
+ return state.toString();
+ }
+
private static String tokenizeServerToken(ServerAccessToken token) {
StringBuilder state = new StringBuilder();
// 0: key
@@ -253,7 +316,7 @@ public class OAuthEncryption {
// 1: type
state.append(SEP);
state.append(tokenizeString(token.getTokenType()));
- // 2: expiresIn
+ // 2: expiresIn
state.append(SEP);
state.append(token.getExpiresIn());
// 3: issuedAt
diff --git a/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/security/oauth2/provider/adapters/SubjectProviderImpl.java b/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/security/oauth2/provider/adapters/SubjectProviderImpl.java
index e8d55464b6b..253386911b6 100644
--- a/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/security/oauth2/provider/adapters/SubjectProviderImpl.java
+++ b/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/security/oauth2/provider/adapters/SubjectProviderImpl.java
@@ -11,8 +11,15 @@
package org.eclipse.osee.jaxrs.server.internal.security.oauth2.provider.adapters;
import static org.eclipse.osee.jaxrs.server.internal.security.oauth2.OAuthUtil.saveSecurityContext;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
import java.util.UUID;
+import javax.crypto.SecretKey;
import javax.servlet.http.HttpSession;
+import javax.ws.rs.core.Cookie;
import javax.ws.rs.core.MultivaluedMap;
import org.apache.cxf.jaxrs.ext.MessageContext;
import org.apache.cxf.jaxrs.ext.MessageContextImpl;
@@ -20,13 +27,16 @@ import org.apache.cxf.phase.PhaseInterceptorChain;
import org.apache.cxf.rs.security.oauth2.common.UserSubject;
import org.apache.cxf.rs.security.oauth2.provider.OAuthServiceException;
import org.apache.cxf.rs.security.oauth2.utils.OAuthConstants;
+import org.apache.cxf.rs.security.oauth2.utils.OAuthUtils;
import org.apache.cxf.security.SecurityContext;
import org.eclipse.osee.framework.jdk.core.type.OseePrincipal;
import org.eclipse.osee.framework.jdk.core.util.Strings;
import org.eclipse.osee.jaxrs.server.internal.security.oauth2.OAuthUtil;
import org.eclipse.osee.jaxrs.server.internal.security.oauth2.provider.SubjectProvider;
+import org.eclipse.osee.jaxrs.server.internal.security.util.OseePrincipalImpl;
import org.eclipse.osee.jaxrs.server.security.JaxRsAuthenticator;
import org.eclipse.osee.jaxrs.server.security.JaxRsSessionProvider;
+import org.eclipse.osee.jaxrs.server.session.SessionData;
import org.eclipse.osee.logger.Log;
/**
@@ -39,12 +49,38 @@ public class SubjectProviderImpl implements SubjectProvider {
private final Log logger;
private final JaxRsAuthenticator authenticator;
private final JaxRsSessionProvider sessionDelegate;
+ private final OAuthEncryption serializer;
- public SubjectProviderImpl(Log logger, JaxRsSessionProvider sessionDelegate, JaxRsAuthenticator authenticator) {
+ private volatile SecretKey secretKey;
+ private String secretKeyEncoded;
+ private String secretKeyAlgorithm;
+ private long sessionTokenExpiration;
+
+ public SubjectProviderImpl(Log logger, JaxRsSessionProvider sessionDelegate, JaxRsAuthenticator authenticator, OAuthEncryption serializer) {
super();
this.logger = logger;
this.sessionDelegate = sessionDelegate;
this.authenticator = authenticator;
+ this.serializer = serializer;
+ }
+
+ @Override
+ public void setSessionTokenExpiration(long sessionTokenExpiration) {
+ this.sessionTokenExpiration = sessionTokenExpiration;
+ }
+
+ @Override
+ public void setSecretKeyEncoded(String secretKeyEncoded) {
+ this.secretKeyEncoded = secretKeyEncoded;
+ }
+
+ @Override
+ public void setSecretKeyAlgorithm(String secretKeyAlgorithm) {
+ this.secretKeyAlgorithm = secretKeyAlgorithm;
+ }
+
+ public long getSessionTokenExpiration() {
+ return sessionTokenExpiration;
}
@Override
@@ -57,56 +93,66 @@ public class SubjectProviderImpl implements SubjectProvider {
return OAuthUtil.getDisplayName(subject);
}
+ private SecretKey getSecretKey() {
+ if (secretKey == null) {
+ secretKey = serializer.decodeSecretKey(secretKeyEncoded, secretKeyAlgorithm);
+ }
+ return secretKey;
+ }
+
+ // Create Authenticity Session Token
@Override
public String createSessionToken(MessageContext mc, MultivaluedMap<String, String> params, UserSubject subject) {
logger.debug("Create Session Token - subject[%s]", subject);
- String sessionToken = null;
+ String sessionAuthenticityToken = null;
if (sessionDelegate != null) {
Long subjectId = OAuthUtil.getUserSubjectUuid(subject);
- sessionToken = sessionDelegate.createSessionToken(subjectId);
+ sessionAuthenticityToken = sessionDelegate.createAuthenticitySessionToken(subjectId);
} else {
HttpSession session = mc.getHttpServletRequest().getSession();
- sessionToken = (String) session.getAttribute(OAuthConstants.SESSION_AUTHENTICITY_TOKEN);
- if (!Strings.isValid(sessionToken)) {
- sessionToken = UUID.randomUUID().toString();
- session.setAttribute(OAuthConstants.SESSION_AUTHENTICITY_TOKEN, sessionToken);
+ sessionAuthenticityToken = (String) session.getAttribute(OAuthConstants.SESSION_AUTHENTICITY_TOKEN);
+ if (!Strings.isValid(sessionAuthenticityToken)) {
+ sessionAuthenticityToken = UUID.randomUUID().toString();
+ session.setAttribute(OAuthConstants.SESSION_AUTHENTICITY_TOKEN, sessionAuthenticityToken);
}
}
- return sessionToken;
+ return sessionAuthenticityToken;
}
+ // Doesn't seem to get called, removeSessionAuthenticityToken is used to retrieve the token
@Override
public String getSessionToken(MessageContext mc, MultivaluedMap<String, String> params, UserSubject subject) {
logger.debug("Get Session Token - subject[%s]", subject);
- String sessionToken = null;
+ String sessionAuthenticityToken = null;
if (sessionDelegate != null) {
Long subjectId = OAuthUtil.getUserSubjectUuid(subject);
- sessionToken = sessionDelegate.getSessionToken(subjectId);
+ sessionAuthenticityToken = sessionDelegate.getSessionAuthenticityToken(subjectId);
} else {
HttpSession session = mc.getHttpServletRequest().getSession();
- sessionToken = (String) session.getAttribute(OAuthConstants.SESSION_AUTHENTICITY_TOKEN);
+ sessionAuthenticityToken = (String) session.getAttribute(OAuthConstants.SESSION_AUTHENTICITY_TOKEN);
}
- return sessionToken;
+ return sessionAuthenticityToken;
}
+ // Get and remove Authenticity Session Token
@Override
public String removeSessionToken(MessageContext mc, MultivaluedMap<String, String> params, UserSubject subject) {
logger.debug("Remove Session Token - subject[%s]", subject);
- String sessionToken = null;
+ String sessionAuthenticityToken = null;
if (sessionDelegate != null) {
Long subjectId = OAuthUtil.getUserSubjectUuid(subject);
- sessionToken = sessionDelegate.removeSessionToken(subjectId);
+ sessionAuthenticityToken = sessionDelegate.removeSessionAuthenticityToken(subjectId);
} else {
HttpSession session = mc.getHttpServletRequest().getSession();
- sessionToken = (String) session.getAttribute(OAuthConstants.SESSION_AUTHENTICITY_TOKEN);
- if (sessionToken != null) {
+ sessionAuthenticityToken = (String) session.getAttribute(OAuthConstants.SESSION_AUTHENTICITY_TOKEN);
+ if (sessionAuthenticityToken != null) {
session.removeAttribute(OAuthConstants.SESSION_AUTHENTICITY_TOKEN);
}
}
- return sessionToken;
+ return sessionAuthenticityToken;
}
@Override
@@ -123,23 +169,55 @@ public class SubjectProviderImpl implements SubjectProvider {
public SecurityContext getSecurityContextFromSession(MessageContext mc) {
SecurityContext securityContext = null;
if (sessionDelegate != null) {
- // Add security context resolution through session delegate
+ Map<String, Cookie> cookies = mc.getHttpHeaders().getCookies();
+ for (String cookieName : cookies.keySet()) {
+ Cookie cookie = cookies.get(cookieName);
+ if (cookie.getName().equalsIgnoreCase("JSESSIONID")) {
+ SessionData session = sessionDelegate.getSession(cookie.getValue());
+ if (session != null) {
+ boolean isExpired = OAuthUtils.isExpired(session.getIssuedAt(), session.getExpiresIn());
+ if (isExpired) {
+ sessionDelegate.removeSession(session.getGuid());
+ } else {
+ securityContext = recreateSecurityContext(session);
+ }
+ }
+ break;
+ }
+ }
} else {
HttpSession session = mc.getHttpServletRequest().getSession(false);
if (session != null) {
securityContext = (SecurityContext) session.getAttribute(SESSION_SECURITY_CONTEXT);
}
}
+
saveSecurityContext(mc, securityContext);
return securityContext;
}
+ private SecurityContext recreateSecurityContext(SessionData sessionData) {
+ SessionData decryptSessionToken = serializer.decryptSessionToken(sessionData.getSubjectToken(), getSecretKey());
+ UserSubject subject = decryptSessionToken.getSubject();
+ Set<String> roles = new HashSet<>();
+ roles.addAll(subject.getRoles());
+ OseePrincipal principal = new OseePrincipalImpl(decryptSessionToken.getAccountId(),
+ decryptSessionToken.getAccountDisplayName(), decryptSessionToken.getAccountEmail(), subject.getLogin(),
+ sessionData.getAccountName(), decryptSessionToken.getAccountUsername(), decryptSessionToken.getAccountActive(),
+ true, roles, subject.getProperties());
+
+ return OAuthUtil.newSecurityContext(principal);
+ }
+
@Override
public void authenticate(MessageContext mc, String scheme, String username, String password) {
OseePrincipal principal = authenticate(scheme, username, password);
SecurityContext securityContext = OAuthUtil.newSecurityContext(principal);
if (sessionDelegate != null) {
- // Add security context resolution through session delegate
+ HttpSession session = mc.getHttpServletRequest().getSession(true);
+ SessionData sessionData = httpSessionToSessionData(session, securityContext);
+ sessionDelegate.storeSession(sessionData);
+ session.setAttribute(SESSION_SECURITY_CONTEXT, securityContext);
} else {
HttpSession session = mc.getHttpServletRequest().getSession(true);
session.setAttribute(SESSION_SECURITY_CONTEXT, securityContext);
@@ -147,6 +225,34 @@ public class SubjectProviderImpl implements SubjectProvider {
saveSecurityContext(mc, securityContext);
}
+ private SessionData httpSessionToSessionData(HttpSession session, SecurityContext securitContext) {
+ OseePrincipal principal = (OseePrincipal) securitContext.getUserPrincipal();
+ SessionData toReturn = new SessionData(session.getId());
+
+ UserSubject subject = new UserSubject();
+ subject.setId(principal.getOseeGuid());
+ subject.setLogin(principal.getLogin());
+ subject.setProperties(principal.getProperties());
+ List<String> roles = new ArrayList<>();
+ roles.addAll(principal.getRoles());
+ subject.setRoles(roles);
+ toReturn.setSubject(subject);
+
+ toReturn.setAccountActive(principal.isActive());
+ toReturn.setAccountDisplayName(principal.getDisplayName());
+ toReturn.setAccountEmail(principal.getEmailAddress());
+ toReturn.setAccountId(principal.getGuid());
+ toReturn.setAccountName(principal.getName());
+ toReturn.setAccountUsername(principal.getUserName());
+
+ toReturn.setIssuedAt(OAuthUtils.getIssuedAt());
+ toReturn.setExpiresIn(getSessionTokenExpiration());
+
+ String token = serializer.encryptSessionToken(toReturn, getSecretKey());
+ toReturn.setSubjectToken(token);
+ return toReturn;
+ }
+
@Override
public UserSubject createSubject(String username, String password) {
OseePrincipal principal = authenticate(OAuthConstants.BASIC_SCHEME, username, password);
@@ -180,14 +286,6 @@ public class SubjectProviderImpl implements SubjectProvider {
}
}
- long subjectId2 = getSubjectId(subject);
- if (subjectId2 != subjectId) {
- if (sessionDelegate != null) {
- OseePrincipal principal = sessionDelegate.getSubjectById(subjectId);
- subject = OAuthUtil.newUserSubject(principal);
- }
- }
return subject;
}
-
} \ No newline at end of file
diff --git a/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/security/oauth2/provider/endpoints/ImplicitGrantEndpoint.java b/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/security/oauth2/provider/endpoints/ImplicitGrantEndpoint.java
index 40e0cdcce0b..7b5a09ef0bc 100644
--- a/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/security/oauth2/provider/endpoints/ImplicitGrantEndpoint.java
+++ b/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/security/oauth2/provider/endpoints/ImplicitGrantEndpoint.java
@@ -64,6 +64,30 @@ public class ImplicitGrantEndpoint extends ImplicitGrantService {
return response;
}
+ @Override
+ protected Response createErrorResponse(MultivaluedMap<String, String> params, String redirectUri, String error) {
+ Response response = super.createErrorResponse(params, redirectUri, error);
+
+ String forwardedServer = OAuthUtil.getForwarderServer();
+
+ if (Strings.isValid(forwardedServer)) {
+ URI location = response.getLocation();
+ String scheme = location.getScheme();
+
+ URI finalUri = UriBuilder//
+ .fromPath(forwardedServer)//
+ .scheme(scheme)//
+ .path(location.getRawPath())//
+ .replaceQuery(location.getRawQuery())//
+ .fragment(location.getRawFragment())//
+ .buildFromEncoded();
+
+ response = Response.seeOther(finalUri).build();
+ }
+
+ return response;
+ }
+
/**
* If a client does not include a redirect_uri parameter but has an exactly one pre-registered redirect_uri then use
* that redirect_uri
@@ -82,14 +106,46 @@ public class ImplicitGrantEndpoint extends ImplicitGrantService {
@Override
protected OAuthAuthorizationData createAuthorizationData(Client client, MultivaluedMap<String, String> params, UserSubject subject, String redirectUri, List<OAuthPermission> perms) {
OAuthAuthorizationData secData = super.createAuthorizationData(client, params, subject, redirectUri, perms);
+
+ String oldReplyTo = secData.getReplyTo();
+ URI replyToUri = UriBuilder.fromPath(oldReplyTo).buildFromEncoded();
+
+ String forwardedServer = OAuthUtil.getForwarderServer();
+
+ if (Strings.isValid(forwardedServer)) {
+ String scheme = replyToUri.getScheme();
+
+ URI newReplyTo = UriBuilder//
+ .fromPath(forwardedServer)//
+ .scheme(scheme)//
+ .path(replyToUri.getRawPath())//
+ .replaceQuery(replyToUri.getRawQuery())//
+ .fragment(replyToUri.getRawFragment())//
+ .buildFromEncoded();
+
+ secData.setReplyTo(newReplyTo.toString());
+ }
+
secData.setApplicationName(client.getApplicationName());
secData.setApplicationCertificates(client.getApplicationCertificates());
UriInfo uriInfo = getMessageContext().getUriInfo();
URI clientLogoUri = clientLogoUriResolver.getClientLogoUri(uriInfo, client);
- String applicationLogoUri = clientLogoUri.toASCIIString();
- secData.setApplicationLogoUri(applicationLogoUri);
+ if (Strings.isValid(forwardedServer)) {
+ String scheme = clientLogoUri.getScheme();
+
+ URI newClientLogoUri = UriBuilder//
+ .fromPath(forwardedServer)//
+ .scheme(scheme)//
+ .path(clientLogoUri.getRawPath())//
+ .replaceQuery(clientLogoUri.getRawQuery())//
+ .fragment(clientLogoUri.getRawFragment())//
+ .buildFromEncoded();
+
+ secData.setApplicationLogoUri(newClientLogoUri.toString());
+ }
+
return secData;
}
diff --git a/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/security/JaxRsSessionProvider.java b/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/security/JaxRsSessionProvider.java
index 09c49771759..4de3e0be594 100644
--- a/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/security/JaxRsSessionProvider.java
+++ b/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/security/JaxRsSessionProvider.java
@@ -10,18 +10,28 @@
*******************************************************************************/
package org.eclipse.osee.jaxrs.server.security;
+import javax.servlet.http.HttpSession;
import org.eclipse.osee.framework.jdk.core.type.OseePrincipal;
+import org.eclipse.osee.jaxrs.server.session.SessionData;
/**
* @author Roberto E. Escobar
*/
public interface JaxRsSessionProvider {
- String createSessionToken(Long subjectId);
+ String createAuthenticitySessionToken(Long subjectId);
- String removeSessionToken(Long subjectId);
+ void storeSession(SessionData session);
- String getSessionToken(Long subjectId);
+ String removeSessionAuthenticityToken(Long subjectId);
+
+ String getSessionAuthenticityToken(Long subjectId);
+
+ SessionData getSession(String sessionId);
+
+ SessionData removeSession(String sessionId);
+
+ HttpSession getSession();
OseePrincipal getSubjectById(Long subjectId);
diff --git a/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/session/AuthenticitySessionStorage.java b/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/session/AuthenticitySessionStorage.java
new file mode 100644
index 00000000000..efdc2585224
--- /dev/null
+++ b/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/session/AuthenticitySessionStorage.java
@@ -0,0 +1,71 @@
+/*******************************************************************************
+ * Copyright (c) 2015 Boeing.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Boeing - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.osee.jaxrs.server.session;
+
+import org.eclipse.osee.jaxrs.server.database.AbstractDatabaseStorage;
+import org.eclipse.osee.jdbc.JdbcClient;
+import org.eclipse.osee.jdbc.JdbcStatement;
+import org.eclipse.osee.logger.Log;
+
+/**
+ * @author Angel Avila
+ */
+public class AuthenticitySessionStorage extends AbstractDatabaseStorage<AuthenticityToken> {
+ private static final String INSERT_AUTHENTICITY =
+ "INSERT INTO osee_oauth_authenticity_token (subject_id, token) VALUES (?,?)";
+
+ private static final String SELECT_AUTHENTICTY_BY_ID =
+ "select * from osee_oauth_authenticity_token where subject_id = ?";
+
+ private static final String DELETE_TOKEN_BY_ID = "DELETE FROM osee_oauth_authenticity_token WHERE subject_id = ?";
+
+ public AuthenticitySessionStorage(Log logger, JdbcClient jdbcClient) {
+ super(logger, jdbcClient);
+ }
+
+ public void insertAuthenticityTokens(AuthenticityToken... sessions) {
+ insertItems(INSERT_AUTHENTICITY, sessions);
+ }
+
+ public AuthenticityToken getSession(Long subjectId) {
+ return selectOneOrNull(SELECT_AUTHENTICTY_BY_ID, subjectId);
+ }
+
+ @Override
+ protected Object[] asInsert(AuthenticityToken data) {
+ return new Object[] {data.getSubjectId(), data.getToken()};
+ }
+
+ @Override
+ protected Object[] asUpdate(AuthenticityToken data) {
+ return null;
+ }
+
+ public void removeAuthenticitySessionTokens(Iterable<AuthenticityToken> datas) {
+ deleteItems(DELETE_TOKEN_BY_ID, datas);
+ }
+
+ @Override
+ protected Object[] asDelete(AuthenticityToken data) {
+ return new Object[] {data.getSubjectId()};
+ }
+
+ @Override
+ protected AuthenticityToken readData(JdbcStatement chStmt) {
+ final Long subjectId = chStmt.getLong("subject_id");
+ final String token = chStmt.getString("token");
+
+ AuthenticityToken authenticityToken = new AuthenticityToken();
+ authenticityToken.setSubjectId(subjectId);
+ authenticityToken.setToken(token);
+ return authenticityToken;
+ }
+}
diff --git a/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/session/AuthenticityToken.java b/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/session/AuthenticityToken.java
new file mode 100644
index 00000000000..c8841518e91
--- /dev/null
+++ b/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/session/AuthenticityToken.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * Copyright (c) 2015 Boeing.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Boeing - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.osee.jaxrs.server.session;
+
+/**
+ * @author Angel Avila
+ */
+public class AuthenticityToken {
+
+ private Long subjectId;
+ private String token;
+
+ public AuthenticityToken() {
+ }
+
+ public Long getSubjectId() {
+ return subjectId;
+ }
+
+ public String getToken() {
+ return token;
+ }
+
+ public void setSubjectId(Long subjectId) {
+ this.subjectId = subjectId;
+ }
+
+ public void setToken(String token) {
+ this.token = token;
+ }
+}
diff --git a/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/session/JaxRsSessionProviderImpl.java b/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/session/JaxRsSessionProviderImpl.java
new file mode 100644
index 00000000000..e616ea42216
--- /dev/null
+++ b/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/session/JaxRsSessionProviderImpl.java
@@ -0,0 +1,116 @@
+/*******************************************************************************
+ * Copyright (c) 2015 Boeing.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Boeing - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.osee.jaxrs.server.session;
+
+import java.util.Collections;
+import java.util.UUID;
+import javax.servlet.http.HttpSession;
+import org.eclipse.osee.framework.jdk.core.type.OseePrincipal;
+import org.eclipse.osee.framework.jdk.core.util.Strings;
+import org.eclipse.osee.jaxrs.server.security.JaxRsSessionProvider;
+import org.eclipse.osee.jdbc.JdbcClient;
+import org.eclipse.osee.jdbc.JdbcService;
+import org.eclipse.osee.logger.Log;
+
+/**
+ * @author Angel Avila
+ */
+public class JaxRsSessionProviderImpl implements JaxRsSessionProvider {
+
+ private AuthenticitySessionStorage authenticitySessionStorage;
+ private SessionStorage sessionStorage;
+ private Log logger;
+ private JdbcClient jdbcClient;
+
+ public JaxRsSessionProviderImpl() {
+
+ }
+
+ public void setLogger(Log logger) {
+ this.logger = logger;
+ }
+
+ public void setJdbcService(JdbcService jdbcService) {
+ JdbcClient jdbcClient = jdbcService.getClient();
+ this.jdbcClient = jdbcClient;
+ }
+
+ public void start() {
+ authenticitySessionStorage = new AuthenticitySessionStorage(logger, jdbcClient);
+ sessionStorage = new SessionStorage(logger, jdbcClient);
+ }
+
+ @Override
+ public String createAuthenticitySessionToken(Long subjectId) {
+ String token = getSessionAuthenticityToken(subjectId);
+
+ if (Strings.isValid(token)) {
+ authenticitySessionStorage.removeAuthenticitySessionTokens(
+ Collections.singletonList(authenticitySessionStorage.getSession(subjectId)));
+ }
+
+ AuthenticityToken authenticityToken = new AuthenticityToken();
+ token = UUID.randomUUID().toString();
+ authenticityToken.setSubjectId(subjectId);
+ authenticityToken.setToken(token);
+ authenticitySessionStorage.insertAuthenticityTokens(authenticityToken);
+
+ return token;
+ }
+
+ @Override
+ public String removeSessionAuthenticityToken(Long subjectId) {
+ String toReturn = "";
+
+ AuthenticityToken authenticityToken = authenticitySessionStorage.getSession(subjectId);
+ if (authenticityToken != null) {
+ authenticitySessionStorage.removeAuthenticitySessionTokens(Collections.singletonList(authenticityToken));
+ toReturn = authenticityToken.getToken();
+ }
+ return toReturn;
+ }
+
+ @Override
+ public String getSessionAuthenticityToken(Long subjectId) {
+ AuthenticityToken authenticityToken = authenticitySessionStorage.getSession(subjectId);
+ return authenticityToken == null ? "" : authenticityToken.getToken();
+ }
+
+ @Override
+ public OseePrincipal getSubjectById(Long subjectId) {
+ return null;
+ }
+
+ @Override
+ public HttpSession getSession() {
+ return null;
+ }
+
+ @Override
+ public void storeSession(SessionData session) {
+ sessionStorage.insertSessions(session);
+ }
+
+ @Override
+ public SessionData getSession(String sessionId) {
+ return sessionStorage.getSession(sessionId);
+ }
+
+ @Override
+ public SessionData removeSession(String sessionId) {
+ SessionData session = sessionStorage.getSession(sessionId);
+ if (session != null) {
+ sessionStorage.deleteSessioin(Collections.singletonList(session));
+ }
+ return session;
+ }
+
+}
diff --git a/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/session/SessionData.java b/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/session/SessionData.java
new file mode 100644
index 00000000000..0b6a83f205a
--- /dev/null
+++ b/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/session/SessionData.java
@@ -0,0 +1,116 @@
+/*******************************************************************************
+ * Copyright (c) 2015 Boeing.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Boeing - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.osee.jaxrs.server.session;
+
+import org.apache.cxf.rs.security.oauth2.common.UserSubject;
+import org.eclipse.osee.framework.jdk.core.type.BaseIdentity;
+
+/**
+ * @author Angel Avila
+ */
+public class SessionData extends BaseIdentity<String> {
+
+ private UserSubject subject;
+ private Long issuedAt;
+ private Long expiresIn;
+ private String subjectToken;
+ private String accountName;
+ private String accountUsername;
+ private Long accountId;
+ private String accountDisplayName;
+ private String accountEmail;
+ private boolean accountActive;
+
+ public SessionData(String id) {
+ super(id);
+ }
+
+ public UserSubject getSubject() {
+ return subject;
+ }
+
+ public Long getIssuedAt() {
+ return issuedAt;
+ }
+
+ public Long getExpiresIn() {
+ return expiresIn;
+ }
+
+ public String getSubjectToken() {
+ return subjectToken;
+ }
+
+ public String getAccountName() {
+ return accountName;
+ }
+
+ public String getAccountUsername() {
+ return accountUsername;
+ }
+
+ public Long getAccountId() {
+ return accountId;
+ }
+
+ public String getAccountDisplayName() {
+ return accountDisplayName;
+ }
+
+ public String getAccountEmail() {
+ return accountEmail;
+ }
+
+ public boolean getAccountActive() {
+ return accountActive;
+ }
+
+ public void setSubject(UserSubject subject) {
+ this.subject = subject;
+ }
+
+ public void setIssuedAt(Long issuedAt) {
+ this.issuedAt = issuedAt;
+ }
+
+ public void setExpiresIn(Long expiresIn) {
+ this.expiresIn = expiresIn;
+ }
+
+ public void setSubjectToken(String subjectToken) {
+ this.subjectToken = subjectToken;
+ }
+
+ public void setAccountName(String accountName) {
+ this.accountName = accountName;
+ }
+
+ public void setAccountUsername(String accountUsername) {
+ this.accountUsername = accountUsername;
+ }
+
+ public void setAccountId(Long accountId) {
+ this.accountId = accountId;
+ }
+
+ public void setAccountDisplayName(String accountDisplayName) {
+ this.accountDisplayName = accountDisplayName;
+ }
+
+ public void setAccountEmail(String accountEmail) {
+ this.accountEmail = accountEmail;
+ }
+
+ public void setAccountActive(boolean accountActive) {
+ this.accountActive = accountActive;
+ }
+
+}
diff --git a/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/session/SessionStorage.java b/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/session/SessionStorage.java
new file mode 100644
index 00000000000..303f0caa596
--- /dev/null
+++ b/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/session/SessionStorage.java
@@ -0,0 +1,75 @@
+/*******************************************************************************
+ * Copyright (c) 2015 Boeing.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Boeing - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.osee.jaxrs.server.session;
+
+import org.eclipse.osee.jaxrs.server.database.AbstractDatabaseStorage;
+import org.eclipse.osee.jdbc.JdbcClient;
+import org.eclipse.osee.jdbc.JdbcStatement;
+import org.eclipse.osee.logger.Log;
+
+/**
+ * @author Angel Avila
+ */
+public class SessionStorage extends AbstractDatabaseStorage<SessionData> {
+
+ private static final String INSERT_SESSION =
+ "INSERT INTO osee_oauth_session (session_id, issued_at, expires_in, subject_token) VALUES (?,?,?,?)";
+
+ private static final String SELECT_SESSION_BY_ID = "select * from osee_oauth_session where session_id = ?";
+
+ private static final String DELETE_SESSION_BY_ID = "DELETE FROM osee_oauth_session WHERE session_id = ?";
+
+ public SessionStorage(Log logger, JdbcClient jdbcClient) {
+ super(logger, jdbcClient);
+ }
+
+ @Override
+ protected Object[] asInsert(SessionData session) {
+ return new Object[] {session.getGuid(), session.getIssuedAt(), session.getExpiresIn(), session.getSubjectToken()};
+ }
+
+ @Override
+ protected Object[] asUpdate(SessionData item) {
+ return null;
+ }
+
+ @Override
+ protected Object[] asDelete(SessionData item) {
+ return new Object[] {item.getGuid()};
+ }
+
+ public void insertSessions(SessionData... sessions) {
+ insertItems(INSERT_SESSION, sessions);
+ }
+
+ public SessionData getSession(String sessionId) {
+ return selectOneOrNull(SELECT_SESSION_BY_ID, sessionId);
+ }
+
+ public void deleteSessioin(Iterable<SessionData> datas) {
+ deleteItems(DELETE_SESSION_BY_ID, datas);
+ }
+
+ @Override
+ protected SessionData readData(JdbcStatement chStmt) {
+ final String sessionId = chStmt.getString("session_id");
+ final Long issuedAt = chStmt.getLong("issued_at");
+ final Long expiresIn = chStmt.getLong("expires_in");
+ final String subjectToken = chStmt.getString("subject_token");
+
+ SessionData sessionData = new SessionData(sessionId);
+ sessionData.setIssuedAt(issuedAt);
+ sessionData.setExpiresIn(expiresIn);
+ sessionData.setSubjectToken(subjectToken);
+
+ return sessionData;
+ }
+}

Back to the top