diff --git a/servlet/src/test/java/io/undertow/servlet/test/security/constraint/SecurityConstraintUrlMappingTestCase.java b/servlet/src/test/java/io/undertow/servlet/test/security/constraint/SecurityConstraintUrlMappingTestCase.java index 55cb995dc0..9e92424edc 100644 --- a/servlet/src/test/java/io/undertow/servlet/test/security/constraint/SecurityConstraintUrlMappingTestCase.java +++ b/servlet/src/test/java/io/undertow/servlet/test/security/constraint/SecurityConstraintUrlMappingTestCase.java @@ -18,10 +18,6 @@ package io.undertow.servlet.test.security.constraint; -import java.io.IOException; - -import javax.servlet.ServletException; - import io.undertow.server.handlers.PathHandler; import io.undertow.servlet.api.DeploymentInfo; import io.undertow.servlet.api.DeploymentManager; @@ -36,18 +32,21 @@ import io.undertow.servlet.test.util.TestClassIntrospector; import io.undertow.testutils.DefaultServer; import io.undertow.testutils.HttpClientUtils; +import io.undertow.testutils.TestHttpClient; import io.undertow.util.FlexBase64; +import io.undertow.util.StatusCodes; import org.apache.http.Header; import org.apache.http.HttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; -import io.undertow.testutils.TestHttpClient; -import io.undertow.util.StatusCodes; import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Test; import org.junit.runner.RunWith; +import javax.servlet.ServletException; +import java.io.IOException; + import static io.undertow.util.Headers.AUTHORIZATION; import static io.undertow.util.Headers.BASIC; import static io.undertow.util.Headers.WWW_AUTHENTICATE; @@ -196,6 +195,19 @@ public void testAggregatedRoles() throws IOException { runSimpleUrlTest(DefaultServer.getDefaultServerURL() + "/servletContext/secured/1/2/aa", "user1:password1", "user2:password2"); } + @Test + public void testUnknown() throws IOException { + TestHttpClient client = new TestHttpClient(); + try { + HttpGet get = new HttpGet(DefaultServer.getDefaultServerURL() + "/servletContext/unknown"); + HttpResponse result = client.execute(get); + assertEquals(StatusCodes.NOT_FOUND, result.getStatusLine().getStatusCode()); + HttpClientUtils.readResponse(result); + } finally { + client.getConnectionManager().shutdown(); + } + } + @Test public void testHttpMethod() throws IOException { TestHttpClient client = new TestHttpClient(); diff --git a/servlet/src/test/java/io/undertow/servlet/test/security/constraint/SecurityConstraintUrlMappingWithUnspecifiedForbiddenTestCase.java b/servlet/src/test/java/io/undertow/servlet/test/security/constraint/SecurityConstraintUrlMappingWithUnspecifiedForbiddenTestCase.java new file mode 100644 index 0000000000..8b36f2950b --- /dev/null +++ b/servlet/src/test/java/io/undertow/servlet/test/security/constraint/SecurityConstraintUrlMappingWithUnspecifiedForbiddenTestCase.java @@ -0,0 +1,195 @@ +/* + * JBoss, Home of Professional Open Source. + * Copyright 2022 Red Hat, Inc., and individual contributors + * as indicated by the @author tags. + * + * Licensed 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 io.undertow.servlet.test.security.constraint; + +import io.undertow.server.handlers.PathHandler; +import io.undertow.servlet.api.DeploymentInfo; +import io.undertow.servlet.api.DeploymentManager; +import io.undertow.servlet.api.LoginConfig; +import io.undertow.servlet.api.SecurityConstraint; +import io.undertow.servlet.api.SecurityInfo; +import io.undertow.servlet.api.ServletContainer; +import io.undertow.servlet.api.ServletInfo; +import io.undertow.servlet.api.WebResourceCollection; +import io.undertow.servlet.test.SimpleServletTestCase; +import io.undertow.servlet.test.util.MessageServlet; +import io.undertow.servlet.test.util.TestClassIntrospector; +import io.undertow.testutils.DefaultServer; +import io.undertow.testutils.HttpClientUtils; +import io.undertow.testutils.TestHttpClient; +import io.undertow.util.StatusCodes; +import org.apache.http.HttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; + +import javax.servlet.ServletException; +import java.io.IOException; + +import static org.junit.Assert.assertEquals; + +/** + * Do the same as SecurityConstraintURLMappingTestCase, with a small difference, all access to / are denied and public/* is no longer + * covered by a SecurityConstraint. + * Verify that all works as in the super class test case, except for public/*, that now is forbidden for all HTTP methods. + * + * @author Flavia Rainone + */ +@RunWith(DefaultServer.class) +public class SecurityConstraintUrlMappingWithUnspecifiedForbiddenTestCase extends SecurityConstraintUrlMappingTestCase { + + @BeforeClass + public static void setup() throws ServletException { + + final PathHandler root = new PathHandler(); + final ServletContainer container = ServletContainer.Factory.newInstance(); + + ServletInfo s = new ServletInfo("servlet", AuthenticationMessageServlet.class) + .addInitParam(MessageServlet.MESSAGE, HELLO_WORLD) + .addMapping("/role1") + .addMapping("/role2") + .addMapping("/starstar") + .addMapping("/secured/role2/*") + .addMapping("/secured/1/2/*") + .addMapping("/public/*") + .addMapping("/extension/*"); + + ServletIdentityManager identityManager = new ServletIdentityManager(); + identityManager.addUser("user1", "password1", "role1"); + identityManager.addUser("user2", "password2", "role2", "**"); + identityManager.addUser("user3", "password3", "role1", "role2"); + identityManager.addUser("user4", "password4", "badRole"); + + DeploymentInfo builder = new DeploymentInfo() + .setClassLoader(SimpleServletTestCase.class.getClassLoader()) + .setContextPath("/servletContext") + .setClassIntrospecter(TestClassIntrospector.INSTANCE) + .setDeploymentName("servletContext.war") + .setIdentityManager(identityManager) + .setLoginConfig(new LoginConfig("BASIC", "Test Realm")) + .addServlet(s); + + builder.addSecurityConstraint(new SecurityConstraint() + .addWebResourceCollection(new WebResourceCollection() + .addUrlPattern("/role1")) + .addRoleAllowed("role1")); + + builder.addSecurityConstraint(new SecurityConstraint() + .addWebResourceCollection(new WebResourceCollection() + .addUrlPattern("/starstar")) + .addRoleAllowed("**")); + builder.addSecurityConstraint(new SecurityConstraint() + .addWebResourceCollection(new WebResourceCollection() + .addUrlPattern("/secured/*")) + .addRoleAllowed("role2")); + builder.addSecurityConstraint(new SecurityConstraint() + .addWebResourceCollection(new WebResourceCollection() + .addUrlPattern("/secured/*")) + .addRoleAllowed("role2")); + builder.addSecurityConstraint(new SecurityConstraint() + .addWebResourceCollection(new WebResourceCollection() + .addUrlPattern("/secured/1/*")) + .addRoleAllowed("role1")); + builder.addSecurityConstraint(new SecurityConstraint() + .addWebResourceCollection(new WebResourceCollection() + .addUrlPattern("/secured/1/2/*")) + .addRoleAllowed("role2")); + builder.addSecurityConstraint(new SecurityConstraint() + .addWebResourceCollection(new WebResourceCollection() + .addUrlPattern("*.html")) + .addRoleAllowed("role2")); + builder.addSecurityConstraint(new SecurityConstraint() + .addWebResourceCollection(new WebResourceCollection() + .addUrlPattern("/")).setEmptyRoleSemantic(SecurityInfo.EmptyRoleSemantic.DENY)); + builder.addSecurityConstraint(new SecurityConstraint() + .addWebResourceCollection(new WebResourceCollection() + .addUrlPattern("/public/postSecured/*") + .addHttpMethod("POST")) + .addRoleAllowed("role1")); + + DeploymentManager manager = container.addDeployment(builder); + manager.deploy(); + root.addPrefixPath(builder.getContextPath(), manager.start()); + + builder = new DeploymentInfo() + .setClassLoader(SimpleServletTestCase.class.getClassLoader()) + .setContextPath("/star") + .setClassIntrospecter(TestClassIntrospector.INSTANCE) + .setDeploymentName("servletContext.war") + .setIdentityManager(identityManager) + .setLoginConfig(new LoginConfig("BASIC", "Test Realm")) + .addSecurityRole("**") + .addServlet(s); + + builder.addSecurityConstraint(new SecurityConstraint() + .addWebResourceCollection(new WebResourceCollection() + .addUrlPattern("/starstar")) + .addRoleAllowed("**")); + + manager = container.addDeployment(builder); + manager.deploy(); + root.addPrefixPath(builder.getContextPath(), manager.start()); + DefaultServer.setRootHandler(root); + } + + @Test + @Override + public void testUnknown() throws IOException { + TestHttpClient client = new TestHttpClient(); + try { + HttpGet get = new HttpGet(DefaultServer.getDefaultServerURL() + "/servletContext/unknown"); + HttpResponse result = client.execute(get); + assertEquals(StatusCodes.FORBIDDEN, result.getStatusLine().getStatusCode()); + HttpClientUtils.readResponse(result); + } finally { + client.getConnectionManager().shutdown(); + } + } + + @Test + public void testPublic() throws IOException { + TestHttpClient client = new TestHttpClient(); + try { + HttpGet get = new HttpGet(DefaultServer.getDefaultServerURL() + "/servletContext/public"); + HttpResponse result = client.execute(get); + assertEquals(StatusCodes.FORBIDDEN, result.getStatusLine().getStatusCode()); + HttpClientUtils.readResponse(result); + } finally { + client.getConnectionManager().shutdown(); + } + } + + @Test + @Override + public void testExtensionMatch() throws IOException { + runSimpleUrlTest(DefaultServer.getDefaultServerURL() + "/servletContext/extension/a.html", "user1:password1", "user2:password2"); + TestHttpClient client = new TestHttpClient(); + try { + HttpGet get = new HttpGet(DefaultServer.getDefaultServerURL() + "/servletContext/public/a.html"); + get.addHeader("ExpectedMechanism", "None"); + get.addHeader("ExpectedUser", "None"); + HttpResponse result = client.execute(get); + assertEquals(StatusCodes.UNAUTHORIZED, result.getStatusLine().getStatusCode()); + HttpClientUtils.readResponse(result); + } finally { + client.getConnectionManager().shutdown(); + } + } +}