405432 Check implementation of section 13.4.1 @ServletSecurity for @HttpConstraint and HttpMethodConstraint clarifications

This commit is contained in:
Jan Bartel 2013-05-03 14:47:56 +10:00
parent 348cbc2173
commit 41304644e6
2 changed files with 179 additions and 17 deletions

View File

@ -235,41 +235,50 @@ public class ConstraintSecurityHandler extends SecurityHandler implements Constr
List<ConstraintMapping> mappings = new ArrayList<ConstraintMapping>(); List<ConstraintMapping> mappings = new ArrayList<ConstraintMapping>();
//Create a constraint that will describe the default case (ie if not overridden by specific HttpMethodConstraints) //Create a constraint that will describe the default case (ie if not overridden by specific HttpMethodConstraints)
Constraint constraint = ConstraintSecurityHandler.createConstraint(name, securityElement); Constraint httpConstraint = null;
ConstraintMapping httpConstraintMapping = null;
if (securityElement.getEmptyRoleSemantic() != EmptyRoleSemantic.PERMIT ||
securityElement.getRolesAllowed().length != 0 ||
securityElement.getTransportGuarantee() != TransportGuarantee.NONE)
{
httpConstraint = ConstraintSecurityHandler.createConstraint(name, securityElement);
//Create a mapping for the pathSpec for the default case //Create a mapping for the pathSpec for the default case
ConstraintMapping defaultMapping = new ConstraintMapping(); httpConstraintMapping = new ConstraintMapping();
defaultMapping.setPathSpec(pathSpec); httpConstraintMapping.setPathSpec(pathSpec);
defaultMapping.setConstraint(constraint); httpConstraintMapping.setConstraint(httpConstraint);
mappings.add(defaultMapping); mappings.add(httpConstraintMapping);
}
//See Spec 13.4.1.2 p127 //See Spec 13.4.1.2 p127
List<String> methodOmissions = new ArrayList<String>(); List<String> methodOmissions = new ArrayList<String>();
//make constraint mappings for this url for each of the HttpMethodConstraintElements //make constraint mappings for this url for each of the HttpMethodConstraintElements
Collection<HttpMethodConstraintElement> methodConstraints = securityElement.getHttpMethodConstraints(); Collection<HttpMethodConstraintElement> methodConstraintElements = securityElement.getHttpMethodConstraints();
if (methodConstraints != null) if (methodConstraintElements != null)
{ {
for (HttpMethodConstraintElement methodConstraint:methodConstraints) for (HttpMethodConstraintElement methodConstraintElement:methodConstraintElements)
{ {
//Make a Constraint that captures the <auth-constraint> and <user-data-constraint> elements supplied for the HttpMethodConstraintElement //Make a Constraint that captures the <auth-constraint> and <user-data-constraint> elements supplied for the HttpMethodConstraintElement
Constraint mconstraint = ConstraintSecurityHandler.createConstraint(name, methodConstraint); Constraint methodConstraint = ConstraintSecurityHandler.createConstraint(name, methodConstraintElement);
ConstraintMapping mapping = new ConstraintMapping(); ConstraintMapping mapping = new ConstraintMapping();
mapping.setConstraint(mconstraint); mapping.setConstraint(methodConstraint);
mapping.setPathSpec(pathSpec); mapping.setPathSpec(pathSpec);
if (methodConstraint.getMethodName() != null) if (methodConstraintElement.getMethodName() != null)
{ {
mapping.setMethod(methodConstraint.getMethodName()); mapping.setMethod(methodConstraintElement.getMethodName());
//See spec 13.4.1.2 p127 - add an omission for every method name to the default constraint //See spec 13.4.1.2 p127 - add an omission for every method name to the default constraint
methodOmissions.add(methodConstraint.getMethodName()); methodOmissions.add(methodConstraintElement.getMethodName());
} }
mappings.add(mapping); mappings.add(mapping);
} }
} }
//See spec 13.4.1.2 p127 - add an omission for every method name to the default constraint //See spec 13.4.1.2 p127 - add an omission for every method name to the default constraint
if (methodOmissions.size() > 0) //UNLESS the default constraint contains all default values. In that case, we won't add it. See Servlet Spec 3.1 pg 129
defaultMapping.setMethodOmissions(methodOmissions.toArray(new String[methodOmissions.size()])); if (methodOmissions.size() > 0 && httpConstraintMapping != null)
httpConstraintMapping.setMethodOmissions(methodOmissions.toArray(new String[methodOmissions.size()]));
return mappings; return mappings;
} }

