diff --git a/appserver/tests/appserv-tests/devtests/security/soteria/app-bundled-ham-basic-login-config-form/README.md b/appserver/tests/appserv-tests/devtests/security/soteria/app-bundled-ham-basic-login-config-form/README.md new file mode 100644 index 00000000000..4e9d394463d --- /dev/null +++ b/appserver/tests/appserv-tests/devtests/security/soteria/app-bundled-ham-basic-login-config-form/README.md @@ -0,0 +1,5 @@ +### app-bundled-ham-basic-login-config-form + +**If an application bundles its own `HttpAuthenticationMechanism`, then for authentication, the container will rely on the bundled mechanism and will ignore the `login-config` element in deployment descriptor of the application. + +In this sample app, the `BASIC` authentication mechanism defined in `HttpAuthenticationMechanism` takes precedencce over `FORM` authentication present in `login-config`. diff --git a/appserver/tests/appserv-tests/devtests/security/soteria/app-bundled-ham-basic-login-config-form/pom.xml b/appserver/tests/appserv-tests/devtests/security/soteria/app-bundled-ham-basic-login-config-form/pom.xml new file mode 100644 index 00000000000..559aa2f2031 --- /dev/null +++ b/appserver/tests/appserv-tests/devtests/security/soteria/app-bundled-ham-basic-login-config-form/pom.xml @@ -0,0 +1,71 @@ + + + + 4.0.0 + + org.glassfish.soteria.test + soteria + 5.0-SNAPSHOT + + + app-bundled-ham-basic-login-config-form + war + + + app-bundled-ham-basic-login-config-form + + + + false + + + + org.glassfish.soteria.test + common + 5.0-SNAPSHOT + test + + + + diff --git a/appserver/tests/appserv-tests/devtests/security/soteria/app-bundled-ham-basic-login-config-form/src/main/java/org/glassfish/soteria/test/BasicAuthenticationServlet.java b/appserver/tests/appserv-tests/devtests/security/soteria/app-bundled-ham-basic-login-config-form/src/main/java/org/glassfish/soteria/test/BasicAuthenticationServlet.java new file mode 100644 index 00000000000..f2254f4021e --- /dev/null +++ b/appserver/tests/appserv-tests/devtests/security/soteria/app-bundled-ham-basic-login-config-form/src/main/java/org/glassfish/soteria/test/BasicAuthenticationServlet.java @@ -0,0 +1,65 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) 2017 Oracle and/or its affiliates. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common Development + * and Distribution License("CDDL") (collectively, the "License"). You + * may not use this file except in compliance with the License. You can + * obtain a copy of the License at + * https://oss.oracle.com/licenses/CDDL+GPL-1.1 + * or LICENSE.txt. See the License for the specific + * language governing permissions and limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at LICENSE.txt. + * + * GPL Classpath Exception: + * Oracle designates this particular file as subject to the "Classpath" + * exception as provided by Oracle in the GPL Version 2 section of the License + * file that accompanied this code. + * + * Modifications: + * If applicable, add the following below the License Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyright [year] [name of copyright owner]" + * + * Contributor(s): + * If you wish your version of this file to be governed by only the CDDL or + * only the GPL Version 2, indicate your decision by adding "[Contributor] + * elects to include this software in this distribution under the [CDDL or GPL + * Version 2] license." If you don't indicate a single choice of license, a + * recipient has the option to distribute your version of this file under + * either the CDDL, the GPL Version 2 or to extend the choice of license to + * its licensees as provided above. However, if you add GPL Version 2 code + * and therefore, elected the GPL Version 2 license, then the option applies + * only if the new code is made subject to such option by the copyright + * holder. + */ + +package org.glassfish.soteria.test; + +import java.io.IOException; + +import javax.inject.Inject; +import javax.security.enterprise.SecurityContext; +import javax.servlet.ServletException; +import javax.servlet.annotation.HttpConstraint; +import javax.servlet.annotation.ServletSecurity; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +@WebServlet(urlPatterns = "/basicAuthenticationServlet") +@ServletSecurity(@HttpConstraint(rolesAllowed = "foo")) + +public class BasicAuthenticationServlet extends HttpServlet { + + @Override + public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + response.getWriter().write("Authentication Mechanism:" + response.getHeader("Authentication Mechanism") +"\n"); + + } +} diff --git a/appserver/tests/appserv-tests/devtests/security/soteria/app-bundled-ham-basic-login-config-form/src/main/java/org/glassfish/soteria/test/TestAuthenticationMechanism.java b/appserver/tests/appserv-tests/devtests/security/soteria/app-bundled-ham-basic-login-config-form/src/main/java/org/glassfish/soteria/test/TestAuthenticationMechanism.java new file mode 100644 index 00000000000..049255588c0 --- /dev/null +++ b/appserver/tests/appserv-tests/devtests/security/soteria/app-bundled-ham-basic-login-config-form/src/main/java/org/glassfish/soteria/test/TestAuthenticationMechanism.java @@ -0,0 +1,96 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) 2017 Oracle and/or its affiliates. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common Development + * and Distribution License("CDDL") (collectively, the "License"). You + * may not use this file except in compliance with the License. You can + * obtain a copy of the License at + * https://oss.oracle.com/licenses/CDDL+GPL-1.1 + * or LICENSE.txt. See the License for the specific + * language governing permissions and limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at LICENSE.txt. + * + * GPL Classpath Exception: + * Oracle designates this particular file as subject to the "Classpath" + * exception as provided by Oracle in the GPL Version 2 section of the License + * file that accompanied this code. + * + * Modifications: + * If applicable, add the following below the License Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyright [year] [name of copyright owner]" + * + * Contributor(s): + * If you wish your version of this file to be governed by only the CDDL or + * only the GPL Version 2, indicate your decision by adding "[Contributor] + * elects to include this software in this distribution under the [CDDL or GPL + * Version 2] license." If you don't indicate a single choice of license, a + * recipient has the option to distribute your version of this file under + * either the CDDL, the GPL Version 2 or to extend the choice of license to + * its licensees as provided above. However, if you add GPL Version 2 code + * and therefore, elected the GPL Version 2 license, then the option applies + * only if the new code is made subject to such option by the copyright + * holder. + */ + +package org.glassfish.soteria.test; + +import javax.enterprise.context.RequestScoped; +import javax.inject.Inject; +import javax.security.enterprise.AuthenticationException; +import javax.security.enterprise.AuthenticationStatus; +import javax.security.enterprise.authentication.mechanism.http.HttpAuthenticationMechanism; +import javax.security.enterprise.authentication.mechanism.http.HttpMessageContext; +import javax.security.enterprise.credential.UsernamePasswordCredential; +import javax.security.enterprise.identitystore.CredentialValidationResult; +import javax.security.enterprise.identitystore.IdentityStoreHandler; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import static javax.security.enterprise.identitystore.CredentialValidationResult.Status.VALID; + +@RequestScoped +public class TestAuthenticationMechanism implements HttpAuthenticationMechanism { + + @Inject + private IdentityStoreHandler identityStoreHandler; + + @Override + public AuthenticationStatus validateRequest(HttpServletRequest request, HttpServletResponse response, HttpMessageContext httpMessageContext) throws AuthenticationException { + + // Get the (caller) name and password from the request + // NOTE: This is for the smallest possible example only. In practice + // putting the password in a request query parameter is highly + // insecure + String name = request.getParameter("name"); + String password = request.getParameter("password"); + + if (name != null && password != null) { + + // Delegate the {credentials in -> identity data out} function to + // the Identity Store + CredentialValidationResult result = identityStoreHandler.validate( + new UsernamePasswordCredential(name, password)); + + if (result.getStatus() == VALID) { + // Communicate the details of the authenticated user to the + // container. In many cases the underlying handler will just store the details + // and the container will actually handle the login after we return from + // this method. + response.addHeader("Authentication Mechanism", "TestAuthenticationMechanism"); + return httpMessageContext.notifyContainerAboutLogin( + result.getCallerPrincipal(), result.getCallerGroups()); + } else { + return httpMessageContext.responseUnauthorized(); + } + } + + return httpMessageContext.doNothing(); + } + +} diff --git a/appserver/tests/appserv-tests/devtests/security/soteria/app-bundled-ham-basic-login-config-form/src/main/java/org/glassfish/soteria/test/TestIdentityStore.java b/appserver/tests/appserv-tests/devtests/security/soteria/app-bundled-ham-basic-login-config-form/src/main/java/org/glassfish/soteria/test/TestIdentityStore.java new file mode 100644 index 00000000000..906353b58cf --- /dev/null +++ b/appserver/tests/appserv-tests/devtests/security/soteria/app-bundled-ham-basic-login-config-form/src/main/java/org/glassfish/soteria/test/TestIdentityStore.java @@ -0,0 +1,65 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) 2017 Oracle and/or its affiliates. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common Development + * and Distribution License("CDDL") (collectively, the "License"). You + * may not use this file except in compliance with the License. You can + * obtain a copy of the License at + * https://oss.oracle.com/licenses/CDDL+GPL-1.1 + * or LICENSE.txt. See the License for the specific + * language governing permissions and limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at LICENSE.txt. + * + * GPL Classpath Exception: + * Oracle designates this particular file as subject to the "Classpath" + * exception as provided by Oracle in the GPL Version 2 section of the License + * file that accompanied this code. + * + * Modifications: + * If applicable, add the following below the License Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyright [year] [name of copyright owner]" + * + * Contributor(s): + * If you wish your version of this file to be governed by only the CDDL or + * only the GPL Version 2, indicate your decision by adding "[Contributor] + * elects to include this software in this distribution under the [CDDL or GPL + * Version 2] license." If you don't indicate a single choice of license, a + * recipient has the option to distribute your version of this file under + * either the CDDL, the GPL Version 2 or to extend the choice of license to + * its licensees as provided above. However, if you add GPL Version 2 code + * and therefore, elected the GPL Version 2 license, then the option applies + * only if the new code is made subject to such option by the copyright + * holder. + */ + +package org.glassfish.soteria.test; + +import static java.util.Arrays.asList; +import static javax.security.enterprise.identitystore.CredentialValidationResult.INVALID_RESULT; + +import java.util.HashSet; + +import javax.enterprise.context.RequestScoped; +import javax.security.enterprise.credential.UsernamePasswordCredential; +import javax.security.enterprise.identitystore.CredentialValidationResult; +import javax.security.enterprise.identitystore.IdentityStore; + +@RequestScoped +public class TestIdentityStore implements IdentityStore { + + public CredentialValidationResult validate(UsernamePasswordCredential usernamePasswordCredential) { + + if (usernamePasswordCredential.compareTo("reza", "secret1")) { + return new CredentialValidationResult("reza", new HashSet<>(asList("foo", "bar"))); + } + + return INVALID_RESULT; + } + +} diff --git a/appserver/tests/appserv-tests/devtests/security/soteria/app-bundled-ham-basic-login-config-form/src/main/webapp/WEB-INF/beans.xml b/appserver/tests/appserv-tests/devtests/security/soteria/app-bundled-ham-basic-login-config-form/src/main/webapp/WEB-INF/beans.xml new file mode 100644 index 00000000000..e69de29bb2d diff --git a/appserver/tests/appserv-tests/devtests/security/soteria/app-bundled-ham-basic-login-config-form/src/main/webapp/WEB-INF/web.xml b/appserver/tests/appserv-tests/devtests/security/soteria/app-bundled-ham-basic-login-config-form/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 00000000000..e73952ab90a --- /dev/null +++ b/appserver/tests/appserv-tests/devtests/security/soteria/app-bundled-ham-basic-login-config-form/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,117 @@ + + + + + + index + index + /index.jsp + + + + + FORM Based Authentication Servlet + / + + + foo + + + NONE + + + + + FORM + file + + /loginform.jsp + /loginerror.jsp + + + + + diff --git a/appserver/tests/appserv-tests/devtests/security/soteria/app-bundled-ham-basic-login-config-form/src/main/webapp/index.jsp b/appserver/tests/appserv-tests/devtests/security/soteria/app-bundled-ham-basic-login-config-form/src/main/webapp/index.jsp new file mode 100644 index 00000000000..0e9473b6caf --- /dev/null +++ b/appserver/tests/appserv-tests/devtests/security/soteria/app-bundled-ham-basic-login-config-form/src/main/webapp/index.jsp @@ -0,0 +1,57 @@ +<%-- + + DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + + Copyright (c) 2017 Oracle and/or its affiliates. All rights reserved. + + The contents of this file are subject to the terms of either the GNU + General Public License Version 2 only ("GPL") or the Common Development + and Distribution License("CDDL") (collectively, the "License"). You + may not use this file except in compliance with the License. You can + obtain a copy of the License at + https://oss.oracle.com/licenses/CDDL+GPL-1.1 + or LICENSE.txt. See the License for the specific + language governing permissions and limitations under the License. + + When distributing the software, include this License Header Notice in each + file and include the License file at LICENSE.txt. + + GPL Classpath Exception: + Oracle designates this particular file as subject to the "Classpath" + exception as provided by Oracle in the GPL Version 2 section of the License + file that accompanied this code. + + Modifications: + If applicable, add the following below the License Header, with the fields + enclosed by brackets [] replaced by your own identifying information: + "Portions Copyright [year] [name of copyright owner]" + + Contributor(s): + If you wish your version of this file to be governed by only the CDDL or + only the GPL Version 2, indicate your decision by adding "[Contributor] + elects to include this software in this distribution under the [CDDL or GPL + Version 2] license." If you don't indicate a single choice of license, a + recipient has the option to distribute your version of this file under + either the CDDL, the GPL Version 2 or to extend the choice of license to + its licensees as provided above. However, if you add GPL Version 2 code + and therefore, elected the GPL Version 2 license, then the option applies + only if the new code is made subject to such option by the copyright + holder. + +--%> + +<%@page contentType="text/html" pageEncoding="UTF-8"%> + + + + + + Form-based Security - Success + + +

