| // |
| // ======================================================================== |
| // Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd. |
| // ------------------------------------------------------------------------ |
| // All rights reserved. This program and the accompanying materials |
| // are made available under the terms of the Eclipse Public License v1.0 |
| // and Apache License v2.0 which accompanies this distribution. |
| // |
| // The Eclipse Public License is available at |
| // http://www.eclipse.org/legal/epl-v10.html |
| // |
| // The Apache License v2.0 is available at |
| // http://www.opensource.org/licenses/apache2.0.php |
| // |
| // You may elect to redistribute this code under either of these licenses. |
| // ======================================================================== |
| // |
| |
| package org.eclipse.jetty.security; |
| |
| import java.io.IOException; |
| import java.nio.charset.StandardCharsets; |
| import java.security.MessageDigest; |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.Collections; |
| import java.util.HashMap; |
| import java.util.HashSet; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Set; |
| import java.util.concurrent.TimeUnit; |
| import java.util.regex.Matcher; |
| import java.util.regex.Pattern; |
| |
| import javax.servlet.HttpConstraintElement; |
| import javax.servlet.HttpMethodConstraintElement; |
| 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.HttpServletResponse; |
| |
| import org.eclipse.jetty.security.authentication.BasicAuthenticator; |
| import org.eclipse.jetty.security.authentication.DigestAuthenticator; |
| import org.eclipse.jetty.security.authentication.FormAuthenticator; |
| import org.eclipse.jetty.server.Connector; |
| import org.eclipse.jetty.server.HttpConfiguration; |
| import org.eclipse.jetty.server.HttpConnectionFactory; |
| import org.eclipse.jetty.server.LocalConnector; |
| import org.eclipse.jetty.server.Request; |
| import org.eclipse.jetty.server.Server; |
| import org.eclipse.jetty.server.UserIdentity; |
| import org.eclipse.jetty.server.handler.AbstractHandler; |
| import org.eclipse.jetty.server.handler.ContextHandler; |
| import org.eclipse.jetty.server.handler.HandlerWrapper; |
| import org.eclipse.jetty.server.session.SessionHandler; |
| import org.eclipse.jetty.util.B64Code; |
| import org.eclipse.jetty.util.TypeUtil; |
| import org.eclipse.jetty.util.security.Constraint; |
| import org.eclipse.jetty.util.security.Password; |
| import org.hamcrest.Matchers; |
| import org.junit.After; |
| import org.junit.Assert; |
| import org.junit.Before; |
| import org.junit.Test; |
| |
| public class ConstraintTest |
| { |
| private static final String TEST_REALM = "TestRealm"; |
| private Server _server; |
| private LocalConnector _connector; |
| private ConstraintSecurityHandler _security; |
| private HttpConfiguration _config; |
| |
| @Before |
| public void startServer() |
| { |
| _server = new Server(); |
| _connector = new LocalConnector(_server); |
| _config=_connector.getConnectionFactory(HttpConnectionFactory.class).getHttpConfiguration(); |
| _server.setConnectors(new Connector[]{_connector}); |
| |
| ContextHandler _context = new ContextHandler(); |
| SessionHandler _session = new SessionHandler(); |
| |
| HashLoginService _loginService = new HashLoginService(TEST_REALM); |
| _loginService.putUser("user0", new Password("password"), new String[]{}); |
| _loginService.putUser("user",new Password("password"), new String[] {"user"}); |
| _loginService.putUser("user2",new Password("password"), new String[] {"user"}); |
| _loginService.putUser("admin",new Password("password"), new String[] {"user","administrator"}); |
| _loginService.putUser("user3", new Password("password"), new String[] {"foo"}); |
| |
| |
| _context.setContextPath("/ctx"); |
| _server.setHandler(_context); |
| _context.setHandler(_session); |
| |
| _server.addBean(_loginService); |
| |
| _security = new ConstraintSecurityHandler(); |
| _session.setHandler(_security); |
| RequestHandler _handler = new RequestHandler(); |
| _security.setHandler(_handler); |
| |
| _security.setConstraintMappings(getConstraintMappings(), getKnownRoles()); |
| } |
| |
| @After |
| public void stopServer() throws Exception |
| { |
| _server.stop(); |
| } |
| |
| public Set<String> getKnownRoles() |
| { |
| Set<String> knownRoles=new HashSet<>(); |
| knownRoles.add("user"); |
| knownRoles.add("administrator"); |
| |
| return knownRoles; |
| } |
| |
| private List<ConstraintMapping> getConstraintMappings() |
| { |
| Constraint constraint0 = new Constraint(); |
| constraint0.setAuthenticate(true); |
| constraint0.setName("forbid"); |
| ConstraintMapping mapping0 = new ConstraintMapping(); |
| mapping0.setPathSpec("/forbid/*"); |
| mapping0.setConstraint(constraint0); |
| |
| Constraint constraint1 = new Constraint(); |
| constraint1.setAuthenticate(true); |
| constraint1.setName("auth"); |
| constraint1.setRoles(new String[]{Constraint.ANY_ROLE}); |
| ConstraintMapping mapping1 = new ConstraintMapping(); |
| mapping1.setPathSpec("/auth/*"); |
| mapping1.setConstraint(constraint1); |
| |
| Constraint constraint2 = new Constraint(); |
| constraint2.setAuthenticate(true); |
| constraint2.setName("admin"); |
| constraint2.setRoles(new String[]{"administrator"}); |
| ConstraintMapping mapping2 = new ConstraintMapping(); |
| mapping2.setPathSpec("/admin/*"); |
| mapping2.setConstraint(constraint2); |
| mapping2.setMethod("GET"); |
| |
| Constraint constraint3 = new Constraint(); |
| constraint3.setAuthenticate(false); |
| constraint3.setName("relax"); |
| ConstraintMapping mapping3 = new ConstraintMapping(); |
| mapping3.setPathSpec("/admin/relax/*"); |
| mapping3.setConstraint(constraint3); |
| |
| Constraint constraint4 = new Constraint(); |
| constraint4.setAuthenticate(true); |
| constraint4.setName("loginpage"); |
| constraint4.setRoles(new String[]{"administrator"}); |
| ConstraintMapping mapping4 = new ConstraintMapping(); |
| mapping4.setPathSpec("/testLoginPage"); |
| mapping4.setConstraint(constraint4); |
| |
| Constraint constraint5 = new Constraint(); |
| constraint5.setAuthenticate(false); |
| constraint5.setName("allow forbidden POST"); |
| ConstraintMapping mapping5 = new ConstraintMapping(); |
| mapping5.setPathSpec("/forbid/post"); |
| mapping5.setConstraint(constraint5); |
| mapping5.setMethod("POST"); |
| |
| Constraint constraint6 = new Constraint(); |
| constraint6.setAuthenticate(false); |
| constraint6.setName("data constraint"); |
| constraint6.setDataConstraint(2); |
| ConstraintMapping mapping6 = new ConstraintMapping(); |
| mapping6.setPathSpec("/data/*"); |
| mapping6.setConstraint(constraint6); |
| |
| Constraint constraint7 = new Constraint(); |
| constraint7.setAuthenticate(true); |
| constraint7.setName("** constraint"); |
| constraint7.setRoles(new String[]{Constraint.ANY_AUTH,"user"}); //the "user" role is superfluous once ** has been defined |
| ConstraintMapping mapping7 = new ConstraintMapping(); |
| mapping7.setPathSpec("/starstar/*"); |
| mapping7.setConstraint(constraint7); |
| |
| |
| return Arrays.asList(mapping0, mapping1, mapping2, mapping3, mapping4, mapping5, mapping6, mapping7); |
| } |
| |
| @Test |
| public void testConstraints() throws Exception |
| { |
| List<ConstraintMapping> mappings = new ArrayList<>(_security.getConstraintMappings()); |
| |
| Assert.assertTrue(mappings.get(0).getConstraint().isForbidden()); |
| Assert.assertFalse(mappings.get(1).getConstraint().isForbidden()); |
| Assert.assertFalse(mappings.get(2).getConstraint().isForbidden()); |
| Assert.assertFalse(mappings.get(3).getConstraint().isForbidden()); |
| |
| Assert.assertFalse(mappings.get(0).getConstraint().isAnyRole()); |
| Assert.assertTrue(mappings.get(1).getConstraint().isAnyRole()); |
| Assert.assertFalse(mappings.get(2).getConstraint().isAnyRole()); |
| Assert.assertFalse(mappings.get(3).getConstraint().isAnyRole()); |
| |
| Assert.assertFalse(mappings.get(0).getConstraint().hasRole("administrator")); |
| Assert.assertTrue(mappings.get(1).getConstraint().hasRole("administrator")); |
| Assert.assertTrue(mappings.get(2).getConstraint().hasRole("administrator")); |
| Assert.assertFalse(mappings.get(3).getConstraint().hasRole("administrator")); |
| |
| Assert.assertTrue(mappings.get(0).getConstraint().getAuthenticate()); |
| Assert.assertTrue(mappings.get(1).getConstraint().getAuthenticate()); |
| Assert.assertTrue(mappings.get(2).getConstraint().getAuthenticate()); |
| Assert.assertFalse(mappings.get(3).getConstraint().getAuthenticate()); |
| } |
| |
| |
| /** |
| * Equivalent of Servlet Spec 3.1 pg 132, sec 13.4.1.1, Example 13-1 |
| * @ServletSecurity |
| * @throws Exception if test fails |
| */ |
| @Test |
| public void testSecurityElementExample13_1() throws Exception |
| { |
| ServletSecurityElement element = new ServletSecurityElement(); |
| List<ConstraintMapping> mappings = ConstraintSecurityHandler.createConstraintsWithMappingsForPath("foo", "/foo/*", element); |
| Assert.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 if test fails |
| */ |
| @Test |
| public void testSecurityElementExample13_2() throws Exception |
| { |
| HttpConstraintElement httpConstraintElement = new HttpConstraintElement(TransportGuarantee.CONFIDENTIAL); |
| ServletSecurityElement element = new ServletSecurityElement(httpConstraintElement); |
| List<ConstraintMapping> mappings = ConstraintSecurityHandler.createConstraintsWithMappingsForPath("foo", "/foo/*", element); |
| Assert.assertTrue(!mappings.isEmpty()); |
| Assert.assertEquals(1, mappings.size()); |
| ConstraintMapping mapping = mappings.get(0); |
| Assert.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 if test fails |
| */ |
| @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); |
| Assert.assertTrue(!mappings.isEmpty()); |
| Assert.assertEquals(1, mappings.size()); |
| ConstraintMapping mapping = mappings.get(0); |
| Assert.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 if test fails |
| */ |
| @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); |
| Assert.assertTrue(!mappings.isEmpty()); |
| Assert.assertEquals(1, mappings.size()); |
| ConstraintMapping mapping = mappings.get(0); |
| Assert.assertTrue(mapping.getConstraint().getAuthenticate()); |
| Assert.assertTrue(mapping.getConstraint().getRoles() != null); |
| Assert.assertEquals(1, mapping.getConstraint().getRoles().length); |
| Assert.assertEquals("R1", mapping.getConstraint().getRoles()[0]); |
| Assert.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 if test fails |
| */ |
| @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); |
| Assert.assertTrue(!mappings.isEmpty()); |
| Assert.assertEquals(2, mappings.size()); |
| Assert.assertEquals("GET", mappings.get(0).getMethod()); |
| Assert.assertEquals("R1", mappings.get(0).getConstraint().getRoles()[0]); |
| Assert.assertTrue(mappings.get(0).getMethodOmissions() == null); |
| Assert.assertEquals(0, mappings.get(0).getConstraint().getDataConstraint()); |
| Assert.assertEquals("POST", mappings.get(1).getMethod()); |
| Assert.assertEquals("R1", mappings.get(1).getConstraint().getRoles()[0]); |
| Assert.assertEquals(2, mappings.get(1).getConstraint().getDataConstraint()); |
| Assert.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 if test fails |
| */ |
| @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); |
| Assert.assertTrue(!mappings.isEmpty()); |
| Assert.assertEquals(2, mappings.size()); |
| Assert.assertTrue(mappings.get(0).getMethodOmissions() != null); |
| Assert.assertEquals("GET", mappings.get(0).getMethodOmissions()[0]); |
| Assert.assertTrue(mappings.get(0).getConstraint().getAuthenticate()); |
| Assert.assertEquals("R1", mappings.get(0).getConstraint().getRoles()[0]); |
| Assert.assertEquals("GET", mappings.get(1).getMethod()); |
| Assert.assertTrue(mappings.get(1).getMethodOmissions() == null); |
| Assert.assertEquals(0, mappings.get(1).getConstraint().getDataConstraint()); |
| Assert.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 if test fails |
| */ |
| @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); |
| Assert.assertTrue(!mappings.isEmpty()); |
| Assert.assertEquals(2, mappings.size()); |
| Assert.assertTrue(mappings.get(0).getMethodOmissions() != null); |
| Assert.assertEquals("TRACE", mappings.get(0).getMethodOmissions()[0]); |
| Assert.assertTrue(mappings.get(0).getConstraint().getAuthenticate()); |
| Assert.assertEquals("R1", mappings.get(0).getConstraint().getRoles()[0]); |
| Assert.assertEquals("TRACE", mappings.get(1).getMethod()); |
| Assert.assertTrue(mappings.get(1).getMethodOmissions() == null); |
| Assert.assertEquals(0, mappings.get(1).getConstraint().getDataConstraint()); |
| Assert.assertTrue(mappings.get(1).getConstraint().isForbidden()); |
| } |
| |
| @Test |
| public void testUncoveredHttpMethodDetection() throws Exception |
| { |
| //Test no methods named |
| Constraint constraint1 = new Constraint(); |
| constraint1.setAuthenticate(true); |
| constraint1.setName("** constraint"); |
| constraint1.setRoles(new String[]{Constraint.ANY_AUTH,"user"}); //No methods named, no uncovered methods |
| ConstraintMapping mapping1 = new ConstraintMapping(); |
| mapping1.setPathSpec("/starstar/*"); |
| mapping1.setConstraint(constraint1); |
| |
| _security.setConstraintMappings(Collections.singletonList(mapping1)); |
| _security.setAuthenticator(new BasicAuthenticator()); |
| _server.start(); |
| |
| Set<String> uncoveredPaths = _security.getPathsWithUncoveredHttpMethods(); |
| Assert.assertTrue(uncoveredPaths.isEmpty()); //no uncovered methods |
| |
| //Test only an explicitly named method, no omissions to cover other methods |
| Constraint constraint2 = new Constraint(); |
| constraint2.setAuthenticate(true); |
| constraint2.setName("user constraint"); |
| constraint2.setRoles(new String[]{"user"}); |
| ConstraintMapping mapping2 = new ConstraintMapping(); |
| mapping2.setPathSpec("/user/*"); |
| mapping2.setMethod("GET"); |
| mapping2.setConstraint(constraint2); |
| |
| _security.addConstraintMapping(mapping2); |
| uncoveredPaths = _security.getPathsWithUncoveredHttpMethods(); |
| Assert.assertNotNull(uncoveredPaths); |
| Assert.assertEquals(1, uncoveredPaths.size()); |
| Assert.assertTrue(uncoveredPaths.contains("/user/*")); |
| |
| //Test an explicitly named method with a http-method-omission to cover all other methods |
| Constraint constraint2a = new Constraint(); |
| constraint2a.setAuthenticate(true); |
| constraint2a.setName("forbid constraint"); |
| ConstraintMapping mapping2a = new ConstraintMapping(); |
| mapping2a.setPathSpec("/user/*"); |
| mapping2a.setMethodOmissions(new String[]{"GET"}); |
| mapping2a.setConstraint(constraint2a); |
| |
| _security.addConstraintMapping(mapping2a); |
| uncoveredPaths = _security.getPathsWithUncoveredHttpMethods(); |
| Assert.assertNotNull(uncoveredPaths); |
| Assert.assertEquals(0, uncoveredPaths.size()); |
| |
| //Test a http-method-omission only |
| Constraint constraint3 = new Constraint(); |
| constraint3.setAuthenticate(true); |
| constraint3.setName("omit constraint"); |
| ConstraintMapping mapping3 = new ConstraintMapping(); |
| mapping3.setPathSpec("/omit/*"); |
| mapping3.setMethodOmissions(new String[]{"GET", "POST"}); |
| mapping3.setConstraint(constraint3); |
| |
| _security.addConstraintMapping(mapping3); |
| uncoveredPaths = _security.getPathsWithUncoveredHttpMethods(); |
| Assert.assertNotNull(uncoveredPaths); |
| Assert.assertTrue(uncoveredPaths.contains("/omit/*")); |
| |
| _security.setDenyUncoveredHttpMethods(true); |
| uncoveredPaths = _security.getPathsWithUncoveredHttpMethods(); |
| Assert.assertNotNull(uncoveredPaths); |
| Assert.assertEquals(0, uncoveredPaths.size()); |
| } |
| |
| @Test |
| public void testBasic() throws Exception |
| { |
| List<ConstraintMapping> list = new ArrayList<>(_security.getConstraintMappings()); |
| |
| Constraint constraint6 = new Constraint(); |
| constraint6.setAuthenticate(true); |
| constraint6.setName("omit HEAD and GET"); |
| constraint6.setRoles(new String[]{"user"}); |
| ConstraintMapping mapping6 = new ConstraintMapping(); |
| mapping6.setPathSpec("/omit/*"); |
| mapping6.setConstraint(constraint6); |
| mapping6.setMethodOmissions(new String[]{"GET", "HEAD"}); //requests for every method except GET and HEAD must be in role "user" |
| list.add(mapping6); |
| |
| Constraint constraint7 = new Constraint(); |
| constraint7.setAuthenticate(true); |
| constraint7.setName("non-omitted GET"); |
| constraint7.setRoles(new String[]{"administrator"}); |
| ConstraintMapping mapping7 = new ConstraintMapping(); |
| mapping7.setPathSpec("/omit/*"); |
| mapping7.setConstraint(constraint7); |
| mapping7.setMethod("GET"); //requests for GET must be in role "admin" |
| list.add(mapping7); |
| |
| Constraint constraint8 = new Constraint(); |
| constraint8.setAuthenticate(true); |
| constraint8.setName("non specific"); |
| constraint8.setRoles(new String[]{"foo"}); |
| ConstraintMapping mapping8 = new ConstraintMapping(); |
| mapping8.setPathSpec("/omit/*"); |
| mapping8.setConstraint(constraint8);//requests for all methods must be in role "foo" |
| list.add(mapping8); |
| |
| Set<String> knownRoles=new HashSet<>(); |
| knownRoles.add("user"); |
| knownRoles.add("administrator"); |
| knownRoles.add("foo"); |
| |
| _security.setConstraintMappings(list, knownRoles); |
| |
| |
| _security.setAuthenticator(new BasicAuthenticator()); |
| _server.start(); |
| |
| String response; |
| response = _connector.getResponses("GET /ctx/noauth/info HTTP/1.0\r\n\r\n"); |
| Assert.assertThat(response, Matchers.startsWith("HTTP/1.1 200 OK")); |
| |
| response = _connector.getResponses("GET /ctx/forbid/info HTTP/1.0\r\n\r\n"); |
| Assert.assertThat(response, Matchers.startsWith("HTTP/1.1 403 Forbidden")); |
| response = _connector.getResponses("GET /ctx/auth/info HTTP/1.0\r\n\r\n"); |
| Assert.assertThat(response, Matchers.startsWith("HTTP/1.1 401 Unauthorized")); |
| Assert.assertThat(response, Matchers.containsString("WWW-Authenticate: basic realm=\"TestRealm\"")); |
| |
| response = _connector.getResponses("GET /ctx/auth/info HTTP/1.0\r\n" + |
| "Authorization: Basic " + B64Code.encode("user:wrong") + "\r\n" + |
| "\r\n"); |
| Assert.assertThat(response, Matchers.startsWith("HTTP/1.1 401 Unauthorized")); |
| Assert.assertThat(response, Matchers.containsString("WWW-Authenticate: basic realm=\"TestRealm\"")); |
| |
| response = _connector.getResponses("GET /ctx/auth/info HTTP/1.0\r\n" + |
| "Authorization: Basic " + B64Code.encode("user:password") + "\r\n" + |
| "\r\n"); |
| Assert.assertThat(response, Matchers.startsWith("HTTP/1.1 200 OK")); |
| |
| // test admin |
| response = _connector.getResponses("GET /ctx/admin/info HTTP/1.0\r\n\r\n"); |
| Assert.assertThat(response, Matchers.startsWith("HTTP/1.1 401 Unauthorized")); |
| Assert.assertThat(response, Matchers.containsString("WWW-Authenticate: basic realm=\"TestRealm\"")); |
| |
| response = _connector.getResponses("GET /ctx/admin/info HTTP/1.0\r\n" + |
| "Authorization: Basic " + B64Code.encode("admin:wrong") + "\r\n" + |
| "\r\n"); |
| Assert.assertThat(response, Matchers.startsWith("HTTP/1.1 401 Unauthorized")); |
| Assert.assertThat(response, Matchers.containsString("WWW-Authenticate: basic realm=\"TestRealm\"")); |
| |
| response = _connector.getResponses("GET /ctx/admin/info HTTP/1.0\r\n" + |
| "Authorization: Basic " + B64Code.encode("user:password") + "\r\n" + |
| "\r\n"); |
| |
| Assert.assertThat(response, Matchers.startsWith("HTTP/1.1 403 ")); |
| Assert.assertThat(response, Matchers.containsString("!role")); |
| |
| response = _connector.getResponses("GET /ctx/admin/info HTTP/1.0\r\n" + |
| "Authorization: Basic " + B64Code.encode("admin:password") + "\r\n" + |
| "\r\n"); |
| Assert.assertThat(response, Matchers.startsWith("HTTP/1.1 200 OK")); |
| |
| response = _connector.getResponses("GET /ctx/admin/relax/info HTTP/1.0\r\n\r\n"); |
| Assert.assertThat(response, Matchers.startsWith("HTTP/1.1 200 OK")); |
| |
| //check GET is in role administrator |
| response = _connector.getResponses("GET /ctx/omit/x HTTP/1.0\r\n" + |
| "Authorization: Basic " + B64Code.encode("admin:password") + "\r\n" + |
| "\r\n"); |
| Assert.assertThat(response, Matchers.startsWith("HTTP/1.1 200 OK")); |
| |
| //check POST is in role user |
| response = _connector.getResponses("POST /ctx/omit/x HTTP/1.0\r\n" + |
| "Authorization: Basic " + B64Code.encode("user2:password") + "\r\n" + |
| "\r\n"); |
| Assert.assertThat(response, Matchers.startsWith("HTTP/1.1 200 OK")); |
| |
| //check POST can be in role foo too |
| response = _connector.getResponses("POST /ctx/omit/x HTTP/1.0\r\n" + |
| "Authorization: Basic " + B64Code.encode("user3:password") + "\r\n" + |
| "\r\n"); |
| Assert.assertThat(response, Matchers.startsWith("HTTP/1.1 200 OK")); |
| |
| //check HEAD cannot be in role user |
| response = _connector.getResponses("HEAD /ctx/omit/x HTTP/1.0\r\n" + |
| "Authorization: Basic " + B64Code.encode("user2:password") + "\r\n" + |
| "\r\n"); |
| Assert.assertThat(response, Matchers.startsWith("HTTP/1.1 403 ")); |
| } |
| |
| |
| private static String CNONCE="1234567890"; |
| private String digest(String nonce, String username,String password,String uri,String nc) throws Exception |
| { |
| MessageDigest md = MessageDigest.getInstance("MD5"); |
| byte[] ha1; |
| // calc A1 digest |
| md.update(username.getBytes(StandardCharsets.ISO_8859_1)); |
| md.update((byte) ':'); |
| md.update("TestRealm".getBytes(StandardCharsets.ISO_8859_1)); |
| md.update((byte) ':'); |
| md.update(password.getBytes(StandardCharsets.ISO_8859_1)); |
| ha1 = md.digest(); |
| // calc A2 digest |
| md.reset(); |
| md.update("GET".getBytes(StandardCharsets.ISO_8859_1)); |
| md.update((byte) ':'); |
| md.update(uri.getBytes(StandardCharsets.ISO_8859_1)); |
| byte[] ha2 = md.digest(); |
| |
| // calc digest |
| // request-digest = <"> < KD ( H(A1), unq(nonce-value) ":" |
| // nc-value ":" unq(cnonce-value) ":" unq(qop-value) ":" H(A2) ) |
| // <"> |
| // request-digest = <"> < KD ( H(A1), unq(nonce-value) ":" H(A2) |
| // ) > <"> |
| |
| md.update(TypeUtil.toString(ha1, 16).getBytes(StandardCharsets.ISO_8859_1)); |
| md.update((byte) ':'); |
| md.update(nonce.getBytes(StandardCharsets.ISO_8859_1)); |
| md.update((byte) ':'); |
| md.update(nc.getBytes(StandardCharsets.ISO_8859_1)); |
| md.update((byte) ':'); |
| md.update(CNONCE.getBytes(StandardCharsets.ISO_8859_1)); |
| md.update((byte) ':'); |
| md.update("auth".getBytes(StandardCharsets.ISO_8859_1)); |
| md.update((byte) ':'); |
| md.update(TypeUtil.toString(ha2, 16).getBytes(StandardCharsets.ISO_8859_1)); |
| byte[] digest = md.digest(); |
| |
| // check digest |
| return TypeUtil.toString(digest, 16); |
| } |
| |
| @Test |
| public void testDigest() throws Exception |
| { |
| DigestAuthenticator authenticator = new DigestAuthenticator(); |
| authenticator.setMaxNonceCount(5); |
| _security.setAuthenticator(authenticator); |
| _server.start(); |
| |
| String response; |
| response = _connector.getResponses("GET /ctx/noauth/info HTTP/1.0\r\n\r\n"); |
| Assert.assertThat(response, Matchers.startsWith("HTTP/1.1 200 OK")); |
| |
| response = _connector.getResponses("GET /ctx/forbid/info HTTP/1.0\r\n\r\n"); |
| Assert.assertThat(response, Matchers.startsWith("HTTP/1.1 403 Forbidden")); |
| response = _connector.getResponses("GET /ctx/auth/info HTTP/1.0\r\n\r\n"); |
| Assert.assertThat(response, Matchers.startsWith("HTTP/1.1 401 Unauthorized")); |
| Assert.assertThat(response, Matchers.containsString("WWW-Authenticate: Digest realm=\"TestRealm\"")); |
| |
| Pattern nonceP = Pattern.compile("nonce=\"([^\"]*)\","); |
| Matcher matcher = nonceP.matcher(response); |
| Assert.assertTrue(matcher.find()); |
| String nonce=matcher.group(1); |
| |
| |
| //wrong password |
| String digest= digest(nonce,"user","WRONG","/ctx/auth/info","1"); |
| response = _connector.getResponses("GET /ctx/auth/info HTTP/1.0\r\n" + |
| "Authorization: Digest username=\"user\", qop=auth, cnonce=\"1234567890\", uri=\"/ctx/auth/info\", realm=\"TestRealm\", "+ |
| "nc=1, "+ |
| "nonce=\""+nonce+"\", "+ |
| "response=\""+digest+"\"\r\n"+ |
| "\r\n"); |
| Assert.assertThat(response, Matchers.startsWith("HTTP/1.1 401 Unauthorized")); |
| |
| // right password |
| digest= digest(nonce,"user","password","/ctx/auth/info","2"); |
| response = _connector.getResponses("GET /ctx/auth/info HTTP/1.0\r\n" + |
| "Authorization: Digest username=\"user\", qop=auth, cnonce=\"1234567890\", uri=\"/ctx/auth/info\", realm=\"TestRealm\", "+ |
| "nc=2, "+ |
| "nonce=\""+nonce+"\", "+ |
| "response=\""+digest+"\"\r\n"+ |
| "\r\n"); |
| Assert.assertThat(response, Matchers.startsWith("HTTP/1.1 200 OK")); |
| |
| |
| // once only |
| digest= digest(nonce,"user","password","/ctx/auth/info","2"); |
| response = _connector.getResponses("GET /ctx/auth/info HTTP/1.0\r\n" + |
| "Authorization: Digest username=\"user\", qop=auth, cnonce=\"1234567890\", uri=\"/ctx/auth/info\", realm=\"TestRealm\", "+ |
| "nc=2, "+ |
| "nonce=\""+nonce+"\", "+ |
| "response=\""+digest+"\"\r\n"+ |
| "\r\n"); |
| Assert.assertThat(response, Matchers.startsWith("HTTP/1.1 401 Unauthorized")); |
| |
| // increasing |
| digest= digest(nonce,"user","password","/ctx/auth/info","4"); |
| response = _connector.getResponses("GET /ctx/auth/info HTTP/1.0\r\n" + |
| "Authorization: Digest username=\"user\", qop=auth, cnonce=\"1234567890\", uri=\"/ctx/auth/info\", realm=\"TestRealm\", "+ |
| "nc=4, "+ |
| "nonce=\""+nonce+"\", "+ |
| "response=\""+digest+"\"\r\n"+ |
| "\r\n"); |
| Assert.assertThat(response, Matchers.startsWith("HTTP/1.1 200 OK")); |
| |
| // out of order |
| digest= digest(nonce,"user","password","/ctx/auth/info","3"); |
| response = _connector.getResponses("GET /ctx/auth/info HTTP/1.0\r\n" + |
| "Authorization: Digest username=\"user\", qop=auth, cnonce=\"1234567890\", uri=\"/ctx/auth/info\", realm=\"TestRealm\", "+ |
| "nc=3, "+ |
| "nonce=\""+nonce+"\", "+ |
| "response=\""+digest+"\"\r\n"+ |
| "\r\n"); |
| Assert.assertThat(response, Matchers.startsWith("HTTP/1.1 200 OK")); |
| |
| // stale |
| digest= digest(nonce,"user","password","/ctx/auth/info","5"); |
| response = _connector.getResponses("GET /ctx/auth/info HTTP/1.0\r\n" + |
| "Authorization: Digest username=\"user\", qop=auth, cnonce=\"1234567890\", uri=\"/ctx/auth/info\", realm=\"TestRealm\", "+ |
| "nc=5, "+ |
| "nonce=\""+nonce+"\", "+ |
| "response=\""+digest+"\"\r\n"+ |
| "\r\n"); |
| Assert.assertThat(response, Matchers.startsWith("HTTP/1.1 401 Unauthorized")); |
| Assert.assertThat(response, Matchers.containsString("stale=true")); |
| } |
| |
| |
| @Test |
| public void testFormDispatch() throws Exception |
| { |
| _security.setAuthenticator(new FormAuthenticator("/testLoginPage","/testErrorPage",true)); |
| _server.start(); |
| |
| String response; |
| |
| response = _connector.getResponses("GET /ctx/noauth/info HTTP/1.0\r\n\r\n"); |
| Assert.assertThat(response, Matchers.startsWith("HTTP/1.1 200 OK")); |
| |
| response = _connector.getResponses("GET /ctx/forbid/info HTTP/1.0\r\n\r\n"); |
| Assert.assertThat(response, Matchers.startsWith("HTTP/1.1 403 Forbidden")); |
| |
| response = _connector.getResponses("GET /ctx/auth/info HTTP/1.0\r\n\r\n"); |
| Assert.assertThat(response, Matchers.containsString("Cache-Control: no-cache")); |
| Assert.assertThat(response, Matchers.containsString("Expires")); |
| Assert.assertThat(response, Matchers.containsString("URI=/ctx/testLoginPage")); |
| |
| String session = response.substring(response.indexOf("JSESSIONID=") + 11, response.indexOf(";Path=/ctx")); |
| |
| response = _connector.getResponses("POST /ctx/j_security_check HTTP/1.0\r\n" + |
| "Cookie: JSESSIONID=" + session + "\r\n" + |
| "Content-Type: application/x-www-form-urlencoded\r\n" + |
| "Content-Length: 31\r\n" + |
| "\r\n" + |
| "j_username=user&j_password=wrong\r\n"); |
| Assert.assertThat(response, Matchers.containsString("testErrorPage")); |
| |
| response = _connector.getResponses("POST /ctx/j_security_check HTTP/1.0\r\n" + |
| "Cookie: JSESSIONID=" + session + "\r\n" + |
| "Content-Type: application/x-www-form-urlencoded\r\n" + |
| "Content-Length: 35\r\n" + |
| "\r\n" + |
| "j_username=user&j_password=password\r\n"); |
| Assert.assertThat(response, Matchers.startsWith("HTTP/1.1 302 ")); |
| Assert.assertThat(response, Matchers.containsString("Location")); |
| Assert.assertThat(response, Matchers.containsString("Location")); |
| Assert.assertThat(response, Matchers.containsString("/ctx/auth/info")); |
| session = response.substring(response.indexOf("JSESSIONID=") + 11, response.indexOf(";Path=/ctx")); |
| |
| response = _connector.getResponses("GET /ctx/auth/info HTTP/1.0\r\n" + |
| "Cookie: JSESSIONID=" + session + "\r\n" + |
| "\r\n"); |
| Assert.assertThat(response, Matchers.startsWith("HTTP/1.1 200 OK")); |
| |
| |
| response = _connector.getResponses("GET /ctx/admin/info HTTP/1.0\r\n" + |
| "Cookie: JSESSIONID=" + session + "\r\n" + |
| "\r\n"); |
| Assert.assertThat(response, Matchers.startsWith("HTTP/1.1 403")); |
| Assert.assertThat(response, Matchers.containsString("!role")); |
| } |
| |
| @Test |
| public void testFormRedirect() throws Exception |
| { |
| _security.setAuthenticator(new FormAuthenticator("/testLoginPage","/testErrorPage",false)); |
| _server.start(); |
| |
| String response; |
| |
| response = _connector.getResponses("GET /ctx/noauth/info HTTP/1.0\r\n\r\n"); |
| Assert.assertThat(response, Matchers.startsWith("HTTP/1.1 200 OK")); |
| |
| response = _connector.getResponses("GET /ctx/forbid/info HTTP/1.0\r\n\r\n"); |
| Assert.assertThat(response, Matchers.startsWith("HTTP/1.1 403 Forbidden")); |
| |
| response = _connector.getResponses("GET /ctx/auth/info HTTP/1.0\r\n\r\n"); |
| Assert.assertThat(response, Matchers.containsString(" 302 Found")); |
| Assert.assertThat(response, Matchers.containsString("/ctx/testLoginPage")); |
| String session = response.substring(response.indexOf("JSESSIONID=") + 11, response.indexOf(";Path=/ctx")); |
| |
| response = _connector.getResponses("GET /ctx/testLoginPage HTTP/1.0\r\n"+ |
| "Cookie: JSESSIONID=" + session + "\r\n" + |
| "\r\n"); |
| Assert.assertThat(response, Matchers.containsString(" 200 OK")); |
| Assert.assertThat(response, Matchers.containsString("URI=/ctx/testLoginPage")); |
| |
| response = _connector.getResponses("POST /ctx/j_security_check HTTP/1.0\r\n" + |
| "Cookie: JSESSIONID=" + session + "\r\n" + |
| "Content-Type: application/x-www-form-urlencoded\r\n" + |
| "Content-Length: 32\r\n" + |
| "\r\n" + |
| "j_username=user&j_password=wrong"); |
| Assert.assertThat(response, Matchers.containsString("Location")); |
| |
| response = _connector.getResponses("POST /ctx/j_security_check HTTP/1.0\r\n" + |
| "Cookie: JSESSIONID=" + session + "\r\n" + |
| "Content-Type: application/x-www-form-urlencoded\r\n" + |
| "Content-Length: 35\r\n" + |
| "\r\n" + |
| "j_username=user&j_password=password"); |
| Assert.assertThat(response, Matchers.startsWith("HTTP/1.1 302 ")); |
| Assert.assertThat(response, Matchers.containsString("Location")); |
| Assert.assertThat(response, Matchers.containsString("/ctx/auth/info")); |
| session = response.substring(response.indexOf("JSESSIONID=") + 11, response.indexOf(";Path=/ctx")); |
| |
| response = _connector.getResponses("GET /ctx/auth/info HTTP/1.0\r\n" + |
| "Cookie: JSESSIONID=" + session + "\r\n" + |
| "\r\n"); |
| Assert.assertThat(response, Matchers.startsWith("HTTP/1.1 200 OK")); |
| |
| response = _connector.getResponses("GET /ctx/admin/info HTTP/1.0\r\n" + |
| "Cookie: JSESSIONID=" + session + "\r\n" + |
| "\r\n"); |
| Assert.assertThat(response, Matchers.startsWith("HTTP/1.1 403")); |
| Assert.assertThat(response, Matchers.containsString("!role")); |
| } |
| |
| @Test |
| public void testFormPostRedirect() throws Exception |
| { |
| _security.setAuthenticator(new FormAuthenticator("/testLoginPage","/testErrorPage",false)); |
| _server.start(); |
| |
| String response; |
| |
| response = _connector.getResponses("GET /ctx/noauth/info HTTP/1.0\r\n\r\n"); |
| Assert.assertThat(response, Matchers.startsWith("HTTP/1.1 200 OK")); |
| |
| response = _connector.getResponses("GET /ctx/forbid/info HTTP/1.0\r\n\r\n"); |
| Assert.assertThat(response, Matchers.startsWith("HTTP/1.1 403 Forbidden")); |
| |
| response = _connector.getResponses("POST /ctx/auth/info HTTP/1.0\r\n"+ |
| "Content-Type: application/x-www-form-urlencoded\r\n" + |
| "Content-Length: 27\r\n" + |
| "\r\n" + |
| "test_parameter=test_value\r\n"); |
| Assert.assertThat(response, Matchers.containsString(" 302 Found")); |
| Assert.assertThat(response, Matchers.containsString("/ctx/testLoginPage")); |
| String session = response.substring(response.indexOf("JSESSIONID=") + 11, response.indexOf(";Path=/ctx")); |
| |
| response = _connector.getResponses("GET /ctx/testLoginPage HTTP/1.0\r\n"+ |
| "Cookie: JSESSIONID=" + session + "\r\n" + |
| "\r\n"); |
| Assert.assertThat(response, Matchers.containsString(" 200 OK")); |
| Assert.assertThat(response, Matchers.containsString("URI=/ctx/testLoginPage")); |
| |
| response = _connector.getResponses("POST /ctx/j_security_check HTTP/1.0\r\n" + |
| "Cookie: JSESSIONID=" + session + "\r\n" + |
| "Content-Type: application/x-www-form-urlencoded\r\n" + |
| "Content-Length: 31\r\n" + |
| "\r\n" + |
| "j_username=user&j_password=wrong\r\n"); |
| |
| Assert.assertThat(response, Matchers.containsString("Location")); |
| |
| response = _connector.getResponses("POST /ctx/j_security_check HTTP/1.0\r\n" + |
| "Cookie: JSESSIONID=" + session + "\r\n" + |
| "Content-Type: application/x-www-form-urlencoded\r\n" + |
| "Content-Length: 35\r\n" + |
| "\r\n" + |
| "j_username=user&j_password=password\r\n"); |
| Assert.assertThat(response, Matchers.startsWith("HTTP/1.1 302 ")); |
| Assert.assertThat(response, Matchers.containsString("Location")); |
| Assert.assertThat(response, Matchers.containsString("/ctx/auth/info")); |
| session = response.substring(response.indexOf("JSESSIONID=") + 11, response.indexOf(";Path=/ctx")); |
| |
| // sneak in other request |
| response = _connector.getResponses("GET /ctx/auth/other HTTP/1.0\r\n" + |
| "Cookie: JSESSIONID=" + session + "\r\n" + |
| "\r\n"); |
| Assert.assertThat(response, Matchers.startsWith("HTTP/1.1 200 OK")); |
| Assert.assertTrue(!response.contains("test_value")); |
| |
| // retry post as GET |
| response = _connector.getResponses("GET /ctx/auth/info HTTP/1.0\r\n" + |
| "Cookie: JSESSIONID=" + session + "\r\n" + |
| "\r\n"); |
| Assert.assertThat(response, Matchers.startsWith("HTTP/1.1 200 OK")); |
| Assert.assertTrue(response.contains("test_value")); |
| |
| response = _connector.getResponses("GET /ctx/admin/info HTTP/1.0\r\n" + |
| "Cookie: JSESSIONID=" + session + "\r\n" + |
| "\r\n"); |
| Assert.assertThat(response, Matchers.startsWith("HTTP/1.1 403")); |
| Assert.assertThat(response, Matchers.containsString("!role")); |
| } |
| |
| @Test |
| public void testFormNoCookies() throws Exception |
| { |
| _security.setAuthenticator(new FormAuthenticator("/testLoginPage","/testErrorPage",false)); |
| _server.start(); |
| |
| String response; |
| |
| response = _connector.getResponses("GET /ctx/noauth/info HTTP/1.0\r\n\r\n"); |
| Assert.assertThat(response, Matchers.startsWith("HTTP/1.1 200 OK")); |
| |
| response = _connector.getResponses("GET /ctx/forbid/info HTTP/1.0\r\n\r\n"); |
| Assert.assertThat(response, Matchers.startsWith("HTTP/1.1 403 Forbidden")); |
| |
| response = _connector.getResponses("GET /ctx/auth/info HTTP/1.0\r\n\r\n"); |
| Assert.assertThat(response, Matchers.containsString(" 302 Found")); |
| Assert.assertThat(response, Matchers.containsString("/ctx/testLoginPage")); |
| int jsession=response.indexOf(";jsessionid="); |
| String session = response.substring(jsession + 12, response.indexOf("\r\n",jsession)); |
| |
| response = _connector.getResponses("GET /ctx/testLoginPage;jsessionid="+session+";other HTTP/1.0\r\n"+ |
| "\r\n"); |
| Assert.assertThat(response, Matchers.containsString(" 200 OK")); |
| Assert.assertThat(response, Matchers.containsString("URI=/ctx/testLoginPage")); |
| |
| response = _connector.getResponses("POST /ctx/j_security_check;jsessionid="+session+";other HTTP/1.0\r\n" + |
| "Content-Type: application/x-www-form-urlencoded\r\n" + |
| "Content-Length: 31\r\n" + |
| "\r\n" + |
| "j_username=user&j_password=wrong\r\n"); |
| Assert.assertThat(response, Matchers.containsString("Location")); |
| |
| response = _connector.getResponses("POST /ctx/j_security_check;jsessionid="+session+";other HTTP/1.0\r\n" + |
| "Content-Type: application/x-www-form-urlencoded\r\n" + |
| "Content-Length: 35\r\n" + |
| "\r\n" + |
| "j_username=user&j_password=password\r\n"); |
| Assert.assertThat(response, Matchers.startsWith("HTTP/1.1 302 ")); |
| Assert.assertThat(response, Matchers.containsString("Location")); |
| Assert.assertThat(response, Matchers.containsString("/ctx/auth/info")); |
| session = response.substring(response.indexOf("JSESSIONID=") + 11, response.indexOf(";Path=/ctx")); |
| |
| response = _connector.getResponses("GET /ctx/auth/info;jsessionid="+session+";other HTTP/1.0\r\n" + |
| "\r\n"); |
| Assert.assertThat(response, Matchers.startsWith("HTTP/1.1 200 OK")); |
| |
| response = _connector.getResponses("GET /ctx/admin/info;jsessionid="+session+";other HTTP/1.0\r\n" + |
| "\r\n"); |
| Assert.assertThat(response, Matchers.startsWith("HTTP/1.1 403")); |
| Assert.assertThat(response, Matchers.containsString("!role")); |
| } |
| |
| @Test |
| public void testStrictBasic() throws Exception |
| { |
| _security.setAuthenticator(new BasicAuthenticator()); |
| _server.start(); |
| |
| String response; |
| response = _connector.getResponses("GET /ctx/noauth/info HTTP/1.0\r\n\r\n"); |
| Assert.assertThat(response, Matchers.startsWith("HTTP/1.1 200 OK")); |
| |
| response = _connector.getResponses("GET /ctx/forbid/info HTTP/1.0\r\n\r\n"); |
| Assert.assertThat(response, Matchers.startsWith("HTTP/1.1 403 Forbidden")); |
| |
| response = _connector.getResponses("GET /ctx/auth/info HTTP/1.0\r\n\r\n"); |
| Assert.assertThat(response, Matchers.startsWith("HTTP/1.1 401 Unauthorized")); |
| Assert.assertThat(response, Matchers.containsString("WWW-Authenticate: basic realm=\"TestRealm\"")); |
| |
| response = _connector.getResponses("GET /ctx/auth/info HTTP/1.0\r\n" + |
| "Authorization: Basic " + B64Code.encode("user:wrong") + "\r\n" + |
| "\r\n"); |
| Assert.assertThat(response, Matchers.startsWith("HTTP/1.1 401 Unauthorized")); |
| Assert.assertThat(response, Matchers.containsString("WWW-Authenticate: basic realm=\"TestRealm\"")); |
| |
| response = _connector.getResponses("GET /ctx/auth/info HTTP/1.0\r\n" + |
| "Authorization: Basic " + B64Code.encode("user3:password") + "\r\n" + |
| "\r\n"); |
| Assert.assertThat(response, Matchers.startsWith("HTTP/1.1 403")); |
| |
| response = _connector.getResponses("GET /ctx/auth/info HTTP/1.0\r\n" + |
| "Authorization: Basic " + B64Code.encode("user2:password") + "\r\n" + |
| "\r\n"); |
| Assert.assertThat(response, Matchers.startsWith("HTTP/1.1 200 OK")); |
| |
| |
| // test admin |
| response = _connector.getResponses("GET /ctx/admin/info HTTP/1.0\r\n\r\n"); |
| Assert.assertThat(response, Matchers.startsWith("HTTP/1.1 401 Unauthorized")); |
| Assert.assertThat(response, Matchers.containsString("WWW-Authenticate: basic realm=\"TestRealm\"")); |
| |
| response = _connector.getResponses("GET /ctx/admin/info HTTP/1.0\r\n" + |
| "Authorization: Basic " + B64Code.encode("admin:wrong") + "\r\n" + |
| "\r\n"); |
| Assert.assertThat(response, Matchers.startsWith("HTTP/1.1 401 Unauthorized")); |
| Assert.assertThat(response, Matchers.containsString("WWW-Authenticate: basic realm=\"TestRealm\"")); |
| |
| response = _connector.getResponses("GET /ctx/admin/info HTTP/1.0\r\n" + |
| "Authorization: Basic " + B64Code.encode("user:password") + "\r\n" + |
| "\r\n"); |
| |
| Assert.assertThat(response, Matchers.startsWith("HTTP/1.1 403 ")); |
| Assert.assertThat(response, Matchers.containsString("!role")); |
| |
| response = _connector.getResponses("GET /ctx/admin/info HTTP/1.0\r\n" + |
| "Authorization: Basic " + B64Code.encode("admin:password") + "\r\n" + |
| "\r\n"); |
| Assert.assertThat(response, Matchers.startsWith("HTTP/1.1 200 OK")); |
| |
| |
| response = _connector.getResponses("GET /ctx/admin/relax/info HTTP/1.0\r\n\r\n"); |
| Assert.assertThat(response, Matchers.startsWith("HTTP/1.1 200 OK")); |
| } |
| |
| @Test |
| public void testStrictFormDispatch() |
| throws Exception |
| { |
| _security.setAuthenticator(new FormAuthenticator("/testLoginPage","/testErrorPage",true)); |
| _server.start(); |
| |
| String response; |
| |
| response = _connector.getResponses("GET /ctx/noauth/info HTTP/1.0\r\n\r\n"); |
| Assert.assertThat(response, Matchers.startsWith("HTTP/1.1 200 OK")); |
| |
| response = _connector.getResponses("GET /ctx/forbid/info HTTP/1.0\r\n\r\n"); |
| Assert.assertThat(response, Matchers.startsWith("HTTP/1.1 403 Forbidden")); |
| |
| response = _connector.getResponses("GET /ctx/auth/info HTTP/1.0\r\n\r\n"); |
| // assertThat(response,containsString(" 302 Found")); |
| // assertThat(response,containsString("/ctx/testLoginPage")); |
| Assert.assertThat(response, Matchers.containsString("Cache-Control: no-cache")); |
| Assert.assertThat(response, Matchers.containsString("Expires")); |
| Assert.assertThat(response, Matchers.containsString("URI=/ctx/testLoginPage")); |
| |
| String session = response.substring(response.indexOf("JSESSIONID=") + 11, response.indexOf(";Path=/ctx")); |
| |
| response = _connector.getResponses("POST /ctx/j_security_check HTTP/1.0\r\n" + |
| "Cookie: JSESSIONID=" + session + "\r\n" + |
| "Content-Type: application/x-www-form-urlencoded\r\n" + |
| "Content-Length: 31\r\n" + |
| "\r\n" + |
| "j_username=user&j_password=wrong\r\n"); |
| // assertThat(response,containsString("Location")); |
| Assert.assertThat(response, Matchers.containsString("testErrorPage")); |
| |
| response = _connector.getResponses("POST /ctx/j_security_check HTTP/1.0\r\n" + |
| "Cookie: JSESSIONID=" + session + "\r\n" + |
| "Content-Type: application/x-www-form-urlencoded\r\n" + |
| "Content-Length: 36\r\n" + |
| "\r\n" + |
| "j_username=user0&j_password=password\r\n"); |
| Assert.assertThat(response, Matchers.startsWith("HTTP/1.1 302 ")); |
| Assert.assertThat(response, Matchers.containsString("Location")); |
| Assert.assertThat(response, Matchers.containsString("/ctx/auth/info")); |
| session = response.substring(response.indexOf("JSESSIONID=") + 11, response.indexOf(";Path=/ctx")); |
| |
| response = _connector.getResponses("GET /ctx/auth/info HTTP/1.0\r\n" + |
| "Cookie: JSESSIONID=" + session + "\r\n" + |
| "\r\n"); |
| Assert.assertThat(response, Matchers.startsWith("HTTP/1.1 403")); |
| Assert.assertThat(response, Matchers.containsString("!role")); |
| |
| response = _connector.getResponses("GET /ctx/admin/info HTTP/1.0\r\n" + |
| "Cookie: JSESSIONID=" + session + "\r\n" + |
| "\r\n"); |
| Assert.assertThat(response, Matchers.startsWith("HTTP/1.1 403")); |
| Assert.assertThat(response, Matchers.containsString("!role")); |
| |
| |
| |
| // log in again as user2 |
| response = _connector.getResponses("GET /ctx/auth/info HTTP/1.0\r\n\r\n"); |
| // assertThat(response,startsWith("HTTP/1.1 302 ")); |
| // assertThat(response,containsString("testLoginPage")); |
| session = response.substring(response.indexOf("JSESSIONID=") + 11, response.indexOf(";Path=/ctx")); |
| |
| response = _connector.getResponses("POST /ctx/j_security_check HTTP/1.0\r\n" + |
| "Cookie: JSESSIONID=" + session + "\r\n" + |
| "Content-Type: application/x-www-form-urlencoded\r\n" + |
| "Content-Length: 36\r\n" + |
| "\r\n" + |
| "j_username=user2&j_password=password\r\n"); |
| Assert.assertThat(response, Matchers.startsWith("HTTP/1.1 302 ")); |
| Assert.assertThat(response, Matchers.containsString("Location")); |
| Assert.assertThat(response, Matchers.containsString("/ctx/auth/info")); |
| session = response.substring(response.indexOf("JSESSIONID=") + 11, response.indexOf(";Path=/ctx")); |
| |
| response = _connector.getResponses("GET /ctx/auth/info HTTP/1.0\r\n" + |
| "Cookie: JSESSIONID=" + session + "\r\n" + |
| "\r\n"); |
| Assert.assertThat(response, Matchers.startsWith("HTTP/1.1 200 OK")); |
| |
| response = _connector.getResponses("GET /ctx/admin/info HTTP/1.0\r\n" + |
| "Cookie: JSESSIONID=" + session + "\r\n" + |
| "\r\n"); |
| Assert.assertThat(response, Matchers.startsWith("HTTP/1.1 403")); |
| Assert.assertThat(response, Matchers.containsString("!role")); |
| |
| |
| |
| // log in again as admin |
| response = _connector.getResponses("GET /ctx/auth/info HTTP/1.0\r\n\r\n"); |
| // assertThat(response,startsWith("HTTP/1.1 302 ")); |
| // assertThat(response,containsString("testLoginPage")); |
| session = response.substring(response.indexOf("JSESSIONID=") + 11, response.indexOf(";Path=/ctx")); |
| |
| response = _connector.getResponses("POST /ctx/j_security_check HTTP/1.0\r\n" + |
| "Cookie: JSESSIONID=" + session + "\r\n" + |
| "Content-Type: application/x-www-form-urlencoded\r\n" + |
| "Content-Length: 36\r\n" + |
| "\r\n" + |
| "j_username=admin&j_password=password\r\n"); |
| Assert.assertThat(response, Matchers.startsWith("HTTP/1.1 302 ")); |
| Assert.assertThat(response, Matchers.containsString("Location")); |
| Assert.assertThat(response, Matchers.containsString("/ctx/auth/info")); |
| session = response.substring(response.indexOf("JSESSIONID=") + 11, response.indexOf(";Path=/ctx")); |
| |
| response = _connector.getResponses("GET /ctx/auth/info HTTP/1.0\r\n" + |
| "Cookie: JSESSIONID=" + session + "\r\n" + |
| "\r\n"); |
| Assert.assertThat(response, Matchers.startsWith("HTTP/1.1 200 OK")); |
| |
| response = _connector.getResponses("GET /ctx/admin/info HTTP/1.0\r\n" + |
| "Cookie: JSESSIONID=" + session + "\r\n" + |
| "\r\n"); |
| Assert.assertThat(response, Matchers.startsWith("HTTP/1.1 200 OK")); |
| } |
| |
| @Test |
| public void testStrictFormRedirect() throws Exception |
| { |
| _security.setAuthenticator(new FormAuthenticator("/testLoginPage","/testErrorPage",false)); |
| _server.start(); |
| |
| String response; |
| |
| response = _connector.getResponses("GET /ctx/noauth/info HTTP/1.0\r\n\r\n"); |
| Assert.assertThat(response, Matchers.startsWith("HTTP/1.1 200 OK")); |
| |
| response = _connector.getResponses("GET /ctx/forbid/info HTTP/1.0\r\n\r\n"); |
| Assert.assertThat(response, Matchers.startsWith("HTTP/1.1 403 Forbidden")); |
| |
| response = _connector.getResponses("GET /ctx/auth/info HTTP/1.0\r\nHost:wibble.com:8888\r\n\r\n"); |
| Assert.assertThat(response, Matchers.containsString(" 302 Found")); |
| Assert.assertThat(response, Matchers.containsString("http://wibble.com:8888/ctx/testLoginPage")); |
| |
| String session = response.substring(response.indexOf("JSESSIONID=") + 11, response.indexOf(";Path=/ctx")); |
| |
| response = _connector.getResponses("POST /ctx/j_security_check HTTP/1.0\r\n" + |
| "Cookie: JSESSIONID=" + session + "\r\n" + |
| "Content-Type: application/x-www-form-urlencoded\r\n" + |
| "Content-Length: 31\r\n" + |
| "\r\n" + |
| "j_username=user&j_password=wrong\r\n"); |
| Assert.assertThat(response, Matchers.containsString("Location")); |
| |
| response = _connector.getResponses("POST /ctx/j_security_check HTTP/1.0\r\n" + |
| "Cookie: JSESSIONID=" + session + "\r\n" + |
| "Content-Type: application/x-www-form-urlencoded\r\n" + |
| "Content-Length: 36\r\n" + |
| "\r\n" + |
| "j_username=user3&j_password=password\r\n"); |
| Assert.assertThat(response, Matchers.startsWith("HTTP/1.1 302 ")); |
| Assert.assertThat(response, Matchers.containsString("Location")); |
| Assert.assertThat(response, Matchers.containsString("/ctx/auth/info")); |
| session = response.substring(response.indexOf("JSESSIONID=") + 11, response.indexOf(";Path=/ctx")); |
| |
| response = _connector.getResponses("GET /ctx/auth/info HTTP/1.0\r\n" + |
| "Cookie: JSESSIONID=" + session + "\r\n" + |
| "\r\n"); |
| Assert.assertThat(response, Matchers.startsWith("HTTP/1.1 403")); |
| Assert.assertThat(response, Matchers.containsString("!role")); |
| |
| response = _connector.getResponses("GET /ctx/admin/info HTTP/1.0\r\n" + |
| "Cookie: JSESSIONID=" + session + "\r\n" + |
| "\r\n"); |
| Assert.assertThat(response, Matchers.startsWith("HTTP/1.1 403")); |
| Assert.assertThat(response, Matchers.containsString("!role")); |
| |
| |
| |
| // log in again as user2 |
| response = _connector.getResponses("GET /ctx/auth/info HTTP/1.0\r\n\r\n"); |
| Assert.assertThat(response, Matchers.startsWith("HTTP/1.1 302 ")); |
| Assert.assertThat(response, Matchers.containsString("testLoginPage")); |
| session = response.substring(response.indexOf("JSESSIONID=") + 11, response.indexOf(";Path=/ctx")); |
| |
| response = _connector.getResponses("POST /ctx/j_security_check HTTP/1.0\r\n" + |
| "Cookie: JSESSIONID=" + session + "\r\n" + |
| "Content-Type: application/x-www-form-urlencoded\r\n" + |
| "Content-Length: 36\r\n" + |
| "\r\n" + |
| "j_username=user2&j_password=password\r\n"); |
| Assert.assertThat(response, Matchers.startsWith("HTTP/1.1 302 ")); |
| Assert.assertThat(response, Matchers.containsString("Location")); |
| Assert.assertThat(response, Matchers.containsString("/ctx/auth/info")); |
| session = response.substring(response.indexOf("JSESSIONID=") + 11, response.indexOf(";Path=/ctx")); |
| |
| |
| response = _connector.getResponses("GET /ctx/auth/info HTTP/1.0\r\n" + |
| "Cookie: JSESSIONID=" + session + "\r\n" + |
| "\r\n"); |
| Assert.assertThat(response, Matchers.startsWith("HTTP/1.1 200 OK")); |
| |
| //check user2 does not have right role to access /admin/* |
| response = _connector.getResponses("GET /ctx/admin/info HTTP/1.0\r\n" + |
| "Cookie: JSESSIONID=" + session + "\r\n" + |
| "\r\n"); |
| Assert.assertThat(response, Matchers.startsWith("HTTP/1.1 403")); |
| Assert.assertThat(response, Matchers.containsString("!role")); |
| |
| //log in as user3, who doesn't have a valid role, but we are checking a constraint |
| //of ** which just means they have to be authenticated |
| response = _connector.getResponses("GET /ctx/starstar/info HTTP/1.0\r\n\r\n"); |
| Assert.assertThat(response, Matchers.startsWith("HTTP/1.1 302 ")); |
| Assert.assertThat(response, Matchers.containsString("testLoginPage")); |
| session = response.substring(response.indexOf("JSESSIONID=") + 11, response.indexOf(";Path=/ctx")); |
| |
| response = _connector.getResponses("POST /ctx/j_security_check HTTP/1.0\r\n" + |
| "Cookie: JSESSIONID=" + session + "\r\n" + |
| "Content-Type: application/x-www-form-urlencoded\r\n" + |
| "Content-Length: 36\r\n" + |
| "\r\n" + |
| "j_username=user3&j_password=password\r\n"); |
| Assert.assertThat(response, Matchers.startsWith("HTTP/1.1 302 ")); |
| Assert.assertThat(response, Matchers.containsString("Location")); |
| Assert.assertThat(response, Matchers.containsString("/ctx/starstar/info")); |
| session = response.substring(response.indexOf("JSESSIONID=") + 11, response.indexOf(";Path=/ctx")); |
| |
| response = _connector.getResponses("GET /ctx/starstar/info HTTP/1.0\r\n" + |
| "Cookie: JSESSIONID=" + session + "\r\n" + |
| "\r\n"); |
| Assert.assertThat(response, Matchers.startsWith("HTTP/1.1 200 OK")); |
| |
| |
| // log in again as admin |
| response = _connector.getResponses("GET /ctx/auth/info HTTP/1.0\r\n\r\n"); |
| // assertThat(response,startsWith("HTTP/1.1 302 ")); |
| // assertThat(response,containsString("testLoginPage")); |
| session = response.substring(response.indexOf("JSESSIONID=") + 11, response.indexOf(";Path=/ctx")); |
| |
| response = _connector.getResponses("POST /ctx/j_security_check HTTP/1.0\r\n" + |
| "Cookie: JSESSIONID=" + session + "\r\n" + |
| "Content-Type: application/x-www-form-urlencoded\r\n" + |
| "Content-Length: 36\r\n" + |
| "\r\n" + |
| "j_username=admin&j_password=password\r\n"); |
| Assert.assertThat(response, Matchers.startsWith("HTTP/1.1 302 ")); |
| Assert.assertThat(response, Matchers.containsString("Location")); |
| Assert.assertThat(response, Matchers.containsString("/ctx/auth/info")); |
| session = response.substring(response.indexOf("JSESSIONID=") + 11, response.indexOf(";Path=/ctx")); |
| |
| response = _connector.getResponses("GET /ctx/auth/info HTTP/1.0\r\n" + |
| "Cookie: JSESSIONID=" + session + "\r\n" + |
| "\r\n"); |
| Assert.assertThat(response, Matchers.startsWith("HTTP/1.1 200 OK")); |
| |
| response = _connector.getResponses("GET /ctx/admin/info HTTP/1.0\r\n" + |
| "Cookie: JSESSIONID=" + session + "\r\n" + |
| "\r\n"); |
| Assert.assertThat(response, Matchers.startsWith("HTTP/1.1 200 OK")); |
| } |
| |
| |
| |
| @Test |
| public void testDataRedirection() throws Exception |
| { |
| _security.setAuthenticator(new BasicAuthenticator()); |
| _server.start(); |
| |
| String response; |
| |
| response = _connector.getResponses("GET /ctx/data/info HTTP/1.0\r\n\r\n"); |
| Assert.assertThat(response, Matchers.startsWith("HTTP/1.1 403")); |
| |
| _config.setSecurePort(8443); |
| _config.setSecureScheme("https"); |
| |
| response = _connector.getResponses("GET /ctx/data/info HTTP/1.0\r\n\r\n"); |
| Assert.assertThat(response, Matchers.startsWith("HTTP/1.1 302 Found")); |
| Assert.assertTrue(response.indexOf("Location") > 0); |
| Assert.assertTrue(response.indexOf(":8443/ctx/data/info") > 0); |
| |
| _config.setSecurePort(443); |
| response = _connector.getResponses("GET /ctx/data/info HTTP/1.0\r\n\r\n"); |
| Assert.assertThat(response, Matchers.startsWith("HTTP/1.1 302 Found")); |
| Assert.assertTrue(response.indexOf("Location") > 0); |
| Assert.assertTrue(!response.contains(":443/ctx/data/info")); |
| |
| _config.setSecurePort(8443); |
| response = _connector.getResponses("GET /ctx/data/info HTTP/1.0\r\nHost: wobble.com\r\n\r\n"); |
| Assert.assertThat(response, Matchers.startsWith("HTTP/1.1 302 Found")); |
| Assert.assertTrue(response.indexOf("Location") > 0); |
| Assert.assertTrue(response.indexOf("https://wobble.com:8443/ctx/data/info") > 0); |
| |
| _config.setSecurePort(443); |
| response = _connector.getResponses("GET /ctx/data/info HTTP/1.0\r\nHost: wobble.com\r\n\r\n"); |
| System.err.println(response); |
| Assert.assertThat(response, Matchers.startsWith("HTTP/1.1 302 Found")); |
| Assert.assertTrue(response.indexOf("Location") > 0); |
| Assert.assertTrue(!response.contains(":443")); |
| Assert.assertTrue(response.indexOf("https://wobble.com/ctx/data/info") > 0); |
| } |
| |
| @Test |
| public void testRoleRef() throws Exception |
| { |
| RoleCheckHandler check=new RoleCheckHandler(); |
| _security.setHandler(check); |
| _security.setAuthenticator(new BasicAuthenticator()); |
| |
| _server.start(); |
| |
| String response; |
| response = _connector.getResponses("GET /ctx/noauth/info HTTP/1.0\r\n\r\n", 100000, TimeUnit.MILLISECONDS); |
| Assert.assertThat(response, Matchers.startsWith("HTTP/1.1 200 OK")); |
| |
| response = _connector.getResponses("GET /ctx/auth/info HTTP/1.0\r\n" + |
| "Authorization: Basic " + B64Code.encode("user2:password") + "\r\n" + |
| "\r\n", 100000, TimeUnit.MILLISECONDS); |
| Assert.assertThat(response, Matchers.startsWith("HTTP/1.1 500 ")); |
| |
| _server.stop(); |
| |
| RoleRefHandler roleref = new RoleRefHandler(); |
| roleref.setHandler(_security.getHandler()); |
| _security.setHandler(roleref); |
| roleref.setHandler(check); |
| |
| _server.start(); |
| |
| response = _connector.getResponses("GET /ctx/auth/info HTTP/1.0\r\n" + |
| "Authorization: Basic " + B64Code.encode("user2:password") + "\r\n" + |
| "\r\n", 100000, TimeUnit.MILLISECONDS); |
| Assert.assertThat(response, Matchers.startsWith("HTTP/1.1 200 OK")); |
| } |
| |
| @Test |
| public void testDeferredBasic() throws Exception |
| { |
| _security.setAuthenticator(new BasicAuthenticator()); |
| _server.start(); |
| |
| String response; |
| |
| response = _connector.getResponses("GET /ctx/noauth/info HTTP/1.0\r\n"+ |
| "\r\n"); |
| Assert.assertThat(response, Matchers.startsWith("HTTP/1.1 200 OK")); |
| Assert.assertThat(response, Matchers.containsString("user=null")); |
| |
| response = _connector.getResponses("GET /ctx/noauth/info HTTP/1.0\r\n"+ |
| "Authorization: Basic " + B64Code.encode("admin:wrong") + "\r\n" + |
| "\r\n"); |
| Assert.assertThat(response, Matchers.startsWith("HTTP/1.1 200 OK")); |
| Assert.assertThat(response, Matchers.containsString("user=null")); |
| |
| response = _connector.getResponses("GET /ctx/noauth/info HTTP/1.0\r\n"+ |
| "Authorization: Basic " + B64Code.encode("admin:password") + "\r\n" + |
| "\r\n"); |
| Assert.assertThat(response, Matchers.startsWith("HTTP/1.1 200 OK")); |
| Assert.assertThat(response, Matchers.containsString("user=admin")); |
| } |
| |
| @Test |
| public void testRelaxedMethod() throws Exception |
| { |
| _security.setAuthenticator(new BasicAuthenticator()); |
| _server.start(); |
| |
| String response; |
| response = _connector.getResponses("GET /ctx/forbid/somethig HTTP/1.0\r\n\r\n"); |
| Assert.assertThat(response, Matchers.startsWith("HTTP/1.1 403 ")); |
| |
| response = _connector.getResponses("POST /ctx/forbid/post HTTP/1.0\r\n\r\n"); |
| Assert.assertThat(response, Matchers.startsWith("HTTP/1.1 200 ")); |
| |
| response = _connector.getResponses("GET /ctx/forbid/post HTTP/1.0\r\n\r\n"); |
| Assert.assertThat(response, Matchers.startsWith("HTTP/1.1 200 ")); // This is so stupid, but it is the S P E C |
| } |
| private class RequestHandler extends AbstractHandler |
| { |
| @Override |
| public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response ) throws IOException, ServletException |
| { |
| baseRequest.setHandled(true); |
| if (request.getAuthType()==null || "user".equals(request.getRemoteUser()) || request.isUserInRole("user") || request.isUserInRole("foo")) |
| { |
| response.setStatus(200); |
| response.setContentType("text/plain; charset=UTF-8"); |
| response.getWriter().println("URI="+request.getRequestURI()); |
| String user = request.getRemoteUser(); |
| response.getWriter().println("user="+user); |
| if (request.getParameter("test_parameter")!=null) |
| response.getWriter().println(request.getParameter("test_parameter")); |
| } |
| else |
| response.sendError(500); |
| } |
| } |
| |
| private class RoleRefHandler extends HandlerWrapper |
| { |
| /* ------------------------------------------------------------ */ |
| /** |
| * @see org.eclipse.jetty.server.handler.HandlerWrapper#handle(java.lang.String, Request, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) |
| */ |
| @Override |
| public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException |
| { |
| UserIdentity.Scope old = ((Request) request).getUserIdentityScope(); |
| |
| UserIdentity.Scope scope = new UserIdentity.Scope() |
| { |
| @Override |
| public String getContextPath() |
| { |
| return "/"; |
| } |
| |
| @Override |
| public String getName() |
| { |
| return "someServlet"; |
| } |
| |
| @Override |
| public Map<String, String> getRoleRefMap() |
| { |
| Map<String, String> map = new HashMap<>(); |
| map.put("untranslated", "user"); |
| return map; |
| } |
| }; |
| |
| ((Request)request).setUserIdentityScope(scope); |
| |
| try |
| { |
| super.handle(target,baseRequest,request, response); |
| } |
| finally |
| { |
| ((Request)request).setUserIdentityScope(old); |
| } |
| } |
| } |
| |
| private class RoleCheckHandler extends AbstractHandler |
| { |
| @Override |
| public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response ) throws IOException, ServletException |
| { |
| ((Request) request).setHandled(true); |
| if (request.getAuthType()==null || "user".equals(request.getRemoteUser()) || request.isUserInRole("untranslated")) |
| response.setStatus(200); |
| else |
| response.sendError(500); |
| } |
| } |
| } |