init
This commit is contained in:
89
test/org/apache/catalina/realm/TestGenericPrincipal.java
Normal file
89
test/org/apache/catalina/realm/TestGenericPrincipal.java
Normal file
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.catalina.realm;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.Serializable;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
public class TestGenericPrincipal {
|
||||
|
||||
private static final String USER = "user";
|
||||
private static final String PASSWORD = "pwd";
|
||||
private static final List<String> ROLES = Collections.unmodifiableList(
|
||||
Arrays.asList(new String[] { "ROLE1", "ROLE2" }));
|
||||
private static final TesterPrincipal PRINCIPAL = new TesterPrincipal("Principal");
|
||||
private static final TesterPrincipalNonSerializable PRINCIPAL_NON_SERIALIZABLE =
|
||||
new TesterPrincipalNonSerializable("PrincipalNonSerializable");
|
||||
|
||||
@Test
|
||||
public void testSerialize01() throws ClassNotFoundException, IOException {
|
||||
GenericPrincipal gpIn = new GenericPrincipal(USER, PASSWORD, ROLES);
|
||||
doTest(gpIn);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSerialize02() throws ClassNotFoundException, IOException {
|
||||
GenericPrincipal gpIn = new GenericPrincipal(USER, PASSWORD, ROLES, PRINCIPAL);
|
||||
doTest(gpIn);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSerialize03() throws ClassNotFoundException, IOException {
|
||||
GenericPrincipal gpIn = new GenericPrincipal(USER, PASSWORD, ROLES, PRINCIPAL_NON_SERIALIZABLE);
|
||||
doTest(gpIn);
|
||||
}
|
||||
|
||||
private void doTest(GenericPrincipal gpIn)
|
||||
throws ClassNotFoundException, IOException {
|
||||
GenericPrincipal gpOut = serializeAndDeserialize(gpIn);
|
||||
|
||||
Assert.assertNull(gpOut.getGssCredential());
|
||||
Assert.assertEquals(gpIn.getName(), gpOut.getName());
|
||||
Assert.assertEquals(gpIn.getPassword(), gpOut.getPassword());
|
||||
Assert.assertArrayEquals(gpIn.getRoles(), gpOut.getRoles());
|
||||
if (gpIn == gpIn.getUserPrincipal()) {
|
||||
Assert.assertEquals(gpOut, gpOut.getUserPrincipal());
|
||||
} else if (gpIn.getUserPrincipal() instanceof Serializable) {
|
||||
Assert.assertEquals(gpIn.getUserPrincipal(), gpOut.getUserPrincipal());
|
||||
} else {
|
||||
Assert.assertEquals(gpOut, gpOut.getUserPrincipal());
|
||||
}
|
||||
}
|
||||
|
||||
private GenericPrincipal serializeAndDeserialize(GenericPrincipal gpIn)
|
||||
throws IOException, ClassNotFoundException {
|
||||
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||
ObjectOutputStream oos = new ObjectOutputStream(bos);
|
||||
oos.writeObject(gpIn);
|
||||
|
||||
byte[] data = bos.toByteArray();
|
||||
|
||||
ByteArrayInputStream bis = new ByteArrayInputStream(data);
|
||||
ObjectInputStream ois = new ObjectInputStream(bis);
|
||||
return (GenericPrincipal) ois.readObject();
|
||||
}
|
||||
}
|
||||
174
test/org/apache/catalina/realm/TestJNDIRealm.java
Normal file
174
test/org/apache/catalina/realm/TestJNDIRealm.java
Normal file
@@ -0,0 +1,174 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.catalina.realm;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.Principal;
|
||||
|
||||
import javax.naming.NamingEnumeration;
|
||||
import javax.naming.NamingException;
|
||||
import javax.naming.directory.BasicAttributes;
|
||||
import javax.naming.directory.DirContext;
|
||||
import javax.naming.directory.InitialDirContext;
|
||||
import javax.naming.directory.SearchControls;
|
||||
import javax.naming.directory.SearchResult;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.apache.catalina.Context;
|
||||
import org.apache.catalina.LifecycleException;
|
||||
import org.apache.naming.NameParserImpl;
|
||||
import org.apache.tomcat.unittest.TesterContext;
|
||||
import org.apache.tomcat.util.security.MD5Encoder;
|
||||
import org.easymock.EasyMock;
|
||||
|
||||
public class TestJNDIRealm {
|
||||
|
||||
private static final String ALGORITHM = "MD5";
|
||||
|
||||
private static final String USER = "test-user";
|
||||
private static final String PASSWORD = "test-password";
|
||||
private static final String REALM = "test-realm";
|
||||
|
||||
private static final String NONCE = "test-nonce";
|
||||
private static final String HA2 = "test-md5a2";
|
||||
public static final String USER_PASSWORD_ATTR = "test-pwd";
|
||||
|
||||
private static MessageDigest md5Helper;
|
||||
|
||||
@BeforeClass
|
||||
public static void setupClass() throws Exception {
|
||||
md5Helper = MessageDigest.getInstance(ALGORITHM);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAuthenticateWithoutUserPassword() throws Exception {
|
||||
// GIVEN
|
||||
JNDIRealm realm = buildRealm(PASSWORD);
|
||||
|
||||
// WHEN
|
||||
String expectedResponse =
|
||||
MD5Encoder.encode(md5Helper.digest((ha1() + ":" + NONCE + ":" + HA2).getBytes()));
|
||||
Principal principal =
|
||||
realm.authenticate(USER, expectedResponse, NONCE, null, null, null, REALM, HA2);
|
||||
|
||||
// THEN
|
||||
Assert.assertNull(principal);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAuthenticateWithUserPassword() throws Exception {
|
||||
// GIVEN
|
||||
JNDIRealm realm = buildRealm(PASSWORD);
|
||||
realm.setUserPassword(USER_PASSWORD_ATTR);
|
||||
|
||||
// WHEN
|
||||
String expectedResponse =
|
||||
MD5Encoder.encode(md5Helper.digest((ha1() + ":" + NONCE + ":" + HA2).getBytes()));
|
||||
Principal principal =
|
||||
realm.authenticate(USER, expectedResponse, NONCE, null, null, null, REALM, HA2);
|
||||
|
||||
// THEN
|
||||
Assert.assertTrue(principal instanceof GenericPrincipal);
|
||||
Assert.assertEquals(PASSWORD, ((GenericPrincipal)principal).getPassword());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAuthenticateWithUserPasswordAndCredentialHandler() throws Exception {
|
||||
// GIVEN
|
||||
JNDIRealm realm = buildRealm(ha1());
|
||||
realm.setCredentialHandler(buildCredentialHandler());
|
||||
realm.setUserPassword(USER_PASSWORD_ATTR);
|
||||
|
||||
// WHEN
|
||||
String expectedResponse =
|
||||
MD5Encoder.encode(md5Helper.digest((ha1() + ":" + NONCE + ":" + HA2).getBytes()));
|
||||
Principal principal =
|
||||
realm.authenticate(USER, expectedResponse, NONCE, null, null, null, REALM, HA2);
|
||||
|
||||
// THEN
|
||||
Assert.assertTrue(principal instanceof GenericPrincipal);
|
||||
Assert.assertEquals(ha1(), ((GenericPrincipal)principal).getPassword());
|
||||
}
|
||||
|
||||
|
||||
private JNDIRealm buildRealm(String password) throws javax.naming.NamingException,
|
||||
NoSuchFieldException, IllegalAccessException, LifecycleException {
|
||||
Context context = new TesterContext();
|
||||
JNDIRealm realm = new JNDIRealm();
|
||||
realm.setContainer(context);
|
||||
realm.setUserSearch("");
|
||||
|
||||
Field field = JNDIRealm.class.getDeclaredField("context");
|
||||
field.setAccessible(true);
|
||||
field.set(realm, mockDirContext(mockSearchResults(password)));
|
||||
|
||||
realm.start();
|
||||
|
||||
return realm;
|
||||
}
|
||||
|
||||
private MessageDigestCredentialHandler buildCredentialHandler()
|
||||
throws NoSuchAlgorithmException {
|
||||
MessageDigestCredentialHandler credentialHandler = new MessageDigestCredentialHandler();
|
||||
credentialHandler.setAlgorithm(ALGORITHM);
|
||||
return credentialHandler;
|
||||
}
|
||||
|
||||
private NamingEnumeration<SearchResult> mockSearchResults(String password)
|
||||
throws NamingException {
|
||||
@SuppressWarnings("unchecked")
|
||||
NamingEnumeration<SearchResult> searchResults =
|
||||
EasyMock.createNiceMock(NamingEnumeration.class);
|
||||
EasyMock.expect(Boolean.valueOf(searchResults.hasMore()))
|
||||
.andReturn(Boolean.TRUE)
|
||||
.andReturn(Boolean.FALSE)
|
||||
.andReturn(Boolean.TRUE)
|
||||
.andReturn(Boolean.FALSE);
|
||||
EasyMock.expect(searchResults.next())
|
||||
.andReturn(new SearchResult("ANY RESULT", "",
|
||||
new BasicAttributes(USER_PASSWORD_ATTR, password)))
|
||||
.times(2);
|
||||
EasyMock.replay(searchResults);
|
||||
return searchResults;
|
||||
}
|
||||
|
||||
private DirContext mockDirContext(NamingEnumeration<SearchResult> namingEnumeration)
|
||||
throws NamingException {
|
||||
DirContext dirContext = EasyMock.createNiceMock(InitialDirContext.class);
|
||||
EasyMock.expect(dirContext.search(EasyMock.anyString(), EasyMock.anyString(),
|
||||
EasyMock.anyObject(SearchControls.class)))
|
||||
.andReturn(namingEnumeration)
|
||||
.times(2);
|
||||
EasyMock.expect(dirContext.getNameParser(""))
|
||||
.andReturn(new NameParserImpl()).times(2);
|
||||
EasyMock.expect(dirContext.getNameInNamespace())
|
||||
.andReturn("ANY NAME")
|
||||
.times(2);
|
||||
EasyMock.replay(dirContext);
|
||||
return dirContext;
|
||||
}
|
||||
|
||||
private String ha1() {
|
||||
String a1 = USER + ":" + REALM + ":" + PASSWORD;
|
||||
return MD5Encoder.encode(md5Helper.digest(a1.getBytes()));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.catalina.realm;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Parameterized;
|
||||
import org.junit.runners.Parameterized.Parameter;
|
||||
|
||||
@RunWith(Parameterized.class)
|
||||
public class TestJNDIRealmConvertToHexEscape {
|
||||
|
||||
@Parameterized.Parameters(name = "{index}: in[{0}], out[{1}]")
|
||||
public static Collection<Object[]> parameters() {
|
||||
List<Object[]> parameterSets = new ArrayList<>();
|
||||
|
||||
parameterSets.add(new String[] { "none", "none" });
|
||||
parameterSets.add(new String[] { "\\", "\\" });
|
||||
parameterSets.add(new String[] { "\\\\", "\\5C" });
|
||||
parameterSets.add(new String[] { "\\5C", "\\5C" });
|
||||
parameterSets.add(new String[] { "\\ ", "\\20" });
|
||||
parameterSets.add(new String[] { "\\20", "\\20" });
|
||||
parameterSets.add(new String[] { "\\ foo", "\\20foo" });
|
||||
parameterSets.add(new String[] { "\\20foo", "\\20foo" });
|
||||
parameterSets.add(new String[] { "\\ foo", "\\20 foo" });
|
||||
parameterSets.add(new String[] { "\\20 foo", "\\20 foo" });
|
||||
parameterSets.add(new String[] { "\\ \\ foo", "\\20\\20foo" });
|
||||
parameterSets.add(new String[] { "\\20\\20foo", "\\20\\20foo" });
|
||||
parameterSets.add(new String[] { "foo\\ ", "foo\\20" });
|
||||
parameterSets.add(new String[] { "foo\\20", "foo\\20" });
|
||||
parameterSets.add(new String[] { "foo \\ ", "foo \\20" });
|
||||
parameterSets.add(new String[] { "foo \\20", "foo \\20" });
|
||||
parameterSets.add(new String[] { "foo\\ \\ ", "foo\\20\\20" });
|
||||
parameterSets.add(new String[] { "foo\\20\\20", "foo\\20\\20" });
|
||||
|
||||
return parameterSets;
|
||||
}
|
||||
|
||||
|
||||
@Parameter(0)
|
||||
public String in;
|
||||
@Parameter(1)
|
||||
public String out;
|
||||
|
||||
|
||||
@Test
|
||||
public void testConvertToHexEscape() throws Exception {
|
||||
String result = JNDIRealm.convertToHexEscape(in);
|
||||
Assert.assertEquals(out, result);
|
||||
}
|
||||
}
|
||||
38
test/org/apache/catalina/realm/TestMemoryRealm.java
Normal file
38
test/org/apache/catalina/realm/TestMemoryRealm.java
Normal file
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.catalina.realm;
|
||||
|
||||
import java.security.Principal;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
public class TestMemoryRealm {
|
||||
|
||||
/**
|
||||
* Unknown user triggers NPE.
|
||||
*/
|
||||
@Test
|
||||
public void testBug56246() {
|
||||
MemoryRealm memoryRealm = new MemoryRealm();
|
||||
memoryRealm.setCredentialHandler(new MessageDigestCredentialHandler());
|
||||
|
||||
Principal p = memoryRealm.authenticate("foo", "bar");
|
||||
|
||||
Assert.assertNull(p);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.catalina.realm;
|
||||
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.apache.tomcat.util.security.ConcurrentMessageDigest;
|
||||
|
||||
public class TestMessageDigestCredentialHandler {
|
||||
|
||||
private static final String[] DIGESTS = new String[] {"MD5", "SHA-1", "SHA-512"};
|
||||
|
||||
private static final String PWD = "password";
|
||||
|
||||
static {
|
||||
try {
|
||||
ConcurrentMessageDigest.init("SHA-512");
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
throw new IllegalArgumentException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGeneral() throws Exception {
|
||||
for (String digest : DIGESTS) {
|
||||
for (int saltLength = 0; saltLength < 20; saltLength++) {
|
||||
for (int iterations = 1; iterations < 100; iterations += 10)
|
||||
doTest(digest, saltLength, iterations);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void doTest(String digest, int saltLength, int iterations) throws NoSuchAlgorithmException {
|
||||
MessageDigestCredentialHandler mdch = new MessageDigestCredentialHandler();
|
||||
MessageDigestCredentialHandler verifier = new MessageDigestCredentialHandler();
|
||||
mdch.setAlgorithm(digest);
|
||||
mdch.setIterations(iterations);
|
||||
mdch.setSaltLength(saltLength);
|
||||
verifier.setAlgorithm(digest);
|
||||
String storedCredential = mdch.mutate(PWD);
|
||||
Assert.assertTrue(verifier.matches(PWD, storedCredential));
|
||||
}
|
||||
}
|
||||
792
test/org/apache/catalina/realm/TestRealmBase.java
Normal file
792
test/org/apache/catalina/realm/TestRealmBase.java
Normal file
@@ -0,0 +1,792 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.catalina.realm;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.security.Principal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.servlet.ServletSecurityElement;
|
||||
import javax.servlet.annotation.ServletSecurity;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.apache.catalina.Context;
|
||||
import org.apache.catalina.connector.Request;
|
||||
import org.apache.catalina.connector.Response;
|
||||
import org.apache.catalina.startup.TesterMapRealm;
|
||||
import org.apache.tomcat.unittest.TesterContext;
|
||||
import org.apache.tomcat.unittest.TesterRequest;
|
||||
import org.apache.tomcat.unittest.TesterResponse;
|
||||
import org.apache.tomcat.util.descriptor.web.SecurityCollection;
|
||||
import org.apache.tomcat.util.descriptor.web.SecurityConstraint;
|
||||
|
||||
public class TestRealmBase {
|
||||
|
||||
private static final String USER1 = "user1";
|
||||
private static final String USER2 = "user2";
|
||||
private static final String USER99 = "user99";
|
||||
private static final String PWD = "password";
|
||||
public static final String ROLE1 = "role1";
|
||||
private static final String ROLE2 = "role2";
|
||||
private static final String ROLE3 = "role3";
|
||||
private static final String ROLE99 = "role99";
|
||||
|
||||
// All digested passwords are the digested form of "password"
|
||||
private static final String PWD_MD5 = "5f4dcc3b5aa765d61d8327deb882cf99";
|
||||
private static final String PWD_SHA = "5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8";
|
||||
private static final String PWD_MD5_PREFIX =
|
||||
"{MD5}X03MO1qnZdYdgyfeuILPmQ==";
|
||||
private static final String PWD_SHA_PREFIX =
|
||||
"{SHA}W6ph5Mm5Pz8GgiULbPgzG37mj9g=";
|
||||
// Salt added to "password" is "salttoprotectpassword"
|
||||
private static final String PWD_SSHA_PREFIX =
|
||||
"{SSHA}oFLhvfQVqFykEWu8v1pPE6nN0QRzYWx0dG9wcm90ZWN0cGFzc3dvcmQ=";
|
||||
|
||||
@Test
|
||||
public void testDigestMD5() throws Exception {
|
||||
doTestDigestDigestPasswords(PWD, "MD5", PWD_MD5);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDigestSHA() throws Exception {
|
||||
doTestDigestDigestPasswords(PWD, "SHA", PWD_SHA);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDigestMD5Prefix() throws Exception {
|
||||
doTestDigestDigestPasswords(PWD, "MD5", PWD_MD5_PREFIX);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDigestSHAPrefix() throws Exception {
|
||||
doTestDigestDigestPasswords(PWD, "SHA", PWD_SHA_PREFIX);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDigestSSHAPrefix() throws Exception {
|
||||
doTestDigestDigestPasswords(PWD, "SHA", PWD_SSHA_PREFIX);
|
||||
}
|
||||
|
||||
private void doTestDigestDigestPasswords(String password,
|
||||
String digest, String digestedPassword) throws Exception {
|
||||
Context context = new TesterContext();
|
||||
TesterMapRealm realm = new TesterMapRealm();
|
||||
realm.setContainer(context);
|
||||
MessageDigestCredentialHandler ch = new MessageDigestCredentialHandler();
|
||||
ch.setAlgorithm(digest);
|
||||
realm.setCredentialHandler(ch);
|
||||
realm.start();
|
||||
|
||||
realm.addUser(USER1, digestedPassword);
|
||||
|
||||
Principal p = realm.authenticate(USER1, password);
|
||||
|
||||
Assert.assertNotNull(p);
|
||||
Assert.assertEquals(USER1, p.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUserWithSingleRole() throws IOException {
|
||||
List<String> userRoles = new ArrayList<>();
|
||||
List<String> constraintRoles = new ArrayList<>();
|
||||
List<String> applicationRoles = new ArrayList<>();
|
||||
|
||||
// Configure this test
|
||||
userRoles.add(ROLE1);
|
||||
constraintRoles.add(ROLE1);
|
||||
applicationRoles.add(ROLE1);
|
||||
|
||||
doRoleTest(userRoles, constraintRoles, applicationRoles, true);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testUserWithNoRoles() throws IOException {
|
||||
List<String> userRoles = new ArrayList<>();
|
||||
List<String> constraintRoles = new ArrayList<>();
|
||||
List<String> applicationRoles = new ArrayList<>();
|
||||
|
||||
// Configure this test
|
||||
constraintRoles.add(ROLE1);
|
||||
applicationRoles.add(ROLE1);
|
||||
|
||||
doRoleTest(userRoles, constraintRoles, applicationRoles, false);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testUserWithSingleRoleAndAllRoles() throws IOException {
|
||||
List<String> userRoles = new ArrayList<>();
|
||||
List<String> constraintRoles = new ArrayList<>();
|
||||
List<String> applicationRoles = new ArrayList<>();
|
||||
|
||||
// Configure this test
|
||||
userRoles.add(ROLE1);
|
||||
applicationRoles.add(ROLE1);
|
||||
constraintRoles.add(SecurityConstraint.ROLE_ALL_ROLES);
|
||||
|
||||
doRoleTest(userRoles, constraintRoles, applicationRoles, true);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testUserWithoutNoRolesAndAllRoles() throws IOException {
|
||||
List<String> userRoles = new ArrayList<>();
|
||||
List<String> constraintRoles = new ArrayList<>();
|
||||
List<String> applicationRoles = new ArrayList<>();
|
||||
|
||||
// Configure this test
|
||||
constraintRoles.add(SecurityConstraint.ROLE_ALL_ROLES);
|
||||
applicationRoles.add(ROLE1);
|
||||
|
||||
doRoleTest(userRoles, constraintRoles, applicationRoles, false);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testAllRolesWithNoAppRole() throws IOException {
|
||||
List<String> userRoles = new ArrayList<>();
|
||||
List<String> constraintRoles = new ArrayList<>();
|
||||
List<String> applicationRoles = new ArrayList<>();
|
||||
|
||||
// Configure this test
|
||||
userRoles.add(ROLE1);
|
||||
constraintRoles.add(SecurityConstraint.ROLE_ALL_ROLES);
|
||||
|
||||
doRoleTest(userRoles, constraintRoles, applicationRoles, false);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testAllAuthenticatedUsers() throws IOException {
|
||||
List<String> userRoles = new ArrayList<>();
|
||||
List<String> constraintRoles = new ArrayList<>();
|
||||
List<String> applicationRoles = new ArrayList<>();
|
||||
|
||||
// Configure this test
|
||||
constraintRoles.add(SecurityConstraint.ROLE_ALL_AUTHENTICATED_USERS);
|
||||
|
||||
doRoleTest(userRoles, constraintRoles, applicationRoles, true);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testAllAuthenticatedUsersAsAppRoleNoUser() throws IOException {
|
||||
List<String> userRoles = new ArrayList<>();
|
||||
List<String> constraintRoles = new ArrayList<>();
|
||||
List<String> applicationRoles = new ArrayList<>();
|
||||
|
||||
// Configure this test
|
||||
userRoles.add(ROLE1);
|
||||
constraintRoles.add(SecurityConstraint.ROLE_ALL_AUTHENTICATED_USERS);
|
||||
applicationRoles.add(SecurityConstraint.ROLE_ALL_AUTHENTICATED_USERS);
|
||||
|
||||
doRoleTest(userRoles, constraintRoles, applicationRoles, false);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testAllAuthenticatedUsersAsAppRoleWithUser()
|
||||
throws IOException {
|
||||
List<String> userRoles = new ArrayList<>();
|
||||
List<String> constraintRoles = new ArrayList<>();
|
||||
List<String> applicationRoles = new ArrayList<>();
|
||||
|
||||
// Configure this test
|
||||
userRoles.add(SecurityConstraint.ROLE_ALL_AUTHENTICATED_USERS);
|
||||
constraintRoles.add(SecurityConstraint.ROLE_ALL_AUTHENTICATED_USERS);
|
||||
applicationRoles.add(SecurityConstraint.ROLE_ALL_AUTHENTICATED_USERS);
|
||||
|
||||
doRoleTest(userRoles, constraintRoles, applicationRoles, true);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testNoAuthConstraint() throws IOException {
|
||||
// No auth constraint == allow access for all
|
||||
List<String> applicationRoles = new ArrayList<>();
|
||||
|
||||
doRoleTest(null, null, applicationRoles, true);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* The combining constraints tests are based on the scenarios described in
|
||||
* section
|
||||
*/
|
||||
|
||||
@Test
|
||||
public void testCombineConstraints01() throws IOException {
|
||||
// Allowed roles should be the union of the roles in the constraints
|
||||
// User role is in first constraint
|
||||
List<String> userRoles = new ArrayList<>();
|
||||
List<String> constraintOneRoles = new ArrayList<>();
|
||||
List<String> constraintTwoRoles = new ArrayList<>();
|
||||
List<String> applicationRoles = new ArrayList<>();
|
||||
|
||||
userRoles.add(ROLE1);
|
||||
constraintOneRoles.add(ROLE1);
|
||||
constraintTwoRoles.add(ROLE2);
|
||||
applicationRoles.add(ROLE1);
|
||||
applicationRoles.add(ROLE2);
|
||||
|
||||
doRoleTest(userRoles, constraintOneRoles, constraintTwoRoles,
|
||||
applicationRoles, true);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testCombineConstraints02() throws IOException {
|
||||
// Allowed roles should be the union of the roles in the constraints
|
||||
// User role is in last constraint
|
||||
List<String> userRoles = new ArrayList<>();
|
||||
List<String> constraintOneRoles = new ArrayList<>();
|
||||
List<String> constraintTwoRoles = new ArrayList<>();
|
||||
List<String> applicationRoles = new ArrayList<>();
|
||||
|
||||
userRoles.add(ROLE2);
|
||||
constraintOneRoles.add(ROLE1);
|
||||
constraintTwoRoles.add(ROLE2);
|
||||
applicationRoles.add(ROLE1);
|
||||
applicationRoles.add(ROLE2);
|
||||
|
||||
doRoleTest(userRoles, constraintOneRoles, constraintTwoRoles,
|
||||
applicationRoles, true);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testCombineConstraints03() throws IOException {
|
||||
// Allowed roles should be the union of the roles in the constraints
|
||||
// User role is not in any constraint
|
||||
List<String> userRoles = new ArrayList<>();
|
||||
List<String> constraintOneRoles = new ArrayList<>();
|
||||
List<String> constraintTwoRoles = new ArrayList<>();
|
||||
List<String> applicationRoles = new ArrayList<>();
|
||||
|
||||
userRoles.add(ROLE3);
|
||||
constraintOneRoles.add(ROLE1);
|
||||
constraintTwoRoles.add(ROLE2);
|
||||
applicationRoles.add(ROLE1);
|
||||
applicationRoles.add(ROLE2);
|
||||
|
||||
doRoleTest(userRoles, constraintOneRoles, constraintTwoRoles,
|
||||
applicationRoles, false);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testCombineConstraints04() throws IOException {
|
||||
// Allowed roles should be the union of the roles in the constraints
|
||||
// * is any app role
|
||||
// User role is not in any constraint
|
||||
List<String> userRoles = new ArrayList<>();
|
||||
List<String> constraintOneRoles = new ArrayList<>();
|
||||
List<String> constraintTwoRoles = new ArrayList<>();
|
||||
List<String> applicationRoles = new ArrayList<>();
|
||||
|
||||
userRoles.add(ROLE99);
|
||||
constraintOneRoles.add(ROLE1);
|
||||
constraintTwoRoles.add(SecurityConstraint.ROLE_ALL_ROLES);
|
||||
applicationRoles.add(ROLE2);
|
||||
applicationRoles.add(ROLE3);
|
||||
|
||||
doRoleTest(userRoles, constraintOneRoles, constraintTwoRoles,
|
||||
applicationRoles, false);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testCombineConstraints05() throws IOException {
|
||||
// Allowed roles should be the union of the roles in the constraints
|
||||
// * is any app role
|
||||
// User role is a non-app constraint role
|
||||
List<String> userRoles = new ArrayList<>();
|
||||
List<String> constraintOneRoles = new ArrayList<>();
|
||||
List<String> constraintTwoRoles = new ArrayList<>();
|
||||
List<String> applicationRoles = new ArrayList<>();
|
||||
|
||||
userRoles.add(ROLE1);
|
||||
constraintOneRoles.add(ROLE1);
|
||||
constraintTwoRoles.add(SecurityConstraint.ROLE_ALL_ROLES);
|
||||
applicationRoles.add(ROLE2);
|
||||
applicationRoles.add(ROLE3);
|
||||
|
||||
doRoleTest(userRoles, constraintOneRoles, constraintTwoRoles,
|
||||
applicationRoles, true);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testCombineConstraints06() throws IOException {
|
||||
// Allowed roles should be the union of the roles in the constraints
|
||||
// * is any app role
|
||||
// User role is an app role
|
||||
List<String> userRoles = new ArrayList<>();
|
||||
List<String> constraintOneRoles = new ArrayList<>();
|
||||
List<String> constraintTwoRoles = new ArrayList<>();
|
||||
List<String> applicationRoles = new ArrayList<>();
|
||||
|
||||
userRoles.add(ROLE2);
|
||||
constraintOneRoles.add(ROLE1);
|
||||
constraintTwoRoles.add(SecurityConstraint.ROLE_ALL_ROLES);
|
||||
applicationRoles.add(ROLE2);
|
||||
applicationRoles.add(ROLE3);
|
||||
|
||||
doRoleTest(userRoles, constraintOneRoles, constraintTwoRoles,
|
||||
applicationRoles, true);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testCombineConstraints07() throws IOException {
|
||||
// Allowed roles should be the union of the roles in the constraints
|
||||
// * is any app role
|
||||
// User has no role
|
||||
List<String> userRoles = new ArrayList<>();
|
||||
List<String> constraintOneRoles = new ArrayList<>();
|
||||
List<String> constraintTwoRoles = new ArrayList<>();
|
||||
List<String> applicationRoles = new ArrayList<>();
|
||||
|
||||
constraintOneRoles.add(ROLE1);
|
||||
constraintTwoRoles.add(SecurityConstraint.ROLE_ALL_ROLES);
|
||||
applicationRoles.add(ROLE2);
|
||||
applicationRoles.add(ROLE3);
|
||||
|
||||
doRoleTest(userRoles, constraintOneRoles, constraintTwoRoles,
|
||||
applicationRoles, false);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testCombineConstraints08() throws IOException {
|
||||
// Allowed roles should be the union of the roles in the constraints
|
||||
// ** is any authenticated user
|
||||
// User has no role
|
||||
List<String> userRoles = new ArrayList<>();
|
||||
List<String> constraintOneRoles = new ArrayList<>();
|
||||
List<String> constraintTwoRoles = new ArrayList<>();
|
||||
List<String> applicationRoles = new ArrayList<>();
|
||||
|
||||
constraintOneRoles.add(ROLE1);
|
||||
constraintTwoRoles.add(SecurityConstraint.ROLE_ALL_AUTHENTICATED_USERS);
|
||||
applicationRoles.add(ROLE2);
|
||||
applicationRoles.add(ROLE3);
|
||||
|
||||
doRoleTest(userRoles, constraintOneRoles, constraintTwoRoles,
|
||||
applicationRoles, true);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testCombineConstraints09() throws IOException {
|
||||
// Allowed roles should be the union of the roles in the constraints
|
||||
// ** is any authenticated user
|
||||
// User has constraint role
|
||||
List<String> userRoles = new ArrayList<>();
|
||||
List<String> constraintOneRoles = new ArrayList<>();
|
||||
List<String> constraintTwoRoles = new ArrayList<>();
|
||||
List<String> applicationRoles = new ArrayList<>();
|
||||
|
||||
userRoles.add(ROLE1);
|
||||
constraintOneRoles.add(ROLE1);
|
||||
constraintTwoRoles.add(SecurityConstraint.ROLE_ALL_AUTHENTICATED_USERS);
|
||||
applicationRoles.add(ROLE2);
|
||||
applicationRoles.add(ROLE3);
|
||||
|
||||
doRoleTest(userRoles, constraintOneRoles, constraintTwoRoles,
|
||||
applicationRoles, true);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testCombineConstraints10() throws IOException {
|
||||
// Allowed roles should be the union of the roles in the constraints
|
||||
// ** is any authenticated user
|
||||
// User has app role
|
||||
List<String> userRoles = new ArrayList<>();
|
||||
List<String> constraintOneRoles = new ArrayList<>();
|
||||
List<String> constraintTwoRoles = new ArrayList<>();
|
||||
List<String> applicationRoles = new ArrayList<>();
|
||||
|
||||
userRoles.add(ROLE2);
|
||||
constraintOneRoles.add(ROLE1);
|
||||
constraintTwoRoles.add(SecurityConstraint.ROLE_ALL_AUTHENTICATED_USERS);
|
||||
applicationRoles.add(ROLE2);
|
||||
applicationRoles.add(ROLE3);
|
||||
|
||||
doRoleTest(userRoles, constraintOneRoles, constraintTwoRoles,
|
||||
applicationRoles, true);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testCombineConstraints11() throws IOException {
|
||||
// Allowed roles should be the union of the roles in the constraints
|
||||
// ** is any authenticated user
|
||||
// User is not authenticated
|
||||
List<String> constraintOneRoles = new ArrayList<>();
|
||||
List<String> constraintTwoRoles = new ArrayList<>();
|
||||
List<String> applicationRoles = new ArrayList<>();
|
||||
|
||||
constraintOneRoles.add(ROLE1);
|
||||
constraintTwoRoles.add(SecurityConstraint.ROLE_ALL_AUTHENTICATED_USERS);
|
||||
applicationRoles.add(ROLE2);
|
||||
applicationRoles.add(ROLE3);
|
||||
|
||||
doRoleTest(null, constraintOneRoles, constraintTwoRoles,
|
||||
applicationRoles, false);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testCombineConstraints12() throws IOException {
|
||||
// Allowed roles should be the union of the roles in the constraints
|
||||
// Constraint without role or implied role permits unauthenticated users
|
||||
// User is not authenticated
|
||||
List<String> constraintTwoRoles = new ArrayList<>();
|
||||
List<String> applicationRoles = new ArrayList<>();
|
||||
|
||||
constraintTwoRoles.add(ROLE1);
|
||||
applicationRoles.add(ROLE1);
|
||||
|
||||
doRoleTest(null, null, constraintTwoRoles,
|
||||
applicationRoles, true);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testCombineConstraints13() throws IOException {
|
||||
// Allowed roles should be the union of the roles in the constraints
|
||||
// Constraint without role or implied role permits unauthenticated users
|
||||
// User is not authenticated
|
||||
List<String> constraintTwoRoles = new ArrayList<>();
|
||||
List<String> applicationRoles = new ArrayList<>();
|
||||
|
||||
constraintTwoRoles.add(SecurityConstraint.ROLE_ALL_ROLES);
|
||||
applicationRoles.add(ROLE1);
|
||||
|
||||
doRoleTest(null, null, constraintTwoRoles,
|
||||
applicationRoles, true);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testCombineConstraints14() throws IOException {
|
||||
// Allowed roles should be the union of the roles in the constraints
|
||||
// Constraint without role or implied role permits unauthenticated users
|
||||
// User is not authenticated
|
||||
List<String> constraintTwoRoles = new ArrayList<>();
|
||||
List<String> applicationRoles = new ArrayList<>();
|
||||
|
||||
constraintTwoRoles.add(SecurityConstraint.ROLE_ALL_AUTHENTICATED_USERS);
|
||||
applicationRoles.add(ROLE1);
|
||||
|
||||
doRoleTest(null, null, constraintTwoRoles,
|
||||
applicationRoles, true);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testCombineConstraints15() throws IOException {
|
||||
// Allowed roles should be the union of the roles in the constraints
|
||||
// Constraint with empty auth section prevents all access
|
||||
// User has matching constraint role
|
||||
List<String> userRoles = new ArrayList<>();
|
||||
List<String> constraintOneRoles = new ArrayList<>();
|
||||
List<String> constraintTwoRoles = new ArrayList<>();
|
||||
List<String> applicationRoles = new ArrayList<>();
|
||||
|
||||
userRoles.add(ROLE1);
|
||||
constraintTwoRoles.add(ROLE1);
|
||||
applicationRoles.add(ROLE1);
|
||||
|
||||
doRoleTest(userRoles, constraintOneRoles, constraintTwoRoles,
|
||||
applicationRoles, false);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testCombineConstraints16() throws IOException {
|
||||
// Allowed roles should be the union of the roles in the constraints
|
||||
// Constraint with empty auth section prevents all access
|
||||
// User has matching role
|
||||
List<String> userRoles = new ArrayList<>();
|
||||
List<String> constraintOneRoles = new ArrayList<>();
|
||||
List<String> constraintTwoRoles = new ArrayList<>();
|
||||
List<String> applicationRoles = new ArrayList<>();
|
||||
|
||||
userRoles.add(ROLE1);
|
||||
constraintTwoRoles.add(SecurityConstraint.ROLE_ALL_ROLES);
|
||||
applicationRoles.add(ROLE1);
|
||||
|
||||
doRoleTest(userRoles, constraintOneRoles, constraintTwoRoles,
|
||||
applicationRoles, false);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testCombineConstraints17() throws IOException {
|
||||
// Allowed roles should be the union of the roles in the constraints
|
||||
// Constraint with empty auth section prevents all access
|
||||
// User matches all authenticated users
|
||||
List<String> userRoles = new ArrayList<>();
|
||||
List<String> constraintOneRoles = new ArrayList<>();
|
||||
List<String> constraintTwoRoles = new ArrayList<>();
|
||||
List<String> applicationRoles = new ArrayList<>();
|
||||
|
||||
userRoles.add(ROLE1);
|
||||
constraintTwoRoles.add(SecurityConstraint.ROLE_ALL_AUTHENTICATED_USERS);
|
||||
applicationRoles.add(ROLE1);
|
||||
|
||||
doRoleTest(userRoles, constraintOneRoles, constraintTwoRoles,
|
||||
applicationRoles, false);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param userRoles <code>null</code> tests unauthenticated access
|
||||
* otherwise access is tested with an authenticated
|
||||
* user with the listed roles
|
||||
* @param constraintRoles <code>null</code> is equivalent to no auth
|
||||
* constraint whereas an empty list is equivalent
|
||||
* to an auth constraint that defines no roles.
|
||||
*/
|
||||
private void doRoleTest(List<String> userRoles,
|
||||
List<String> constraintRoles, List<String> applicationRoles,
|
||||
boolean expected) throws IOException {
|
||||
|
||||
List<String> constraintTwoRoles = new ArrayList<>();
|
||||
constraintTwoRoles.add(ROLE99);
|
||||
doRoleTest(userRoles, constraintRoles, constraintTwoRoles,
|
||||
applicationRoles, expected);
|
||||
}
|
||||
|
||||
|
||||
private void doRoleTest(List<String> userRoles,
|
||||
List<String> constraintOneRoles, List<String> constraintTwoRoles,
|
||||
List<String> applicationRoles, boolean expected)
|
||||
throws IOException {
|
||||
|
||||
TesterMapRealm mapRealm = new TesterMapRealm();
|
||||
|
||||
// Configure the security constraints for the resource
|
||||
SecurityConstraint constraintOne = new SecurityConstraint();
|
||||
if (constraintOneRoles != null) {
|
||||
constraintOne.setAuthConstraint(true);
|
||||
for (String constraintRole : constraintOneRoles) {
|
||||
constraintOne.addAuthRole(constraintRole);
|
||||
if (applicationRoles.contains(
|
||||
SecurityConstraint.ROLE_ALL_AUTHENTICATED_USERS)) {
|
||||
constraintOne.treatAllAuthenticatedUsersAsApplicationRole();
|
||||
}
|
||||
}
|
||||
}
|
||||
SecurityConstraint constraintTwo = new SecurityConstraint();
|
||||
if (constraintTwoRoles != null) {
|
||||
constraintTwo.setAuthConstraint(true);
|
||||
for (String constraintRole : constraintTwoRoles) {
|
||||
constraintTwo.addAuthRole(constraintRole);
|
||||
if (applicationRoles.contains(
|
||||
SecurityConstraint.ROLE_ALL_AUTHENTICATED_USERS)) {
|
||||
constraintTwo.treatAllAuthenticatedUsersAsApplicationRole();
|
||||
}
|
||||
}
|
||||
}
|
||||
SecurityConstraint[] constraints =
|
||||
new SecurityConstraint[] { constraintOne, constraintTwo };
|
||||
|
||||
// Set up the mock request and response
|
||||
Request request = new Request();
|
||||
Response response = new TesterResponse();
|
||||
Context context = new TesterContext();
|
||||
for (String applicationRole : applicationRoles) {
|
||||
context.addSecurityRole(applicationRole);
|
||||
}
|
||||
request.getMappingData().context = context;
|
||||
|
||||
// Set up an authenticated user
|
||||
// Configure the users in the Realm
|
||||
if (userRoles != null) {
|
||||
GenericPrincipal gp = new GenericPrincipal(USER1, PWD, userRoles);
|
||||
request.setUserPrincipal(gp);
|
||||
}
|
||||
|
||||
// Check if user meets constraints
|
||||
boolean result = mapRealm.hasResourcePermission(
|
||||
request, response, constraints, null);
|
||||
|
||||
Assert.assertEquals(Boolean.valueOf(expected), Boolean.valueOf(result));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* This test case covers the special case in section 13.4.1 of the Servlet
|
||||
* 3.1 specification for {@link javax.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, PWD, userRoles1);
|
||||
|
||||
List<String> userRoles2 = new ArrayList<>();
|
||||
userRoles2.add(ROLE2);
|
||||
GenericPrincipal gp2 = new GenericPrincipal(USER2, PWD, userRoles2);
|
||||
|
||||
List<String> userRoles99 = new ArrayList<>();
|
||||
GenericPrincipal gp99 = new GenericPrincipal(USER99, PWD, 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));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.catalina.realm;
|
||||
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
public class TestSecretKeyCredentialHandler {
|
||||
|
||||
private static final String[] ALGORITHMS = { "PBKDF2WithHmacSHA1", "PBEWithMD5AndDES" };
|
||||
private static final String[] PASSWORDS = { "password", "$!&#%!%@$#@*^$%&%%#!!*%$%&#@!^" };
|
||||
private static final int[] KEYLENGTHS = { 8, 111, 256 };
|
||||
private static final int[] SALTLENGTHS = { 1, 7, 12, 20 };
|
||||
private static final int[] ITERATIONS = { 1, 2111, 10000 };
|
||||
|
||||
@Test
|
||||
public void testGeneral() throws Exception {
|
||||
for (String digest : ALGORITHMS) {
|
||||
for (String password : PASSWORDS) {
|
||||
for (int saltLength : SALTLENGTHS) {
|
||||
for (int iterations : ITERATIONS) {
|
||||
for (int keyLength : KEYLENGTHS) {
|
||||
doTest(password, digest, saltLength, iterations, keyLength, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testZeroSalt() throws NoSuchAlgorithmException {
|
||||
doTest(PASSWORDS[0], ALGORITHMS[0], 0, ITERATIONS[0], KEYLENGTHS[0], false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testZeroIterations() throws NoSuchAlgorithmException {
|
||||
doTest(PASSWORDS[0], ALGORITHMS[0], SALTLENGTHS[0], 0, KEYLENGTHS[0], false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testZeroKeyLength() throws NoSuchAlgorithmException {
|
||||
doTest(PASSWORDS[0], ALGORITHMS[0], SALTLENGTHS[0], ITERATIONS[0], 0, false);
|
||||
}
|
||||
|
||||
private void doTest(String password, String digest, int saltLength, int iterations,
|
||||
int keyLength, boolean expectMatch) throws NoSuchAlgorithmException {
|
||||
SecretKeyCredentialHandler pbech = new SecretKeyCredentialHandler();
|
||||
SecretKeyCredentialHandler verifier = new SecretKeyCredentialHandler();
|
||||
pbech.setAlgorithm(digest);
|
||||
pbech.setIterations(iterations);
|
||||
pbech.setSaltLength(saltLength);
|
||||
pbech.setKeyLength(keyLength);
|
||||
verifier.setAlgorithm(digest);
|
||||
String storedCredential = pbech.mutate(password);
|
||||
if (expectMatch) {
|
||||
Assert.assertTrue(
|
||||
"[" + digest + "] [" + saltLength + "] [" + iterations + "] [" + keyLength + "] ["
|
||||
+ password + "] [" + storedCredential + "]",
|
||||
verifier.matches(password, storedCredential));
|
||||
} else {
|
||||
Assert.assertFalse(
|
||||
"[" + digest + "] [" + saltLength + "] [" + iterations + "] [" + keyLength + "] ["
|
||||
+ password + "] [" + storedCredential + "]",
|
||||
verifier.matches(password, storedCredential));
|
||||
}
|
||||
}
|
||||
}
|
||||
66
test/org/apache/catalina/realm/TesterPrincipal.java
Normal file
66
test/org/apache/catalina/realm/TesterPrincipal.java
Normal file
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.catalina.realm;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.security.Principal;
|
||||
|
||||
public class TesterPrincipal implements Principal, Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private final String name;
|
||||
|
||||
public TesterPrincipal(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((name == null) ? 0 : name.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
TesterPrincipal other = (TesterPrincipal) obj;
|
||||
if (name == null) {
|
||||
if (other.name != null) {
|
||||
return false;
|
||||
}
|
||||
} else if (!name.equals(other.name)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.catalina.realm;
|
||||
|
||||
import java.security.Principal;
|
||||
|
||||
public class TesterPrincipalNonSerializable implements Principal {
|
||||
|
||||
private final String name;
|
||||
|
||||
public TesterPrincipalNonSerializable(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((name == null) ? 0 : name.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
TesterPrincipalNonSerializable other = (TesterPrincipalNonSerializable) obj;
|
||||
if (name == null) {
|
||||
if (other.name != null) {
|
||||
return false;
|
||||
}
|
||||
} else if (!name.equals(other.name)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
35
test/org/apache/catalina/realm/TesterServletSecurity01.java
Normal file
35
test/org/apache/catalina/realm/TesterServletSecurity01.java
Normal file
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.catalina.realm;
|
||||
|
||||
import javax.servlet.annotation.HttpConstraint;
|
||||
import javax.servlet.annotation.HttpMethodConstraint;
|
||||
import javax.servlet.annotation.ServletSecurity;
|
||||
|
||||
import org.apache.tomcat.util.descriptor.web.SecurityConstraint;
|
||||
|
||||
@ServletSecurity(value=@HttpConstraint,
|
||||
httpMethodConstraints={
|
||||
@HttpMethodConstraint(value="POST",
|
||||
rolesAllowed=TestRealmBase.ROLE1),
|
||||
@HttpMethodConstraint(value="PUT",
|
||||
rolesAllowed=SecurityConstraint.ROLE_ALL_ROLES),
|
||||
@HttpMethodConstraint(value="TRACE",
|
||||
rolesAllowed=SecurityConstraint.ROLE_ALL_AUTHENTICATED_USERS)})
|
||||
public class TesterServletSecurity01 {
|
||||
// Class is NO-OP. It is only used to 'host' the annotation.
|
||||
}
|
||||
Reference in New Issue
Block a user