Form-based Security - Success

+ + If you reached this page that means form-based security credentials are correctly configured. + + diff --git a/appserver/tests/appserv-tests/devtests/security/soteria/app-bundled-ham-basic-login-config-form/src/main/webapp/loginerror.jsp b/appserver/tests/appserv-tests/devtests/security/soteria/app-bundled-ham-basic-login-config-form/src/main/webapp/loginerror.jsp new file mode 100644 index 00000000000..2a6d9e91169 --- /dev/null +++ b/appserver/tests/appserv-tests/devtests/security/soteria/app-bundled-ham-basic-login-config-form/src/main/webapp/loginerror.jsp @@ -0,0 +1,62 @@ +<%-- + + DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + + Copyright (c) 2017 Oracle and/or its affiliates. All rights reserved. + + The contents of this file are subject to the terms of either the GNU + General Public License Version 2 only ("GPL") or the Common Development + and Distribution License("CDDL") (collectively, the "License"). You + may not use this file except in compliance with the License. You can + obtain a copy of the License at + https://oss.oracle.com/licenses/CDDL+GPL-1.1 + or LICENSE.txt. See the License for the specific + language governing permissions and limitations under the License. + + When distributing the software, include this License Header Notice in each + file and include the License file at LICENSE.txt. + + GPL Classpath Exception: + Oracle designates this particular file as subject to the "Classpath" + exception as provided by Oracle in the GPL Version 2 section of the License + file that accompanied this code. + + Modifications: + If applicable, add the following below the License Header, with the fields + enclosed by brackets [] replaced by your own identifying information: + "Portions Copyright [year] [name of copyright owner]" + + Contributor(s): + If you wish your version of this file to be governed by only the CDDL or + only the GPL Version 2, indicate your decision by adding "[Contributor] + elects to include this software in this distribution under the [CDDL or GPL + Version 2] license." If you don't indicate a single choice of license, a + recipient has the option to distribute your version of this file under + either the CDDL, the GPL Version 2 or to extend the choice of license to + its licensees as provided above. However, if you add GPL Version 2 code + and therefore, elected the GPL Version 2 license, then the option applies + only if the new code is made subject to such option by the copyright + holder. + +--%> + +<%@page contentType="text/html" pageEncoding="UTF-8"%> + + + + + + Form-Based Login Error Page + + +

