Search in sources :

Example 1 with ServletSecurityElement

use of jakarta.servlet.ServletSecurityElement in project tomcat by apache.

the class WebAnnotationSet method loadApplicationServletAnnotations.

/**
 * Process the annotations for the servlets.
 *
 * @param context The context which will have its annotations processed
 */
protected static void loadApplicationServletAnnotations(Context context) {
    Container[] children = context.findChildren();
    for (Container child : children) {
        if (child instanceof Wrapper) {
            Wrapper wrapper = (Wrapper) child;
            if (wrapper.getServletClass() == null) {
                continue;
            }
            Class<?> clazz = Introspection.loadClass(context, wrapper.getServletClass());
            if (clazz == null) {
                continue;
            }
            loadClassAnnotation(context, clazz);
            loadFieldsAnnotation(context, clazz);
            loadMethodsAnnotation(context, clazz);
            /* Process RunAs annotation which can be only on servlets.
                 * Ref JSR 250, equivalent to the run-as element in
                 * the deployment descriptor
                 */
            RunAs runAs = clazz.getAnnotation(RunAs.class);
            if (runAs != null) {
                wrapper.setRunAs(runAs.value());
            }
            // Process ServletSecurity annotation
            ServletSecurity servletSecurity = clazz.getAnnotation(ServletSecurity.class);
            if (servletSecurity != null) {
                context.addServletSecurity(new ApplicationServletRegistration(wrapper, context), new ServletSecurityElement(servletSecurity));
            }
        }
    }
}
Also used : Wrapper(org.apache.catalina.Wrapper) Container(org.apache.catalina.Container) ServletSecurity(jakarta.servlet.annotation.ServletSecurity) RunAs(jakarta.annotation.security.RunAs) ApplicationServletRegistration(org.apache.catalina.core.ApplicationServletRegistration) ServletSecurityElement(jakarta.servlet.ServletSecurityElement)

Example 2 with ServletSecurityElement

use of jakarta.servlet.ServletSecurityElement in project tomcat by apache.

the class ApplicationContext method addServlet.

private ServletRegistration.Dynamic addServlet(String servletName, String servletClass, Servlet servlet, Map<String, String> initParams) throws IllegalStateException {
    if (servletName == null || servletName.equals("")) {
        throw new IllegalArgumentException(sm.getString("applicationContext.invalidServletName", servletName));
    }
    if (!context.getState().equals(LifecycleState.STARTING_PREP)) {
        // TODO Spec breaking enhancement to ignore this restriction
        throw new IllegalStateException(sm.getString("applicationContext.addServlet.ise", getContextPath()));
    }
    Wrapper wrapper = (Wrapper) context.findChild(servletName);
    // a name
    if (wrapper == null) {
        wrapper = context.createWrapper();
        wrapper.setName(servletName);
        context.addChild(wrapper);
    } else {
        if (wrapper.getName() != null && wrapper.getServletClass() != null) {
            if (wrapper.isOverridable()) {
                wrapper.setOverridable(false);
            } else {
                return null;
            }
        }
    }
    ServletSecurity annotation = null;
    if (servlet == null) {
        wrapper.setServletClass(servletClass);
        Class<?> clazz = Introspection.loadClass(context, servletClass);
        if (clazz != null) {
            annotation = clazz.getAnnotation(ServletSecurity.class);
        }
    } else {
        wrapper.setServletClass(servlet.getClass().getName());
        wrapper.setServlet(servlet);
        if (context.wasCreatedDynamicServlet(servlet)) {
            annotation = servlet.getClass().getAnnotation(ServletSecurity.class);
        }
    }
    if (initParams != null) {
        for (Map.Entry<String, String> initParam : initParams.entrySet()) {
            wrapper.addInitParameter(initParam.getKey(), initParam.getValue());
        }
    }
    ServletRegistration.Dynamic registration = new ApplicationServletRegistration(wrapper, context);
    if (annotation != null) {
        registration.setServletSecurity(new ServletSecurityElement(annotation));
    }
    return registration;
}
Also used : Wrapper(org.apache.catalina.Wrapper) ServletRegistration(jakarta.servlet.ServletRegistration) ServletSecurity(jakarta.servlet.annotation.ServletSecurity) Dynamic(jakarta.servlet.ServletRegistration.Dynamic) Map(java.util.Map) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) ServletSecurityElement(jakarta.servlet.ServletSecurityElement)

