You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tomee.apache.org by ra...@apache.org on 2019/01/09 17:26:22 UTC
[tomee] 34/48: TOMEE-2365 - Perform authentication on the second
step of the form.
This is an automated email from the ASF dual-hosted git repository.
radcortez pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/tomee.git
commit c5c8a3e78ffd64edbd721223cc250b46fd6e1b6f
Author: Roberto Cortez <ra...@yahoo.com>
AuthorDate: Fri Dec 28 13:10:59 2018 +0000
TOMEE-2365 - Perform authentication on the second step of the form.
---
.../security/cdi/LoginToContinueInterceptor.java | 41 ++++-
.../security/http/LoginToContinueMechanism.java | 48 +++++-
.../tomee/security/http/SavedAuthentication.java | 41 +++++
.../apache/tomee/security/http/SavedRequest.java | 178 +++++++++++++++++++++
.../security/http/TomEEHttpMessageContext.java | 12 +-
5 files changed, 311 insertions(+), 9 deletions(-)
diff --git a/tomee/tomee-security/src/main/java/org/apache/tomee/security/cdi/LoginToContinueInterceptor.java b/tomee/tomee-security/src/main/java/org/apache/tomee/security/cdi/LoginToContinueInterceptor.java
index 1895689..1e0b0f3 100644
--- a/tomee/tomee-security/src/main/java/org/apache/tomee/security/cdi/LoginToContinueInterceptor.java
+++ b/tomee/tomee-security/src/main/java/org/apache/tomee/security/cdi/LoginToContinueInterceptor.java
@@ -17,6 +17,7 @@
package org.apache.tomee.security.cdi;
import org.apache.tomee.security.http.LoginToContinueMechanism;
+import org.apache.tomee.security.http.SavedRequest;
import javax.annotation.Priority;
import javax.interceptor.AroundInvoke;
@@ -30,7 +31,13 @@ import javax.servlet.http.HttpServletResponse;
import java.util.Arrays;
import static javax.interceptor.Interceptor.Priority.PLATFORM_BEFORE;
-import static org.apache.tomee.security.http.LoginToContinueMechanism.isOriginalRequestInSession;
+import static javax.security.enterprise.AuthenticationStatus.SEND_FAILURE;
+import static javax.security.enterprise.AuthenticationStatus.SUCCESS;
+import static org.apache.tomee.security.http.LoginToContinueMechanism.getRequest;
+import static org.apache.tomee.security.http.LoginToContinueMechanism.hasAuthentication;
+import static org.apache.tomee.security.http.LoginToContinueMechanism.hasRequest;
+import static org.apache.tomee.security.http.LoginToContinueMechanism.matchRequest;
+import static org.apache.tomee.security.http.LoginToContinueMechanism.saveAuthentication;
import static org.apache.tomee.security.http.LoginToContinueMechanism.saveRequest;
@LoginToContinue
@@ -90,7 +97,33 @@ public class LoginToContinueInterceptor {
}
if (isOnLoginPostback(httpMessageContext)) {
- return null;
+ final AuthenticationStatus authenticationStatus = (AuthenticationStatus) invocationContext.proceed();
+
+ if (authenticationStatus.equals(SUCCESS)) {
+ if (httpMessageContext.getCallerPrincipal() == null) {
+ return SUCCESS;
+ }
+
+ if (matchRequest(httpMessageContext.getRequest())) {
+ return SUCCESS;
+ }
+
+ saveAuthentication(httpMessageContext.getRequest(),
+ httpMessageContext.getCallerPrincipal(),
+ httpMessageContext.getGroups());
+
+ final SavedRequest savedRequest = getRequest(httpMessageContext.getRequest());
+ return httpMessageContext.redirect(savedRequest.getRequestURLWithQueryString());
+ }
+
+ if (authenticationStatus.equals(SEND_FAILURE)) {
+ final LoginToContinue loginToContinue = getLoginToContinue(invocationContext);
+ if (!loginToContinue.errorPage().isEmpty()) {
+ return httpMessageContext.forward(loginToContinue.errorPage());
+ }
+
+ return authenticationStatus;
+ }
}
if (isOnOriginalURLAfterAuthenticate(httpMessageContext)) {
@@ -101,11 +134,11 @@ public class LoginToContinueInterceptor {
}
private boolean isOnInitialProtectedURL(final HttpMessageContext httpMessageContext) {
- return httpMessageContext.isProtected() && !isOriginalRequestInSession(httpMessageContext.getRequest());
+ return httpMessageContext.isProtected() && !hasRequest(httpMessageContext.getRequest());
}
private boolean isOnLoginPostback(final HttpMessageContext httpMessageContext) {
- return false;
+ return hasRequest(httpMessageContext.getRequest()) && !hasAuthentication(httpMessageContext.getRequest());
}
private boolean isOnOriginalURLAfterAuthenticate(final HttpMessageContext httpMessageContext) {
diff --git a/tomee/tomee-security/src/main/java/org/apache/tomee/security/http/LoginToContinueMechanism.java b/tomee/tomee-security/src/main/java/org/apache/tomee/security/http/LoginToContinueMechanism.java
index 482bae6..e67b4b4 100644
--- a/tomee/tomee-security/src/main/java/org/apache/tomee/security/http/LoginToContinueMechanism.java
+++ b/tomee/tomee-security/src/main/java/org/apache/tomee/security/http/LoginToContinueMechanism.java
@@ -16,21 +16,24 @@
*/
package org.apache.tomee.security.http;
-import org.apache.catalina.authenticator.SavedRequest;
import org.apache.tomcat.util.buf.ByteChunk;
import javax.security.enterprise.authentication.mechanism.http.LoginToContinue;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.InputStream;
+import java.security.Principal;
import java.util.Enumeration;
import java.util.Locale;
+import java.util.Set;
public interface LoginToContinueMechanism {
int MAX_SAVE_POST_SIZE = 4 * 1024;
String ORIGINAL_REQUEST = "org.apache.tomee.security.request.original";
+ String AUTHENTICATION = "org.apache.tomee.security.request.authentication";
LoginToContinue getLoginToContinue();
@@ -80,12 +83,53 @@ public interface LoginToContinueMechanism {
saved.setMethod(request.getMethod());
saved.setQueryString(request.getQueryString());
saved.setRequestURI(request.getRequestURI());
+ saved.setRequestURL(request.getRequestURL().toString());
// Stash the SavedRequest in our session for later use
request.getSession().setAttribute(ORIGINAL_REQUEST, saved);
}
- static boolean isOriginalRequestInSession(final HttpServletRequest request) {
+ static boolean matchRequest(final HttpServletRequest request) {
+ // Has a session been created?
+ final HttpSession session = request.getSession(false);
+ if (session == null) {
+ return false;
+ }
+
+ // Is there a saved request?
+ final SavedRequest originalRequest = (SavedRequest) request.getSession().getAttribute(ORIGINAL_REQUEST);
+ if (originalRequest == null) {
+ return false;
+ }
+
+ // Is there a saved principal?
+ /*
+ if (session.getNote(Constants.FORM_PRINCIPAL_NOTE) == null) {
+ return false;
+ }
+ */
+
+ // Does the request URI match?
+ final String requestURI = request.getRequestURI();
+ return requestURI != null && requestURI.equals(originalRequest.getRequestURI());
+ }
+
+ static boolean hasRequest(final HttpServletRequest request) {
return request.getSession().getAttribute(ORIGINAL_REQUEST) != null;
}
+
+ static SavedRequest getRequest(final HttpServletRequest request) {
+ return (SavedRequest) request.getSession().getAttribute(ORIGINAL_REQUEST);
+ }
+
+ static void saveAuthentication(final HttpServletRequest request,
+ final Principal principal,
+ final Set<String> groups) {
+ final SavedAuthentication savedAuthentication = new SavedAuthentication(principal, groups);
+ request.getSession().setAttribute(AUTHENTICATION, savedAuthentication);
+ }
+
+ static boolean hasAuthentication(final HttpServletRequest request) {
+ return request.getSession().getAttribute(AUTHENTICATION) != null;
+ }
}
diff --git a/tomee/tomee-security/src/main/java/org/apache/tomee/security/http/SavedAuthentication.java b/tomee/tomee-security/src/main/java/org/apache/tomee/security/http/SavedAuthentication.java
new file mode 100644
index 0000000..5c30353
--- /dev/null
+++ b/tomee/tomee-security/src/main/java/org/apache/tomee/security/http/SavedAuthentication.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tomee.security.http;
+
+
+import java.security.Principal;
+import java.util.Set;
+
+import static java.util.Collections.unmodifiableSet;
+
+public final class SavedAuthentication {
+ private final Principal principal;
+ private final Set<String> groups;
+
+ SavedAuthentication(final Principal principal, final Set<String> groups) {
+ this.principal = principal;
+ this.groups = unmodifiableSet(groups);
+ }
+
+ public Principal getPrincipal() {
+ return principal;
+ }
+
+ public Set<String> getGroups() {
+ return groups;
+ }
+}
diff --git a/tomee/tomee-security/src/main/java/org/apache/tomee/security/http/SavedRequest.java b/tomee/tomee-security/src/main/java/org/apache/tomee/security/http/SavedRequest.java
new file mode 100644
index 0000000..ca49c53
--- /dev/null
+++ b/tomee/tomee-security/src/main/java/org/apache/tomee/security/http/SavedRequest.java
@@ -0,0 +1,178 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tomee.security.http;
+
+import org.apache.tomcat.util.buf.ByteChunk;
+
+import javax.servlet.http.Cookie;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+
+/**
+ * Mostly copied from org.apache.catalina.authenticator.SavedRequest.
+ */
+public final class SavedRequest {
+
+ SavedRequest() {
+ }
+
+ /**
+ * The set of Cookies associated with this Request.
+ */
+ private final List<Cookie> cookies = new ArrayList<>();
+
+ public void addCookie(Cookie cookie) {
+ cookies.add(cookie);
+ }
+
+ public Iterator<Cookie> getCookies() {
+ return cookies.iterator();
+ }
+
+
+ /**
+ * The set of Headers associated with this Request. Each key is a header
+ * name, while the value is a List containing one or more actual
+ * values for this header. The values are returned as an Iterator when
+ * you ask for them.
+ */
+ private final Map<String, List<String>> headers = new HashMap<>();
+
+ public void addHeader(String name, String value) {
+ List<String> values = headers.get(name);
+ if (values == null) {
+ values = new ArrayList<>();
+ headers.put(name, values);
+ }
+ values.add(value);
+ }
+
+ public Iterator<String> getHeaderNames() {
+ return headers.keySet().iterator();
+ }
+
+ public Iterator<String> getHeaderValues(String name) {
+ List<String> values = headers.get(name);
+ if (values == null) { return Collections.emptyIterator(); } else { return values.iterator(); }
+ }
+
+
+ /**
+ * The set of Locales associated with this Request.
+ */
+ private final List<Locale> locales = new ArrayList<>();
+
+ public void addLocale(Locale locale) {
+ locales.add(locale);
+ }
+
+ public Iterator<Locale> getLocales() {
+ return locales.iterator();
+ }
+
+
+ /**
+ * The request method used on this Request.
+ */
+ private String method = null;
+
+ public String getMethod() {
+ return this.method;
+ }
+
+ public void setMethod(String method) {
+ this.method = method;
+ }
+
+
+ /**
+ * The query string associated with this Request.
+ */
+ private String queryString = null;
+
+ public String getQueryString() {
+ return this.queryString;
+ }
+
+ public void setQueryString(String queryString) {
+ this.queryString = queryString;
+ }
+
+
+ /**
+ * The request URI associated with this Request. See javax.servlet.http.HttpServletRequest#getRequestURI().
+ */
+ private String requestURI = null;
+
+ public String getRequestURI() {
+ return this.requestURI;
+ }
+
+ public void setRequestURI(String requestURI) {
+ this.requestURI = requestURI;
+ }
+
+
+ /**
+ * The decode request URL associated with this Request. See javax.servlet.http.HttpServletRequest#getRequestURL().
+ */
+ private String requestURL = null;
+
+ public String getRequestURL() {
+ return this.requestURL;
+ }
+
+ public void setRequestURL(String requestURL) {
+ this.requestURL = requestURL;
+ }
+
+
+ /**
+ * The body of this request.
+ */
+ private ByteChunk body = null;
+
+ public ByteChunk getBody() {
+ return this.body;
+ }
+
+ public void setBody(ByteChunk body) {
+ this.body = body;
+ }
+
+ /**
+ * The content type of the request, used if this is a POST.
+ */
+ private String contentType = null;
+
+ public String getContentType() {
+ return this.contentType;
+ }
+
+ public void setContentType(String contentType) {
+ this.contentType = contentType;
+ }
+
+ public String getRequestURLWithQueryString() {
+ return queryString == null || queryString.isEmpty() ? requestURL : requestURL + "?" + queryString;
+ }
+}
diff --git a/tomee/tomee-security/src/main/java/org/apache/tomee/security/http/TomEEHttpMessageContext.java b/tomee/tomee-security/src/main/java/org/apache/tomee/security/http/TomEEHttpMessageContext.java
index 4c087da..d67d74d 100644
--- a/tomee/tomee-security/src/main/java/org/apache/tomee/security/http/TomEEHttpMessageContext.java
+++ b/tomee/tomee-security/src/main/java/org/apache/tomee/security/http/TomEEHttpMessageContext.java
@@ -50,6 +50,9 @@ public class TomEEHttpMessageContext implements HttpMessageContext {
private final Subject clientSubject;
private final Subject serviceSubject;
+ private Principal principal;
+ private Set<String> groups;
+
private TomEEHttpMessageContext(
final CallbackHandler handler,
final MessageInfo messageInfo,
@@ -190,10 +193,13 @@ public class TomEEHttpMessageContext implements HttpMessageContext {
new CallerPrincipalCallback(clientSubject, principal),
new GroupPrincipalCallback(clientSubject, groups.toArray(new String[groups.size()]))
});
- } catch (IOException | UnsupportedCallbackException e) {
+ } catch (final IOException | UnsupportedCallbackException e) {
e.printStackTrace();
}
+ this.principal = principal;
+ this.groups = groups;
+
return SUCCESS;
}
@@ -213,11 +219,11 @@ public class TomEEHttpMessageContext implements HttpMessageContext {
@Override
public Principal getCallerPrincipal() {
- return null;
+ return principal;
}
@Override
public Set<String> getGroups() {
- return null;
+ return groups;
}
}