Login Error Page

+ +

Invalid user name or password.

+ +

Please specify a valid user/password combination

+ + Click here to Try Again

+ + + diff --git a/appserver/tests/appserv-tests/devtests/security/soteria/app-bundled-ham-basic-login-config-form/src/main/webapp/loginform.jsp b/appserver/tests/appserv-tests/devtests/security/soteria/app-bundled-ham-basic-login-config-form/src/main/webapp/loginform.jsp new file mode 100644 index 00000000000..ac9f8d27dbd --- /dev/null +++ b/appserver/tests/appserv-tests/devtests/security/soteria/app-bundled-ham-basic-login-config-form/src/main/webapp/loginform.jsp @@ -0,0 +1,63 @@ +<%-- + + DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + + Copyright (c) 2017 Oracle and/or its affiliates. All rights reserved. + + The contents of this file are subject to the terms of either the GNU + General Public License Version 2 only ("GPL") or the Common Development + and Distribution License("CDDL") (collectively, the "License"). You + may not use this file except in compliance with the License. You can + obtain a copy of the License at + https://oss.oracle.com/licenses/CDDL+GPL-1.1 + or LICENSE.txt. See the License for the specific + language governing permissions and limitations under the License. + + When distributing the software, include this License Header Notice in each + file and include the License file at LICENSE.txt. + + GPL Classpath Exception: + Oracle designates this particular file as subject to the "Classpath" + exception as provided by Oracle in the GPL Version 2 section of the License + file that accompanied this code. + + Modifications: + If applicable, add the following below the License Header, with the fields + enclosed by brackets [] replaced by your own identifying information: + "Portions Copyright [year] [name of copyright owner]" + + Contributor(s): + If you wish your version of this file to be governed by only the CDDL or + only the GPL Version 2, indicate your decision by adding "[Contributor] + elects to include this software in this distribution under the [CDDL or GPL + Version 2] license." If you don't indicate a single choice of license, a + recipient has the option to distribute your version of this file under + either the CDDL, the GPL Version 2 or to extend the choice of license to + its licensees as provided above. However, if you add GPL Version 2 code + and therefore, elected the GPL Version 2 license, then the option applies + only if the new code is made subject to such option by the copyright + holder. + +--%> + +<%@page contentType="text/html" pageEncoding="UTF-8"%> + + + + + + Form-Based Login Page + + +

Form-Based Login Page

+ +
+ Username:

+ Password:

+ + +