View File

@ -40,7 +40,12 @@ import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import javax.servlet.HttpConstraintElement;
import javax.servlet.HttpMethodConstraintElement;
import javax.servlet.ServletException; import javax.servlet.ServletException;
import javax.servlet.ServletSecurityElement;
import javax.servlet.annotation.ServletSecurity.EmptyRoleSemantic;
import javax.servlet.annotation.ServletSecurity.TransportGuarantee;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
@ -223,6 +228,154 @@ public class ConstraintTest
} }
/**
* Equivalent of Servlet Spec 3.1 pg 132, sec 13.4.1.1, Example 13-1
* @ServletSecurity
* @throws Exception
*/
@Test
public void testSecurityElementExample13_1() throws Exception
{
ServletSecurityElement element = new ServletSecurityElement();
List<ConstraintMapping> mappings = ConstraintSecurityHandler.createConstraintsWithMappingsForPath("foo", "/foo/*", element);
assertTrue(mappings.isEmpty());
}
/**
* Equivalent of Servlet Spec 3.1 pg 132, sec 13.4.1.1, Example 13-2
* @ServletSecurity(@HttpConstraint(transportGuarantee = TransportGuarantee.CONFIDENTIAL))
*
* @throws Exception
*/
@Test
public void testSecurityElementExample13_2() throws Exception
{
HttpConstraintElement httpConstraintElement = new HttpConstraintElement(TransportGuarantee.CONFIDENTIAL, new String[]{});
ServletSecurityElement element = new ServletSecurityElement(httpConstraintElement);
List<ConstraintMapping> mappings = ConstraintSecurityHandler.createConstraintsWithMappingsForPath("foo", "/foo/*", element);
assertTrue(!mappings.isEmpty());
assertEquals(1, mappings.size());
ConstraintMapping mapping = mappings.get(0);
assertEquals(2, mapping.getConstraint().getDataConstraint());
}
/**
* Equivalent of Servlet Spec 3.1 pg 132, sec 13.4.1.1, Example 13-3
* @ServletSecurity(@HttpConstraint(EmptyRoleSemantic.DENY))
* @throws Exception
*/
@Test
public void testSecurityElementExample13_3() throws Exception
{
HttpConstraintElement httpConstraintElement = new HttpConstraintElement(EmptyRoleSemantic.DENY);
ServletSecurityElement element = new ServletSecurityElement(httpConstraintElement);
List<ConstraintMapping> mappings = ConstraintSecurityHandler.createConstraintsWithMappingsForPath("foo", "/foo/*", element);
assertTrue(!mappings.isEmpty());
assertEquals(1, mappings.size());
ConstraintMapping mapping = mappings.get(0);
assertTrue(mapping.getConstraint().isForbidden());
}
/**
* Equivalent of Servlet Spec 3.1 pg 132, sec 13.4.1.1, Example 13-4
* @ServletSecurity(@HttpConstraint(rolesAllowed = "R1"))
* @throws Exception
*/
@Test
public void testSecurityElementExample13_4() throws Exception
{
HttpConstraintElement httpConstraintElement = new HttpConstraintElement(TransportGuarantee.NONE, "R1");
ServletSecurityElement element = new ServletSecurityElement(httpConstraintElement);
List<ConstraintMapping> mappings = ConstraintSecurityHandler.createConstraintsWithMappingsForPath("foo", "/foo/*", element);
assertTrue(!mappings.isEmpty());
assertEquals(1, mappings.size());
ConstraintMapping mapping = mappings.get(0);
assertTrue(mapping.getConstraint().getAuthenticate());
assertTrue(mapping.getConstraint().getRoles() != null);
assertEquals(1, mapping.getConstraint().getRoles().length);
assertEquals("R1", mapping.getConstraint().getRoles()[0]);
assertEquals(0, mapping.getConstraint().getDataConstraint());
}
/**
* Equivalent of Servlet Spec 3.1 pg 132, sec 13.4.1.1, Example 13-5
* @ServletSecurity((httpMethodConstraints = {
* @HttpMethodConstraint(value = "GET", rolesAllowed = "R1"),
* @HttpMethodConstraint(value = "POST", rolesAllowed = "R1",
* transportGuarantee = TransportGuarantee.CONFIDENTIAL)})
* @throws Exception
*/
@Test
public void testSecurityElementExample13_5() throws Exception
{
List<HttpMethodConstraintElement> methodElements = new ArrayList<HttpMethodConstraintElement>();
methodElements.add(new HttpMethodConstraintElement("GET", new HttpConstraintElement(TransportGuarantee.NONE, "R1")));
methodElements.add(new HttpMethodConstraintElement("POST", new HttpConstraintElement(TransportGuarantee.CONFIDENTIAL, "R1")));
ServletSecurityElement element = new ServletSecurityElement(methodElements);
List<ConstraintMapping> mappings = ConstraintSecurityHandler.createConstraintsWithMappingsForPath("foo", "/foo/*", element);
assertTrue(!mappings.isEmpty());
assertEquals(2, mappings.size());
assertEquals("GET", mappings.get(0).getMethod());
assertEquals("R1", mappings.get(0).getConstraint().getRoles()[0]);
assertTrue(mappings.get(0).getMethodOmissions() == null);
assertEquals(0, mappings.get(0).getConstraint().getDataConstraint());
assertEquals("POST", mappings.get(1).getMethod());
assertEquals("R1", mappings.get(1).getConstraint().getRoles()[0]);
assertEquals(2, mappings.get(1).getConstraint().getDataConstraint());
assertTrue(mappings.get(1).getMethodOmissions() == null);
}
/**
* Equivalent of Servlet Spec 3.1 pg 132, sec 13.4.1.1, Example 13-6
* @ServletSecurity(value = @HttpConstraint(rolesAllowed = "R1"), httpMethodConstraints = @HttpMethodConstraint("GET"))
* @throws Exception
*/
@Test
public void testSecurityElementExample13_6 () throws Exception
{
List<HttpMethodConstraintElement> methodElements = new ArrayList<HttpMethodConstraintElement>();
methodElements.add(new HttpMethodConstraintElement("GET"));
ServletSecurityElement element = new ServletSecurityElement(new HttpConstraintElement(TransportGuarantee.NONE, "R1"), methodElements);
List<ConstraintMapping> mappings = ConstraintSecurityHandler.createConstraintsWithMappingsForPath("foo", "/foo/*", element);
assertTrue(!mappings.isEmpty());
assertEquals(2, mappings.size());
assertTrue(mappings.get(0).getMethodOmissions() != null);
assertEquals("GET", mappings.get(0).getMethodOmissions()[0]);
assertTrue(mappings.get(0).getConstraint().getAuthenticate());
assertEquals("R1", mappings.get(0).getConstraint().getRoles()[0]);
assertEquals("GET", mappings.get(1).getMethod());
assertTrue(mappings.get(1).getMethodOmissions() == null);
assertEquals(0, mappings.get(1).getConstraint().getDataConstraint());
assertFalse(mappings.get(1).getConstraint().getAuthenticate());
}
/**
* Equivalent of Servlet Spec 3.1 pg 132, sec 13.4.1.1, Example 13-7
* @ServletSecurity(value = @HttpConstraint(rolesAllowed = "R1"),
* httpMethodConstraints = @HttpMethodConstraint(value="TRACE",
* emptyRoleSemantic = EmptyRoleSemantic.DENY))
* @throws Exception
*/
@Test
public void testSecurityElementExample13_7() throws Exception
{
List<HttpMethodConstraintElement> methodElements = new ArrayList<HttpMethodConstraintElement>();
methodElements.add(new HttpMethodConstraintElement("TRACE", new HttpConstraintElement(EmptyRoleSemantic.DENY)));
ServletSecurityElement element = new ServletSecurityElement(new HttpConstraintElement(TransportGuarantee.NONE, "R1"), methodElements);
List<ConstraintMapping> mappings = ConstraintSecurityHandler.createConstraintsWithMappingsForPath("foo", "/foo/*", element);
assertTrue(!mappings.isEmpty());
assertEquals(2, mappings.size());
assertTrue(mappings.get(0).getMethodOmissions() != null);
assertEquals("TRACE", mappings.get(0).getMethodOmissions()[0]);
assertTrue(mappings.get(0).getConstraint().getAuthenticate());
assertEquals("R1", mappings.get(0).getConstraint().getRoles()[0]);
assertEquals("TRACE", mappings.get(1).getMethod());
assertTrue(mappings.get(1).getMethodOmissions() == null);
assertEquals(0, mappings.get(1).getConstraint().getDataConstraint());
assertTrue(mappings.get(1).getConstraint().isForbidden());
}
@Test @Test
public void testUncoveredHttpMethodDetection() throws Exception public void testUncoveredHttpMethodDetection() throws Exception
{ {