Example 3 with ServletSecurityElement

use of jakarta.servlet.ServletSecurityElement in project tomcat by apache.

the class TestSecurityConstraint method testCreateConstraints.

/**
 * Uses the examples in SRV.13.4 as the basis for these tests
 */
@Test
public void testCreateConstraints() {
    ServletSecurityElement element;
    SecurityConstraint[] result;
    Set<HttpMethodConstraintElement> hmces = new HashSet<>();
    // Example 13-1
    // @ServletSecurity
    element = new ServletSecurityElement();
    result = SecurityConstraint.createConstraints(element, URL_PATTERN);
    Assert.assertEquals(0, result.length);
    // Example 13-2
    // @ServletSecurity(
    // @HttpConstraint(
    // transportGuarantee = TransportGuarantee.CONFIDENTIAL))
    element = new ServletSecurityElement(new HttpConstraintElement(ServletSecurity.TransportGuarantee.CONFIDENTIAL));
    result = SecurityConstraint.createConstraints(element, URL_PATTERN);
    Assert.assertEquals(1, result.length);
    Assert.assertFalse(result[0].getAuthConstraint());
    Assert.assertTrue(result[0].findCollections()[0].findPattern(URL_PATTERN));
    Assert.assertEquals(0, result[0].findCollections()[0].findMethods().length);
    Assert.assertEquals(ServletSecurity.TransportGuarantee.CONFIDENTIAL.name(), result[0].getUserConstraint());
    // Example 13-3
    // @ServletSecurity(@HttpConstraint(EmptyRoleSemantic.DENY))
    element = new ServletSecurityElement(new HttpConstraintElement(EmptyRoleSemantic.DENY));
    result = SecurityConstraint.createConstraints(element, URL_PATTERN);
    Assert.assertEquals(1, result.length);
    Assert.assertTrue(result[0].getAuthConstraint());
    Assert.assertTrue(result[0].findCollections()[0].findPattern(URL_PATTERN));
    Assert.assertEquals(0, result[0].findCollections()[0].findMethods().length);
    Assert.assertEquals(ServletSecurity.TransportGuarantee.NONE.name(), result[0].getUserConstraint());
    // Example 13-4
    // @ServletSecurity(@HttpConstraint(rolesAllowed = "R1"))
    element = new ServletSecurityElement(new HttpConstraintElement(ServletSecurity.TransportGuarantee.NONE, ROLE1));
    result = SecurityConstraint.createConstraints(element, URL_PATTERN);
    Assert.assertEquals(1, result.length);
    Assert.assertTrue(result[0].getAuthConstraint());
    Assert.assertEquals(1, result[0].findAuthRoles().length);
    Assert.assertTrue(result[0].findAuthRole(ROLE1));
    Assert.assertTrue(result[0].findCollections()[0].findPattern(URL_PATTERN));
    Assert.assertEquals(0, result[0].findCollections()[0].findMethods().length);
    Assert.assertEquals(ServletSecurity.TransportGuarantee.NONE.name(), result[0].getUserConstraint());
    // Example 13-5
    // @ServletSecurity((httpMethodConstraints = {
    // @HttpMethodConstraint(value = "GET", rolesAllowed = "R1"),
    // @HttpMethodConstraint(value = "POST", rolesAllowed = "R1",
    // transportGuarantee = TransportGuarantee.CONFIDENTIAL)
    // })
    hmces.clear();
    hmces.add(new HttpMethodConstraintElement("GET", new HttpConstraintElement(ServletSecurity.TransportGuarantee.NONE, ROLE1)));
    hmces.add(new HttpMethodConstraintElement("POST", new HttpConstraintElement(ServletSecurity.TransportGuarantee.CONFIDENTIAL, ROLE1)));
    element = new ServletSecurityElement(hmces);
    result = SecurityConstraint.createConstraints(element, URL_PATTERN);
    Assert.assertEquals(2, result.length);
    for (int i = 0; i < 2; i++) {
        Assert.assertTrue(result[i].getAuthConstraint());
        Assert.assertEquals(1, result[i].findAuthRoles().length);
        Assert.assertTrue(result[i].findAuthRole(ROLE1));
        Assert.assertTrue(result[i].findCollections()[0].findPattern(URL_PATTERN));
        Assert.assertEquals(1, result[i].findCollections()[0].findMethods().length);
        String method = result[i].findCollections()[0].findMethods()[0];
        if ("GET".equals(method)) {
            Assert.assertEquals(ServletSecurity.TransportGuarantee.NONE.name(), result[i].getUserConstraint());
        } else if ("POST".equals(method)) {
            Assert.assertEquals(ServletSecurity.TransportGuarantee.CONFIDENTIAL.name(), result[i].getUserConstraint());
        } else {
            Assert.fail("Unexpected method :[" + method + "]");
        }
    }
    // Example 13-6
    // @ServletSecurity(value = @HttpConstraint(rolesAllowed = "R1"),
    // httpMethodConstraints = @HttpMethodConstraint("GET"))
    hmces.clear();
    hmces.add(new HttpMethodConstraintElement("GET"));
    element = new ServletSecurityElement(new HttpConstraintElement(ServletSecurity.TransportGuarantee.NONE, ROLE1), hmces);
    result = SecurityConstraint.createConstraints(element, URL_PATTERN);
    Assert.assertEquals(2, result.length);
    for (int i = 0; i < 2; i++) {
        Assert.assertTrue(result[i].findCollections()[0].findPattern(URL_PATTERN));
        if (result[i].findCollections()[0].findMethods().length == 1) {
            Assert.assertEquals("GET", result[i].findCollections()[0].findMethods()[0]);
            Assert.assertFalse(result[i].getAuthConstraint());
        } else if (result[i].findCollections()[0].findOmittedMethods().length == 1) {
            Assert.assertEquals("GET", result[i].findCollections()[0].findOmittedMethods()[0]);
            Assert.assertTrue(result[i].getAuthConstraint());
            Assert.assertEquals(1, result[i].findAuthRoles().length);
            Assert.assertEquals(ROLE1, result[i].findAuthRoles()[0]);
        } else {
            Assert.fail("Unexpected number of methods defined");
        }
        Assert.assertEquals(ServletSecurity.TransportGuarantee.NONE.name(), result[i].getUserConstraint());
    }
    // Example 13-7
    // @ServletSecurity(value = @HttpConstraint(rolesAllowed = "R1"),
    // httpMethodConstraints = @HttpMethodConstraint(value="TRACE",
    // emptyRoleSemantic = EmptyRoleSemantic.DENY))
    hmces.clear();
    hmces.add(new HttpMethodConstraintElement("TRACE", new HttpConstraintElement(EmptyRoleSemantic.DENY)));
    element = new ServletSecurityElement(new HttpConstraintElement(ServletSecurity.TransportGuarantee.NONE, ROLE1), hmces);
    result = SecurityConstraint.createConstraints(element, URL_PATTERN);
    Assert.assertEquals(2, result.length);
    for (int i = 0; i < 2; i++) {
        Assert.assertTrue(result[i].findCollections()[0].findPattern(URL_PATTERN));
        if (result[i].findCollections()[0].findMethods().length == 1) {
            Assert.assertEquals("TRACE", result[i].findCollections()[0].findMethods()[0]);
            Assert.assertTrue(result[i].getAuthConstraint());
            Assert.assertEquals(0, result[i].findAuthRoles().length);
        } else if (result[i].findCollections()[0].findOmittedMethods().length == 1) {
            Assert.assertEquals("TRACE", result[i].findCollections()[0].findOmittedMethods()[0]);
            Assert.assertTrue(result[i].getAuthConstraint());
            Assert.assertEquals(1, result[i].findAuthRoles().length);
            Assert.assertEquals(ROLE1, result[i].findAuthRoles()[0]);
        } else {
            Assert.fail("Unexpected number of methods defined");
        }
        Assert.assertEquals(ServletSecurity.TransportGuarantee.NONE.name(), result[i].getUserConstraint());
    }
// Example 13-8 is the same as 13-4
// Example 13-9 is the same as 13-7
}
Also used : HttpConstraintElement(jakarta.servlet.HttpConstraintElement) ServletSecurityElement(jakarta.servlet.ServletSecurityElement) HttpMethodConstraintElement(jakarta.servlet.HttpMethodConstraintElement) HashSet(java.util.HashSet) Test(org.junit.Test)