+ + + diff --git a/appserver/tests/appserv-tests/devtests/security/soteria/app-bundled-ham-basic-login-config-form/src/test/java/org/glassfish/soteria/test/AppBundledHAMPrecendenceOverLoginConfigInWebXmlIT.java b/appserver/tests/appserv-tests/devtests/security/soteria/app-bundled-ham-basic-login-config-form/src/test/java/org/glassfish/soteria/test/AppBundledHAMPrecendenceOverLoginConfigInWebXmlIT.java new file mode 100644 index 00000000000..bc2c86fe0b7 --- /dev/null +++ b/appserver/tests/appserv-tests/devtests/security/soteria/app-bundled-ham-basic-login-config-form/src/test/java/org/glassfish/soteria/test/AppBundledHAMPrecendenceOverLoginConfigInWebXmlIT.java @@ -0,0 +1,85 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) 2017 Oracle and/or its affiliates. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common Development + * and Distribution License("CDDL") (collectively, the "License"). You + * may not use this file except in compliance with the License. You can + * obtain a copy of the License at + * https://oss.oracle.com/licenses/CDDL+GPL-1.1 + * or LICENSE.txt. See the License for the specific + * language governing permissions and limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at LICENSE.txt. + * + * GPL Classpath Exception: + * Oracle designates this particular file as subject to the "Classpath" + * exception as provided by Oracle in the GPL Version 2 section of the License + * file that accompanied this code. + * + * Modifications: + * If applicable, add the following below the License Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyright [year] [name of copyright owner]" + * + * Contributor(s): + * If you wish your version of this file to be governed by only the CDDL or + * only the GPL Version 2, indicate your decision by adding "[Contributor] + * elects to include this software in this distribution under the [CDDL or GPL + * Version 2] license." If you don't indicate a single choice of license, a + * recipient has the option to distribute your version of this file under + * either the CDDL, the GPL Version 2 or to extend the choice of license to + * its licensees as provided above. However, if you add GPL Version 2 code + * and therefore, elected the GPL Version 2 license, then the option applies + * only if the new code is made subject to such option by the copyright + * holder. + */ + +package org.glassfish.soteria.test; + +import static org.glassfish.soteria.test.Assert.*; +import static org.glassfish.soteria.test.ShrinkWrap.mavenWar; + +import org.glassfish.soteria.test.ArquillianBase; +import org.jboss.arquillian.container.test.api.Deployment; +import org.jboss.arquillian.junit.Arquillian; +import org.jboss.shrinkwrap.api.Archive; +import org.junit.Test; +import org.junit.runner.RunWith; + +import org.junit.Rule; +import org.junit.AfterClass; +import org.junit.rules.TestWatcher; + +import com.gargoylesoftware.htmlunit.DefaultCredentialsProvider; +import com.gargoylesoftware.htmlunit.WebResponse; +import com.sun.ejte.ccl.reporter.SimpleReporterAdapter; + +@RunWith(Arquillian.class) +public class AppBundledHAMPrecendenceOverLoginConfigInWebXmlIT extends ArquillianBase { + private static SimpleReporterAdapter stat = + new SimpleReporterAdapter("appserv-tests"); + @Rule + public TestWatcher reportWatcher=new ReportWatcher(stat, "Security::soteria::AppBundledHAMPrecendenceOverLoginConfigInWebXml"); + + @AfterClass + public static void printSummary(){ + stat.printSummary(); + } + + @Deployment(testable = false) + public static Archive createDeployment() { + return mavenWar(); + } + + @Test + public void testHAMPrecedenceOverLoginConfig() { + + assertBundledHAMPrecedenceOverLoginConfig( + responseFromServer("/basicAuthenticationServlet?name=reza&password=secret1")); + } + +} diff --git a/appserver/tests/appserv-tests/devtests/security/soteria/app-caller-principal/README.md b/appserver/tests/appserv-tests/devtests/security/soteria/app-caller-principal/README.md new file mode 100644 index 00000000000..0bb7d106674 --- /dev/null +++ b/appserver/tests/appserv-tests/devtests/security/soteria/app-caller-principal/README.md @@ -0,0 +1,12 @@ + +### app-container-application-principal-getname + +**From JSR 375 Specification** + +> **1.2.2. Caller Principal Types** + +> When both a container caller principal and an application caller principal are present, the value obtained by calling getName() on both principals MUST be the same. + +In this test, application provides its own caller principal, +and hence, subject contains two such principals, one +representing the container and other one representing the application itself. diff --git a/appserver/tests/appserv-tests/devtests/security/soteria/app-caller-principal/pom.xml b/appserver/tests/appserv-tests/devtests/security/soteria/app-caller-principal/pom.xml new file mode 100644 index 00000000000..3fdff8f78c5 --- /dev/null +++ b/appserver/tests/appserv-tests/devtests/security/soteria/app-caller-principal/pom.xml @@ -0,0 +1,71 @@ + + + + 4.0.0 + + org.glassfish.soteria.test + soteria + 5.0-SNAPSHOT + + + app-caller-principal + war + + + app-caller-principal + + + + false + + + + org.glassfish.soteria.test + common + 5.0-SNAPSHOT + test + + + + diff --git a/appserver/tests/appserv-tests/devtests/security/soteria/app-caller-principal/src/main/java/org/glassfish/soteria/test/AppPrincipal.java b/appserver/tests/appserv-tests/devtests/security/soteria/app-caller-principal/src/main/java/org/glassfish/soteria/test/AppPrincipal.java new file mode 100644 index 00000000000..7ad65ffb671 --- /dev/null +++ b/appserver/tests/appserv-tests/devtests/security/soteria/app-caller-principal/src/main/java/org/glassfish/soteria/test/AppPrincipal.java @@ -0,0 +1,59 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) 2017 Oracle and/or its affiliates. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common Development + * and Distribution License("CDDL") (collectively, the "License"). You + * may not use this file except in compliance with the License. You can + * obtain a copy of the License at + * https://oss.oracle.com/licenses/CDDL+GPL-1.1 + * or LICENSE.txt. See the License for the specific + * language governing permissions and limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at LICENSE.txt. + * + * GPL Classpath Exception: + * Oracle designates this particular file as subject to the "Classpath" + * exception as provided by Oracle in the GPL Version 2 section of the License + * file that accompanied this code. + * + * Modifications: + * If applicable, add the following below the License Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyright [year] [name of copyright owner]" + * + * Contributor(s): + * If you wish your version of this file to be governed by only the CDDL or + * only the GPL Version 2, indicate your decision by adding "[Contributor] + * elects to include this software in this distribution under the [CDDL or GPL + * Version 2] license." If you don't indicate a single choice of license, a + * recipient has the option to distribute your version of this file under + * either the CDDL, the GPL Version 2 or to extend the choice of license to + * its licensees as provided above. However, if you add GPL Version 2 code + * and therefore, elected the GPL Version 2 license, then the option applies + * only if the new code is made subject to such option by the copyright + * holder. + */ + +package org.glassfish.soteria.test; + +import java.security.Principal; + +/** + * Created by vinay on 7/8/17. + */ +public class AppPrincipal implements Principal { + String name; + + public AppPrincipal(String name){ + this.name = name; + } + + @Override + public String getName() { + return name; + } +} diff --git a/appserver/tests/appserv-tests/devtests/security/soteria/app-caller-principal/src/main/java/org/glassfish/soteria/test/CallerSubjectServlet.java b/appserver/tests/appserv-tests/devtests/security/soteria/app-caller-principal/src/main/java/org/glassfish/soteria/test/CallerSubjectServlet.java new file mode 100644 index 00000000000..3db443f2e90 --- /dev/null +++ b/appserver/tests/appserv-tests/devtests/security/soteria/app-caller-principal/src/main/java/org/glassfish/soteria/test/CallerSubjectServlet.java @@ -0,0 +1,117 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) 2017 Oracle and/or its affiliates. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common Development + * and Distribution License("CDDL") (collectively, the "License"). You + * may not use this file except in compliance with the License. You can + * obtain a copy of the License at + * https://oss.oracle.com/licenses/CDDL+GPL-1.1 + * or LICENSE.txt. See the License for the specific + * language governing permissions and limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at LICENSE.txt. + * + * GPL Classpath Exception: + * Oracle designates this particular file as subject to the "Classpath" + * exception as provided by Oracle in the GPL Version 2 section of the License + * file that accompanied this code. + * + * Modifications: + * If applicable, add the following below the License Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyright [year] [name of copyright owner]" + * + * Contributor(s): + * If you wish your version of this file to be governed by only the CDDL or + * only the GPL Version 2, indicate your decision by adding "[Contributor] + * elects to include this software in this distribution under the [CDDL or GPL + * Version 2] license." If you don't indicate a single choice of license, a + * recipient has the option to distribute your version of this file under + * either the CDDL, the GPL Version 2 or to extend the choice of license to + * its licensees as provided above. However, if you add GPL Version 2 code + * and therefore, elected the GPL Version 2 license, then the option applies + * only if the new code is made subject to such option by the copyright + * holder. + */ + +package org.glassfish.soteria.test; + +import java.io.IOException; + +import javax.inject.Inject; +import javax.security.enterprise.SecurityContext; +import javax.security.enterprise.CallerPrincipal; +import javax.servlet.ServletException; +import javax.servlet.annotation.HttpConstraint; +import javax.servlet.annotation.ServletSecurity; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.security.Principal; +import java.util.Optional; +import java.util.Set; + +/** + * The Servlet which validates if for the authenticated user, both + * container and caller principals are present in the subject + * representing the caller. + */ +@WebServlet("/callerSubjectServlet") +@ServletSecurity(@HttpConstraint(rolesAllowed = "foo")) +public class CallerSubjectServlet extends HttpServlet { + + private static final long serialVersionUID = 1L; + + @Inject + private SecurityContext securityContext; + + @Override + public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + + String containerCallerPrincipalName = null; + String appPrincipalName = null; + String callerPrincipalFromSecurityContextName = null; + boolean isUserInRole = securityContext.isCallerInRole("foo"); + int callerPrincipalCount = 0; + + Principal containerCallerPrincipal = securityContext.getCallerPrincipal(); + containerCallerPrincipalName = containerCallerPrincipal.getName(); + + Set principals = securityContext.getPrincipalsByType(java.security.Principal.class); + + Optional appCallerPrincipalOptional = principals.stream().filter((p) -> p.getClass().getName() == AppPrincipal.class.getName()) + .findAny(); + Principal appPrincipal = null; + if (appCallerPrincipalOptional.isPresent()) { + callerPrincipalCount++; + appPrincipal = appCallerPrincipalOptional.get(); + appPrincipalName = appPrincipal.getName(); + } + + Optional containerCallerPrincipalOptional = principals.stream().filter((p) -> p.getClass().getName() == CallerPrincipal + .class.getName()) + .findAny(); + Principal callerPrincipalFromSecurityContext = null; + if (containerCallerPrincipalOptional.isPresent()) { + callerPrincipalCount++; + callerPrincipalFromSecurityContext = containerCallerPrincipalOptional.get(); + callerPrincipalFromSecurityContextName = callerPrincipalFromSecurityContext.getName(); + } + + if (!containerCallerPrincipalName.isEmpty() && !appPrincipalName.isEmpty() && containerCallerPrincipalName.equals + (appPrincipalName) && isUserInRole & callerPrincipalCount == 1) { + response.getWriter().write(String.format("Container caller principal and application caller principal both are " + + "represented by same principal for user %s and is in role %s", containerCallerPrincipal.getName(), "foo")); + } else { + response.getWriter().write(String.format("Both %s and %s principal types are available wherein only principal of " + + "type %s was expected for user %s and is in role %s",AppPrincipal.class.getName(), CallerPrincipal.class + .getName(), AppPrincipal.class.getName(), containerCallerPrincipal.getName(), + "foo")); + } + } +} diff --git a/appserver/tests/appserv-tests/devtests/security/soteria/app-caller-principal/src/main/java/org/glassfish/soteria/test/TestAuthenticationMechanism.java b/appserver/tests/appserv-tests/devtests/security/soteria/app-caller-principal/src/main/java/org/glassfish/soteria/test/TestAuthenticationMechanism.java new file mode 100644 index 00000000000..31393aa623e --- /dev/null +++ b/appserver/tests/appserv-tests/devtests/security/soteria/app-caller-principal/src/main/java/org/glassfish/soteria/test/TestAuthenticationMechanism.java @@ -0,0 +1,96 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) 2017 Oracle and/or its affiliates. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common Development + * and Distribution License("CDDL") (collectively, the "License"). You + * may not use this file except in compliance with the License. You can + * obtain a copy of the License at + * https://oss.oracle.com/licenses/CDDL+GPL-1.1 + * or LICENSE.txt. See the License for the specific + * language governing permissions and limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at LICENSE.txt. + * + * GPL Classpath Exception: + * Oracle designates this particular file as subject to the "Classpath" + * exception as provided by Oracle in the GPL Version 2 section of the License + * file that accompanied this code. + * + * Modifications: + * If applicable, add the following below the License Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyright [year] [name of copyright owner]" + * + * Contributor(s): + * If you wish your version of this file to be governed by only the CDDL or + * only the GPL Version 2, indicate your decision by adding "[Contributor] + * elects to include this software in this distribution under the [CDDL or GPL + * Version 2] license." If you don't indicate a single choice of license, a + * recipient has the option to distribute your version of this file under + * either the CDDL, the GPL Version 2 or to extend the choice of license to + * its licensees as provided above. However, if you add GPL Version 2 code + * and therefore, elected the GPL Version 2 license, then the option applies + * only if the new code is made subject to such option by the copyright + * holder. + */ + +package org.glassfish.soteria.test; + +import static javax.security.enterprise.identitystore.CredentialValidationResult.Status.VALID; + +import javax.enterprise.context.RequestScoped; +import javax.inject.Inject; +import javax.security.enterprise.AuthenticationStatus; +import javax.security.enterprise.AuthenticationException; +import javax.security.enterprise.authentication.mechanism.http.HttpAuthenticationMechanism; +import javax.security.enterprise.authentication.mechanism.http.HttpMessageContext; +import javax.security.enterprise.identitystore.CredentialValidationResult; +import javax.security.enterprise.identitystore.IdentityStoreHandler; +import javax.security.enterprise.credential.UsernamePasswordCredential; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + + + + +@RequestScoped +public class TestAuthenticationMechanism implements HttpAuthenticationMechanism { + + @Inject + private IdentityStoreHandler identityStoreHandler; + + @Override + public AuthenticationStatus validateRequest(HttpServletRequest request, HttpServletResponse response, HttpMessageContext httpMessageContext) throws AuthenticationException { + + // Get the (caller) name and password from the request + // NOTE: This is for the smallest possible example only. In practice + // putting the password in a request query parameter is highly + // insecure + String name = request.getParameter("name"); + String password = request.getParameter("password"); + + if (name != null && password != null) { + + // Delegate the {credentials in -> identity data out} function to + // the Identity Store + CredentialValidationResult result = identityStoreHandler.validate( + new UsernamePasswordCredential(name, password)); + + if (result.getStatus() == VALID) { + // In this case , application chooses to provide its own caller principal + return httpMessageContext.notifyContainerAboutLogin( + new AppPrincipal(name), result.getCallerGroups()); + + } else { + return httpMessageContext.responseUnauthorized(); + } + } + + return httpMessageContext.doNothing(); + } + +} diff --git a/appserver/tests/appserv-tests/devtests/security/soteria/app-caller-principal/src/main/java/org/glassfish/soteria/test/TestIdentityStore.java b/appserver/tests/appserv-tests/devtests/security/soteria/app-caller-principal/src/main/java/org/glassfish/soteria/test/TestIdentityStore.java new file mode 100644 index 00000000000..a476772aa66 --- /dev/null +++ b/appserver/tests/appserv-tests/devtests/security/soteria/app-caller-principal/src/main/java/org/glassfish/soteria/test/TestIdentityStore.java @@ -0,0 +1,65 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) 2017 Oracle and/or its affiliates. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common Development + * and Distribution License("CDDL") (collectively, the "License"). You + * may not use this file except in compliance with the License. You can + * obtain a copy of the License at + * https://oss.oracle.com/licenses/CDDL+GPL-1.1 + * or LICENSE.txt. See the License for the specific + * language governing permissions and limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at LICENSE.txt. + * + * GPL Classpath Exception: + * Oracle designates this particular file as subject to the "Classpath" + * exception as provided by Oracle in the GPL Version 2 section of the License + * file that accompanied this code. + * + * Modifications: + * If applicable, add the following below the License Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyright [year] [name of copyright owner]" + * + * Contributor(s): + * If you wish your version of this file to be governed by only the CDDL or + * only the GPL Version 2, indicate your decision by adding "[Contributor] + * elects to include this software in this distribution under the [CDDL or GPL + * Version 2] license." If you don't indicate a single choice of license, a + * recipient has the option to distribute your version of this file under + * either the CDDL, the GPL Version 2 or to extend the choice of license to + * its licensees as provided above. However, if you add GPL Version 2 code + * and therefore, elected the GPL Version 2 license, then the option applies + * only if the new code is made subject to such option by the copyright + * holder. + */ + +package org.glassfish.soteria.test; + +import static java.util.Arrays.asList; +import static javax.security.enterprise.identitystore.CredentialValidationResult.INVALID_RESULT; + +import java.util.HashSet; + +import javax.enterprise.context.RequestScoped; +import javax.security.enterprise.identitystore.CredentialValidationResult; +import javax.security.enterprise.identitystore.IdentityStore; +import javax.security.enterprise.credential.UsernamePasswordCredential; + +@RequestScoped +public class TestIdentityStore implements IdentityStore { + + public CredentialValidationResult validate(UsernamePasswordCredential usernamePasswordCredential) { + + if (usernamePasswordCredential.compareTo("reza", "secret1")) { + return new CredentialValidationResult("reza", new HashSet<>(asList("foo", "bar"))); + } + + return INVALID_RESULT; + } + +} diff --git a/appserver/tests/appserv-tests/devtests/security/soteria/app-caller-principal/src/main/webapp/WEB-INF/beans.xml b/appserver/tests/appserv-tests/devtests/security/soteria/app-caller-principal/src/main/webapp/WEB-INF/beans.xml new file mode 100644 index 00000000000..e69de29bb2d diff --git a/appserver/tests/appserv-tests/devtests/security/soteria/app-caller-principal/src/main/webapp/WEB-INF/web.xml b/appserver/tests/appserv-tests/devtests/security/soteria/app-caller-principal/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 00000000000..33c5f91736b --- /dev/null +++ b/appserver/tests/appserv-tests/devtests/security/soteria/app-caller-principal/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,68 @@ + + + + + + + + + + User pages + /protectedServlet + + + foo + + + + + + foo + + + diff --git a/appserver/tests/appserv-tests/devtests/security/soteria/app-caller-principal/src/test/java/org/glassfish/soteria/test/AppCallerPrincipalIT.java b/appserver/tests/appserv-tests/devtests/security/soteria/app-caller-principal/src/test/java/org/glassfish/soteria/test/AppCallerPrincipalIT.java new file mode 100644 index 00000000000..a7f9e78fc04 --- /dev/null +++ b/appserver/tests/appserv-tests/devtests/security/soteria/app-caller-principal/src/test/java/org/glassfish/soteria/test/AppCallerPrincipalIT.java @@ -0,0 +1,84 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) 2017 Oracle and/or its affiliates. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common Development + * and Distribution License("CDDL") (collectively, the "License"). You + * may not use this file except in compliance with the License. You can + * obtain a copy of the License at + * https://oss.oracle.com/licenses/CDDL+GPL-1.1 + * or LICENSE.txt. See the License for the specific + * language governing permissions and limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at LICENSE.txt. + * + * GPL Classpath Exception: + * Oracle designates this particular file as subject to the "Classpath" + * exception as provided by Oracle in the GPL Version 2 section of the License + * file that accompanied this code. + * + * Modifications: + * If applicable, add the following below the License Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyright [year] [name of copyright owner]" + * + * Contributor(s): + * If you wish your version of this file to be governed by only the CDDL or + * only the GPL Version 2, indicate your decision by adding "[Contributor] + * elects to include this software in this distribution under the [CDDL or GPL + * Version 2] license." If you don't indicate a single choice of license, a + * recipient has the option to distribute your version of this file under + * either the CDDL, the GPL Version 2 or to extend the choice of license to + * its licensees as provided above. However, if you add GPL Version 2 code + * and therefore, elected the GPL Version 2 license, then the option applies + * only if the new code is made subject to such option by the copyright + * holder. + */ + +package org.glassfish.soteria.test; + +import static org.glassfish.soteria.test.Assert.*; +import static org.glassfish.soteria.test.ShrinkWrap.mavenWar; + +import org.glassfish.soteria.test.ArquillianBase; +import org.jboss.arquillian.container.test.api.Deployment; +import org.jboss.arquillian.junit.Arquillian; +import org.jboss.shrinkwrap.api.Archive; +import org.junit.Test; +import org.junit.runner.RunWith; + +import org.junit.Rule; +import org.junit.AfterClass; +import org.junit.rules.TestWatcher; + +import com.gargoylesoftware.htmlunit.DefaultCredentialsProvider; +import com.gargoylesoftware.htmlunit.WebResponse; +import com.sun.ejte.ccl.reporter.SimpleReporterAdapter; + +@RunWith(Arquillian.class) +public class AppCallerPrincipalIT extends ArquillianBase { + private static SimpleReporterAdapter stat = + new SimpleReporterAdapter("appserv-tests"); + @Rule + public TestWatcher reportWatcher=new ReportWatcher(stat, "Security::soteria::AppCallerPrincipal"); + + @AfterClass + public static void printSummary(){ + stat.printSummary(); + } + + @Deployment(testable = false) + public static Archive createDeployment() { + return mavenWar(); + } + + @Test + public void testCallerSubjectPrincipals() { + assertApplicationPrincipalAndContainerPrincipalName( + responseFromServer("/callerSubjectServlet?name=reza&password=secret1")); + } + +} diff --git a/appserver/tests/appserv-tests/devtests/security/soteria/app-no-application-caller-principal/README.md b/appserver/tests/appserv-tests/devtests/security/soteria/app-no-application-caller-principal/README.md new file mode 100644 index 00000000000..fea016aafee --- /dev/null +++ b/appserver/tests/appserv-tests/devtests/security/soteria/app-no-application-caller-principal/README.md @@ -0,0 +1,10 @@ + +### app-no-application-caller-principal + +**From JSR 375 Specification** + +> **1.2.2. Caller Principal Types** + +> When no specific application caller principal is supplied during authentication, the caller’s identity should be represented by a single principal, the container’s caller principal. + +In this test, no application caller principal is provided when container gets notified about login inside `TestAuthenticationMechanism`. diff --git a/appserver/tests/appserv-tests/devtests/security/soteria/app-no-application-caller-principal/pom.xml b/appserver/tests/appserv-tests/devtests/security/soteria/app-no-application-caller-principal/pom.xml new file mode 100644 index 00000000000..b91790cd714 --- /dev/null +++ b/appserver/tests/appserv-tests/devtests/security/soteria/app-no-application-caller-principal/pom.xml @@ -0,0 +1,71 @@ + + + + 4.0.0 + + org.glassfish.soteria.test + soteria + 5.0-SNAPSHOT + + + app-no-application-caller-principal + war + + + app-no-application-caller-principal + + + + false + + + + org.glassfish.soteria.test + common + 5.0-SNAPSHOT + test + + + + diff --git a/appserver/tests/appserv-tests/devtests/security/soteria/app-no-application-caller-principal/src/main/java/org/glassfish/soteria/test/AppPrincipal.java b/appserver/tests/appserv-tests/devtests/security/soteria/app-no-application-caller-principal/src/main/java/org/glassfish/soteria/test/AppPrincipal.java new file mode 100644 index 00000000000..3e9088198d4 --- /dev/null +++ b/appserver/tests/appserv-tests/devtests/security/soteria/app-no-application-caller-principal/src/main/java/org/glassfish/soteria/test/AppPrincipal.java @@ -0,0 +1,56 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) 2017 Oracle and/or its affiliates. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common Development + * and Distribution License("CDDL") (collectively, the "License"). You + * may not use this file except in compliance with the License. You can + * obtain a copy of the License at + * https://oss.oracle.com/licenses/CDDL+GPL-1.1 + * or LICENSE.txt. See the License for the specific + * language governing permissions and limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at LICENSE.txt. + * + * GPL Classpath Exception: + * Oracle designates this particular file as subject to the "Classpath" + * exception as provided by Oracle in the GPL Version 2 section of the License + * file that accompanied this code. + * + * Modifications: + * If applicable, add the following below the License Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyright [year] [name of copyright owner]" + * + * Contributor(s): + * If you wish your version of this file to be governed by only the CDDL or + * only the GPL Version 2, indicate your decision by adding "[Contributor] + * elects to include this software in this distribution under the [CDDL or GPL + * Version 2] license." If you don't indicate a single choice of license, a + * recipient has the option to distribute your version of this file under + * either the CDDL, the GPL Version 2 or to extend the choice of license to + * its licensees as provided above. However, if you add GPL Version 2 code + * and therefore, elected the GPL Version 2 license, then the option applies + * only if the new code is made subject to such option by the copyright + * holder. + */ + +package org.glassfish.soteria.test; + +import java.security.Principal; + +public class AppPrincipal implements Principal { + String name; + + public AppPrincipal(String name){ + this.name = name; + } + + @Override + public String getName() { + return name; + } +} diff --git a/appserver/tests/appserv-tests/devtests/security/soteria/app-no-application-caller-principal/src/main/java/org/glassfish/soteria/test/TestAuthenticationMechanism.java b/appserver/tests/appserv-tests/devtests/security/soteria/app-no-application-caller-principal/src/main/java/org/glassfish/soteria/test/TestAuthenticationMechanism.java new file mode 100644 index 00000000000..e2900498a98 --- /dev/null +++ b/appserver/tests/appserv-tests/devtests/security/soteria/app-no-application-caller-principal/src/main/java/org/glassfish/soteria/test/TestAuthenticationMechanism.java @@ -0,0 +1,91 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) 2017 Oracle and/or its affiliates. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common Development + * and Distribution License("CDDL") (collectively, the "License"). You + * may not use this file except in compliance with the License. You can + * obtain a copy of the License at + * https://oss.oracle.com/licenses/CDDL+GPL-1.1 + * or LICENSE.txt. See the License for the specific + * language governing permissions and limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at LICENSE.txt. + * + * GPL Classpath Exception: + * Oracle designates this particular file as subject to the "Classpath" + * exception as provided by Oracle in the GPL Version 2 section of the License + * file that accompanied this code. + * + * Modifications: + * If applicable, add the following below the License Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyright [year] [name of copyright owner]" + * + * Contributor(s): + * If you wish your version of this file to be governed by only the CDDL or + * only the GPL Version 2, indicate your decision by adding "[Contributor] + * elects to include this software in this distribution under the [CDDL or GPL + * Version 2] license." If you don't indicate a single choice of license, a + * recipient has the option to distribute your version of this file under + * either the CDDL, the GPL Version 2 or to extend the choice of license to + * its licensees as provided above. However, if you add GPL Version 2 code + * and therefore, elected the GPL Version 2 license, then the option applies + * only if the new code is made subject to such option by the copyright + * holder. + */ + +package org.glassfish.soteria.test; + +import static javax.security.enterprise.identitystore.CredentialValidationResult.Status.VALID; + +import javax.enterprise.context.RequestScoped; +import javax.inject.Inject; +import javax.security.enterprise.AuthenticationStatus; +import javax.security.enterprise.AuthenticationException; +import javax.security.enterprise.authentication.mechanism.http.HttpAuthenticationMechanism; +import javax.security.enterprise.authentication.mechanism.http.HttpMessageContext; +import javax.security.enterprise.identitystore.CredentialValidationResult; +import javax.security.enterprise.identitystore.IdentityStoreHandler; +import javax.security.enterprise.credential.UsernamePasswordCredential; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +@RequestScoped +public class TestAuthenticationMechanism implements HttpAuthenticationMechanism { + + @Inject + private IdentityStoreHandler identityStoreHandler; + + @Override + public AuthenticationStatus validateRequest(HttpServletRequest request, HttpServletResponse response, HttpMessageContext httpMessageContext) throws AuthenticationException { + + // Get the (caller) name and password from the request + // NOTE: This is for the smallest possible example only. In practice + // putting the password in a request query parameter is highly + // insecure + String name = request.getParameter("name"); + String password = request.getParameter("password"); + + if (name != null && password != null) { + + // Delegate the {credentials in -> identity data out} function to + // the Identity Store + CredentialValidationResult result = identityStoreHandler.validate( + new UsernamePasswordCredential(name, password)); + + if (result.getStatus() == VALID) { + return httpMessageContext.notifyContainerAboutLogin(result); + + } else { + return httpMessageContext.responseUnauthorized(); + } + } + + return httpMessageContext.doNothing(); + } + +} diff --git a/appserver/tests/appserv-tests/devtests/security/soteria/app-no-application-caller-principal/src/main/java/org/glassfish/soteria/test/TestIdentityStore.java b/appserver/tests/appserv-tests/devtests/security/soteria/app-no-application-caller-principal/src/main/java/org/glassfish/soteria/test/TestIdentityStore.java new file mode 100644 index 00000000000..a476772aa66 --- /dev/null +++ b/appserver/tests/appserv-tests/devtests/security/soteria/app-no-application-caller-principal/src/main/java/org/glassfish/soteria/test/TestIdentityStore.java @@ -0,0 +1,65 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) 2017 Oracle and/or its affiliates. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common Development + * and Distribution License("CDDL") (collectively, the "License"). You + * may not use this file except in compliance with the License. You can + * obtain a copy of the License at + * https://oss.oracle.com/licenses/CDDL+GPL-1.1 + * or LICENSE.txt. See the License for the specific + * language governing permissions and limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at LICENSE.txt. + * + * GPL Classpath Exception: + * Oracle designates this particular file as subject to the "Classpath" + * exception as provided by Oracle in the GPL Version 2 section of the License + * file that accompanied this code. + * + * Modifications: + * If applicable, add the following below the License Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyright [year] [name of copyright owner]" + * + * Contributor(s): + * If you wish your version of this file to be governed by only the CDDL or + * only the GPL Version 2, indicate your decision by adding "[Contributor] + * elects to include this software in this distribution under the [CDDL or GPL + * Version 2] license." If you don't indicate a single choice of license, a + * recipient has the option to distribute your version of this file under + * either the CDDL, the GPL Version 2 or to extend the choice of license to + * its licensees as provided above. However, if you add GPL Version 2 code + * and therefore, elected the GPL Version 2 license, then the option applies + * only if the new code is made subject to such option by the copyright + * holder. + */ + +package org.glassfish.soteria.test; + +import static java.util.Arrays.asList; +import static javax.security.enterprise.identitystore.CredentialValidationResult.INVALID_RESULT; + +import java.util.HashSet; + +import javax.enterprise.context.RequestScoped; +import javax.security.enterprise.identitystore.CredentialValidationResult; +import javax.security.enterprise.identitystore.IdentityStore; +import javax.security.enterprise.credential.UsernamePasswordCredential; + +@RequestScoped +public class TestIdentityStore implements IdentityStore { + + public CredentialValidationResult validate(UsernamePasswordCredential usernamePasswordCredential) { + + if (usernamePasswordCredential.compareTo("reza", "secret1")) { + return new CredentialValidationResult("reza", new HashSet<>(asList("foo", "bar"))); + } + + return INVALID_RESULT; + } + +} diff --git a/appserver/tests/appserv-tests/devtests/security/soteria/app-no-application-caller-principal/src/main/java/org/glassfish/soteria/test/ValidateAvailablePrincipalServlet.java b/appserver/tests/appserv-tests/devtests/security/soteria/app-no-application-caller-principal/src/main/java/org/glassfish/soteria/test/ValidateAvailablePrincipalServlet.java new file mode 100644 index 00000000000..e76ca4ae0dc --- /dev/null +++ b/appserver/tests/appserv-tests/devtests/security/soteria/app-no-application-caller-principal/src/main/java/org/glassfish/soteria/test/ValidateAvailablePrincipalServlet.java @@ -0,0 +1,111 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) 2017 Oracle and/or its affiliates. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common Development + * and Distribution License("CDDL") (collectively, the "License"). You + * may not use this file except in compliance with the License. You can + * obtain a copy of the License at + * https://oss.oracle.com/licenses/CDDL+GPL-1.1 + * or LICENSE.txt. See the License for the specific + * language governing permissions and limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at LICENSE.txt. + * + * GPL Classpath Exception: + * Oracle designates this particular file as subject to the "Classpath" + * exception as provided by Oracle in the GPL Version 2 section of the License + * file that accompanied this code. + * + * Modifications: + * If applicable, add the following below the License Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyright [year] [name of copyright owner]" + * + * Contributor(s): + * If you wish your version of this file to be governed by only the CDDL or + * only the GPL Version 2, indicate your decision by adding "[Contributor] + * elects to include this software in this distribution under the [CDDL or GPL + * Version 2] license." If you don't indicate a single choice of license, a + * recipient has the option to distribute your version of this file under + * either the CDDL, the GPL Version 2 or to extend the choice of license to + * its licensees as provided above. However, if you add GPL Version 2 code + * and therefore, elected the GPL Version 2 license, then the option applies + * only if the new code is made subject to such option by the copyright + * holder. + */ + +package org.glassfish.soteria.test; + +import java.io.IOException; + +import javax.inject.Inject; +import javax.security.enterprise.SecurityContext; +import javax.security.enterprise.CallerPrincipal; +import javax.servlet.ServletException; +import javax.servlet.annotation.HttpConstraint; +import javax.servlet.annotation.ServletSecurity; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.security.Principal; +import java.util.Optional; +import java.util.Set; + +/** + * The Servlet which validates if for the authenticated user, both + * container and caller principals are present in the subject + * representing the caller. + */ +@WebServlet("/valildateAvailablePrincipalServlet") +@ServletSecurity(@HttpConstraint(rolesAllowed = "foo")) +public class ValidateAvailablePrincipalServlet extends HttpServlet { + + private static final long serialVersionUID = 1L; + + @Inject + private SecurityContext securityContext; + + @Override + public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + + boolean isUserInRole = securityContext.isCallerInRole("foo"); + boolean hasContainerCallerPrincipal = false; + boolean hasApplicationCallerPrincipal = false; + + Principal containerCallerPrincipal = securityContext.getCallerPrincipal(); + + if (containerCallerPrincipal instanceof javax.security.enterprise.CallerPrincipal) { + hasContainerCallerPrincipal = true; + } + + Set principals = securityContext.getPrincipalsByType(java.security.Principal.class); + + Optional principalOptional = principals.stream().filter((p) -> p.getClass().getName() == CallerPrincipal.class + .getName()) + .findAny(); + if (principalOptional.isPresent()) { + Principal applicationPrincipal = principalOptional.get(); + if(applicationPrincipal.equals(containerCallerPrincipal)) { + response.getWriter().write("containerPrincipal:" + containerCallerPrincipal + "\n"); + response.getWriter().write("appPrincipal:" + applicationPrincipal + "\n"); + hasApplicationCallerPrincipal = true; + response.getWriter().write("hasApplicationCallerPrincipal:" + hasApplicationCallerPrincipal + "\n"); + } + } + if (!hasApplicationCallerPrincipal && hasContainerCallerPrincipal && isUserInRole) { + response.getWriter().write(String.format("Container caller principal and application caller principal must have " + + "been one and the same but are not for user %s in role " + + "%s", + containerCallerPrincipal.getName(), "foo")); + } else { + response.getWriter().write(String.format("Both container caller principal and application caller principals are one" + + " and the same for user %s in role %s", + containerCallerPrincipal.getName(), "foo")); + } + } +} diff --git a/appserver/tests/appserv-tests/devtests/security/soteria/app-no-application-caller-principal/src/main/webapp/WEB-INF/beans.xml b/appserver/tests/appserv-tests/devtests/security/soteria/app-no-application-caller-principal/src/main/webapp/WEB-INF/beans.xml new file mode 100644 index 00000000000..e69de29bb2d diff --git a/appserver/tests/appserv-tests/devtests/security/soteria/app-no-application-caller-principal/src/main/webapp/WEB-INF/web.xml b/appserver/tests/appserv-tests/devtests/security/soteria/app-no-application-caller-principal/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 00000000000..1f4ba8534cc --- /dev/null +++ b/appserver/tests/appserv-tests/devtests/security/soteria/app-no-application-caller-principal/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,67 @@ + + + + + + + + + + User pages + /protectedServlet + + + foo + + + + + + foo + + + diff --git a/appserver/tests/appserv-tests/devtests/security/soteria/app-no-application-caller-principal/src/test/java/org/glassfish/soteria/test/ValidateAvailablePrincipalIT.java b/appserver/tests/appserv-tests/devtests/security/soteria/app-no-application-caller-principal/src/test/java/org/glassfish/soteria/test/ValidateAvailablePrincipalIT.java new file mode 100644 index 00000000000..5b3b60b1eff --- /dev/null +++ b/appserver/tests/appserv-tests/devtests/security/soteria/app-no-application-caller-principal/src/test/java/org/glassfish/soteria/test/ValidateAvailablePrincipalIT.java @@ -0,0 +1,84 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) 2017 Oracle and/or its affiliates. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common Development + * and Distribution License("CDDL") (collectively, the "License"). You + * may not use this file except in compliance with the License. You can + * obtain a copy of the License at + * https://oss.oracle.com/licenses/CDDL+GPL-1.1 + * or LICENSE.txt. See the License for the specific + * language governing permissions and limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at LICENSE.txt. + * + * GPL Classpath Exception: + * Oracle designates this particular file as subject to the "Classpath" + * exception as provided by Oracle in the GPL Version 2 section of the License + * file that accompanied this code. + * + * Modifications: + * If applicable, add the following below the License Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyright [year] [name of copyright owner]" + * + * Contributor(s): + * If you wish your version of this file to be governed by only the CDDL or + * only the GPL Version 2, indicate your decision by adding "[Contributor] + * elects to include this software in this distribution under the [CDDL or GPL + * Version 2] license." If you don't indicate a single choice of license, a + * recipient has the option to distribute your version of this file under + * either the CDDL, the GPL Version 2 or to extend the choice of license to + * its licensees as provided above. However, if you add GPL Version 2 code + * and therefore, elected the GPL Version 2 license, then the option applies + * only if the new code is made subject to such option by the copyright + * holder. + */ + +package org.glassfish.soteria.test; + +import static org.glassfish.soteria.test.Assert.*; +import static org.glassfish.soteria.test.ShrinkWrap.mavenWar; + +import org.glassfish.soteria.test.ArquillianBase; +import org.jboss.arquillian.container.test.api.Deployment; +import org.jboss.arquillian.junit.Arquillian; +import org.jboss.shrinkwrap.api.Archive; +import org.junit.Test; +import org.junit.runner.RunWith; + +import org.junit.Rule; +import org.junit.AfterClass; +import org.junit.rules.TestWatcher; + +import com.gargoylesoftware.htmlunit.DefaultCredentialsProvider; +import com.gargoylesoftware.htmlunit.WebResponse; +import com.sun.ejte.ccl.reporter.SimpleReporterAdapter; + +@RunWith(Arquillian.class) +public class ValidateAvailablePrincipalIT extends ArquillianBase { + private static SimpleReporterAdapter stat = + new SimpleReporterAdapter("appserv-tests"); + @Rule + public TestWatcher reportWatcher=new ReportWatcher(stat, "Security::soteria::ValidateAvailablePrincipalIT"); + + @AfterClass + public static void printSummary(){ + stat.printSummary(); + } + + @Deployment(testable = false) + public static Archive createDeployment() { + return mavenWar(); + } + + @Test + public void testCallerSubjectPrincipals() { + assertBothContainerAndApplicationPrincipalsAreSame( + responseFromServer("/valildateAvailablePrincipalServlet?name=reza&password=secret1")); + } + +} diff --git a/appserver/tests/appserv-tests/devtests/security/soteria/common/src/main/java/org/glassfish/soteria/test/Assert.java b/appserver/tests/appserv-tests/devtests/security/soteria/common/src/main/java/org/glassfish/soteria/test/Assert.java index db4315ae969..e8acc6587d7 100644 --- a/appserver/tests/appserv-tests/devtests/security/soteria/common/src/main/java/org/glassfish/soteria/test/Assert.java +++ b/appserver/tests/appserv-tests/devtests/security/soteria/common/src/main/java/org/glassfish/soteria/test/Assert.java @@ -80,6 +80,27 @@ public static void assertNotAuthenticatedError(WebResponse response) { assertNotNull(response); assertEquals(500, response.getStatusCode()); } + + public static void assertApplicationPrincipalAndContainerPrincipalName(WebResponse response) { + assertNotNull(response); + assertEquals(200, response.getStatusCode()); + assertApplicationPrincipalAndContainerPrincipalSubject("reza", "foo", response + .getContentAsString()); + } + + public static void assertBundledHAMPrecedenceOverLoginConfig(WebResponse response) { + assertNotNull(response); + assertEquals(200, response.getStatusCode()); + assertBundledHAMPrecedenceOverLoginConfig("reza", "foo", response + .getContentAsString()); + } + + public static void assertBothContainerAndApplicationPrincipalsAreSame(WebResponse response) { + assertNotNull(response); + assertEquals(200, response.getStatusCode()); + assertBothContainerAndApplicationPrincipalsAreSame("reza", "foo", response + .getContentAsString()); + } public static void assertAuthenticated(String userType, String name, String response, String... roles) { assertTrue( @@ -155,4 +176,33 @@ public static void assertNotHasAccessToResource(String userType, String name, St response.contains(userType + " user has access to " + resource + ": true")); } + public static void assertBundledHAMPrecedenceOverLoginConfig(String name, String role, String response) { + assertTrue( + "For " + name + " authentication should have been performed by TestAuthenticationMechanism, but wasn't. \n" + + "+ Response: \n" + + response, + response.contains(String.format("Authentication Mechanism:TestAuthenticationMechanism"))); + } + + public static void assertApplicationPrincipalAndContainerPrincipalSubject(String name, String role, String response) { + assertTrue( + "Both application principal's and container principal's name should have been same as " + + " but was not. \n Response: \n" + + response, + response.contains(String.format("Container caller principal and application caller principal both are " + + "represented by same principal for user %s and is in role %s", name, role))); + } + + public static void assertBothContainerAndApplicationPrincipalsAreSame(String name, String role, String response) { + assertTrue( + "For user " + name + " both container caller principal and application caller principal should have been same, " + + "but " + + "wasn't. \n" + + "+ Response: \n" + + response, + response.contains(String.format("Both container caller principal and application caller principals are one and " + + "the same for user %s in role %s", + name, role))); + } + } diff --git a/appserver/tests/appserv-tests/devtests/security/soteria/pom.xml b/appserver/tests/appserv-tests/devtests/security/soteria/pom.xml index d53d0018044..198e1beee47 100644 --- a/appserver/tests/appserv-tests/devtests/security/soteria/pom.xml +++ b/appserver/tests/appserv-tests/devtests/security/soteria/pom.xml @@ -77,7 +77,9 @@ app-multiple-store app-multiple-store-backup app-no-role-mapping - + app-bundled-ham-basic-login-config-form + app-caller-principal + app-no-application-caller-principal