Merge pull request #23867 from dmatej/grizzly4

Using grizzly 4.0.0-M1 instead of a snapshot
diff --git a/appserver/security/core-ee/src/main/java/com/sun/enterprise/security/jmac/callback/BaseContainerCallbackHandler.java b/appserver/security/core-ee/src/main/java/com/sun/enterprise/security/jmac/callback/BaseContainerCallbackHandler.java
index e0dd7a9..8366c1e 100644
--- a/appserver/security/core-ee/src/main/java/com/sun/enterprise/security/jmac/callback/BaseContainerCallbackHandler.java
+++ b/appserver/security/core-ee/src/main/java/com/sun/enterprise/security/jmac/callback/BaseContainerCallbackHandler.java
@@ -1,6 +1,6 @@
 /*
+ * Copyright (c) 2021, 2022 Contributors to the Eclipse Foundation
  * Copyright (c) 1997, 2020 Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2021 Contributors to the Eclipse Foundation
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -307,6 +307,19 @@
         final Subject fs = cpCallback.getSubject();
         Principal principal = cpCallback.getPrincipal();
 
+        // See if we need to wrap back the principal. This looks weird, but is needed for the
+        // check to re-use that is done below to work.
+        if (principal != null && !(principal instanceof WebPrincipal)) {
+            Principal sessionPrincipal = SecurityContext.getCurrent().getSessionPrincipal();
+            if (sessionPrincipal instanceof WebPrincipal) {
+                WebPrincipal webPrincipalFromSession = (WebPrincipal) sessionPrincipal;
+
+                if (webPrincipalFromSession.getCustomPrincipal() == principal) {
+                    principal = webPrincipalFromSession;
+                }
+            }
+        }
+
         if (principal instanceof WebPrincipal) {
             WebPrincipal wp = (WebPrincipal) principal;
             /**
diff --git a/appserver/security/core-ee/src/main/java/com/sun/enterprise/security/web/integration/WebPrincipal.java b/appserver/security/core-ee/src/main/java/com/sun/enterprise/security/web/integration/WebPrincipal.java
index 5c794a9..c3536ae 100644
--- a/appserver/security/core-ee/src/main/java/com/sun/enterprise/security/web/integration/WebPrincipal.java
+++ b/appserver/security/core-ee/src/main/java/com/sun/enterprise/security/web/integration/WebPrincipal.java
@@ -1,4 +1,5 @@
 /*
+ * Copyright (c) 2022, 2022 Contributors to the Eclipse Foundation
  * Copyright (c) 1997, 2021 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
@@ -84,6 +85,10 @@
         return securityContext;
     }
 
+    public Principal getCustomPrincipal() {
+        return customPrincipal;
+    }
+
     @Override
     public String getName() {
         if (customPrincipal == null) {
diff --git a/appserver/security/webintegration/src/main/java/com/sun/web/security/RealmAdapter.java b/appserver/security/webintegration/src/main/java/com/sun/web/security/RealmAdapter.java
index a56dc13..aa035a2 100644
--- a/appserver/security/webintegration/src/main/java/com/sun/web/security/RealmAdapter.java
+++ b/appserver/security/webintegration/src/main/java/com/sun/web/security/RealmAdapter.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2021 Contributors to the Eclipse Foundation.
+ * Copyright 2021, 2022 Contributors to the Eclipse Foundation.
  * Copyright (c) 1997, 2020 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
@@ -80,6 +80,7 @@
 import org.apache.catalina.HttpResponse;
 import org.apache.catalina.LifecycleException;
 import org.apache.catalina.authenticator.AuthenticatorBase;
+import org.apache.catalina.connector.RequestFacade;
 import org.apache.catalina.deploy.LoginConfig;
 import org.apache.catalina.deploy.SecurityConstraint;
 import org.apache.catalina.realm.Constants;
@@ -479,8 +480,11 @@
             // Jakarta Authentication is enabled for this application
             try {
                 context.fireContainerEvent(BEFORE_AUTHENTICATION, null);
+                RequestFacade requestFacade = (RequestFacade) request.getRequest();
+                SecurityContext.getCurrent().setSessionPrincipal(requestFacade.getRequestPrincipal());
                 return validate(request, response, config, authenticator, calledFromAuthenticate);
             } finally {
+                SecurityContext.getCurrent().setSessionPrincipal(null);
                 context.fireContainerEvent(AFTER_AUTHENTICATION, null);
             }
         }
diff --git a/appserver/web/web-core/src/main/java/org/apache/catalina/connector/RequestFacade.java b/appserver/web/web-core/src/main/java/org/apache/catalina/connector/RequestFacade.java
index 57a2a19..11533ba 100644
--- a/appserver/web/web-core/src/main/java/org/apache/catalina/connector/RequestFacade.java
+++ b/appserver/web/web-core/src/main/java/org/apache/catalina/connector/RequestFacade.java
@@ -1,5 +1,6 @@
 /*
- * Copyright (c) 1997-2018 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2022, 2022 Contributors to the Eclipse Foundation
+ * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
  * Copyright 2004 The Apache Software Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -17,27 +18,43 @@
 
 package org.apache.catalina.connector;
 
-import org.apache.catalina.LogFacade;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.security.AccessControlException;
+import java.security.AccessController;
+import java.security.Principal;
+import java.security.PrivilegedAction;
+import java.security.SecurityPermission;
+import java.util.Collection;
+import java.util.Enumeration;
+import java.util.Locale;
+import java.util.Map;
+import java.util.ResourceBundle;
+
 import org.apache.catalina.Globals;
+import org.apache.catalina.LogFacade;
 import org.apache.catalina.core.RequestFacadeHelper;
 import org.apache.catalina.security.SecurityUtil;
 
-import jakarta.servlet.*;
+import com.sun.enterprise.security.web.integration.WebPrincipal;
+
+import jakarta.servlet.AsyncContext;
+import jakarta.servlet.DispatcherType;
+import jakarta.servlet.RequestDispatcher;
+import jakarta.servlet.ServletConnection;
+import jakarta.servlet.ServletContext;
+import jakarta.servlet.ServletException;
+import jakarta.servlet.ServletInputStream;
+import jakarta.servlet.ServletRequest;
+import jakarta.servlet.ServletResponse;
 import jakarta.servlet.http.Cookie;
+import jakarta.servlet.http.HttpServletMapping;
 import jakarta.servlet.http.HttpServletRequest;
 import jakarta.servlet.http.HttpServletResponse;
 import jakarta.servlet.http.HttpSession;
 import jakarta.servlet.http.HttpUpgradeHandler;
 import jakarta.servlet.http.Part;
 import jakarta.servlet.http.PushBuilder;
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.security.AccessControlException;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import java.security.SecurityPermission;
-import java.util.*;
-import jakarta.servlet.http.HttpServletMapping;
 
 
 /**
@@ -837,12 +854,30 @@
     }
 
     @Override
-    public java.security.Principal getUserPrincipal() {
+    public Principal getUserPrincipal() {
 
         if (request == null) {
             throw new IllegalStateException(rb.getString(LogFacade.CANNOT_USE_REQUEST_OBJECT_OUTSIDE_SCOPE_EXCEPTION));
         }
 
+        Principal principal = request.getUserPrincipal();
+        if (principal instanceof WebPrincipal) {
+            WebPrincipal webPrincipal = (WebPrincipal) principal;
+            if (webPrincipal.getCustomPrincipal() != null) {
+                principal = webPrincipal.getCustomPrincipal();
+            }
+        }
+
+        return principal;
+    }
+
+    // returns the original, unwrapped principal from the underlying request
+    public Principal getRequestPrincipal() {
+        if (request == null) {
+            throw new IllegalStateException(rb.getString(LogFacade.CANNOT_USE_REQUEST_OBJECT_OUTSIDE_SCOPE_EXCEPTION));
+        }
+
+
         return request.getUserPrincipal();
     }
 
diff --git a/nucleus/security/core/src/main/java/com/sun/enterprise/security/SecurityContext.java b/nucleus/security/core/src/main/java/com/sun/enterprise/security/SecurityContext.java
index 7f1789d..3770f04 100644
--- a/nucleus/security/core/src/main/java/com/sun/enterprise/security/SecurityContext.java
+++ b/nucleus/security/core/src/main/java/com/sun/enterprise/security/SecurityContext.java
@@ -1,4 +1,5 @@
 /*
+ * Copyright (c) 2022, 2022 Contributors to the Eclipse Foundation
  * Copyright (c) 1997, 2021 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
@@ -46,6 +47,9 @@
  *
  * This class is used on the server side to represent the security context.
  *
+ * Class is a concept introduced in JDK1.0.
+ * Thread is a concept introduced in JDK1.0.
+ * Principal is a concept introduced in JDK1.1.
  * Thread Local Storage is a concept introduced in JDK1.2.
  *
  * @see java.lang.ThreadLocal
@@ -71,6 +75,8 @@
     // Did the client log in as or did the server generate the context
     private boolean SERVER_GENERATED_SECURITY_CONTEXT = false;
 
+    private Principal sessionPrincipal;
+
     /* This creates a new SecurityContext object.
      * Note: that the docs for Subject state that the internal sets
      * (eg. the principal set) cannot be modified unless the caller
@@ -352,6 +358,14 @@
         return "SecurityContext[ " + "Initiator: " + initiator + "Subject " + subject + " ]";
     }
 
+    public Principal getSessionPrincipal() {
+        return sessionPrincipal;
+    }
+
+    public void setSessionPrincipal(Principal sessionPrincipal) {
+        this.sessionPrincipal = sessionPrincipal;
+    }
+
     public Set<Principal> getPrincipalSet() {
         return subject.getPrincipals();
     }