Example 4 with ServletSecurityElement

use of jakarta.servlet.ServletSecurityElement in project tomcat by apache.

the class TestRealmBase method testHttpConstraint.

/*
     * This test case covers the special case in section 13.4.1 of the Servlet
     * 3.1 specification for {@link jakarta.servlet.annotation.HttpConstraint}.
     */
@Test
public void testHttpConstraint() throws IOException {
    // Get the annotation from the test case
    Class<TesterServletSecurity01> clazz = TesterServletSecurity01.class;
    ServletSecurity servletSecurity = clazz.getAnnotation(ServletSecurity.class);
    // Convert the annotation into constraints
    ServletSecurityElement servletSecurityElement = new ServletSecurityElement(servletSecurity);
    SecurityConstraint[] constraints = SecurityConstraint.createConstraints(servletSecurityElement, "/*");
    // Create a separate constraint that covers DELETE
    SecurityConstraint deleteConstraint = new SecurityConstraint();
    deleteConstraint.addAuthRole(ROLE1);
    SecurityCollection deleteCollection = new SecurityCollection();
    deleteCollection.addMethod("DELETE");
    deleteCollection.addPatternDecoded("/*");
    deleteConstraint.addCollection(deleteCollection);
    TesterMapRealm mapRealm = new TesterMapRealm();
    // Set up the mock request and response
    TesterRequest request = new TesterRequest();
    Response response = new TesterResponse();
    Context context = request.getContext();
    context.addSecurityRole(ROLE1);
    context.addSecurityRole(ROLE2);
    request.getMappingData().context = context;
    // Create the principals
    List<String> userRoles1 = new ArrayList<>();
    userRoles1.add(ROLE1);
    GenericPrincipal gp1 = new GenericPrincipal(USER1, userRoles1);
    List<String> userRoles2 = new ArrayList<>();
    userRoles2.add(ROLE2);
    GenericPrincipal gp2 = new GenericPrincipal(USER2, userRoles2);
    List<String> userRoles99 = new ArrayList<>();
    GenericPrincipal gp99 = new GenericPrincipal(USER99, userRoles99);
    // Add the constraints to the context
    for (SecurityConstraint constraint : constraints) {
        context.addConstraint(constraint);
    }
    context.addConstraint(deleteConstraint);
    // All users should be able to perform a GET
    request.setMethod("GET");
    SecurityConstraint[] constraintsGet = mapRealm.findSecurityConstraints(request, context);
    request.setUserPrincipal(null);
    Assert.assertTrue(mapRealm.hasResourcePermission(request, response, constraintsGet, null));
    request.setUserPrincipal(gp1);
    Assert.assertTrue(mapRealm.hasResourcePermission(request, response, constraintsGet, null));
    request.setUserPrincipal(gp2);
    Assert.assertTrue(mapRealm.hasResourcePermission(request, response, constraintsGet, null));
    request.setUserPrincipal(gp99);
    Assert.assertTrue(mapRealm.hasResourcePermission(request, response, constraintsGet, null));
    // Only user1 should be able to perform a POST as only that user has
    // role1.
    request.setMethod("POST");
    SecurityConstraint[] constraintsPost = mapRealm.findSecurityConstraints(request, context);
    request.setUserPrincipal(null);
    Assert.assertFalse(mapRealm.hasResourcePermission(request, response, constraintsPost, null));
    request.setUserPrincipal(gp1);
    Assert.assertTrue(mapRealm.hasResourcePermission(request, response, constraintsPost, null));
    request.setUserPrincipal(gp2);
    Assert.assertFalse(mapRealm.hasResourcePermission(request, response, constraintsPost, null));
    request.setUserPrincipal(gp99);
    Assert.assertFalse(mapRealm.hasResourcePermission(request, response, constraintsPost, null));
    // Only users with application roles (role1 or role2 so user1 or user2)
    // should be able to perform a PUT.
    request.setMethod("PUT");
    SecurityConstraint[] constraintsPut = mapRealm.findSecurityConstraints(request, context);
    request.setUserPrincipal(null);
    Assert.assertFalse(mapRealm.hasResourcePermission(request, response, constraintsPut, null));
    request.setUserPrincipal(gp1);
    Assert.assertTrue(mapRealm.hasResourcePermission(request, response, constraintsPut, null));
    request.setUserPrincipal(gp2);
    Assert.assertTrue(mapRealm.hasResourcePermission(request, response, constraintsPut, null));
    request.setUserPrincipal(gp99);
    Assert.assertFalse(mapRealm.hasResourcePermission(request, response, constraintsPut, null));
    // Any authenticated user should be able to perform a TRACE.
    request.setMethod("TRACE");
    SecurityConstraint[] constraintsTrace = mapRealm.findSecurityConstraints(request, context);
    request.setUserPrincipal(null);
    Assert.assertFalse(mapRealm.hasResourcePermission(request, response, constraintsTrace, null));
    request.setUserPrincipal(gp1);
    Assert.assertTrue(mapRealm.hasResourcePermission(request, response, constraintsTrace, null));
    request.setUserPrincipal(gp2);
    Assert.assertTrue(mapRealm.hasResourcePermission(request, response, constraintsTrace, null));
    request.setUserPrincipal(gp99);
    Assert.assertTrue(mapRealm.hasResourcePermission(request, response, constraintsTrace, null));
    // Only user1 should be able to perform a DELETE as only that user has
    // role1.
    request.setMethod("DELETE");
    SecurityConstraint[] constraintsDelete = mapRealm.findSecurityConstraints(request, context);
    request.setUserPrincipal(null);
    Assert.assertFalse(mapRealm.hasResourcePermission(request, response, constraintsDelete, null));
    request.setUserPrincipal(gp1);
    Assert.assertTrue(mapRealm.hasResourcePermission(request, response, constraintsDelete, null));
    request.setUserPrincipal(gp2);
    Assert.assertFalse(mapRealm.hasResourcePermission(request, response, constraintsDelete, null));
    request.setUserPrincipal(gp99);
    Assert.assertFalse(mapRealm.hasResourcePermission(request, response, constraintsDelete, null));
}
Also used : Context(org.apache.catalina.Context) TesterContext(org.apache.tomcat.unittest.TesterContext) ServletSecurity(jakarta.servlet.annotation.ServletSecurity) ArrayList(java.util.ArrayList) TesterResponse(org.apache.tomcat.unittest.TesterResponse) ServletSecurityElement(jakarta.servlet.ServletSecurityElement) SecurityConstraint(org.apache.tomcat.util.descriptor.web.SecurityConstraint) TesterResponse(org.apache.tomcat.unittest.TesterResponse) Response(org.apache.catalina.connector.Response) TesterMapRealm(org.apache.catalina.startup.TesterMapRealm) TesterRequest(org.apache.tomcat.unittest.TesterRequest) SecurityCollection(org.apache.tomcat.util.descriptor.web.SecurityCollection) Test(org.junit.Test)

Aggregations

ServletSecurityElement (jakarta.servlet.ServletSecurityElement)4 ServletSecurity (jakarta.servlet.annotation.ServletSecurity)3 Wrapper (org.apache.catalina.Wrapper)2 Test (org.junit.Test)2 RunAs (jakarta.annotation.security.RunAs)1 HttpConstraintElement (jakarta.servlet.HttpConstraintElement)1 HttpMethodConstraintElement (jakarta.servlet.HttpMethodConstraintElement)1 ServletRegistration (jakarta.servlet.ServletRegistration)1 Dynamic (jakarta.servlet.ServletRegistration.Dynamic)1 ArrayList (java.util.ArrayList)1 HashMap (java.util.HashMap)1 HashSet (java.util.HashSet)1 Map (java.util.Map)1 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)1 Container (org.apache.catalina.Container)1 Context (org.apache.catalina.Context)1 Response (org.apache.catalina.connector.Response)1 ApplicationServletRegistration (org.apache.catalina.core.ApplicationServletRegistration)1 TesterMapRealm (org.apache.catalina.startup.TesterMapRealm)1 TesterContext (org.apache.tomcat.unittest.TesterContext)1