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;
     }
 }