Compare commits
24 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| afcad4f0d4 | |||
| 32c767a30d | |||
| a11746a8d1 | |||
| a18265a163 | |||
| d7a2c0a98c | |||
| 9057fbe0ed | |||
| 537d8f974f | |||
| 783af4012b | |||
| 5f5b8052d8 | |||
| 7dbb8e777e | |||
| bb563967cc | |||
| 974105ed19 | |||
| 2cad2f401b | |||
| 3048e2c6e7 | |||
| 561f284718 | |||
| afc6a6ee0d | |||
| fa05e9c590 | |||
| 818be86d46 | |||
| 60704eb50e | |||
| f02b77794f | |||
| 1172d44397 | |||
| 49738e4588 | |||
| 3b13c1fdf4 | |||
| 8f6450ede1 |
+2
-1
@@ -18,4 +18,5 @@ build/
|
||||
*.ipr
|
||||
*.iws
|
||||
.gradle/
|
||||
atlassian-ide-plugin.xml
|
||||
atlassian-ide-plugin.xml
|
||||
/samples
|
||||
|
||||
+1
-1
@@ -8,7 +8,7 @@ dependencies {
|
||||
"org.springframework:spring-tx:$springVersion",
|
||||
"org.springframework:spring-jdbc:$springVersion"
|
||||
|
||||
optional "net.sf.ehcache:ehcache-core:$ehcacheVersion"
|
||||
optional "net.sf.ehcache:ehcache:$ehcacheVersion"
|
||||
|
||||
testCompile "org.springframework:spring-beans:$springVersion",
|
||||
"org.springframework:spring-context-support:$springVersion",
|
||||
|
||||
+13
-19
@@ -4,7 +4,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-acl</artifactId>
|
||||
<version>4.0.0.M2</version>
|
||||
<version>3.2.3.RELEASE</version>
|
||||
<name>spring-security-acl</name>
|
||||
<description>spring-security-acl</description>
|
||||
<url>http://spring.io/spring-security</url>
|
||||
@@ -42,12 +42,6 @@
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>spring-milestone</id>
|
||||
<url>https://repo.spring.io/milestone</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>aopalliance</groupId>
|
||||
@@ -58,25 +52,25 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-core</artifactId>
|
||||
<version>4.0.0.M2</version>
|
||||
<version>3.2.3.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-aop</artifactId>
|
||||
<version>4.1.0.RC2</version>
|
||||
<version>3.2.8.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-context</artifactId>
|
||||
<version>4.1.0.RC2</version>
|
||||
<version>3.2.8.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-core</artifactId>
|
||||
<version>4.1.0.RC2</version>
|
||||
<version>3.2.8.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
@@ -88,13 +82,13 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-jdbc</artifactId>
|
||||
<version>4.1.0.RC2</version>
|
||||
<version>3.2.8.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-tx</artifactId>
|
||||
<version>4.1.0.RC2</version>
|
||||
<version>3.2.8.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@@ -106,8 +100,8 @@
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.sf.ehcache</groupId>
|
||||
<artifactId>ehcache-core</artifactId>
|
||||
<version>2.6.5</version>
|
||||
<artifactId>ehcache</artifactId>
|
||||
<version>1.6.2</version>
|
||||
<scope>compile</scope>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
@@ -120,7 +114,7 @@
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.11</version>
|
||||
<version>4.10</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@@ -150,19 +144,19 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-beans</artifactId>
|
||||
<version>4.1.0.RC2</version>
|
||||
<version>3.2.8.RELEASE</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-context-support</artifactId>
|
||||
<version>4.1.0.RC2</version>
|
||||
<version>3.2.8.RELEASE</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-test</artifactId>
|
||||
<version>4.1.0.RC2</version>
|
||||
<version>3.2.8.RELEASE</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
+119
-133
@@ -1,34 +1,11 @@
|
||||
package org.springframework.security.acls.jdbc;
|
||||
|
||||
import static org.mockito.Matchers.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.fest.assertions.Assertions.*;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import net.sf.ehcache.Cache;
|
||||
import net.sf.ehcache.CacheManager;
|
||||
import net.sf.ehcache.Ehcache;
|
||||
import net.sf.ehcache.Element;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Captor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.runners.MockitoJUnitRunner;
|
||||
import org.junit.*;
|
||||
import org.springframework.security.acls.domain.AclAuthorizationStrategy;
|
||||
import org.springframework.security.acls.domain.AclAuthorizationStrategyImpl;
|
||||
import org.springframework.security.acls.domain.AclImpl;
|
||||
@@ -42,44 +19,50 @@ import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.security.util.FieldUtils;
|
||||
import org.springframework.test.util.ReflectionTestUtils;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.Serializable;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Tests {@link EhCacheBasedAclCache}
|
||||
*
|
||||
* @author Andrei Stefan
|
||||
*/
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class EhCacheBasedAclCacheTests {
|
||||
private static final String TARGET_CLASS = "org.springframework.security.acls.TargetObject";
|
||||
|
||||
@Mock
|
||||
private Ehcache cache;
|
||||
@Captor
|
||||
private ArgumentCaptor<Element> element;
|
||||
private static CacheManager cacheManager;
|
||||
|
||||
private EhCacheBasedAclCache myCache;
|
||||
@BeforeClass
|
||||
public static void initCacheManaer() {
|
||||
cacheManager = CacheManager.create();
|
||||
// Use disk caching immediately (to test for serialization issue reported in SEC-527)
|
||||
cacheManager.addCache(new Cache("ehcachebasedacltests", 0, true, false, 600, 300));
|
||||
}
|
||||
|
||||
private MutableAcl acl;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
myCache = new EhCacheBasedAclCache(cache);
|
||||
|
||||
ObjectIdentity identity = new ObjectIdentityImpl(TARGET_CLASS, Long.valueOf(100));
|
||||
AclAuthorizationStrategy aclAuthorizationStrategy = new AclAuthorizationStrategyImpl(
|
||||
new SimpleGrantedAuthority("ROLE_OWNERSHIP"), new SimpleGrantedAuthority("ROLE_AUDITING"),
|
||||
new SimpleGrantedAuthority("ROLE_GENERAL"));
|
||||
|
||||
acl = new AclImpl(identity, Long.valueOf(1), aclAuthorizationStrategy, new ConsoleAuditLogger());
|
||||
@AfterClass
|
||||
public static void shutdownCacheManager() {
|
||||
cacheManager.removalAll();
|
||||
cacheManager.shutdown();
|
||||
}
|
||||
|
||||
@After
|
||||
public void cleanup() {
|
||||
public void clearContext() {
|
||||
SecurityContextHolder.clearContext();
|
||||
}
|
||||
|
||||
private Ehcache getCache() {
|
||||
Ehcache cache = cacheManager.getCache("ehcachebasedacltests");
|
||||
cache.removeAll();
|
||||
|
||||
return cache;
|
||||
}
|
||||
|
||||
@Test(expected=IllegalArgumentException.class)
|
||||
public void constructorRejectsNullParameters() throws Exception {
|
||||
new EhCacheBasedAclCache(null);
|
||||
@@ -87,6 +70,9 @@ public class EhCacheBasedAclCacheTests {
|
||||
|
||||
@Test
|
||||
public void methodsRejectNullParameters() throws Exception {
|
||||
Ehcache cache = new MockEhcache();
|
||||
EhCacheBasedAclCache myCache = new EhCacheBasedAclCache(cache);
|
||||
|
||||
try {
|
||||
Serializable id = null;
|
||||
myCache.evictFromCache(id);
|
||||
@@ -136,6 +122,12 @@ public class EhCacheBasedAclCacheTests {
|
||||
// SEC-527
|
||||
@Test
|
||||
public void testDiskSerializationOfMutableAclObjectInstance() throws Exception {
|
||||
ObjectIdentity identity = new ObjectIdentityImpl(TARGET_CLASS, Long.valueOf(100));
|
||||
AclAuthorizationStrategy aclAuthorizationStrategy = new AclAuthorizationStrategyImpl(
|
||||
new SimpleGrantedAuthority("ROLE_OWNERSHIP"), new SimpleGrantedAuthority("ROLE_AUDITING"),
|
||||
new SimpleGrantedAuthority("ROLE_GENERAL"));
|
||||
MutableAcl acl = new AclImpl(identity, Long.valueOf(1), aclAuthorizationStrategy, new ConsoleAuditLogger());
|
||||
|
||||
// Serialization test
|
||||
File file = File.createTempFile("SEC_TEST", ".object");
|
||||
FileOutputStream fos = new FileOutputStream(file);
|
||||
@@ -158,117 +150,111 @@ public class EhCacheBasedAclCacheTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void clearCache() throws Exception {
|
||||
myCache.clearCache();
|
||||
public void cacheOperationsAclWithoutParent() throws Exception {
|
||||
Ehcache cache = getCache();
|
||||
EhCacheBasedAclCache myCache = new EhCacheBasedAclCache(cache);
|
||||
|
||||
verify(cache).removeAll();
|
||||
}
|
||||
ObjectIdentity identity = new ObjectIdentityImpl(TARGET_CLASS, Long.valueOf(100));
|
||||
AclAuthorizationStrategy aclAuthorizationStrategy = new AclAuthorizationStrategyImpl(
|
||||
new SimpleGrantedAuthority("ROLE_OWNERSHIP"), new SimpleGrantedAuthority("ROLE_AUDITING"),
|
||||
new SimpleGrantedAuthority("ROLE_GENERAL"));
|
||||
MutableAcl acl = new AclImpl(identity, Long.valueOf(1), aclAuthorizationStrategy, new ConsoleAuditLogger());
|
||||
|
||||
@Test
|
||||
public void putInCache() throws Exception {
|
||||
assertEquals(0, cache.getDiskStoreSize());
|
||||
myCache.putInCache(acl);
|
||||
assertEquals(cache.getSize(), 2);
|
||||
assertEquals(2, cache.getDiskStoreSize());
|
||||
assertTrue(cache.isElementOnDisk(acl.getObjectIdentity()));
|
||||
assertFalse(cache.isElementInMemory(acl.getObjectIdentity()));
|
||||
|
||||
verify(cache, times(2)).put(element.capture());
|
||||
assertThat(element.getValue().getKey()).isEqualTo(acl.getId());
|
||||
assertThat(element.getValue().getObjectValue()).isEqualTo(acl);
|
||||
assertThat(element.getAllValues().get(0).getKey()).isEqualTo(acl.getObjectIdentity());
|
||||
assertThat(element.getAllValues().get(0).getObjectValue()).isEqualTo(acl);
|
||||
// Check we can get from cache the same objects we put in
|
||||
assertEquals(myCache.getFromCache(Long.valueOf(1)), acl);
|
||||
assertEquals(myCache.getFromCache(identity), acl);
|
||||
|
||||
// Put another object in cache
|
||||
ObjectIdentity identity2 = new ObjectIdentityImpl(TARGET_CLASS, Long.valueOf(101));
|
||||
MutableAcl acl2 = new AclImpl(identity2, Long.valueOf(2), aclAuthorizationStrategy, new ConsoleAuditLogger());
|
||||
|
||||
myCache.putInCache(acl2);
|
||||
assertEquals(cache.getSize(), 4);
|
||||
assertEquals(4, cache.getDiskStoreSize());
|
||||
|
||||
// Try to evict an entry that doesn't exist
|
||||
myCache.evictFromCache(Long.valueOf(3));
|
||||
myCache.evictFromCache(new ObjectIdentityImpl(TARGET_CLASS, Long.valueOf(102)));
|
||||
assertEquals(cache.getSize(), 4);
|
||||
assertEquals(4, cache.getDiskStoreSize());
|
||||
|
||||
myCache.evictFromCache(Long.valueOf(1));
|
||||
assertEquals(cache.getSize(), 2);
|
||||
assertEquals(2, cache.getDiskStoreSize());
|
||||
|
||||
// Check the second object inserted
|
||||
assertEquals(myCache.getFromCache(Long.valueOf(2)), acl2);
|
||||
assertEquals(myCache.getFromCache(identity2), acl2);
|
||||
|
||||
myCache.evictFromCache(identity2);
|
||||
assertEquals(cache.getSize(), 0);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test
|
||||
public void putInCacheAclWithParent() throws Exception {
|
||||
public void cacheOperationsAclWithParent() throws Exception {
|
||||
Ehcache cache = getCache();
|
||||
EhCacheBasedAclCache myCache = new EhCacheBasedAclCache(cache);
|
||||
|
||||
Authentication auth = new TestingAuthenticationToken("user", "password", "ROLE_GENERAL");
|
||||
auth.setAuthenticated(true);
|
||||
SecurityContextHolder.getContext().setAuthentication(auth);
|
||||
|
||||
ObjectIdentity identity = new ObjectIdentityImpl(TARGET_CLASS, Long.valueOf(1));
|
||||
ObjectIdentity identityParent = new ObjectIdentityImpl(TARGET_CLASS, Long.valueOf(2));
|
||||
AclAuthorizationStrategy aclAuthorizationStrategy = new AclAuthorizationStrategyImpl(
|
||||
new SimpleGrantedAuthority("ROLE_OWNERSHIP"), new SimpleGrantedAuthority("ROLE_AUDITING"),
|
||||
new SimpleGrantedAuthority("ROLE_GENERAL"));
|
||||
MutableAcl acl = new AclImpl(identity, Long.valueOf(1), aclAuthorizationStrategy, new ConsoleAuditLogger());
|
||||
MutableAcl parentAcl = new AclImpl(identityParent, Long.valueOf(2), aclAuthorizationStrategy, new ConsoleAuditLogger());
|
||||
|
||||
acl.setParent(parentAcl);
|
||||
|
||||
assertEquals(0, cache.getDiskStoreSize());
|
||||
myCache.putInCache(acl);
|
||||
assertEquals(cache.getSize(), 4);
|
||||
assertEquals(4, cache.getDiskStoreSize());
|
||||
assertTrue(cache.isElementOnDisk(acl.getObjectIdentity()));
|
||||
assertTrue(cache.isElementOnDisk(Long.valueOf(1)));
|
||||
assertFalse(cache.isElementInMemory(acl.getObjectIdentity()));
|
||||
assertFalse(cache.isElementInMemory(Long.valueOf(1)));
|
||||
cache.flush();
|
||||
// Wait for the spool to be written to disk (it's asynchronous)
|
||||
Map spool = (Map) FieldUtils.getFieldValue(cache, "diskStore.spool");
|
||||
|
||||
verify(cache, times(4)).put(element.capture());
|
||||
while(spool.size() > 0) {
|
||||
Thread.sleep(50);
|
||||
}
|
||||
|
||||
List<Element> allValues = element.getAllValues();
|
||||
|
||||
assertThat(allValues.get(0).getKey()).isEqualTo(parentAcl.getObjectIdentity());
|
||||
assertThat(allValues.get(0).getObjectValue()).isEqualTo(parentAcl);
|
||||
|
||||
assertThat(allValues.get(1).getKey()).isEqualTo(parentAcl.getId());
|
||||
assertThat(allValues.get(1).getObjectValue()).isEqualTo(parentAcl);
|
||||
|
||||
|
||||
assertThat(allValues.get(2).getKey()).isEqualTo(acl.getObjectIdentity());
|
||||
assertThat(allValues.get(2).getObjectValue()).isEqualTo(acl);
|
||||
|
||||
assertThat(allValues.get(3).getKey()).isEqualTo(acl.getId());
|
||||
assertThat(allValues.get(3).getObjectValue()).isEqualTo(acl);
|
||||
// Check we can get from cache the same objects we put in
|
||||
AclImpl aclFromCache = (AclImpl) myCache.getFromCache(Long.valueOf(1));
|
||||
// For the checks on transient fields, we need to be sure that the object is being loaded from the cache,
|
||||
// not from the ehcache spool or elsewhere...
|
||||
assertFalse(acl == aclFromCache);
|
||||
assertEquals(acl, aclFromCache);
|
||||
// SEC-951 check transient fields are set on parent
|
||||
assertNotNull(FieldUtils.getFieldValue(aclFromCache.getParentAcl(), "aclAuthorizationStrategy"));
|
||||
assertNotNull(FieldUtils.getFieldValue(aclFromCache.getParentAcl(), "permissionGrantingStrategy"));
|
||||
assertEquals(acl, myCache.getFromCache(identity));
|
||||
assertNotNull(FieldUtils.getFieldValue(aclFromCache, "aclAuthorizationStrategy"));
|
||||
AclImpl parentAclFromCache = (AclImpl) myCache.getFromCache(Long.valueOf(2));
|
||||
assertEquals(parentAcl, parentAclFromCache);
|
||||
assertNotNull(FieldUtils.getFieldValue(parentAclFromCache, "aclAuthorizationStrategy"));
|
||||
assertEquals(parentAcl, myCache.getFromCache(identityParent));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getFromCacheSerializable() throws Exception {
|
||||
when(cache.get(acl.getId())).thenReturn(new Element(acl.getId(),acl));
|
||||
//~ Inner Classes ==================================================================================================
|
||||
|
||||
assertThat(myCache.getFromCache(acl.getId())).isEqualTo(acl);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getFromCacheSerializablePopulatesTransient() throws Exception {
|
||||
when(cache.get(acl.getId())).thenReturn(new Element(acl.getId(),acl));
|
||||
|
||||
myCache.putInCache(acl);
|
||||
|
||||
ReflectionTestUtils.setField(acl, "permissionGrantingStrategy", null);
|
||||
ReflectionTestUtils.setField(acl, "aclAuthorizationStrategy", null);
|
||||
|
||||
MutableAcl fromCache = myCache.getFromCache(acl.getId());
|
||||
|
||||
assertThat(ReflectionTestUtils.getField(fromCache, "aclAuthorizationStrategy")).isNotNull();
|
||||
assertThat(ReflectionTestUtils.getField(fromCache, "permissionGrantingStrategy")).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getFromCacheObjectIdentity() throws Exception {
|
||||
when(cache.get(acl.getId())).thenReturn(new Element(acl.getId(),acl));
|
||||
|
||||
assertThat(myCache.getFromCache(acl.getId())).isEqualTo(acl);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getFromCacheObjectIdentityPopulatesTransient() throws Exception {
|
||||
when(cache.get(acl.getObjectIdentity())).thenReturn(new Element(acl.getId(),acl));
|
||||
|
||||
myCache.putInCache(acl);
|
||||
|
||||
ReflectionTestUtils.setField(acl, "permissionGrantingStrategy", null);
|
||||
ReflectionTestUtils.setField(acl, "aclAuthorizationStrategy", null);
|
||||
|
||||
MutableAcl fromCache = myCache.getFromCache(acl.getObjectIdentity());
|
||||
|
||||
assertThat(ReflectionTestUtils.getField(fromCache, "aclAuthorizationStrategy")).isNotNull();
|
||||
assertThat(ReflectionTestUtils.getField(fromCache, "permissionGrantingStrategy")).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void evictCacheSerializable() throws Exception {
|
||||
when(cache.get(acl.getObjectIdentity())).thenReturn(new Element(acl.getId(),acl));
|
||||
|
||||
myCache.evictFromCache(acl.getObjectIdentity());
|
||||
|
||||
verify(cache).remove(acl.getId());
|
||||
verify(cache).remove(acl.getObjectIdentity());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void evictCacheObjectIdentity() throws Exception {
|
||||
when(cache.get(acl.getId())).thenReturn(new Element(acl.getId(),acl));
|
||||
|
||||
myCache.evictFromCache(acl.getId());
|
||||
|
||||
verify(cache).remove(acl.getId());
|
||||
verify(cache).remove(acl.getObjectIdentity());
|
||||
private class MockEhcache extends Cache {
|
||||
public MockEhcache() {
|
||||
super("cache", 0, true, true, 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
Implementation-Title: org.springframework.security.acls
|
||||
Implementation-Version: ${version}
|
||||
Bundle-SymbolicName: org.springframework.security.acls
|
||||
Bundle-Name: Spring Security Acls
|
||||
Bundle-Vendor: SpringSource
|
||||
Bundle-Version: ${version}
|
||||
Bundle-ManifestVersion: 2
|
||||
Ignored-Existing-Headers:
|
||||
Import-Package,
|
||||
Export-Package
|
||||
Import-Template:
|
||||
org.aopalliance.*;version="${aopAllianceRange}",
|
||||
org.apache.commons.logging.*;version="${cloggingRange}",
|
||||
org.springframework.cache.*;version="${springRange}";resolution:=optional,
|
||||
org.springframework.security.core.*;version="${secRange}",
|
||||
org.springframework.security.access.*;version="${secRange}",
|
||||
org.springframework.security.util.*;version="${secRange}",
|
||||
org.springframework.context.*;version="${springRange}";resolution:=optional,
|
||||
org.springframework.dao.*;version="${springRange}";resolution:=optional,
|
||||
org.springframework.jdbc.core.*;version="${springRange}";resolution:=optional,
|
||||
org.springframework.transaction.support.*;version="${springRange}";resolution:=optional,
|
||||
org.springframework.util.*;version="${springRange}";resolution:=optional,
|
||||
net.sf.ehcache.*;version="${ehcacheRange}";resolution:=optional,
|
||||
javax.sql.*;version="0";resolution:=optional
|
||||
+8
-14
@@ -4,7 +4,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-aspects</artifactId>
|
||||
<version>4.0.0.M2</version>
|
||||
<version>3.2.3.RELEASE</version>
|
||||
<name>spring-security-aspects</name>
|
||||
<description>spring-security-aspects</description>
|
||||
<url>http://spring.io/spring-security</url>
|
||||
@@ -42,35 +42,29 @@
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>spring-milestone</id>
|
||||
<url>https://repo.spring.io/milestone</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-core</artifactId>
|
||||
<version>4.0.0.M2</version>
|
||||
<version>3.2.3.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-beans</artifactId>
|
||||
<version>4.1.0.RC2</version>
|
||||
<version>3.2.8.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-context</artifactId>
|
||||
<version>4.1.0.RC2</version>
|
||||
<version>3.2.8.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-core</artifactId>
|
||||
<version>4.1.0.RC2</version>
|
||||
<version>3.2.8.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
@@ -108,7 +102,7 @@
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.11</version>
|
||||
<version>4.10</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@@ -132,13 +126,13 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-aop</artifactId>
|
||||
<version>4.1.0.RC2</version>
|
||||
<version>3.2.8.RELEASE</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-test</artifactId>
|
||||
<version>4.1.0.RC2</version>
|
||||
<version>3.2.8.RELEASE</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
Implementation-Title: org.springframework.security.aspects
|
||||
Implementation-Version: ${version}
|
||||
Bundle-SymbolicName: org.springframework.security.aspects
|
||||
Bundle-Name: Spring Security Aspects
|
||||
Bundle-Vendor: SpringSource
|
||||
Bundle-ManifestVersion: 2
|
||||
Bundle-Version: ${version}
|
||||
Ignored-Existing-Headers:
|
||||
Import-Package,
|
||||
Export-Package
|
||||
Import-Template:
|
||||
org.aspectj.*;version="${aspectjRange}";resolution:=optional,
|
||||
org.apache.commons.logging.*;version="${cloggingRange}",
|
||||
org.springframework.security.core.*;version="${secRange}",
|
||||
org.springframework.security.access.intercept.aspectj;version="${secRange}",
|
||||
org.springframework.beans.factory;version="${springRange}"
|
||||
+41
-13
@@ -2,12 +2,12 @@ import groovy.text.SimpleTemplateEngine
|
||||
|
||||
buildscript {
|
||||
repositories {
|
||||
maven { url "https://repo.spring.io/plugins-release" }
|
||||
maven { url "http://repo.springsource.org/plugins-release" }
|
||||
}
|
||||
dependencies {
|
||||
classpath("org.springframework.build.gradle:propdeps-plugin:0.0.6")
|
||||
classpath("org.springframework.build.gradle:spring-io-plugin:0.0.3.RELEASE")
|
||||
classpath("org.gradle.api.plugins:gradle-tomcat-plugin:1.2.3")
|
||||
classpath("org.springframework.build.gradle:propdeps-plugin:0.0.5")
|
||||
classpath("org.springframework.build.gradle:bundlor-plugin:0.1.2")
|
||||
classpath("org.gradle.api.plugins:gradle-tomcat-plugin:0.9.8")
|
||||
classpath('me.champeau.gradle:gradle-javadoc-hotfix-plugin:0.1')
|
||||
classpath('org.asciidoctor:asciidoctor-gradle-plugin:0.7.0')
|
||||
classpath('org.asciidoctor:asciidoctor-java-integration:0.1.4.preview.1')
|
||||
@@ -25,8 +25,10 @@ allprojects {
|
||||
|
||||
ext.releaseBuild = version.endsWith('RELEASE')
|
||||
ext.snapshotBuild = version.endsWith('SNAPSHOT')
|
||||
ext.springVersion = '4.1.0.RC2'
|
||||
ext.springLdapVersion = '2.0.1.RELEASE'
|
||||
ext.springVersion = '3.2.8.RELEASE'
|
||||
ext.spring4Version = '4.0.2.RELEASE'
|
||||
ext.springLdapVersion = '1.3.2.RELEASE'
|
||||
ext.springLdap2Version = '2.0.1.RELEASE'
|
||||
|
||||
group = 'org.springframework.security'
|
||||
|
||||
@@ -37,7 +39,7 @@ allprojects {
|
||||
maven { url "http://repo.terracotta.org/maven2/" }
|
||||
}
|
||||
|
||||
eclipse.project.name = "${project.name}-4.0.x"
|
||||
eclipse.project.name = "${project.name}-3.2.x"
|
||||
}
|
||||
|
||||
sonarRunner {
|
||||
@@ -59,7 +61,7 @@ ext.javaProjects = subprojects.findAll { project -> project.name != 'docs' && pr
|
||||
ext.sampleProjects = subprojects.findAll { project -> project.name.startsWith('spring-security-samples') }
|
||||
ext.itestProjects = subprojects.findAll { project -> project.name.startsWith('itest') }
|
||||
ext.coreModuleProjects = javaProjects - sampleProjects - itestProjects
|
||||
ext.aspectjProjects = [project(':spring-security-aspects'), project(':spring-security-samples-aspectj-xml'), project(':spring-security-samples-aspectj-jc')]
|
||||
ext.aspectjProjects = [project(':spring-security-aspects'), project(':spring-security-samples-aspectj-xml')]
|
||||
|
||||
configure(allprojects - javaProjects) {
|
||||
task afterEclipseImport {
|
||||
@@ -96,17 +98,35 @@ configure(javaProjects) {
|
||||
}
|
||||
|
||||
configure(coreModuleProjects) {
|
||||
apply plugin: 'bundlor'
|
||||
apply plugin: 'emma'
|
||||
apply plugin: 'spring-io'
|
||||
|
||||
ext.springIoVersion = project.hasProperty('platformVersion') ? platformVersion : '1.1.0.BUILD-SNAPSHOT'
|
||||
|
||||
bundlor.doFirst {
|
||||
def templateText = file("template.mf").text
|
||||
bundlor.manifestTemplate = new SimpleTemplateEngine().createTemplate(templateText).make(bundlorProperties).toString()
|
||||
}
|
||||
configurations {
|
||||
jacoco //Configuration Group used by Sonar to provide Code Coverage using JaCoCo
|
||||
spring4TestRuntime.extendsFrom testRuntime
|
||||
}
|
||||
configurations.spring4TestRuntime {
|
||||
resolutionStrategy.eachDependency { DependencyResolveDetails details ->
|
||||
if (details.requested.group == 'org.springframework') {
|
||||
details.useVersion spring4Version
|
||||
}
|
||||
if (details.requested.name == 'ehcache') {
|
||||
details.useVersion '2.6.5'
|
||||
}
|
||||
if (details.requested.name == 'ehcache-terracotta') {
|
||||
details.useVersion '2.1.1'
|
||||
}
|
||||
if (details.requested.group == 'org.springframework.ldap') {
|
||||
details.useVersion springLdap2Version
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
springIoVersions "io.spring.platform:platform-versions:${springIoVersion}@properties"
|
||||
jacoco "org.jacoco:org.jacoco.agent:0.6.2.201302030002:runtime"
|
||||
}
|
||||
test {
|
||||
@@ -115,6 +135,14 @@ configure(coreModuleProjects) {
|
||||
integrationTest {
|
||||
jvmArgs "-javaagent:${configurations.jacoco.asPath}=destfile=${buildDir}/jacoco.exec,includes=${project.group}.*"
|
||||
}
|
||||
task spring4Test(type: Test) {
|
||||
jvmArgs = ['-ea', '-Xmx500m', '-XX:MaxPermSize=128M']
|
||||
exclude "**/EhCacheBasedAclCacheTests.class", "**/Issue55Tests.class"
|
||||
classpath = sourceSets.test.output + sourceSets.main.output + configurations.spring4TestRuntime
|
||||
testResultsDir = file("$buildDir/spring4-test-results/")
|
||||
testReportDir = file("$buildDir/reports/spring4-tests/")
|
||||
}
|
||||
check.dependsOn spring4Test
|
||||
}
|
||||
|
||||
configure (aspectjProjects) {
|
||||
@@ -166,5 +194,5 @@ artifacts {
|
||||
}
|
||||
|
||||
task wrapper(type: Wrapper) {
|
||||
gradleVersion = '1.12'
|
||||
gradleVersion = '1.10-rc-2'
|
||||
}
|
||||
|
||||
+3
-3
@@ -5,9 +5,9 @@ dependencies {
|
||||
"org.springframework:spring-context:$springVersion",
|
||||
"org.springframework:spring-beans:$springVersion",
|
||||
"org.springframework:spring-web:$springVersion",
|
||||
"org.jasig.cas.client:cas-client-core:3.3.3"
|
||||
"org.jasig.cas.client:cas-client-core:3.2.1"
|
||||
|
||||
optional "net.sf.ehcache:ehcache-core:$ehcacheVersion"
|
||||
optional "net.sf.ehcache:ehcache:$ehcacheVersion"
|
||||
|
||||
provided "javax.servlet:javax.servlet-api:$servletApiVersion"
|
||||
provided "org.apache.tomcat:tomcat-servlet-api:$servletApiVersion"
|
||||
}
|
||||
|
||||
+15
-21
@@ -4,7 +4,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-cas</artifactId>
|
||||
<version>4.0.0.M2</version>
|
||||
<version>3.2.3.RELEASE</version>
|
||||
<name>spring-security-cas</name>
|
||||
<description>spring-security-cas</description>
|
||||
<url>http://spring.io/spring-security</url>
|
||||
@@ -42,47 +42,41 @@
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>spring-milestone</id>
|
||||
<url>https://repo.spring.io/milestone</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.jasig.cas.client</groupId>
|
||||
<artifactId>cas-client-core</artifactId>
|
||||
<version>3.3.3</version>
|
||||
<version>3.2.1</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-core</artifactId>
|
||||
<version>4.0.0.M2</version>
|
||||
<version>3.2.3.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-web</artifactId>
|
||||
<version>4.0.0.M2</version>
|
||||
<version>3.2.3.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-beans</artifactId>
|
||||
<version>4.1.0.RC2</version>
|
||||
<version>3.2.8.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-context</artifactId>
|
||||
<version>4.1.0.RC2</version>
|
||||
<version>3.2.8.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-core</artifactId>
|
||||
<version>4.1.0.RC2</version>
|
||||
<version>3.2.8.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
@@ -94,7 +88,7 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-web</artifactId>
|
||||
<version>4.1.0.RC2</version>
|
||||
<version>3.2.8.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@@ -106,15 +100,15 @@
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.sf.ehcache</groupId>
|
||||
<artifactId>ehcache-core</artifactId>
|
||||
<version>2.6.5</version>
|
||||
<artifactId>ehcache</artifactId>
|
||||
<version>1.6.2</version>
|
||||
<scope>compile</scope>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>javax.servlet-api</artifactId>
|
||||
<version>3.0.1</version>
|
||||
<groupId>org.apache.tomcat</groupId>
|
||||
<artifactId>tomcat-servlet-api</artifactId>
|
||||
<version>7.0.33</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@@ -126,7 +120,7 @@
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.11</version>
|
||||
<version>4.10</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@@ -150,7 +144,7 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-test</artifactId>
|
||||
<version>4.1.0.RC2</version>
|
||||
<version>3.2.8.RELEASE</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
@@ -49,7 +49,9 @@ public class ServiceProperties implements InitializingBean {
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
Assert.hasLength(this.service, "service cannot be empty.");
|
||||
if(!authenticateAllArtifacts) {
|
||||
Assert.hasLength(this.service, "service must be specified unless authenticateAllArtifacts is true.");
|
||||
}
|
||||
Assert.hasLength(this.artifactParameter, "artifactParameter cannot be empty.");
|
||||
Assert.hasLength(this.serviceParameter, "serviceParameter cannot be empty.");
|
||||
}
|
||||
|
||||
+3
-20
@@ -15,8 +15,6 @@
|
||||
*/
|
||||
package org.springframework.security.cas.web.authentication;
|
||||
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
@@ -52,13 +50,11 @@ final class DefaultServiceAuthenticationDetails extends WebAuthenticationDetails
|
||||
* string from containing the artifact name and value. This can
|
||||
* be created using {@link #createArtifactPattern(String)}.
|
||||
*/
|
||||
DefaultServiceAuthenticationDetails(String casService, HttpServletRequest request, Pattern artifactPattern) throws MalformedURLException {
|
||||
DefaultServiceAuthenticationDetails(HttpServletRequest request, Pattern artifactPattern) {
|
||||
super(request);
|
||||
URL casServiceUrl = new URL(casService);
|
||||
int port = getServicePort(casServiceUrl);
|
||||
final String query = getQueryString(request,artifactPattern);
|
||||
this.serviceUrl = UrlUtils.buildFullRequestUrl(casServiceUrl.getProtocol(),
|
||||
casServiceUrl.getHost(), port,
|
||||
this.serviceUrl = UrlUtils.buildFullRequestUrl(request.getScheme(),
|
||||
request.getServerName(), request.getServerPort(),
|
||||
request.getRequestURI(), query);
|
||||
}
|
||||
|
||||
@@ -132,17 +128,4 @@ final class DefaultServiceAuthenticationDetails extends WebAuthenticationDetails
|
||||
Assert.hasLength(artifactParameterName);
|
||||
return Pattern.compile("&?"+Pattern.quote(artifactParameterName)+"=[^&]*");
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the port from the casServiceURL ensuring to return the proper value if the default port is being used.
|
||||
* @param casServiceUrl the casServerUrl to be used (i.e. "https://example.com/context/j_spring_security_cas_check")
|
||||
* @return the port that is configured for the casServerUrl
|
||||
*/
|
||||
private static int getServicePort(URL casServiceUrl) {
|
||||
int port = casServiceUrl.getPort();
|
||||
if(port == -1) {
|
||||
port = casServiceUrl.getDefaultPort();
|
||||
}
|
||||
return port;
|
||||
}
|
||||
}
|
||||
+2
-48
@@ -15,18 +15,12 @@
|
||||
*/
|
||||
package org.springframework.security.cas.web.authentication;
|
||||
|
||||
import java.net.MalformedURLException;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.security.authentication.AuthenticationDetailsSource;
|
||||
import org.springframework.security.cas.ServiceProperties;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* The {@code AuthenticationDetailsSource} that is set on the
|
||||
@@ -39,33 +33,20 @@ import org.springframework.util.Assert;
|
||||
* @author Rob Winch
|
||||
*/
|
||||
public class ServiceAuthenticationDetailsSource implements AuthenticationDetailsSource<HttpServletRequest,
|
||||
ServiceAuthenticationDetails>, ApplicationContextAware {
|
||||
ServiceAuthenticationDetails> {
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
private final Pattern artifactPattern;
|
||||
|
||||
private ServiceProperties serviceProperties;
|
||||
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
/**
|
||||
* Creates an implementation that uses the default CAS artifactParameterName.
|
||||
* @deprecated Use ServiceAuthenticationDetailsSource(ServiceProperties)
|
||||
*/
|
||||
@Deprecated
|
||||
public ServiceAuthenticationDetailsSource() {
|
||||
this(ServiceProperties.DEFAULT_CAS_ARTIFACT_PARAMETER);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an implementation that uses the specified ServiceProperites and the default CAS artifactParameterName.
|
||||
*
|
||||
* @param serviceProperties The ServiceProperties to use to construct the serviceUrl.
|
||||
*/
|
||||
public ServiceAuthenticationDetailsSource(ServiceProperties serviceProperties) {
|
||||
this(serviceProperties,ServiceProperties.DEFAULT_CAS_ARTIFACT_PARAMETER);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an implementation that uses the specified artifactParameterName
|
||||
*
|
||||
@@ -73,27 +54,11 @@ public class ServiceAuthenticationDetailsSource implements AuthenticationDetails
|
||||
* the artifactParameterName that is removed from the current
|
||||
* URL. The result becomes the service url. Cannot be null and
|
||||
* cannot be an empty String.
|
||||
* @deprecated Use ServiceAuthenticationDetailsSource(ServiceProperties,String)
|
||||
*/
|
||||
public ServiceAuthenticationDetailsSource(final String artifactParameterName) {
|
||||
this.artifactPattern = DefaultServiceAuthenticationDetails.createArtifactPattern(artifactParameterName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an implementation that uses the specified artifactParameterName
|
||||
*
|
||||
* @param serviceProperties The ServiceProperties to use to construct the serviceUrl.
|
||||
* @param artifactParameterName
|
||||
* the artifactParameterName that is removed from the current
|
||||
* URL. The result becomes the service url. Cannot be null and
|
||||
* cannot be an empty String.
|
||||
*/
|
||||
public ServiceAuthenticationDetailsSource(ServiceProperties serviceProperties, String artifactParameterName) {
|
||||
Assert.notNull(serviceProperties, "serviceProperties cannot be null");
|
||||
this.serviceProperties = serviceProperties;
|
||||
this.artifactPattern = DefaultServiceAuthenticationDetails.createArtifactPattern(artifactParameterName);
|
||||
}
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
/**
|
||||
@@ -101,17 +66,6 @@ public class ServiceAuthenticationDetailsSource implements AuthenticationDetails
|
||||
* @return the {@code ServiceAuthenticationDetails} containing information about the current request
|
||||
*/
|
||||
public ServiceAuthenticationDetails buildDetails(HttpServletRequest context) {
|
||||
try {
|
||||
return new DefaultServiceAuthenticationDetails(serviceProperties.getService(),context,artifactPattern);
|
||||
} catch (MalformedURLException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||
if(serviceProperties == null) {
|
||||
serviceProperties = applicationContext.getBean(ServiceProperties.class);
|
||||
}
|
||||
return new DefaultServiceAuthenticationDetails(context,artifactPattern);
|
||||
}
|
||||
}
|
||||
@@ -36,13 +36,10 @@ public class ServicePropertiesTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void nullServiceWhenAuthenticateAllTokens() throws Exception {
|
||||
public void allowNullServiceWhenAuthenticateAllTokens() throws Exception {
|
||||
ServiceProperties sp = new ServiceProperties();
|
||||
sp.setAuthenticateAllArtifacts(true);
|
||||
try {
|
||||
sp.afterPropertiesSet();
|
||||
fail("Expected Exception");
|
||||
}catch(IllegalArgumentException success) {}
|
||||
sp.afterPropertiesSet();
|
||||
sp.setAuthenticateAllArtifacts(false);
|
||||
try {
|
||||
sp.afterPropertiesSet();
|
||||
|
||||
+10
-61
@@ -18,21 +18,11 @@ import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
import org.springframework.context.support.GenericApplicationContext;
|
||||
import org.springframework.context.support.GenericXmlApplicationContext;
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
import org.springframework.security.cas.ServiceProperties;
|
||||
import org.springframework.security.web.util.UrlUtils;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -42,13 +32,9 @@ public class DefaultServiceAuthenticationDetailsTests {
|
||||
private DefaultServiceAuthenticationDetails details;
|
||||
private MockHttpServletRequest request;
|
||||
private Pattern artifactPattern;
|
||||
private String casServiceUrl;
|
||||
|
||||
private ConfigurableApplicationContext context;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
casServiceUrl = "https://localhost:8443/j_spring_security_cas";
|
||||
request = new MockHttpServletRequest();
|
||||
request.setScheme("https");
|
||||
request.setServerName("localhost");
|
||||
@@ -58,82 +44,45 @@ public class DefaultServiceAuthenticationDetailsTests {
|
||||
|
||||
}
|
||||
|
||||
@After
|
||||
public void cleanup() {
|
||||
if(context != null) {
|
||||
context.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getServiceUrlNullQuery() throws Exception {
|
||||
details = new DefaultServiceAuthenticationDetails(casServiceUrl, request,artifactPattern);
|
||||
assertEquals(UrlUtils.buildFullRequestUrl(request), details.getServiceUrl());
|
||||
details = new DefaultServiceAuthenticationDetails(request,artifactPattern);
|
||||
assertEquals(UrlUtils.buildFullRequestUrl(request),details.getServiceUrl());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getServiceUrlTicketOnlyParam() throws Exception {
|
||||
public void getServiceUrlTicketOnlyParam() {
|
||||
request.setQueryString("ticket=123");
|
||||
details = new DefaultServiceAuthenticationDetails(casServiceUrl,request,artifactPattern);
|
||||
details = new DefaultServiceAuthenticationDetails(request,artifactPattern);
|
||||
String serviceUrl = details.getServiceUrl();
|
||||
request.setQueryString(null);
|
||||
assertEquals(UrlUtils.buildFullRequestUrl(request),serviceUrl);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getServiceUrlTicketFirstMultiParam() throws Exception {
|
||||
public void getServiceUrlTicketFirstMultiParam() {
|
||||
request.setQueryString("ticket=123&other=value");
|
||||
details = new DefaultServiceAuthenticationDetails(casServiceUrl, request,artifactPattern);
|
||||
details = new DefaultServiceAuthenticationDetails(request,artifactPattern);
|
||||
String serviceUrl = details.getServiceUrl();
|
||||
request.setQueryString("other=value");
|
||||
assertEquals(UrlUtils.buildFullRequestUrl(request),serviceUrl);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getServiceUrlTicketLastMultiParam() throws Exception {
|
||||
public void getServiceUrlTicketLastMultiParam() {
|
||||
request.setQueryString("other=value&ticket=123");
|
||||
details = new DefaultServiceAuthenticationDetails(casServiceUrl,request,artifactPattern);
|
||||
details = new DefaultServiceAuthenticationDetails(request,artifactPattern);
|
||||
String serviceUrl = details.getServiceUrl();
|
||||
request.setQueryString("other=value");
|
||||
assertEquals(UrlUtils.buildFullRequestUrl(request),serviceUrl);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getServiceUrlTicketMiddleMultiParam() throws Exception {
|
||||
public void getServiceUrlTicketMiddleMultiParam() {
|
||||
request.setQueryString("other=value&ticket=123&last=this");
|
||||
details = new DefaultServiceAuthenticationDetails(casServiceUrl,request,artifactPattern);
|
||||
details = new DefaultServiceAuthenticationDetails(request,artifactPattern);
|
||||
String serviceUrl = details.getServiceUrl();
|
||||
request.setQueryString("other=value&last=this");
|
||||
assertEquals(UrlUtils.buildFullRequestUrl(request),serviceUrl);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getServiceUrlDoesNotUseHostHeader() throws Exception {
|
||||
casServiceUrl = "https://example.com/j_spring_security_cas";
|
||||
request.setServerName("evil.com");
|
||||
details = new DefaultServiceAuthenticationDetails(casServiceUrl, request,artifactPattern);
|
||||
assertEquals("https://example.com/cas-sample/secure/",details.getServiceUrl());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getServiceUrlDoesNotUseHostHeaderPassivity() {
|
||||
casServiceUrl = "https://example.com/j_spring_security_cas";
|
||||
request.setServerName("evil.com");
|
||||
ServiceAuthenticationDetails details = loadServiceAuthenticationDetails("defaultserviceauthenticationdetails-passivity.xml");
|
||||
assertEquals("https://example.com/cas-sample/secure/", details.getServiceUrl());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getServiceUrlDoesNotUseHostHeaderExplicit() {
|
||||
casServiceUrl = "https://example.com/j_spring_security_cas";
|
||||
request.setServerName("evil.com");
|
||||
ServiceAuthenticationDetails details = loadServiceAuthenticationDetails("defaultserviceauthenticationdetails-explicit.xml");
|
||||
assertEquals("https://example.com/cas-sample/secure/", details.getServiceUrl());
|
||||
}
|
||||
|
||||
private ServiceAuthenticationDetails loadServiceAuthenticationDetails(String resourceName) {
|
||||
context = new GenericXmlApplicationContext(getClass(), resourceName);
|
||||
ServiceAuthenticationDetailsSource source = context.getBean(ServiceAuthenticationDetailsSource.class);
|
||||
return source.buildDetails(request);
|
||||
}
|
||||
}
|
||||
|
||||
-23
@@ -1,23 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
|
||||
|
||||
<bean id="serviceProperties"
|
||||
class="org.springframework.security.cas.ServiceProperties">
|
||||
<property name="service"
|
||||
value="https://example.com/j_spring_security_cas"/>
|
||||
<property name="sendRenew" value="false"/>
|
||||
</bean>
|
||||
<bean id="serviceProperties2"
|
||||
class="org.springframework.security.cas.ServiceProperties">
|
||||
<property name="service"
|
||||
value="https://example2.com/j_spring_security_cas"/>
|
||||
<property name="sendRenew" value="false"/>
|
||||
</bean>
|
||||
|
||||
<bean class="org.springframework.security.cas.web.authentication.ServiceAuthenticationDetailsSource">
|
||||
<constructor-arg ref="serviceProperties"/>
|
||||
</bean>
|
||||
</beans>
|
||||
-15
@@ -1,15 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
|
||||
|
||||
<bean id="serviceProperties"
|
||||
class="org.springframework.security.cas.ServiceProperties">
|
||||
<property name="service"
|
||||
value="https://example.com/j_spring_security_cas"/>
|
||||
<property name="sendRenew" value="false"/>
|
||||
</bean>
|
||||
|
||||
<bean class="org.springframework.security.cas.web.authentication.ServiceAuthenticationDetailsSource"/>
|
||||
</beans>
|
||||
@@ -0,0 +1,23 @@
|
||||
Implementation-Title: org.springframework.security.cas
|
||||
Implementation-Version: ${version}
|
||||
Bundle-SymbolicName: org.springframework.security.cas
|
||||
Bundle-Name: Spring Security CAS
|
||||
Bundle-Vendor: SpringSource
|
||||
Bundle-Version: ${version}
|
||||
Bundle-ManifestVersion: 2
|
||||
Ignored-Existing-Headers:
|
||||
Import-Package,
|
||||
Export-Package
|
||||
Import-Template:
|
||||
org.apache.commons.logging.*;version="${cloggingRange}",
|
||||
org.jasig.cas.client.*;version="${casRange}",
|
||||
org.springframework.security.core.*;version="${secRange}",
|
||||
org.springframework.security.authentication.*;version="${secRange}",
|
||||
org.springframework.security.web.*;version="${secRange}",
|
||||
org.springframework.beans.factory;version="${springRange}",
|
||||
org.springframework.cache.*;version="${springRange}";resolution:=optional,
|
||||
org.springframework.context.*;version="${springRange}",
|
||||
org.springframework.dao;version="${springRange}",
|
||||
org.springframework.util;version="${springRange}",
|
||||
net.sf.ehcache.*;version="${ehcacheRange}";resolution:=optional,
|
||||
javax.servlet.*;version="0"
|
||||
+9
-13
@@ -18,27 +18,26 @@ dependencies {
|
||||
optional project(':spring-security-web'),
|
||||
project(':spring-security-ldap'),
|
||||
project(':spring-security-openid'),
|
||||
project(':spring-security-messaging'),
|
||||
"org.springframework:spring-web:$springVersion",
|
||||
"org.springframework:spring-websocket:$springVersion",
|
||||
"org.springframework:spring-web:$springVersion",
|
||||
"org.springframework:spring-webmvc:$springVersion",
|
||||
"org.aspectj:aspectjweaver:$aspectjVersion",
|
||||
"org.springframework:spring-jdbc:$springVersion",
|
||||
"org.springframework:spring-tx:$springVersion"
|
||||
|
||||
provided "javax.servlet:javax.servlet-api:$servletApiVersion"
|
||||
provided "org.apache.tomcat:tomcat-servlet-api:$servletApiVersion"
|
||||
|
||||
testCompile project(':spring-security-cas'),
|
||||
project(':spring-security-core').sourceSets.test.output,
|
||||
project(':spring-security-aspects'),
|
||||
'javax.annotation:jsr250-api:1.0',
|
||||
"org.springframework.ldap:spring-ldap-core:$springLdapVersion",
|
||||
"org.springframework:spring-expression:$springVersion",
|
||||
"org.springframework:spring-jdbc:$springVersion",
|
||||
"org.springframework:spring-orm:$springVersion",
|
||||
"org.springframework:spring-tx:$springVersion",
|
||||
"org.spockframework:spock-core:$spockVersion",
|
||||
"org.spockframework:spock-spring:$spockVersion",
|
||||
"org.slf4j:jcl-over-slf4j:$slf4jVersion",
|
||||
"org.eclipse.persistence:javax.persistence:2.0.5",
|
||||
"org.hibernate.javax.persistence:hibernate-jpa-2.0-api:1.0.1.Final",
|
||||
"org.hibernate:hibernate-entitymanager:4.1.0.Final",
|
||||
"org.codehaus.groovy:groovy-all:$groovyVersion",
|
||||
"org.apache.directory.server:apacheds-core:$apacheDsVersion",
|
||||
@@ -49,15 +48,12 @@ dependencies {
|
||||
'org.apache.directory.shared:shared-ldap:0.9.15',
|
||||
'ldapsdk:ldapsdk:4.1',
|
||||
powerMockDependencies,
|
||||
"org.springframework.data:spring-data-jpa:1.2.0.RELEASE",
|
||||
"org.hibernate.javax.persistence:hibernate-jpa-2.0-api:1.0.0.Final",
|
||||
"org.hibernate:hibernate-entitymanager:3.6.10.Final",
|
||||
"org.hsqldb:hsqldb:2.2.8",
|
||||
spockDependencies
|
||||
|
||||
"org.hsqldb:hsqldb:2.2.8"
|
||||
testCompile('org.openid4java:openid4java-nodeps:0.9.6') {
|
||||
exclude group: 'com.google.code.guice', module: 'guice'
|
||||
}
|
||||
testCompile("org.springframework.data:spring-data-jpa:$springDataJpaVersion") {
|
||||
exclude group: 'org.aspectj', module: 'aspectjrt'
|
||||
exclude group: 'com.google.code.guice', module: 'guice'
|
||||
}
|
||||
|
||||
testRuntime "org.hsqldb:hsqldb:$hsqlVersion",
|
||||
|
||||
+32
-76
@@ -4,7 +4,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-config</artifactId>
|
||||
<version>4.0.0.M2</version>
|
||||
<version>3.2.3.RELEASE</version>
|
||||
<name>spring-security-config</name>
|
||||
<description>spring-security-config</description>
|
||||
<url>http://spring.io/spring-security</url>
|
||||
@@ -42,12 +42,6 @@
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>spring-milestone</id>
|
||||
<url>https://repo.spring.io/milestone</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>aopalliance</groupId>
|
||||
@@ -58,31 +52,31 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-core</artifactId>
|
||||
<version>4.0.0.M2</version>
|
||||
<version>3.2.3.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-aop</artifactId>
|
||||
<version>4.1.0.RC2</version>
|
||||
<version>3.2.8.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-beans</artifactId>
|
||||
<version>4.1.0.RC2</version>
|
||||
<version>3.2.8.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-context</artifactId>
|
||||
<version>4.1.0.RC2</version>
|
||||
<version>3.2.8.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-core</artifactId>
|
||||
<version>4.1.0.RC2</version>
|
||||
<version>3.2.8.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
@@ -108,70 +102,56 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-ldap</artifactId>
|
||||
<version>4.0.0.M2</version>
|
||||
<scope>compile</scope>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-messaging</artifactId>
|
||||
<version>4.0.0.M2</version>
|
||||
<version>3.2.3.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-openid</artifactId>
|
||||
<version>4.0.0.M2</version>
|
||||
<version>3.2.3.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-web</artifactId>
|
||||
<version>4.0.0.M2</version>
|
||||
<version>3.2.3.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-jdbc</artifactId>
|
||||
<version>4.1.0.RC2</version>
|
||||
<version>3.2.8.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-tx</artifactId>
|
||||
<version>4.1.0.RC2</version>
|
||||
<version>3.2.8.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-web</artifactId>
|
||||
<version>4.1.0.RC2</version>
|
||||
<version>3.2.8.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-webmvc</artifactId>
|
||||
<version>4.1.0.RC2</version>
|
||||
<version>3.2.8.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-websocket</artifactId>
|
||||
<version>4.1.0.RC2</version>
|
||||
<scope>compile</scope>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>javax.servlet-api</artifactId>
|
||||
<version>3.0.1</version>
|
||||
<groupId>org.apache.tomcat</groupId>
|
||||
<artifactId>tomcat-servlet-api</artifactId>
|
||||
<version>7.0.33</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@@ -195,7 +175,7 @@
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.11</version>
|
||||
<version>4.10</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@@ -253,9 +233,15 @@
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.persistence</groupId>
|
||||
<artifactId>javax.persistence</artifactId>
|
||||
<version>2.0.5</version>
|
||||
<groupId>org.hibernate.javax.persistence</groupId>
|
||||
<artifactId>hibernate-jpa-2.0-api</artifactId>
|
||||
<version>1.0.0.Final</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.hibernate.javax.persistence</groupId>
|
||||
<artifactId>hibernate-jpa-2.0-api</artifactId>
|
||||
<version>1.0.1.Final</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@@ -305,12 +291,6 @@
|
||||
<artifactId>powermock-api-mockito</artifactId>
|
||||
<version>1.5.1</version>
|
||||
<scope>test</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>mockito-all</artifactId>
|
||||
<groupId>org.mockito</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.powermock</groupId>
|
||||
@@ -353,71 +333,47 @@
|
||||
<artifactId>spock-core</artifactId>
|
||||
<version>0.7-groovy-2.0</version>
|
||||
<scope>test</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>junit-dep</artifactId>
|
||||
<groupId>junit</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.spockframework</groupId>
|
||||
<artifactId>spock-spring</artifactId>
|
||||
<version>0.7-groovy-2.0</version>
|
||||
<scope>test</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>junit-dep</artifactId>
|
||||
<groupId>junit</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-jpa</artifactId>
|
||||
<version>1.7.0.RC1</version>
|
||||
<version>1.2.0.RELEASE</version>
|
||||
<scope>test</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>aspectjrt</artifactId>
|
||||
<groupId>org.aspectj</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.ldap</groupId>
|
||||
<artifactId>spring-ldap-core</artifactId>
|
||||
<version>2.0.1.RELEASE</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-aspects</artifactId>
|
||||
<version>4.0.0.M2</version>
|
||||
<version>1.3.2.RELEASE</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-cas</artifactId>
|
||||
<version>4.0.0.M2</version>
|
||||
<version>3.2.3.RELEASE</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-expression</artifactId>
|
||||
<version>4.1.0.RC2</version>
|
||||
<version>3.2.8.RELEASE</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-orm</artifactId>
|
||||
<version>4.1.0.RC2</version>
|
||||
<version>3.2.8.RELEASE</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-test</artifactId>
|
||||
<version>4.1.0.RC2</version>
|
||||
<version>3.2.8.RELEASE</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
-61
@@ -1,61 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.security.config.annotation.authentication.ldap
|
||||
|
||||
import org.springframework.context.annotation.Configuration
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken
|
||||
import org.springframework.security.config.annotation.BaseSpringSpec
|
||||
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder
|
||||
import org.springframework.security.config.annotation.authentication.ldap.NamespaceLdapAuthenticationProviderTestsConfigs.LdapAuthenticationProviderConfig
|
||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity
|
||||
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter
|
||||
import org.springframework.security.ldap.authentication.LdapAuthenticationProvider
|
||||
import org.springframework.security.ldap.authentication.PasswordComparisonAuthenticator
|
||||
import org.springframework.security.ldap.userdetails.LdapAuthoritiesPopulator
|
||||
import org.springframework.security.ldap.userdetails.PersonContextMapper
|
||||
import org.springframework.test.util.ReflectionTestUtils
|
||||
|
||||
import static org.springframework.security.config.annotation.authentication.ldap.NamespaceLdapAuthenticationProviderTestsConfigs.*
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Rob Winch
|
||||
*
|
||||
*/
|
||||
class LdapAuthenticationProviderConfigurerTests extends BaseSpringSpec {
|
||||
|
||||
def "authentication-manager support multiple default ldap contexts (ports dynamically allocated)"() {
|
||||
when:
|
||||
loadConfig(MultiLdapAuthenticationProvidersConfig)
|
||||
then:
|
||||
authenticationManager.authenticate(new UsernamePasswordAuthenticationToken("bob","bobspassword"))
|
||||
}
|
||||
|
||||
@EnableWebSecurity
|
||||
@Configuration
|
||||
static class MultiLdapAuthenticationProvidersConfig extends WebSecurityConfigurerAdapter {
|
||||
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
|
||||
auth
|
||||
.ldapAuthentication()
|
||||
.groupSearchBase("ou=groups")
|
||||
.userDnPatterns("uid={0},ou=people")
|
||||
.and()
|
||||
.ldapAuthentication()
|
||||
.groupSearchBase("ou=groups")
|
||||
.userDnPatterns("uid={0},ou=people")
|
||||
}
|
||||
}
|
||||
}
|
||||
+4
-32
@@ -1,13 +1,7 @@
|
||||
package org.springframework.security.config.ldap
|
||||
|
||||
|
||||
import static org.mockito.Mockito.*
|
||||
|
||||
import java.text.MessageFormat
|
||||
|
||||
import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer
|
||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder
|
||||
import org.springframework.security.config.AbstractXmlConfigTests
|
||||
import org.springframework.security.config.BeanIds
|
||||
import org.springframework.security.util.FieldUtils
|
||||
@@ -42,7 +36,7 @@ class LdapProviderBeanDefinitionParserTests extends AbstractXmlConfigTests {
|
||||
|
||||
|
||||
def simpleProviderAuthenticatesCorrectly() {
|
||||
xml.'ldap-server'(ldif:'test-server.ldif')
|
||||
xml.'ldap-server'()
|
||||
xml.'authentication-manager'{
|
||||
'ldap-authentication-provider'('group-search-filter':'member={0}')
|
||||
}
|
||||
@@ -72,7 +66,7 @@ class LdapProviderBeanDefinitionParserTests extends AbstractXmlConfigTests {
|
||||
}
|
||||
|
||||
def supportsPasswordComparisonAuthentication() {
|
||||
xml.'ldap-server'(ldif:'test-server.ldif')
|
||||
xml.'ldap-server'()
|
||||
xml.'authentication-manager'{
|
||||
'ldap-authentication-provider'('user-dn-pattern': 'uid={0},ou=people')
|
||||
'password-compare'
|
||||
@@ -89,7 +83,7 @@ class LdapProviderBeanDefinitionParserTests extends AbstractXmlConfigTests {
|
||||
}
|
||||
|
||||
def supportsPasswordComparisonAuthenticationWithHashAttribute() {
|
||||
xml.'ldap-server'(ldif:'test-server.ldif')
|
||||
xml.'ldap-server'()
|
||||
xml.'authentication-manager'{
|
||||
'ldap-authentication-provider'('user-dn-pattern': 'uid={0},ou=people') {
|
||||
'password-compare'('password-attribute': 'uid', hash: 'plaintext')
|
||||
@@ -108,7 +102,7 @@ class LdapProviderBeanDefinitionParserTests extends AbstractXmlConfigTests {
|
||||
}
|
||||
|
||||
def supportsPasswordComparisonAuthenticationWithPasswordEncoder() {
|
||||
xml.'ldap-server'(ldif:'test-server.ldif')
|
||||
xml.'ldap-server'()
|
||||
xml.'authentication-manager'{
|
||||
'ldap-authentication-provider'('user-dn-pattern': 'uid={0},ou=people') {
|
||||
'password-compare'('password-attribute': 'uid') {
|
||||
@@ -128,28 +122,6 @@ class LdapProviderBeanDefinitionParserTests extends AbstractXmlConfigTests {
|
||||
notThrown(AuthenticationException)
|
||||
}
|
||||
|
||||
def 'SEC-2472: Supports Crypto PasswordEncoder'() {
|
||||
setup:
|
||||
xml.'ldap-server'(ldif:'test-server.ldif')
|
||||
xml.'authentication-manager'{
|
||||
'ldap-authentication-provider'('user-dn-pattern': 'uid={0},ou=people') {
|
||||
'password-compare'() {
|
||||
'password-encoder'(ref: 'pe')
|
||||
}
|
||||
}
|
||||
}
|
||||
xml.'b:bean'(id:'pe','class':BCryptPasswordEncoder.class.name)
|
||||
|
||||
createAppContext('')
|
||||
def am = appContext.getBean(BeanIds.AUTHENTICATION_MANAGER)
|
||||
|
||||
when:
|
||||
def auth = am.authenticate(new UsernamePasswordAuthenticationToken("bcrypt", 'password'))
|
||||
|
||||
then:
|
||||
auth != null
|
||||
}
|
||||
|
||||
def inetOrgContextMapperIsSupported() {
|
||||
xml.'ldap-server'(url: 'ldap://127.0.0.1:343/dc=springframework,dc=org')
|
||||
xml.'authentication-manager'{
|
||||
|
||||
+6
-62
@@ -15,12 +15,10 @@
|
||||
*/
|
||||
package org.springframework.security.config.annotation.authentication.ldap
|
||||
|
||||
import org.springframework.beans.factory.config.AutowireCapableBeanFactory
|
||||
import org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Bean
|
||||
import org.springframework.context.annotation.Configuration
|
||||
import org.springframework.context.annotation.Import
|
||||
import org.springframework.ldap.core.ContextSource;
|
||||
import org.springframework.ldap.core.support.BaseLdapPathContextSource;
|
||||
import org.springframework.security.authentication.AuthenticationManager
|
||||
@@ -29,13 +27,7 @@ import org.springframework.security.authentication.UsernamePasswordAuthenticatio
|
||||
import org.springframework.security.config.annotation.BaseSpringSpec
|
||||
import org.springframework.security.config.annotation.SecurityBuilder;
|
||||
import org.springframework.security.config.annotation.authentication.AuthenticationManagerBuilder
|
||||
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder
|
||||
import org.springframework.security.config.annotation.authentication.configuration.EnableGlobalAuthentication
|
||||
import org.springframework.security.config.annotation.configuration.AutowireBeanFactoryObjectPostProcessor
|
||||
import org.springframework.security.config.annotation.configuration.AutowireBeanFactoryObjectPostProcessorTests
|
||||
import org.springframework.security.config.annotation.configuration.ObjectPostProcessorConfiguration
|
||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder
|
||||
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
|
||||
import org.springframework.security.ldap.DefaultSpringSecurityContextSource;
|
||||
import org.springframework.security.ldap.authentication.LdapAuthenticationProvider;
|
||||
import org.springframework.security.ldap.server.ApacheDSContainer;
|
||||
@@ -65,7 +57,6 @@ class LdapAuthenticationProviderBuilderSecurityBuilderTests extends BaseSpringSp
|
||||
auth
|
||||
.ldapAuthentication()
|
||||
.contextSource(contextSource())
|
||||
.userDnPatterns("uid={0},ou=people")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -83,7 +74,6 @@ class LdapAuthenticationProviderBuilderSecurityBuilderTests extends BaseSpringSp
|
||||
auth
|
||||
.ldapAuthentication()
|
||||
.contextSource(contextSource())
|
||||
.userDnPatterns("uid={0},ou=people")
|
||||
.groupRoleAttribute("group")
|
||||
}
|
||||
}
|
||||
@@ -102,7 +92,6 @@ class LdapAuthenticationProviderBuilderSecurityBuilderTests extends BaseSpringSp
|
||||
auth
|
||||
.ldapAuthentication()
|
||||
.contextSource(contextSource())
|
||||
.userDnPatterns("uid={0},ou=people")
|
||||
.groupSearchFilter("ou=groupName");
|
||||
}
|
||||
}
|
||||
@@ -121,7 +110,6 @@ class LdapAuthenticationProviderBuilderSecurityBuilderTests extends BaseSpringSp
|
||||
auth
|
||||
.ldapAuthentication()
|
||||
.contextSource(contextSource())
|
||||
.userDnPatterns("uid={0},ou=people")
|
||||
.rolePrefix("role_")
|
||||
}
|
||||
}
|
||||
@@ -132,7 +120,7 @@ class LdapAuthenticationProviderBuilderSecurityBuilderTests extends BaseSpringSp
|
||||
AuthenticationManager auth = context.getBean(AuthenticationManager)
|
||||
then:
|
||||
auth
|
||||
auth.authenticate(new UsernamePasswordAuthenticationToken("bob","bobspassword")).authorities.collect { it.authority }.sort() == ["ROLE_DEVELOPERS"]
|
||||
auth.authenticate(new UsernamePasswordAuthenticationToken("admin","password")).authorities.collect { it.authority }.sort() == ["ROLE_ADMIN","ROLE_USER"]
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@@ -142,29 +130,6 @@ class LdapAuthenticationProviderBuilderSecurityBuilderTests extends BaseSpringSp
|
||||
.ldapAuthentication()
|
||||
.contextSource(contextSource())
|
||||
.groupSearchBase("ou=groups")
|
||||
.groupSearchFilter("(member={0})")
|
||||
.userDnPatterns("uid={0},ou=people");
|
||||
}
|
||||
}
|
||||
|
||||
def "SEC-2472: Can use crypto PasswordEncoder"() {
|
||||
setup:
|
||||
loadConfig(PasswordEncoderConfig)
|
||||
when:
|
||||
AuthenticationManager auth = context.getBean(AuthenticationManager)
|
||||
then:
|
||||
auth.authenticate(new UsernamePasswordAuthenticationToken("bcrypt","password")).authorities.collect { it.authority }.sort() == ["ROLE_DEVELOPERS"]
|
||||
}
|
||||
|
||||
@Configuration
|
||||
static class PasswordEncoderConfig extends BaseLdapServerConfig {
|
||||
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
|
||||
auth
|
||||
.ldapAuthentication()
|
||||
.contextSource(contextSource())
|
||||
.passwordEncoder(new BCryptPasswordEncoder())
|
||||
.groupSearchBase("ou=groups")
|
||||
.groupSearchFilter("(member={0})")
|
||||
.userDnPatterns("uid={0},ou=people");
|
||||
}
|
||||
}
|
||||
@@ -177,44 +142,23 @@ class LdapAuthenticationProviderBuilderSecurityBuilderTests extends BaseSpringSp
|
||||
static abstract class BaseLdapServerConfig extends BaseLdapProviderConfig {
|
||||
@Bean
|
||||
public ApacheDSContainer ldapServer() throws Exception {
|
||||
ApacheDSContainer apacheDSContainer = new ApacheDSContainer("dc=springframework,dc=org", "classpath:/test-server.ldif");
|
||||
apacheDSContainer.setPort(getPort());
|
||||
ApacheDSContainer apacheDSContainer = new ApacheDSContainer("dc=springframework,dc=org", "classpath:/users.ldif");
|
||||
apacheDSContainer.setPort(33389);
|
||||
return apacheDSContainer;
|
||||
}
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableGlobalAuthentication
|
||||
@Import(ObjectPostProcessorConfiguration)
|
||||
static abstract class BaseLdapProviderConfig {
|
||||
|
||||
@Bean
|
||||
public BaseLdapPathContextSource contextSource() throws Exception {
|
||||
DefaultSpringSecurityContextSource contextSource = new DefaultSpringSecurityContextSource(
|
||||
"ldap://127.0.0.1:"+ getPort() + "/dc=springframework,dc=org")
|
||||
"ldap://127.0.0.1:33389/dc=springframework,dc=org")
|
||||
contextSource.userDn = "uid=admin,ou=system"
|
||||
contextSource.password = "secret"
|
||||
contextSource.afterPropertiesSet()
|
||||
contextSource.afterPropertiesSet();
|
||||
return contextSource;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public AuthenticationManager authenticationManager(AuthenticationManagerBuilder auth) {
|
||||
configure(auth)
|
||||
auth.build()
|
||||
}
|
||||
|
||||
abstract protected void configure(AuthenticationManagerBuilder auth)
|
||||
}
|
||||
|
||||
static Integer port;
|
||||
|
||||
static int getPort() {
|
||||
if(port == null) {
|
||||
ServerSocket socket = new ServerSocket(0)
|
||||
port = socket.localPort
|
||||
socket.close()
|
||||
}
|
||||
port
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -40,7 +40,7 @@ class NamespaceLdapAuthenticationProviderTests extends BaseSpringSpec {
|
||||
when:
|
||||
loadConfig(LdapAuthenticationProviderConfig)
|
||||
then:
|
||||
authenticationManager.authenticate(new UsernamePasswordAuthenticationToken("bob","bobspassword"))
|
||||
authenticationManager.authenticate(new UsernamePasswordAuthenticationToken("user","password")).authorities*.authority.sort() == ['ROLE_USER']
|
||||
}
|
||||
|
||||
def "ldap-authentication-provider custom"() {
|
||||
@@ -75,6 +75,6 @@ class NamespaceLdapAuthenticationProviderTests extends BaseSpringSpec {
|
||||
LdapAuthenticationProvider provider = findAuthenticationProvider(LdapAuthenticationProvider)
|
||||
then:
|
||||
provider.authenticator instanceof PasswordComparisonAuthenticator
|
||||
authenticationManager.authenticate(new UsernamePasswordAuthenticationToken("bob","bobspassword"))
|
||||
authenticationManager.authenticate(new UsernamePasswordAuthenticationToken("user","password")).authorities*.authority.sort() == ['ROLE_USER']
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -56,7 +56,7 @@ public class NamespaceLdapAuthenticationProviderTestsConfigs {
|
||||
.userSearchFilter("(uid={0})") // ldap-authentication-provider@user-search-filter
|
||||
// .contextSource(contextSource) // ldap-authentication-provider@server-ref
|
||||
.contextSource()
|
||||
.ldif("classpath:users.xldif") // ldap-server@ldif
|
||||
.ldif("classpath:user.ldif") // ldap-server@ldif
|
||||
.managerDn("uid=admin,ou=system") // ldap-server@manager-dn
|
||||
.managerPassword("secret") // ldap-server@manager-password
|
||||
.port(33399) // ldap-server@port
|
||||
|
||||
@@ -28,16 +28,6 @@ sn: Alex
|
||||
uid: ben
|
||||
userPassword: {SHA}nFCebWjxfaLbHHG1Qk5UU4trbvQ=
|
||||
|
||||
dn: uid=bcrypt,ou=people,dc=springframework,dc=org
|
||||
objectclass: top
|
||||
objectclass: person
|
||||
objectclass: organizationalPerson
|
||||
objectclass: inetOrgPerson
|
||||
cn: BCrypt user
|
||||
sn: BCrypt
|
||||
uid: bcrypt
|
||||
userPassword: $2a$10$FBAKClV1zBIOOC9XMXf3AO8RoGXYVYsfvUdoLxGkd/BnXEn4tqT3u
|
||||
|
||||
dn: uid=bob,ou=people,dc=springframework,dc=org
|
||||
objectclass: top
|
||||
objectclass: person
|
||||
@@ -68,22 +58,11 @@ sn: Mouse
|
||||
uid: jerry
|
||||
userPassword: jerryspassword
|
||||
|
||||
dn: uid=bcrypt,ou=people,dc=springframework,dc=org
|
||||
objectclass: top
|
||||
objectclass: person
|
||||
objectclass: organizationalPerson
|
||||
objectclass: inetOrgPerson
|
||||
cn: BCrypt user
|
||||
sn: BCrypt
|
||||
uid: bcrypt
|
||||
userPassword: $2a$10$lDa0YFNHAt63MjIzK/wUqeM0qjIhzPhp3RNI/MLUQEAUbzhB/SnnS
|
||||
|
||||
dn: cn=developers,ou=groups,dc=springframework,dc=org
|
||||
objectclass: top
|
||||
objectclass: groupOfNames
|
||||
cn: developers
|
||||
ou: developer
|
||||
member: uid=bcrypt,ou=people,dc=springframework,dc=org
|
||||
member: uid=ben,ou=people,dc=springframework,dc=org
|
||||
member: uid=bob,ou=people,dc=springframework,dc=org
|
||||
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
dn: ou=groups,dc=springframework,dc=org
|
||||
objectclass: top
|
||||
objectclass: organizationalUnit
|
||||
ou: groups
|
||||
|
||||
dn: ou=people,dc=springframework,dc=org
|
||||
objectclass: top
|
||||
objectclass: organizationalUnit
|
||||
ou: people
|
||||
|
||||
dn: uid=admin,ou=people,dc=springframework,dc=org
|
||||
objectclass: top
|
||||
objectclass: person
|
||||
objectclass: organizationalPerson
|
||||
objectclass: inetOrgPerson
|
||||
cn: Rod Johnson
|
||||
sn: Johnson
|
||||
uid: admin
|
||||
userPassword: password
|
||||
|
||||
dn: uid=user,ou=people,dc=springframework,dc=org
|
||||
objectclass: top
|
||||
objectclass: person
|
||||
objectclass: organizationalPerson
|
||||
objectclass: inetOrgPerson
|
||||
cn: Dianne Emu
|
||||
sn: Emu
|
||||
uid: user
|
||||
userPassword: password
|
||||
|
||||
dn: cn=user,ou=groups,dc=springframework,dc=org
|
||||
objectclass: top
|
||||
objectclass: groupOfNames
|
||||
cn: user
|
||||
uniqueMember: uid=admin,ou=people,dc=springframework,dc=org
|
||||
uniqueMember: uid=user,ou=people,dc=springframework,dc=org
|
||||
|
||||
dn: cn=admin,ou=groups,dc=springframework,dc=org
|
||||
objectclass: top
|
||||
objectclass: groupOfNames
|
||||
cn: admin
|
||||
uniqueMember: uid=admin,ou=people,dc=springframework,dc=org
|
||||
@@ -1,92 +0,0 @@
|
||||
dn: ou=groups,dc=springframework,dc=org
|
||||
objectclass: top
|
||||
objectclass: organizationalUnit
|
||||
ou: groups
|
||||
|
||||
dn: ou=subgroups,ou=groups,dc=springframework,dc=org
|
||||
objectclass: top
|
||||
objectclass: organizationalUnit
|
||||
ou: subgroups
|
||||
|
||||
dn: ou=people,dc=springframework,dc=org
|
||||
objectclass: top
|
||||
objectclass: organizationalUnit
|
||||
ou: people
|
||||
|
||||
dn: ou=otherpeople,dc=springframework,dc=org
|
||||
objectclass: top
|
||||
objectclass: organizationalUnit
|
||||
ou: otherpeople
|
||||
|
||||
dn: uid=ben,ou=people,dc=springframework,dc=org
|
||||
objectclass: top
|
||||
objectclass: person
|
||||
objectclass: organizationalPerson
|
||||
objectclass: inetOrgPerson
|
||||
cn: Ben Alex
|
||||
sn: Alex
|
||||
uid: ben
|
||||
userPassword: {SHA}nFCebWjxfaLbHHG1Qk5UU4trbvQ=
|
||||
|
||||
dn: uid=bcrypt,ou=people,dc=springframework,dc=org
|
||||
objectclass: top
|
||||
objectclass: person
|
||||
objectclass: organizationalPerson
|
||||
objectclass: inetOrgPerson
|
||||
cn: BCrypt user
|
||||
sn: BCrypt
|
||||
uid: bcrypt
|
||||
userPassword: $2a$10$lDa0YFNHAt63MjIzK/wUqeM0qjIhzPhp3RNI/MLUQEAUbzhB/SnnS
|
||||
|
||||
dn: uid=bob,ou=people,dc=springframework,dc=org
|
||||
objectclass: top
|
||||
objectclass: person
|
||||
objectclass: organizationalPerson
|
||||
objectclass: inetOrgPerson
|
||||
cn: Bob Hamilton
|
||||
sn: Hamilton
|
||||
uid: bob
|
||||
userPassword: bobspassword
|
||||
|
||||
dn: uid=joe,ou=otherpeople,dc=springframework,dc=org
|
||||
objectclass: top
|
||||
objectclass: person
|
||||
objectclass: organizationalPerson
|
||||
objectclass: inetOrgPerson
|
||||
cn: Joe Smeth
|
||||
sn: Smeth
|
||||
uid: joe
|
||||
userPassword: joespassword
|
||||
|
||||
dn: cn=mouse\, jerry,ou=people,dc=springframework,dc=org
|
||||
objectclass: top
|
||||
objectclass: person
|
||||
objectclass: organizationalPerson
|
||||
objectclass: inetOrgPerson
|
||||
cn: Mouse, Jerry
|
||||
sn: Mouse
|
||||
uid: jerry
|
||||
userPassword: jerryspassword
|
||||
|
||||
dn: cn=developers,ou=groups,dc=springframework,dc=org
|
||||
objectclass: top
|
||||
objectclass: groupOfNames
|
||||
cn: developers
|
||||
ou: developer
|
||||
member: uid=ben,ou=people,dc=springframework,dc=org
|
||||
member: uid=bob,ou=people,dc=springframework,dc=org
|
||||
|
||||
dn: cn=managers,ou=groups,dc=springframework,dc=org
|
||||
objectclass: top
|
||||
objectclass: groupOfNames
|
||||
cn: managers
|
||||
ou: manager
|
||||
member: uid=ben,ou=people,dc=springframework,dc=org
|
||||
member: cn=mouse\, jerry,ou=people,dc=springframework,dc=org
|
||||
|
||||
dn: cn=submanagers,ou=subgroups,ou=groups,dc=springframework,dc=org
|
||||
objectclass: top
|
||||
objectclass: groupOfNames
|
||||
cn: submanagers
|
||||
ou: submanager
|
||||
member: uid=ben,ou=people,dc=springframework,dc=org
|
||||
+2
@@ -29,6 +29,8 @@ import org.springframework.security.config.annotation.web.builders.WebSecurity;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.web.filter.DelegatingFilterProxy;
|
||||
|
||||
import com.google.inject.internal.ImmutableList.Builder;
|
||||
|
||||
/**
|
||||
* <p>A base {@link SecurityBuilder} that allows {@link SecurityConfigurer} to be
|
||||
* applied to it. This makes modifying the {@link SecurityBuilder} a strategy
|
||||
|
||||
+6
-18
@@ -138,31 +138,19 @@ public class AuthenticationManagerBuilder extends AbstractConfiguredSecurityBuil
|
||||
|
||||
/**
|
||||
* Add JDBC authentication to the {@link AuthenticationManagerBuilder} and
|
||||
* return a {@link JdbcUserDetailsManagerConfigurer} to allow customization
|
||||
* of the JDBC authentication.
|
||||
*
|
||||
* <p>
|
||||
* When using with a persistent data store, it is best to add users external
|
||||
* of configuration using something like <a
|
||||
* href="http://flywaydb.org/">Flyway</a> or <a
|
||||
* href="http://www.liquibase.org/">Liquibase</a> to create the schema and
|
||||
* adding users to ensure these steps are only done once and that the
|
||||
* optimal SQL is used.
|
||||
* </p>
|
||||
* return a {@link JdbcUserDetailsManagerConfigurer} to allow customization of the
|
||||
* JDBC authentication.
|
||||
*
|
||||
* <p>
|
||||
* This method also ensure that a {@link UserDetailsService} is available
|
||||
* for the {@link #getDefaultUserDetailsService()} method. Note that
|
||||
* additional {@link UserDetailsService}'s may override this
|
||||
* {@link UserDetailsService} as the default. See the <a href=
|
||||
* "http://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/#user-schema"
|
||||
* >User Schema</a> section of the reference for the default schema.
|
||||
* {@link UserDetailsService} as the default.
|
||||
* </p>
|
||||
*
|
||||
* @return a {@link JdbcUserDetailsManagerConfigurer} to allow customization
|
||||
* of the JDBC authentication
|
||||
* @throws Exception
|
||||
* if an error occurs when adding the JDBC authentication
|
||||
* @return a {@link JdbcUserDetailsManagerConfigurer} to allow customization of the
|
||||
* JDBC authentication
|
||||
* @throws Exception if an error occurs when adding the JDBC authentication
|
||||
*/
|
||||
public JdbcUserDetailsManagerConfigurer<AuthenticationManagerBuilder> jdbcAuthentication()
|
||||
throws Exception {
|
||||
|
||||
+3
@@ -115,6 +115,7 @@ public class AuthenticationConfiguration {
|
||||
ProxyFactoryBean proxyFactory = new ProxyFactoryBean();
|
||||
proxyFactory = objectPostProcessor.postProcess(proxyFactory);
|
||||
proxyFactory.setTargetSource(lazyTargetSource);
|
||||
proxyFactory.setInterfaces(new Class[] { interfaceName, LazyBean.class });
|
||||
return (T) proxyFactory.getObject();
|
||||
}
|
||||
|
||||
@@ -122,6 +123,8 @@ public class AuthenticationConfiguration {
|
||||
return lazyBean(AuthenticationManager.class);
|
||||
}
|
||||
|
||||
private interface LazyBean {}
|
||||
|
||||
private static class EnableGlobalAuthenticationAutowiredConfigurer extends GlobalAuthenticationConfigurerAdapter {
|
||||
private final ApplicationContext context;
|
||||
private static final Log logger = LogFactory.getLog(EnableGlobalAuthenticationAutowiredConfigurer.class);
|
||||
|
||||
+6
-56
@@ -40,10 +40,6 @@ import org.springframework.security.ldap.userdetails.LdapAuthoritiesPopulator;
|
||||
import org.springframework.security.ldap.userdetails.LdapUserDetailsMapper;
|
||||
import org.springframework.security.ldap.userdetails.PersonContextMapper;
|
||||
import org.springframework.security.ldap.userdetails.UserDetailsContextMapper;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.ServerSocket;
|
||||
|
||||
/**
|
||||
* Configures LDAP {@link AuthenticationProvider} in the {@link ProviderManagerBuilder}.
|
||||
@@ -64,7 +60,7 @@ public class LdapAuthenticationProviderConfigurer<B extends ProviderManagerBuild
|
||||
private BaseLdapPathContextSource contextSource;
|
||||
private ContextSourceBuilder contextSourceBuilder = new ContextSourceBuilder();
|
||||
private UserDetailsContextMapper userDetailsContextMapper;
|
||||
private Object passwordEncoder;
|
||||
private PasswordEncoder passwordEncoder;
|
||||
private String passwordAttribute;
|
||||
private LdapAuthoritiesPopulator ldapAuthoritiesPopulator;
|
||||
|
||||
@@ -153,9 +149,7 @@ public class LdapAuthenticationProviderConfigurer<B extends ProviderManagerBuild
|
||||
*/
|
||||
private PasswordComparisonAuthenticator createPasswordCompareAuthenticator(BaseLdapPathContextSource contextSource) {
|
||||
PasswordComparisonAuthenticator ldapAuthenticator = new PasswordComparisonAuthenticator(contextSource);
|
||||
if(passwordAttribute != null) {
|
||||
ldapAuthenticator.setPasswordAttributeName(passwordAttribute);
|
||||
}
|
||||
ldapAuthenticator.setPasswordAttributeName(passwordAttribute);
|
||||
ldapAuthenticator.setPasswordEncoder(passwordEncoder);
|
||||
return ldapAuthenticator;
|
||||
}
|
||||
@@ -210,26 +204,12 @@ public class LdapAuthenticationProviderConfigurer<B extends ProviderManagerBuild
|
||||
*
|
||||
* @param passwordEncoder the {@link PasswordEncoder} to use
|
||||
* @return the {@link LdapAuthenticationProviderConfigurer} for further customization
|
||||
* @deprecated Use {@link #passwordEncoder(org.springframework.security.crypto.password.PasswordEncoder)} instead
|
||||
*/
|
||||
public LdapAuthenticationProviderConfigurer<B> passwordEncoder(PasswordEncoder passwordEncoder) {
|
||||
this.passwordEncoder = passwordEncoder;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies the {@link org.springframework.security.crypto.password.PasswordEncoder} to be used when authenticating with
|
||||
* password comparison.
|
||||
*
|
||||
* @param passwordEncoder the {@link org.springframework.security.crypto.password.PasswordEncoder} to use
|
||||
* @return the {@link LdapAuthenticationProviderConfigurer} for further customization
|
||||
*/
|
||||
public LdapAuthenticationProviderConfigurer<B> passwordEncoder(final org.springframework.security.crypto.password.PasswordEncoder passwordEncoder) {
|
||||
Assert.notNull(passwordEncoder, "passwordEncoder must not be null.");
|
||||
this.passwordEncoder = passwordEncoder;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* If your users are at a fixed location in the directory (i.e. you can work
|
||||
* out the DN directly from the username without doing a directory search),
|
||||
@@ -393,8 +373,7 @@ public class LdapAuthenticationProviderConfigurer<B extends ProviderManagerBuild
|
||||
private String ldif = "classpath*:*.ldif";
|
||||
private String managerPassword;
|
||||
private String managerDn;
|
||||
private Integer port;
|
||||
private static final int DEFAULT_PORT = 33389;
|
||||
private int port = 33389;
|
||||
private String root = "dc=springframework,dc=org";
|
||||
private String url;
|
||||
|
||||
@@ -439,7 +418,7 @@ public class LdapAuthenticationProviderConfigurer<B extends ProviderManagerBuild
|
||||
}
|
||||
|
||||
/**
|
||||
* The port to connect to LDAP to (the default is 33389 or random available port if unavailable).
|
||||
* The port to connect to LDAP to (the default is 33389).
|
||||
* @param port the port to connect to
|
||||
* @return the {@link ContextSourceBuilder} for further customization
|
||||
*/
|
||||
@@ -499,43 +478,14 @@ public class LdapAuthenticationProviderConfigurer<B extends ProviderManagerBuild
|
||||
return contextSource;
|
||||
}
|
||||
ApacheDSContainer apacheDsContainer = new ApacheDSContainer(root, ldif);
|
||||
apacheDsContainer.setPort(getPort());
|
||||
apacheDsContainer.setPort(port);
|
||||
postProcess(apacheDsContainer);
|
||||
return contextSource;
|
||||
}
|
||||
|
||||
private int getPort() {
|
||||
if(port == null) {
|
||||
port = getDefaultPort();
|
||||
}
|
||||
return port;
|
||||
}
|
||||
|
||||
private int getDefaultPort() {
|
||||
ServerSocket serverSocket = null;
|
||||
try {
|
||||
try {
|
||||
serverSocket = new ServerSocket(DEFAULT_PORT);
|
||||
} catch (IOException e) {
|
||||
try {
|
||||
serverSocket = new ServerSocket(0);
|
||||
} catch(IOException e2) {
|
||||
return DEFAULT_PORT;
|
||||
}
|
||||
}
|
||||
return serverSocket.getLocalPort();
|
||||
} finally {
|
||||
if(serverSocket != null) {
|
||||
try {
|
||||
serverSocket.close();
|
||||
} catch (IOException e) {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String getProviderUrl() {
|
||||
if(url == null) {
|
||||
return "ldap://127.0.0.1:" + getPort() + "/" + root;
|
||||
return "ldap://127.0.0.1:" + port + "/" + root;
|
||||
}
|
||||
return url;
|
||||
}
|
||||
|
||||
+10
-9
@@ -18,8 +18,6 @@ package org.springframework.security.config.annotation.method.configuration;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.aop.config.AopConfigUtils;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
|
||||
import org.springframework.core.annotation.AnnotationAttributes;
|
||||
@@ -52,15 +50,18 @@ class GlobalMethodSecurityAspectJAutoProxyRegistrar implements
|
||||
AnnotationMetadata importingClassMetadata,
|
||||
BeanDefinitionRegistry registry) {
|
||||
|
||||
BeanDefinition interceptor = registry.getBeanDefinition("methodSecurityInterceptor");
|
||||
AopConfigUtils
|
||||
.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
|
||||
|
||||
BeanDefinitionBuilder aspect =
|
||||
BeanDefinitionBuilder.rootBeanDefinition("org.springframework.security.access.intercept.aspectj.aspect.AnnotationSecurityAspect");
|
||||
aspect.setFactoryMethod("aspectOf");
|
||||
aspect.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
|
||||
aspect.addPropertyValue("securityInterceptor", interceptor);
|
||||
Map<String, Object> annotationAttributes = importingClassMetadata
|
||||
.getAnnotationAttributes(EnableGlobalMethodSecurity.class
|
||||
.getName());
|
||||
AnnotationAttributes enableAJAutoProxy = AnnotationAttributes
|
||||
.fromMap(annotationAttributes);
|
||||
|
||||
registry.registerBeanDefinition("annotationSecurityAspect$0", aspect.getBeanDefinition());
|
||||
if (enableAJAutoProxy.getBoolean("proxyTargetClass")) {
|
||||
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+5
-7
@@ -24,7 +24,10 @@ import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.context.annotation.*;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.ImportAware;
|
||||
import org.springframework.context.annotation.Role;
|
||||
import org.springframework.core.annotation.AnnotationAttributes;
|
||||
import org.springframework.core.annotation.AnnotationUtils;
|
||||
import org.springframework.core.type.AnnotationMetadata;
|
||||
@@ -45,7 +48,6 @@ import org.springframework.security.access.intercept.AfterInvocationProviderMana
|
||||
import org.springframework.security.access.intercept.RunAsManager;
|
||||
import org.springframework.security.access.intercept.aopalliance.MethodSecurityInterceptor;
|
||||
import org.springframework.security.access.intercept.aopalliance.MethodSecurityMetadataSourceAdvisor;
|
||||
import org.springframework.security.access.intercept.aspectj.AspectJMethodSecurityInterceptor;
|
||||
import org.springframework.security.access.method.DelegatingMethodSecurityMetadataSource;
|
||||
import org.springframework.security.access.method.MethodSecurityMetadataSource;
|
||||
import org.springframework.security.access.prepost.PostInvocationAdviceProvider;
|
||||
@@ -109,7 +111,7 @@ public class GlobalMethodSecurityConfiguration implements ImportAware {
|
||||
*/
|
||||
@Bean
|
||||
public MethodInterceptor methodSecurityInterceptor() throws Exception {
|
||||
MethodSecurityInterceptor methodSecurityInterceptor = isAspectJ() ? new AspectJMethodSecurityInterceptor() : new MethodSecurityInterceptor();
|
||||
MethodSecurityInterceptor methodSecurityInterceptor = new MethodSecurityInterceptor();
|
||||
methodSecurityInterceptor
|
||||
.setAccessDecisionManager(accessDecisionManager());
|
||||
methodSecurityInterceptor
|
||||
@@ -377,10 +379,6 @@ public class GlobalMethodSecurityConfiguration implements ImportAware {
|
||||
return (Integer) enableMethodSecurity().get("order");
|
||||
}
|
||||
|
||||
private boolean isAspectJ() {
|
||||
return enableMethodSecurity().getEnum("mode") == AdviceMode.ASPECTJ;
|
||||
}
|
||||
|
||||
private AnnotationAttributes enableMethodSecurity() {
|
||||
if (enableMethodSecurity == null) {
|
||||
// if it is null look at this instance (i.e. a subclass was used)
|
||||
|
||||
+1
-1
@@ -1000,7 +1000,7 @@ public final class HttpSecurity extends AbstractConfiguredSecurityBuilder<Defaul
|
||||
* .and()
|
||||
* .formLogin()
|
||||
* .and()
|
||||
* .requiresChannel()
|
||||
* .channelSecurity()
|
||||
* .anyRequest().requiresSecure();
|
||||
* }
|
||||
*
|
||||
|
||||
+11
-28
@@ -18,18 +18,11 @@ package org.springframework.security.config.annotation.web.configuration;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.aop.TargetSource;
|
||||
import org.springframework.aop.framework.Advised;
|
||||
import org.springframework.aop.target.LazyInitTargetSource;
|
||||
import org.springframework.beans.FatalBeanException;
|
||||
import org.springframework.beans.factory.BeanFactoryUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.core.annotation.Order;
|
||||
@@ -217,7 +210,7 @@ public abstract class WebSecurityConfigurerAdapter implements WebSecurityConfigu
|
||||
* @throws Exception
|
||||
*/
|
||||
public AuthenticationManager authenticationManagerBean() throws Exception {
|
||||
return new AuthenticationManagerDelegator(authenticationBuilder, context);
|
||||
return new AuthenticationManagerDelegator(authenticationBuilder);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -420,14 +413,12 @@ public abstract class WebSecurityConfigurerAdapter implements WebSecurityConfigu
|
||||
private AuthenticationManagerBuilder delegateBuilder;
|
||||
private AuthenticationManager delegate;
|
||||
private final Object delegateMonitor = new Object();
|
||||
private Set<String> beanNames;
|
||||
|
||||
AuthenticationManagerDelegator(AuthenticationManagerBuilder delegateBuilder, ApplicationContext context) {
|
||||
AuthenticationManagerDelegator(AuthenticationManagerBuilder delegateBuilder) {
|
||||
Assert.notNull(delegateBuilder,"delegateBuilder cannot be null");
|
||||
Field parentAuthMgrField = ReflectionUtils.findField(AuthenticationManagerBuilder.class, "parentAuthenticationManager");
|
||||
ReflectionUtils.makeAccessible(parentAuthMgrField);
|
||||
beanNames = getAuthenticationManagerBeanNames(context);
|
||||
validateBeanCycle(ReflectionUtils.getField(parentAuthMgrField, delegateBuilder), beanNames);
|
||||
validateBeanCycle(ReflectionUtils.getField(parentAuthMgrField, delegateBuilder));
|
||||
this.delegateBuilder = delegateBuilder;
|
||||
}
|
||||
|
||||
@@ -446,24 +437,16 @@ public abstract class WebSecurityConfigurerAdapter implements WebSecurityConfigu
|
||||
return delegate.authenticate(authentication);
|
||||
}
|
||||
|
||||
private static Set<String> getAuthenticationManagerBeanNames(ApplicationContext applicationContext) {
|
||||
String[] beanNamesForType = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(applicationContext, AuthenticationManager.class);
|
||||
return new HashSet<String>(Arrays.asList(beanNamesForType));
|
||||
}
|
||||
|
||||
private static void validateBeanCycle(Object auth, Set<String> beanNames) {
|
||||
if(auth != null && !beanNames.isEmpty()) {
|
||||
if(auth instanceof Advised){
|
||||
Advised advised = (Advised) auth;
|
||||
TargetSource targetSource = advised.getTargetSource();
|
||||
if(targetSource instanceof LazyInitTargetSource) {
|
||||
LazyInitTargetSource lits = (LazyInitTargetSource) targetSource;
|
||||
if(beanNames.contains(lits.getTargetBeanName())) {
|
||||
throw new FatalBeanException("A dependency cycle was detected when trying to resolve the AuthenticationManager. Please ensure you have configured authentication.");
|
||||
}
|
||||
private static void validateBeanCycle(Object auth) {
|
||||
if(auth != null) {
|
||||
String lazyBeanClassName = AuthenticationConfiguration.class.getName() + "$LazyBean";
|
||||
Class<?>[] interfaces = auth.getClass().getInterfaces();
|
||||
for(Class<?> i : interfaces) {
|
||||
String className = i.getName();
|
||||
if(className.equals(lazyBeanClassName)) {
|
||||
throw new FatalBeanException("A dependency cycle was detected when trying to resolve the AuthenticationManager. Please ensure you have configured authentication.");
|
||||
}
|
||||
}
|
||||
beanNames = Collections.emptySet();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-3
@@ -294,9 +294,7 @@ public final class LogoutConfigurer<H extends HttpSecurityBuilder<H>> extends Ab
|
||||
}
|
||||
if(http.getConfigurer(CsrfConfigurer.class) != null) {
|
||||
this.logoutRequestMatcher = new AntPathRequestMatcher(this.logoutUrl, "POST");
|
||||
} else {
|
||||
this.logoutRequestMatcher = new AntPathRequestMatcher(this.logoutUrl);
|
||||
}
|
||||
return this.logoutRequestMatcher;
|
||||
return new AntPathRequestMatcher(this.logoutUrl);
|
||||
}
|
||||
}
|
||||
-303
@@ -1,303 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package org.springframework.security.config.annotation.web.messaging;
|
||||
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.security.config.annotation.web.configurers.RememberMeConfigurer;
|
||||
import org.springframework.security.messaging.access.expression.ExpressionBasedMessageSecurityMetadataSourceFactory;
|
||||
import org.springframework.security.messaging.access.intercept.MessageSecurityMetadataSource;
|
||||
import org.springframework.security.messaging.util.matcher.MessageMatcher;
|
||||
import org.springframework.security.messaging.util.matcher.SimpDestinationMessageMatcher;
|
||||
import org.springframework.util.AntPathMatcher;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.PathMatcher;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Allows mapping security constraints using {@link MessageMatcher} to the security expressions.
|
||||
*
|
||||
* @since 4.0
|
||||
* @author Rob Winch
|
||||
*/
|
||||
public class MessageSecurityMetadataSourceRegistry {
|
||||
private static final String permitAll = "permitAll";
|
||||
private static final String denyAll = "denyAll";
|
||||
private static final String anonymous = "anonymous";
|
||||
private static final String authenticated = "authenticated";
|
||||
private static final String fullyAuthenticated = "fullyAuthenticated";
|
||||
private static final String rememberMe = "rememberMe";
|
||||
|
||||
private final LinkedHashMap<MatcherBuilder,String> matcherToExpression = new LinkedHashMap<MatcherBuilder,String>();
|
||||
|
||||
private PathMatcher pathMatcher = new AntPathMatcher();
|
||||
|
||||
/**
|
||||
* Maps any {@link Message} to a security expression.
|
||||
*
|
||||
* @return the Expression to associate
|
||||
*/
|
||||
public Constraint anyMessage() {
|
||||
return matchers(MessageMatcher.ANY_MESSAGE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps a {@link List} of {@link org.springframework.security.messaging.util.matcher.SimpDestinationMessageMatcher} instances.
|
||||
*
|
||||
* @param patterns the patterns to create {@link org.springframework.security.messaging.util.matcher.SimpDestinationMessageMatcher}
|
||||
* from. Uses {@link MessageSecurityMetadataSourceRegistry#pathMatcher(PathMatcher)}.
|
||||
*
|
||||
* @return the {@link Constraint} that is associated to the {@link MessageMatcher}
|
||||
* @see {@link MessageSecurityMetadataSourceRegistry#pathMatcher(PathMatcher)}
|
||||
*/
|
||||
public Constraint destinationMatchers(String... patterns) {
|
||||
List<MatcherBuilder> matchers = new ArrayList<MatcherBuilder>(patterns.length);
|
||||
for(String pattern : patterns) {
|
||||
matchers.add(new PathMatcherMessageMatcherBuilder(pattern));
|
||||
}
|
||||
return new Constraint(matchers);
|
||||
}
|
||||
|
||||
/**
|
||||
* The {@link PathMatcher} to be used with the {@link MessageSecurityMetadataSourceRegistry#destinationMatchers(String...)}.
|
||||
* The default is to use the default constructor of {@link AntPathMatcher}.
|
||||
*
|
||||
* @param pathMatcher the {@link PathMatcher} to use. Cannot be null.
|
||||
* @return the {@link MessageSecurityMetadataSourceRegistry} for further customization.
|
||||
*/
|
||||
public MessageSecurityMetadataSourceRegistry pathMatcher(PathMatcher pathMatcher) {
|
||||
Assert.notNull(pathMatcher, "pathMatcher cannot be null");
|
||||
this.pathMatcher = pathMatcher;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps a {@link List} of {@link MessageMatcher} instances to a security expression.
|
||||
*
|
||||
* @param matchers the {@link MessageMatcher} instances to map.
|
||||
* @return The {@link Constraint} that is associated to the {@link MessageMatcher} instances
|
||||
*/
|
||||
public Constraint matchers(MessageMatcher<?>... matchers) {
|
||||
List<MatcherBuilder> builders = new ArrayList<MatcherBuilder>(matchers.length);
|
||||
for(MessageMatcher<?> matcher : matchers) {
|
||||
builders.add(new PreBuiltMatcherBuilder(matcher));
|
||||
}
|
||||
return new Constraint(builders);
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows subclasses to create creating a {@link MessageSecurityMetadataSource}.
|
||||
*
|
||||
* <p>This is not exposed so as not to confuse users of the API, which should never invoke this method.</p>
|
||||
*
|
||||
* @return the {@link MessageSecurityMetadataSource} to use
|
||||
*/
|
||||
protected MessageSecurityMetadataSource createMetadataSource() {
|
||||
LinkedHashMap<MessageMatcher<?>,String> matcherToExpression = new LinkedHashMap<MessageMatcher<?>,String>();
|
||||
for(Map.Entry<MatcherBuilder,String> entry : this.matcherToExpression.entrySet()) {
|
||||
matcherToExpression.put(entry.getKey().build(), entry.getValue());
|
||||
}
|
||||
return ExpressionBasedMessageSecurityMetadataSourceFactory.createExpressionMessageMetadataSource(matcherToExpression);
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents the security constraint to be applied to the {@link MessageMatcher} instances.
|
||||
*/
|
||||
public class Constraint {
|
||||
private final List<MatcherBuilder> messageMatchers;
|
||||
|
||||
/**
|
||||
* Creates a new instance
|
||||
*
|
||||
* @param messageMatchers the {@link MessageMatcher} instances to map to this constraint
|
||||
*/
|
||||
private Constraint(List<MatcherBuilder> messageMatchers) {
|
||||
Assert.notEmpty(messageMatchers, "messageMatchers cannot be null or empty");
|
||||
this.messageMatchers = messageMatchers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Shortcut for specifying {@link Message} instances require a particular role. If you do not want to have "ROLE_" automatically
|
||||
* inserted see {@link #hasAuthority(String)}.
|
||||
*
|
||||
* @param role the role to require (i.e. USER, ADMIN, etc). Note, it should not start with "ROLE_" as
|
||||
* this is automatically inserted.
|
||||
* @return the {@link MessageSecurityMetadataSourceRegistry} for further customization
|
||||
*/
|
||||
public MessageSecurityMetadataSourceRegistry hasRole(String role) {
|
||||
return access(MessageSecurityMetadataSourceRegistry.hasRole(role));
|
||||
}
|
||||
|
||||
/**
|
||||
* Shortcut for specifying {@link Message} instances require any of a number of roles. If you
|
||||
* do not want to have "ROLE_" automatically inserted see
|
||||
* {@link #hasAnyAuthority(String...)}
|
||||
*
|
||||
* @param roles
|
||||
* the roles to require (i.e. USER, ADMIN, etc). Note, it
|
||||
* should not start with "ROLE_" as this is automatically
|
||||
* inserted.
|
||||
* @return the {@link MessageSecurityMetadataSourceRegistry} for further
|
||||
* customization
|
||||
*/
|
||||
public MessageSecurityMetadataSourceRegistry hasAnyRole(String... roles) {
|
||||
return access(MessageSecurityMetadataSourceRegistry.hasAnyRole(roles));
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify that {@link Message} instances require a particular authority.
|
||||
*
|
||||
* @param authority the authority to require (i.e. ROLE_USER, ROLE_ADMIN, etc).
|
||||
* @return the {@link MessageSecurityMetadataSourceRegistry} for further customization
|
||||
*/
|
||||
public MessageSecurityMetadataSourceRegistry hasAuthority(String authority) {
|
||||
return access(MessageSecurityMetadataSourceRegistry.hasAuthority(authority));
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify that {@link Message} instances requires any of a number authorities.
|
||||
*
|
||||
* @param authorities the requests require at least one of the authorities (i.e. "ROLE_USER","ROLE_ADMIN" would
|
||||
* mean either "ROLE_USER" or "ROLE_ADMIN" is required).
|
||||
* @return the {@link MessageSecurityMetadataSourceRegistry} for further customization
|
||||
*/
|
||||
public MessageSecurityMetadataSourceRegistry hasAnyAuthority(String... authorities) {
|
||||
return access(MessageSecurityMetadataSourceRegistry.hasAnyAuthority(authorities));
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify that Messages are allowed by anyone.
|
||||
*
|
||||
* @return the {@link MessageSecurityMetadataSourceRegistry} for further customization
|
||||
*/
|
||||
public MessageSecurityMetadataSourceRegistry permitAll() {
|
||||
return access(permitAll);
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify that Messages are allowed by anonymous users.
|
||||
*
|
||||
* @return the {@link MessageSecurityMetadataSourceRegistry} for further customization
|
||||
*/
|
||||
public MessageSecurityMetadataSourceRegistry anonymous() {
|
||||
return access(anonymous);
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify that Messages are allowed by users that have been remembered.
|
||||
*
|
||||
* @return the {@link MessageSecurityMetadataSourceRegistry} for further customization
|
||||
* @see {@link RememberMeConfigurer}
|
||||
*/
|
||||
public MessageSecurityMetadataSourceRegistry rememberMe() {
|
||||
return access(rememberMe);
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify that Messages are not allowed by anyone.
|
||||
*
|
||||
* @return the {@link MessageSecurityMetadataSourceRegistry} for further customization
|
||||
*/
|
||||
public MessageSecurityMetadataSourceRegistry denyAll() {
|
||||
return access(denyAll);
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify that Messages are allowed by any authenticated user.
|
||||
*
|
||||
* @return the {@link MessageSecurityMetadataSourceRegistry} for further customization
|
||||
*/
|
||||
public MessageSecurityMetadataSourceRegistry authenticated() {
|
||||
return access(authenticated);
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify that Messages are allowed by users who have authenticated and were not "remembered".
|
||||
*
|
||||
* @return the {@link MessageSecurityMetadataSourceRegistry} for further customization
|
||||
* @see {@link RememberMeConfigurer}
|
||||
*/
|
||||
public MessageSecurityMetadataSourceRegistry fullyAuthenticated() {
|
||||
return access(fullyAuthenticated);
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows specifying that Messages are secured by an arbitrary expression
|
||||
*
|
||||
* @param attribute the expression to secure the URLs (i.e. "hasRole('ROLE_USER') and hasRole('ROLE_SUPER')")
|
||||
* @return the {@link MessageSecurityMetadataSourceRegistry} for further customization
|
||||
*/
|
||||
public MessageSecurityMetadataSourceRegistry access(String attribute) {
|
||||
for(MatcherBuilder messageMatcher : messageMatchers) {
|
||||
matcherToExpression.put(messageMatcher, attribute);
|
||||
}
|
||||
return MessageSecurityMetadataSourceRegistry.this;
|
||||
}
|
||||
}
|
||||
|
||||
private static String hasAnyRole(String... authorities) {
|
||||
String anyAuthorities = StringUtils.arrayToDelimitedString(authorities, "','ROLE_");
|
||||
return "hasAnyRole('ROLE_" + anyAuthorities + "')";
|
||||
}
|
||||
|
||||
private static String hasRole(String role) {
|
||||
Assert.notNull(role, "role cannot be null");
|
||||
if (role.startsWith("ROLE_")) {
|
||||
throw new IllegalArgumentException("role should not start with 'ROLE_' since it is automatically inserted. Got '" + role + "'");
|
||||
}
|
||||
return "hasRole('ROLE_" + role + "')";
|
||||
}
|
||||
|
||||
private static String hasAuthority(String authority) {
|
||||
return "hasAuthority('" + authority + "')";
|
||||
}
|
||||
|
||||
private static String hasAnyAuthority(String... authorities) {
|
||||
String anyAuthorities = StringUtils.arrayToDelimitedString(authorities, "','");
|
||||
return "hasAnyAuthority('" + anyAuthorities + "')";
|
||||
}
|
||||
|
||||
private class PreBuiltMatcherBuilder implements MatcherBuilder {
|
||||
private MessageMatcher<?> matcher;
|
||||
|
||||
private PreBuiltMatcherBuilder(MessageMatcher<?> matcher) {
|
||||
this.matcher = matcher;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MessageMatcher<?> build() {
|
||||
return matcher;
|
||||
}
|
||||
}
|
||||
|
||||
private class PathMatcherMessageMatcherBuilder implements MatcherBuilder {
|
||||
private final String pattern;
|
||||
|
||||
private PathMatcherMessageMatcherBuilder(String pattern) {
|
||||
this.pattern = pattern;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MessageMatcher<?> build() {
|
||||
return new SimpDestinationMessageMatcher(pattern, pathMatcher);
|
||||
}
|
||||
}
|
||||
|
||||
private interface MatcherBuilder {
|
||||
MessageMatcher<?> build();
|
||||
}
|
||||
}
|
||||
-112
@@ -1,112 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package org.springframework.security.config.annotation.web.socket;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.messaging.simp.config.ChannelRegistration;
|
||||
import org.springframework.security.access.AccessDecisionVoter;
|
||||
import org.springframework.security.access.vote.AffirmativeBased;
|
||||
import org.springframework.security.config.annotation.web.messaging.MessageSecurityMetadataSourceRegistry;
|
||||
import org.springframework.security.messaging.access.expression.ExpressionBasedMessageSecurityMetadataSourceFactory;
|
||||
import org.springframework.security.messaging.access.expression.MessageExpressionVoter;
|
||||
import org.springframework.security.messaging.access.intercept.ChannelSecurityInterceptor;
|
||||
import org.springframework.security.messaging.access.intercept.MessageSecurityMetadataSource;
|
||||
import org.springframework.security.messaging.context.SecurityContextChannelInterceptor;
|
||||
import org.springframework.security.messaging.util.matcher.MessageMatcher;
|
||||
import org.springframework.security.messaging.util.matcher.SimpDestinationMessageMatcher;
|
||||
import org.springframework.web.socket.config.annotation.AbstractWebSocketMessageBrokerConfigurer;
|
||||
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Allows configuring WebSocket Authorization.
|
||||
*
|
||||
* <p>For example:</p>
|
||||
*
|
||||
* <pre>
|
||||
* @Configuration
|
||||
* public class WebSocketSecurityConfig extends AbstractSecurityWebSocketMessageBrokerConfigurer {
|
||||
*
|
||||
* @Override
|
||||
* protected void configure(MessageSecurityMetadataSourceRegistry messages) {
|
||||
* messages
|
||||
* .destinationMatchers("/user/queue/errors").permitAll()
|
||||
* .destinationMatchers("/admin/**").hasRole("ADMIN")
|
||||
* .anyMessage().authenticated();
|
||||
* }
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
*
|
||||
* @since 4.0
|
||||
* @author Rob Winch
|
||||
*/
|
||||
@Order(Ordered.HIGHEST_PRECEDENCE + 100)
|
||||
public abstract class AbstractSecurityWebSocketMessageBrokerConfigurer extends AbstractWebSocketMessageBrokerConfigurer {
|
||||
|
||||
@Override
|
||||
public void registerStompEndpoints(StompEndpointRegistry registry) {}
|
||||
|
||||
@Override
|
||||
public void configureClientInboundChannel(ChannelRegistration registration) {
|
||||
registration.setInterceptors(securityContextChannelInterceptor(),channelSecurity());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configureClientOutboundChannel(ChannelRegistration registration) {
|
||||
registration.setInterceptors(securityContextChannelInterceptor(),channelSecurity());
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ChannelSecurityInterceptor channelSecurity() {
|
||||
ChannelSecurityInterceptor channelSecurityInterceptor = new ChannelSecurityInterceptor(metadataSource());
|
||||
List<AccessDecisionVoter> voters = new ArrayList<AccessDecisionVoter>();
|
||||
voters.add(new MessageExpressionVoter());
|
||||
AffirmativeBased manager = new AffirmativeBased(voters);
|
||||
channelSecurityInterceptor.setAccessDecisionManager(manager);
|
||||
return channelSecurityInterceptor;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public SecurityContextChannelInterceptor securityContextChannelInterceptor() {
|
||||
return new SecurityContextChannelInterceptor();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public MessageSecurityMetadataSource metadataSource() {
|
||||
WebSocketMessageSecurityMetadataSourceRegistry registry = new WebSocketMessageSecurityMetadataSourceRegistry();
|
||||
configure(registry);
|
||||
return registry.createMetadataSource();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param messages
|
||||
*/
|
||||
protected abstract void configure(MessageSecurityMetadataSourceRegistry messages);
|
||||
|
||||
private class WebSocketMessageSecurityMetadataSourceRegistry extends MessageSecurityMetadataSourceRegistry {
|
||||
@Override
|
||||
public MessageSecurityMetadataSource createMetadataSource() {
|
||||
return super.createMetadataSource();
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -208,7 +208,7 @@ public class HeadersBeanDefinitionParser implements BeanDefinitionParser {
|
||||
}
|
||||
String fromParameter = getAttribute(frameElt, ATT_FROM_PARAMETER, "from");
|
||||
allowFromStrategy.addPropertyValue("allowFromParameterName", fromParameter);
|
||||
builder.addConstructorArgValue(allowFromStrategy.getBeanDefinition());
|
||||
builder.addConstructorArgValue(allowFromStrategy);
|
||||
}
|
||||
} else {
|
||||
parserContext.getReaderContext().error("One of 'strategy' and 'strategy-ref' must be set.",
|
||||
|
||||
+1
-2
@@ -123,8 +123,7 @@ abstract class BaseSpringSpec extends Specification {
|
||||
AuthenticationManager getAuthenticationManager() {
|
||||
try {
|
||||
authenticationManager().delegateBuilder.getObject()
|
||||
} catch(NoSuchBeanDefinitionException e) {
|
||||
} catch(MissingPropertyException e) {}
|
||||
} catch(NoSuchBeanDefinitionException e) {}
|
||||
findFilter(FilterSecurityInterceptor).authenticationManager
|
||||
}
|
||||
|
||||
|
||||
+4
-7
@@ -15,14 +15,11 @@
|
||||
*/
|
||||
package org.springframework.security.config.annotation.method.configuration
|
||||
|
||||
import org.springframework.security.access.intercept.aspectj.AspectJMethodSecurityInterceptor
|
||||
|
||||
import static org.fest.assertions.Assertions.assertThat
|
||||
import static org.junit.Assert.fail
|
||||
|
||||
import java.lang.reflect.Method
|
||||
|
||||
import org.springframework.security.access.intercept.aspectj.aspect.AnnotationSecurityAspect
|
||||
import org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator
|
||||
import org.springframework.beans.factory.BeanCreationException
|
||||
import org.springframework.context.ConfigurableApplicationContext
|
||||
@@ -191,8 +188,8 @@ public class NamespaceGlobalMethodSecurityTests extends BaseSpringSpec {
|
||||
when:
|
||||
context = new AnnotationConfigApplicationContext(AspectJModeConfig)
|
||||
then:
|
||||
context.getBean(AnnotationSecurityAspect)
|
||||
context.getBean(AspectJMethodSecurityInterceptor)
|
||||
AnnotationAwareAspectJAutoProxyCreator autoProxyCreator = context.getBean(AnnotationAwareAspectJAutoProxyCreator)
|
||||
autoProxyCreator.proxyTargetClass == true
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@@ -204,8 +201,8 @@ public class NamespaceGlobalMethodSecurityTests extends BaseSpringSpec {
|
||||
when:
|
||||
context = new AnnotationConfigApplicationContext(BaseMethodConfig,AspectJModeExtendsGMSCConfig)
|
||||
then:
|
||||
context.getBean(AnnotationSecurityAspect)
|
||||
context.getBean(AspectJMethodSecurityInterceptor)
|
||||
AnnotationAwareAspectJAutoProxyCreator autoProxyCreator = context.getBean(AnnotationAwareAspectJAutoProxyCreator)
|
||||
autoProxyCreator.proxyTargetClass == false
|
||||
}
|
||||
|
||||
@Configuration
|
||||
|
||||
-45
@@ -15,13 +15,10 @@
|
||||
*/
|
||||
package org.springframework.security.config.annotation.web.configuration;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired
|
||||
import org.springframework.beans.FatalBeanException;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext
|
||||
import org.springframework.context.annotation.Bean
|
||||
import org.springframework.context.annotation.Configuration
|
||||
import org.springframework.security.authentication.AuthenticationManager
|
||||
import org.springframework.security.authentication.TestingAuthenticationToken
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken
|
||||
import org.springframework.security.config.annotation.BaseSpringSpec
|
||||
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
|
||||
@@ -47,48 +44,6 @@ public class Sec2515Tests extends BaseSpringSpec {
|
||||
}
|
||||
}
|
||||
|
||||
def "Custom Name Prevent StackOverflow with bean graph cycle"() {
|
||||
when:
|
||||
loadConfig(StackOverflowSecurityConfig)
|
||||
then:
|
||||
thrown(FatalBeanException)
|
||||
}
|
||||
|
||||
@EnableWebSecurity
|
||||
@Configuration
|
||||
static class CustomBeanNameStackOverflowSecurityConfig extends WebSecurityConfigurerAdapter {
|
||||
|
||||
@Override
|
||||
@Bean(name="custom")
|
||||
public AuthenticationManager authenticationManagerBean()
|
||||
throws Exception {
|
||||
return super.authenticationManagerBean();
|
||||
}
|
||||
}
|
||||
|
||||
def "SEC-2549: Can load with child classloader"() {
|
||||
setup:
|
||||
CanLoadWithChildConfig.AM = Mock(AuthenticationManager)
|
||||
context = new AnnotationConfigApplicationContext()
|
||||
context.classLoader = new URLClassLoader(new URL[0], context.classLoader)
|
||||
context.register(CanLoadWithChildConfig)
|
||||
context.refresh()
|
||||
when:
|
||||
authenticationManager.authenticate(new UsernamePasswordAuthenticationToken("user", "password"))
|
||||
then:
|
||||
noExceptionThrown()
|
||||
1 * CanLoadWithChildConfig.AM.authenticate(_) >> new TestingAuthenticationToken("user","password","ROLE_USER")
|
||||
}
|
||||
|
||||
@EnableWebSecurity
|
||||
@Configuration
|
||||
static class CanLoadWithChildConfig extends WebSecurityConfigurerAdapter {
|
||||
static AuthenticationManager AM
|
||||
@Bean
|
||||
public AuthenticationManager am() {
|
||||
AM
|
||||
}
|
||||
}
|
||||
|
||||
def "SEC-2515: @Bean still works when configure(AuthenticationManagerBuilder) used"() {
|
||||
when:
|
||||
|
||||
-40
@@ -15,8 +15,6 @@
|
||||
*/
|
||||
package org.springframework.security.config.annotation.web.configurers
|
||||
|
||||
import org.springframework.security.web.util.matcher.AntPathRequestMatcher
|
||||
|
||||
import javax.servlet.http.HttpServletResponse
|
||||
|
||||
import org.springframework.context.annotation.Configuration
|
||||
@@ -338,18 +336,6 @@ class CsrfConfigurerTests extends BaseSpringSpec {
|
||||
currentAuthentication != null
|
||||
}
|
||||
|
||||
def "SEC-2543: CSRF means logout requires POST"() {
|
||||
setup:
|
||||
loadConfig(LogoutConfig)
|
||||
login()
|
||||
request.servletPath = "/logout"
|
||||
request.method = "GET"
|
||||
when:
|
||||
springSecurityFilterChain.doFilter(request,response,chain)
|
||||
then: "logout with GET is not performed"
|
||||
currentAuthentication != null
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableWebSecurity
|
||||
static class LogoutConfig extends WebSecurityConfigurerAdapter {
|
||||
@@ -362,32 +348,6 @@ class CsrfConfigurerTests extends BaseSpringSpec {
|
||||
}
|
||||
}
|
||||
|
||||
def "CSRF can explicitly enable GET for logout"() {
|
||||
setup:
|
||||
loadConfig(LogoutAllowsGetConfig)
|
||||
login()
|
||||
request.servletPath = "/logout"
|
||||
request.method = "GET"
|
||||
when:
|
||||
springSecurityFilterChain.doFilter(request,response,chain)
|
||||
then: "logout with GET is not performed"
|
||||
currentAuthentication == null
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableWebSecurity
|
||||
static class LogoutAllowsGetConfig extends WebSecurityConfigurerAdapter {
|
||||
static AccessDeniedHandler deniedHandler
|
||||
|
||||
@Override
|
||||
protected void configure(HttpSecurity http) throws Exception {
|
||||
http
|
||||
.formLogin().and()
|
||||
.logout()
|
||||
.logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
|
||||
}
|
||||
}
|
||||
|
||||
def "csrf disables POST requests from RequestCache"() {
|
||||
setup:
|
||||
CsrfDisablesPostRequestFromRequestCacheConfig.repo = Mock(CsrfTokenRepository)
|
||||
|
||||
-20
@@ -172,26 +172,6 @@ class HttpHeadersConfigTests extends AbstractHttpConfigTests {
|
||||
assertHeaders(response, ['X-Frame-Options':'ALLOW-FROM https://example.com'])
|
||||
}
|
||||
|
||||
def 'http headers frame-options ALLOW-FROM with whitelist strategy'() {
|
||||
when:
|
||||
httpAutoConfig {
|
||||
'headers'() {
|
||||
'frame-options'(policy : 'ALLOW-FROM', strategy: 'whitelist', value : 'https://example.com')
|
||||
}
|
||||
}
|
||||
createAppContext()
|
||||
|
||||
def hf = getFilter(HeaderWriterFilter)
|
||||
MockHttpServletResponse response = new MockHttpServletResponse()
|
||||
|
||||
def request = new MockHttpServletRequest()
|
||||
request.setParameter("from", "https://example.com");
|
||||
hf.doFilter(request, response, new MockFilterChain())
|
||||
|
||||
then:
|
||||
assertHeaders(response, ['X-Frame-Options':'ALLOW-FROM https://example.com'])
|
||||
}
|
||||
|
||||
def 'http headers header a=b'() {
|
||||
when:
|
||||
httpAutoConfig {
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.security.config;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.web.AuthenticationEntryPoint;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration("classpath:org/springframework/security/config/sec-2508.xml" )
|
||||
public class Sec2508Tests {
|
||||
|
||||
@Autowired
|
||||
private AuthenticationEntryPoint ep;
|
||||
|
||||
@Test
|
||||
public void loads() {}
|
||||
}
|
||||
-231
@@ -1,231 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package org.springframework.security.config.annotation.web.messaging;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.runners.MockitoJUnitRunner;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.simp.SimpMessageHeaderAccessor;
|
||||
import org.springframework.messaging.support.MessageBuilder;
|
||||
import org.springframework.security.access.ConfigAttribute;
|
||||
import org.springframework.security.messaging.access.intercept.MessageSecurityMetadataSource;
|
||||
import org.springframework.security.messaging.util.matcher.MessageMatcher;
|
||||
import org.springframework.util.AntPathMatcher;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import static org.fest.assertions.Assertions.assertThat;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class MessageSecurityMetadataSourceRegistryTests {
|
||||
@Mock
|
||||
private MessageMatcher<Object> matcher;
|
||||
|
||||
private MessageSecurityMetadataSourceRegistry messages;
|
||||
|
||||
private Message<String> message;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
messages = new MessageSecurityMetadataSourceRegistry();
|
||||
message = MessageBuilder
|
||||
.withPayload("Hi")
|
||||
.setHeader(SimpMessageHeaderAccessor.DESTINATION_HEADER, "location")
|
||||
.build();
|
||||
}
|
||||
|
||||
// See https://github.com/spring-projects/spring-security/commit/3f30529039c76facf335d6ca69d18d8ae287f3f9#commitcomment-7412712
|
||||
// https://jira.spring.io/browse/SPR-11660
|
||||
@Test
|
||||
public void destinationMatcherCustom() {
|
||||
message = MessageBuilder
|
||||
.withPayload("Hi")
|
||||
.setHeader(SimpMessageHeaderAccessor.DESTINATION_HEADER, "price.stock.1.2")
|
||||
.build();
|
||||
messages
|
||||
.pathMatcher(new AntPathMatcher("."))
|
||||
.destinationMatchers("price.stock.*").permitAll();
|
||||
|
||||
assertThat(getAttribute()).isNull();
|
||||
|
||||
message = MessageBuilder
|
||||
.withPayload("Hi")
|
||||
.setHeader(SimpMessageHeaderAccessor.DESTINATION_HEADER, "price.stock.1.2")
|
||||
.build();
|
||||
messages
|
||||
.pathMatcher(new AntPathMatcher("."))
|
||||
.destinationMatchers("price.stock.**").permitAll();
|
||||
|
||||
assertThat(getAttribute()).isEqualTo("permitAll");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void destinationMatcherCustomSetAfterMatchersDoesNotMatter() {
|
||||
message = MessageBuilder
|
||||
.withPayload("Hi")
|
||||
.setHeader(SimpMessageHeaderAccessor.DESTINATION_HEADER, "price.stock.1.2")
|
||||
.build();
|
||||
messages
|
||||
.destinationMatchers("price.stock.*").permitAll()
|
||||
.pathMatcher(new AntPathMatcher("."));
|
||||
|
||||
assertThat(getAttribute()).isNull();
|
||||
|
||||
message = MessageBuilder
|
||||
.withPayload("Hi")
|
||||
.setHeader(SimpMessageHeaderAccessor.DESTINATION_HEADER, "price.stock.1.2")
|
||||
.build();
|
||||
messages
|
||||
.destinationMatchers("price.stock.**").permitAll()
|
||||
.pathMatcher(new AntPathMatcher("."));
|
||||
|
||||
assertThat(getAttribute()).isEqualTo("permitAll");
|
||||
}
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void pathMatcherNull() {
|
||||
messages.pathMatcher(null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void matchersFalse() {
|
||||
messages
|
||||
.matchers(matcher).permitAll();
|
||||
|
||||
assertThat(getAttribute()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void matchersTrue() {
|
||||
when(matcher.matches(message)).thenReturn(true);
|
||||
messages
|
||||
.matchers(matcher).permitAll();
|
||||
|
||||
assertThat(getAttribute()).isEqualTo("permitAll");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void destinationMatcherExact() {
|
||||
messages
|
||||
.destinationMatchers("location").permitAll();
|
||||
|
||||
assertThat(getAttribute()).isEqualTo("permitAll");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void destinationMatcherMulti() {
|
||||
messages
|
||||
.destinationMatchers("admin/**","api/**").hasRole("ADMIN")
|
||||
.destinationMatchers("location").permitAll();
|
||||
|
||||
assertThat(getAttribute()).isEqualTo("permitAll");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void destinationMatcherRole() {
|
||||
messages
|
||||
.destinationMatchers("admin/**","location/**").hasRole("ADMIN")
|
||||
.anyMessage().denyAll();
|
||||
|
||||
assertThat(getAttribute()).isEqualTo("hasRole('ROLE_ADMIN')");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void destinationMatcherAnyRole() {
|
||||
messages
|
||||
.destinationMatchers("admin/**","location/**").hasAnyRole("ADMIN", "ROOT")
|
||||
.anyMessage().denyAll();
|
||||
|
||||
assertThat(getAttribute()).isEqualTo("hasAnyRole('ROLE_ADMIN','ROLE_ROOT')");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void destinationMatcherAuthority() {
|
||||
messages
|
||||
.destinationMatchers("admin/**","location/**").hasAuthority("ROLE_ADMIN")
|
||||
.anyMessage().fullyAuthenticated();
|
||||
|
||||
assertThat(getAttribute()).isEqualTo("hasAuthority('ROLE_ADMIN')");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void destinationMatcherAccess() {
|
||||
String expected = "hasRole('ROLE_ADMIN') and fullyAuthenticated";
|
||||
messages
|
||||
.destinationMatchers("admin/**","location/**").access(expected)
|
||||
.anyMessage().denyAll();
|
||||
|
||||
assertThat(getAttribute()).isEqualTo(expected);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void destinationMatcherAnyAuthority() {
|
||||
messages
|
||||
.destinationMatchers("admin/**","location/**").hasAnyAuthority("ROLE_ADMIN", "ROLE_ROOT")
|
||||
.anyMessage().denyAll();
|
||||
|
||||
assertThat(getAttribute()).isEqualTo("hasAnyAuthority('ROLE_ADMIN','ROLE_ROOT')");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void destinationMatcherRememberMe() {
|
||||
messages
|
||||
.destinationMatchers("admin/**","location/**").rememberMe()
|
||||
.anyMessage().denyAll();
|
||||
|
||||
assertThat(getAttribute()).isEqualTo("rememberMe");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void destinationMatcherAnonymous() {
|
||||
messages
|
||||
.destinationMatchers("admin/**","location/**").anonymous()
|
||||
.anyMessage().denyAll();
|
||||
|
||||
assertThat(getAttribute()).isEqualTo("anonymous");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void destinationMatcherFullyAuthenticated() {
|
||||
messages
|
||||
.destinationMatchers("admin/**","location/**").fullyAuthenticated()
|
||||
.anyMessage().denyAll();
|
||||
|
||||
assertThat(getAttribute()).isEqualTo("fullyAuthenticated");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void destinationMatcherDenyAll() {
|
||||
messages
|
||||
.destinationMatchers("admin/**","location/**").denyAll()
|
||||
.anyMessage().permitAll();
|
||||
|
||||
assertThat(getAttribute()).isEqualTo("denyAll");
|
||||
}
|
||||
|
||||
private String getAttribute() {
|
||||
MessageSecurityMetadataSource source = messages.createMetadataSource();
|
||||
Collection<ConfigAttribute> attrs = source.getAttributes(message);
|
||||
if(attrs == null) {
|
||||
return null;
|
||||
}
|
||||
assertThat(attrs.size()).isEqualTo(1);
|
||||
return attrs.iterator().next().toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
|
||||
|
||||
<bean class="org.springframework.security.web.authentication.DelegatingAuthenticationEntryPoint">
|
||||
<constructor-arg>
|
||||
<map>
|
||||
<entry>
|
||||
<key>
|
||||
<bean class="org.springframework.security.web.util.AntPathRequestMatcher">
|
||||
<constructor-arg value="/**"/>
|
||||
</bean>
|
||||
</key>
|
||||
<bean class="org.springframework.security.web.authentication.Http403ForbiddenEntryPoint"/>
|
||||
</entry>
|
||||
</map>
|
||||
</constructor-arg>
|
||||
<property name="defaultEntryPoint">
|
||||
<bean class="org.springframework.security.web.authentication.Http403ForbiddenEntryPoint"/>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
</beans>
|
||||
@@ -0,0 +1,46 @@
|
||||
Implementation-Title: org.springframework.security.config
|
||||
Implementation-Version: ${version}
|
||||
Bundle-SymbolicName: org.springframework.security.config
|
||||
Bundle-Name: Spring Security Namespace Configuration
|
||||
Bundle-Vendor: SpringSource
|
||||
Bundle-Version: ${version}
|
||||
Bundle-ManifestVersion: 2
|
||||
Ignored-Existing-Headers:
|
||||
Import-Package,
|
||||
Export-Package
|
||||
Import-Template:
|
||||
org.aopalliance.*;version="${aopAllianceRange}",
|
||||
org.apache.commons.logging.*;version="${cloggingRange}",
|
||||
org.aopalliance.*;version="${aopAllianceRange}";resolution:=optional,
|
||||
org.aspectj.*;version="${aspectjRange}";resolution:=optional,
|
||||
org.openid4java.*;version="${openid4javaRange}";resolution:=optional,
|
||||
org.springframework.security.access.*;version="${secRange}",
|
||||
org.springframework.security.authentication.*;version="${secRange}",
|
||||
org.springframework.security.core.*;version="${secRange}",
|
||||
org.springframework.security.crypto.bcrypt.*;version="${secRange}",
|
||||
org.springframework.security.crypto.password.*;version="${secRange}",
|
||||
org.springframework.security.crypto.*;version="${secRange}",
|
||||
org.springframework.security.util;version="${secRange}",
|
||||
org.springframework.security.provisioning;version="${secRange}",
|
||||
org.springframework.security.ldap.*;version="${secRange}",
|
||||
org.springframework.security.openid.*;version="${secRange}";resolution:=optional,
|
||||
org.springframework.security.web.*;version="${secRange}";resolution:=optional,
|
||||
org.springframework.security.ldap.*;version="${secRange}";resolution:=optional,
|
||||
org.springframework.security.openid.*;version="${secRange}";resolution:=optional,
|
||||
org.springframework.ldap.*;version="${springLdapRange}";resolution:=optional,
|
||||
org.springframework.aop.*;version="${springRange}";resolution:=optional,
|
||||
org.springframework.jdbc.*;version="${springRange}";resolution:=optional,
|
||||
org.springframework.http.*;version="${springRange}";resolution:=optional,
|
||||
org.springframework.beans.*;version="${springRange}",
|
||||
org.springframework.context.*;version="${springRange}",
|
||||
org.springframework.core.*;version="${springRange}",
|
||||
org.springframework.http.*;version="${springRange}",
|
||||
org.springframework.ldap.*;version="${springLdapRange}",
|
||||
org.springframework.jdbc.*;version="${springRange}",
|
||||
org.springframework.web.*;version="${springRange}",
|
||||
org.springframework.util.*;version="${springRange}",
|
||||
javax.servlet.*;version="0";resolution:=optional,
|
||||
org.openid4java.*;version="${openid4javaRange}",
|
||||
javax.sql.*;version="0";resolution:=optional,
|
||||
javax.naming.directory;version="0";resolution:=optional,
|
||||
org.w3c.dom;version="0";resolution:=optional
|
||||
+4
-5
@@ -8,8 +8,6 @@ configurations {
|
||||
included
|
||||
|
||||
compile.extendsFrom included
|
||||
|
||||
testCompile.exclude group: 'org.mockito', module: 'mockito-all'
|
||||
}
|
||||
|
||||
dependencies {
|
||||
@@ -19,7 +17,7 @@ dependencies {
|
||||
"org.springframework:spring-context:$springVersion",
|
||||
"org.springframework:spring-expression:$springVersion"
|
||||
|
||||
optional "net.sf.ehcache:ehcache-core:$ehcacheVersion",
|
||||
optional "net.sf.ehcache:ehcache:$ehcacheVersion",
|
||||
'javax.annotation:jsr250-api:1.0',
|
||||
"org.aspectj:aspectjrt:$aspectjVersion",
|
||||
"org.springframework:spring-jdbc:$springVersion",
|
||||
@@ -32,7 +30,8 @@ dependencies {
|
||||
"org.slf4j:jcl-over-slf4j:$slf4jVersion",
|
||||
powerMockDependencies
|
||||
|
||||
testRuntime "org.hsqldb:hsqldb:$hsqlVersion"
|
||||
testRuntime "org.hsqldb:hsqldb:$hsqlVersion",
|
||||
"cglib:cglib-nodep:$cglibVersion"
|
||||
}
|
||||
|
||||
classes.doLast {
|
||||
@@ -44,7 +43,7 @@ classes.doLast {
|
||||
|
||||
sourceJar.from cryptoProject.sourceSets.main.java
|
||||
|
||||
configure(project.tasks.withType(Test)) {
|
||||
configure([test,spring4Test]) {
|
||||
systemProperties['springSecurityVersion'] = version
|
||||
systemProperties['springVersion'] = springVersion
|
||||
}
|
||||
+18
-90
@@ -4,7 +4,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-core</artifactId>
|
||||
<version>4.0.0.M2</version>
|
||||
<version>3.2.3.RELEASE</version>
|
||||
<name>spring-security-core</name>
|
||||
<description>spring-security-core</description>
|
||||
<url>http://spring.io/spring-security</url>
|
||||
@@ -42,12 +42,6 @@
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>spring-milestone</id>
|
||||
<url>https://repo.spring.io/milestone</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>aopalliance</groupId>
|
||||
@@ -58,25 +52,25 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-aop</artifactId>
|
||||
<version>4.1.0.RC2</version>
|
||||
<version>3.2.8.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-beans</artifactId>
|
||||
<version>4.1.0.RC2</version>
|
||||
<version>3.2.8.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-context</artifactId>
|
||||
<version>4.1.0.RC2</version>
|
||||
<version>3.2.8.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-core</artifactId>
|
||||
<version>4.1.0.RC2</version>
|
||||
<version>3.2.8.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
@@ -88,7 +82,7 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-expression</artifactId>
|
||||
<version>4.1.0.RC2</version>
|
||||
<version>3.2.8.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@@ -107,8 +101,8 @@
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.sf.ehcache</groupId>
|
||||
<artifactId>ehcache-core</artifactId>
|
||||
<version>2.6.5</version>
|
||||
<artifactId>ehcache</artifactId>
|
||||
<version>1.6.2</version>
|
||||
<scope>compile</scope>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
@@ -122,17 +116,23 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-jdbc</artifactId>
|
||||
<version>4.1.0.RC2</version>
|
||||
<version>3.2.8.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-tx</artifactId>
|
||||
<version>4.1.0.RC2</version>
|
||||
<version>3.2.8.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>cglib</groupId>
|
||||
<artifactId>cglib-nodep</artifactId>
|
||||
<version>2.2</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ch.qos.logback</groupId>
|
||||
<artifactId>logback-classic</artifactId>
|
||||
@@ -144,36 +144,18 @@
|
||||
<artifactId>commons-collections</artifactId>
|
||||
<version>3.2</version>
|
||||
<scope>test</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>mockito-all</artifactId>
|
||||
<groupId>org.mockito</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.11</version>
|
||||
<version>4.10</version>
|
||||
<scope>test</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>mockito-all</artifactId>
|
||||
<groupId>org.mockito</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.easytesting</groupId>
|
||||
<artifactId>fest-assert</artifactId>
|
||||
<version>1.4</version>
|
||||
<scope>test</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>mockito-all</artifactId>
|
||||
<groupId>org.mockito</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.hsqldb</groupId>
|
||||
@@ -186,108 +168,54 @@
|
||||
<artifactId>mockito-core</artifactId>
|
||||
<version>1.9.5</version>
|
||||
<scope>test</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>mockito-all</artifactId>
|
||||
<groupId>org.mockito</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.powermock</groupId>
|
||||
<artifactId>powermock-api-mockito</artifactId>
|
||||
<version>1.5.1</version>
|
||||
<scope>test</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>mockito-all</artifactId>
|
||||
<groupId>org.mockito</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.powermock</groupId>
|
||||
<artifactId>powermock-api-support</artifactId>
|
||||
<version>1.5.1</version>
|
||||
<scope>test</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>mockito-all</artifactId>
|
||||
<groupId>org.mockito</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.powermock</groupId>
|
||||
<artifactId>powermock-core</artifactId>
|
||||
<version>1.5.1</version>
|
||||
<scope>test</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>mockito-all</artifactId>
|
||||
<groupId>org.mockito</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.powermock</groupId>
|
||||
<artifactId>powermock-module-junit4</artifactId>
|
||||
<version>1.5.1</version>
|
||||
<scope>test</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>mockito-all</artifactId>
|
||||
<groupId>org.mockito</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.powermock</groupId>
|
||||
<artifactId>powermock-module-junit4-common</artifactId>
|
||||
<version>1.5.1</version>
|
||||
<scope>test</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>mockito-all</artifactId>
|
||||
<groupId>org.mockito</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.powermock</groupId>
|
||||
<artifactId>powermock-reflect</artifactId>
|
||||
<version>1.5.1</version>
|
||||
<scope>test</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>mockito-all</artifactId>
|
||||
<groupId>org.mockito</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>jcl-over-slf4j</artifactId>
|
||||
<version>1.7.5</version>
|
||||
<scope>test</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>mockito-all</artifactId>
|
||||
<groupId>org.mockito</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-test</artifactId>
|
||||
<version>4.1.0.RC2</version>
|
||||
<version>3.2.8.RELEASE</version>
|
||||
<scope>test</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>mockito-all</artifactId>
|
||||
<groupId>org.mockito</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
||||
+1
-11
@@ -38,9 +38,7 @@ import org.springframework.security.access.event.AuthorizedEvent;
|
||||
import org.springframework.security.access.event.PublicInvocationEvent;
|
||||
import org.springframework.security.authentication.AuthenticationCredentialsNotFoundException;
|
||||
import org.springframework.security.authentication.AuthenticationManager;
|
||||
import org.springframework.security.authentication.AuthenticationServiceException;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.AuthenticationException;
|
||||
import org.springframework.security.core.SpringSecurityMessageSource;
|
||||
import org.springframework.security.core.context.SecurityContext;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
@@ -107,7 +105,7 @@ public abstract class AbstractSecurityInterceptor implements InitializingBean, A
|
||||
private ApplicationEventPublisher eventPublisher;
|
||||
private AccessDecisionManager accessDecisionManager;
|
||||
private AfterInvocationManager afterInvocationManager;
|
||||
private AuthenticationManager authenticationManager = new NoOpAuthenticationManager();
|
||||
private AuthenticationManager authenticationManager;
|
||||
private RunAsManager runAsManager = new NullRunAsManager();
|
||||
|
||||
private boolean alwaysReauthenticate = false;
|
||||
@@ -462,12 +460,4 @@ public abstract class AbstractSecurityInterceptor implements InitializingBean, A
|
||||
this.eventPublisher.publishEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
private static class NoOpAuthenticationManager implements AuthenticationManager {
|
||||
|
||||
@Override
|
||||
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
|
||||
throw new AuthenticationServiceException("Cannot authenticate " + authentication);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
-3
@@ -18,7 +18,6 @@ package org.springframework.security.authentication.dao;
|
||||
import org.springframework.security.authentication.AuthenticationProvider;
|
||||
import org.springframework.security.authentication.AuthenticationServiceException;
|
||||
import org.springframework.security.authentication.BadCredentialsException;
|
||||
import org.springframework.security.authentication.InternalAuthenticationServiceException;
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||
import org.springframework.security.authentication.encoding.PasswordEncoder;
|
||||
import org.springframework.security.authentication.encoding.PlaintextPasswordEncoder;
|
||||
@@ -107,11 +106,11 @@ public class DaoAuthenticationProvider extends AbstractUserDetailsAuthentication
|
||||
}
|
||||
throw notFound;
|
||||
} catch (Exception repositoryProblem) {
|
||||
throw new InternalAuthenticationServiceException(repositoryProblem.getMessage(), repositoryProblem);
|
||||
throw new AuthenticationServiceException(repositoryProblem.getMessage(), repositoryProblem);
|
||||
}
|
||||
|
||||
if (loadedUser == null) {
|
||||
throw new InternalAuthenticationServiceException(
|
||||
throw new AuthenticationServiceException(
|
||||
"UserDetailsService returned null, which is an interface contract violation");
|
||||
}
|
||||
return loadedUser;
|
||||
|
||||
-10
@@ -52,14 +52,4 @@ public class SystemWideSaltSource implements SaltSource, InitializingBean {
|
||||
public void setSystemWideSalt(String systemWideSalt) {
|
||||
this.systemWideSalt = systemWideSalt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays the system wide salt
|
||||
* @since 4.0
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return systemWideSalt;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,469 +0,0 @@
|
||||
package org.springframework.security.core;
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
import java.util.Locale;
|
||||
import java.util.Properties;
|
||||
import java.util.Stack;
|
||||
|
||||
/**
|
||||
* Generic implementation of version comparison.
|
||||
*
|
||||
* NOTE: This is a copy from https://svn.apache.org/repos/asf/maven/maven-3/tags/maven-3.1.0/maven-artifact/src/main/java/org/apache/maven/artifact/versioning/ComparableVersion.java
|
||||
*
|
||||
* <p>Features:
|
||||
* <ul>
|
||||
* <li>mixing of '<code>-</code>' (dash) and '<code>.</code>' (dot) separators,</li>
|
||||
* <li>transition between characters and digits also constitutes a separator:
|
||||
* <code>1.0alpha1 => [1, 0, alpha, 1]</code></li>
|
||||
* <li>unlimited number of version components,</li>
|
||||
* <li>version components in the text can be digits or strings,</li>
|
||||
* <li>strings are checked for well-known qualifiers and the qualifier ordering is used for version ordering.
|
||||
* Well-known qualifiers (case insensitive) are:<ul>
|
||||
* <li><code>alpha</code> or <code>a</code></li>
|
||||
* <li><code>beta</code> or <code>b</code></li>
|
||||
* <li><code>milestone</code> or <code>m</code></li>
|
||||
* <li><code>rc</code> or <code>cr</code></li>
|
||||
* <li><code>snapshot</code></li>
|
||||
* <li><code>(the empty string)</code> or <code>ga</code> or <code>final</code></li>
|
||||
* <li><code>sp</code></li>
|
||||
* </ul>
|
||||
* Unknown qualifiers are considered after known qualifiers, with lexical order (always case insensitive),
|
||||
* </li>
|
||||
* <li>a dash usually precedes a qualifier, and is always less important than something preceded with a dot.</li>
|
||||
* </ul></p>
|
||||
*
|
||||
* @see <a href="https://cwiki.apache.org/confluence/display/MAVENOLD/Versioning">"Versioning" on Maven Wiki</a>
|
||||
* @author <a href="mailto:kenney@apache.org">Kenney Westerhof</a>
|
||||
* @author <a href="mailto:hboutemy@apache.org">Hervé Boutemy</a>
|
||||
*/
|
||||
class ComparableVersion
|
||||
implements Comparable<ComparableVersion>
|
||||
{
|
||||
private String value;
|
||||
|
||||
private String canonical;
|
||||
|
||||
private ListItem items;
|
||||
|
||||
private interface Item
|
||||
{
|
||||
final int INTEGER_ITEM = 0;
|
||||
final int STRING_ITEM = 1;
|
||||
final int LIST_ITEM = 2;
|
||||
|
||||
int compareTo( Item item );
|
||||
|
||||
int getType();
|
||||
|
||||
boolean isNull();
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a numeric item in the version item list.
|
||||
*/
|
||||
private static class IntegerItem
|
||||
implements Item
|
||||
{
|
||||
private static final BigInteger BigInteger_ZERO = new BigInteger( "0" );
|
||||
|
||||
private final BigInteger value;
|
||||
|
||||
public static final IntegerItem ZERO = new IntegerItem();
|
||||
|
||||
private IntegerItem()
|
||||
{
|
||||
this.value = BigInteger_ZERO;
|
||||
}
|
||||
|
||||
public IntegerItem( String str )
|
||||
{
|
||||
this.value = new BigInteger( str );
|
||||
}
|
||||
|
||||
public int getType()
|
||||
{
|
||||
return INTEGER_ITEM;
|
||||
}
|
||||
|
||||
public boolean isNull()
|
||||
{
|
||||
return BigInteger_ZERO.equals( value );
|
||||
}
|
||||
|
||||
public int compareTo( Item item )
|
||||
{
|
||||
if ( item == null )
|
||||
{
|
||||
return BigInteger_ZERO.equals( value ) ? 0 : 1; // 1.0 == 1, 1.1 > 1
|
||||
}
|
||||
|
||||
switch ( item.getType() )
|
||||
{
|
||||
case INTEGER_ITEM:
|
||||
return value.compareTo( ( (IntegerItem) item ).value );
|
||||
|
||||
case STRING_ITEM:
|
||||
return 1; // 1.1 > 1-sp
|
||||
|
||||
case LIST_ITEM:
|
||||
return 1; // 1.1 > 1-1
|
||||
|
||||
default:
|
||||
throw new RuntimeException( "invalid item: " + item.getClass() );
|
||||
}
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return value.toString();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a string in the version item list, usually a qualifier.
|
||||
*/
|
||||
private static class StringItem
|
||||
implements Item
|
||||
{
|
||||
private static final String[] QUALIFIERS = { "alpha", "beta", "milestone", "rc", "snapshot", "", "sp" };
|
||||
|
||||
private static final List<String> _QUALIFIERS = Arrays.asList( QUALIFIERS );
|
||||
|
||||
private static final Properties ALIASES = new Properties();
|
||||
static
|
||||
{
|
||||
ALIASES.put( "ga", "" );
|
||||
ALIASES.put( "final", "" );
|
||||
ALIASES.put( "cr", "rc" );
|
||||
}
|
||||
|
||||
/**
|
||||
* A comparable value for the empty-string qualifier. This one is used to determine if a given qualifier makes
|
||||
* the version older than one without a qualifier, or more recent.
|
||||
*/
|
||||
private static final String RELEASE_VERSION_INDEX = String.valueOf( _QUALIFIERS.indexOf( "" ) );
|
||||
|
||||
private String value;
|
||||
|
||||
public StringItem( String value, boolean followedByDigit )
|
||||
{
|
||||
if ( followedByDigit && value.length() == 1 )
|
||||
{
|
||||
// a1 = alpha-1, b1 = beta-1, m1 = milestone-1
|
||||
switch ( value.charAt( 0 ) )
|
||||
{
|
||||
case 'a':
|
||||
value = "alpha";
|
||||
break;
|
||||
case 'b':
|
||||
value = "beta";
|
||||
break;
|
||||
case 'm':
|
||||
value = "milestone";
|
||||
break;
|
||||
}
|
||||
}
|
||||
this.value = ALIASES.getProperty( value , value );
|
||||
}
|
||||
|
||||
public int getType()
|
||||
{
|
||||
return STRING_ITEM;
|
||||
}
|
||||
|
||||
public boolean isNull()
|
||||
{
|
||||
return ( comparableQualifier( value ).compareTo( RELEASE_VERSION_INDEX ) == 0 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a comparable value for a qualifier.
|
||||
*
|
||||
* This method takes into account the ordering of known qualifiers then unknown qualifiers with lexical ordering.
|
||||
*
|
||||
* just returning an Integer with the index here is faster, but requires a lot of if/then/else to check for -1
|
||||
* or QUALIFIERS.size and then resort to lexical ordering. Most comparisons are decided by the first character,
|
||||
* so this is still fast. If more characters are needed then it requires a lexical sort anyway.
|
||||
*
|
||||
* @param qualifier
|
||||
* @return an equivalent value that can be used with lexical comparison
|
||||
*/
|
||||
public static String comparableQualifier( String qualifier )
|
||||
{
|
||||
int i = _QUALIFIERS.indexOf( qualifier );
|
||||
|
||||
return i == -1 ? ( _QUALIFIERS.size() + "-" + qualifier ) : String.valueOf( i );
|
||||
}
|
||||
|
||||
public int compareTo( Item item )
|
||||
{
|
||||
if ( item == null )
|
||||
{
|
||||
// 1-rc < 1, 1-ga > 1
|
||||
return comparableQualifier( value ).compareTo( RELEASE_VERSION_INDEX );
|
||||
}
|
||||
switch ( item.getType() )
|
||||
{
|
||||
case INTEGER_ITEM:
|
||||
return -1; // 1.any < 1.1 ?
|
||||
|
||||
case STRING_ITEM:
|
||||
return comparableQualifier( value ).compareTo( comparableQualifier( ( (StringItem) item ).value ) );
|
||||
|
||||
case LIST_ITEM:
|
||||
return -1; // 1.any < 1-1
|
||||
|
||||
default:
|
||||
throw new RuntimeException( "invalid item: " + item.getClass() );
|
||||
}
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a version list item. This class is used both for the global item list and for sub-lists (which start
|
||||
* with '-(number)' in the version specification).
|
||||
*/
|
||||
private static class ListItem
|
||||
extends ArrayList<Item>
|
||||
implements Item
|
||||
{
|
||||
public int getType()
|
||||
{
|
||||
return LIST_ITEM;
|
||||
}
|
||||
|
||||
public boolean isNull()
|
||||
{
|
||||
return ( size() == 0 );
|
||||
}
|
||||
|
||||
void normalize()
|
||||
{
|
||||
for( ListIterator<Item> iterator = listIterator( size() ); iterator.hasPrevious(); )
|
||||
{
|
||||
Item item = iterator.previous();
|
||||
if ( item.isNull() )
|
||||
{
|
||||
iterator.remove(); // remove null trailing items: 0, "", empty list
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int compareTo( Item item )
|
||||
{
|
||||
if ( item == null )
|
||||
{
|
||||
if ( size() == 0 )
|
||||
{
|
||||
return 0; // 1-0 = 1- (normalize) = 1
|
||||
}
|
||||
Item first = get( 0 );
|
||||
return first.compareTo( null );
|
||||
}
|
||||
switch ( item.getType() )
|
||||
{
|
||||
case INTEGER_ITEM:
|
||||
return -1; // 1-1 < 1.0.x
|
||||
|
||||
case STRING_ITEM:
|
||||
return 1; // 1-1 > 1-sp
|
||||
|
||||
case LIST_ITEM:
|
||||
Iterator<Item> left = iterator();
|
||||
Iterator<Item> right = ( (ListItem) item ).iterator();
|
||||
|
||||
while ( left.hasNext() || right.hasNext() )
|
||||
{
|
||||
Item l = left.hasNext() ? left.next() : null;
|
||||
Item r = right.hasNext() ? right.next() : null;
|
||||
|
||||
// if this is shorter, then invert the compare and mul with -1
|
||||
int result = l == null ? -1 * r.compareTo( l ) : l.compareTo( r );
|
||||
|
||||
if ( result != 0 )
|
||||
{
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
default:
|
||||
throw new RuntimeException( "invalid item: " + item.getClass() );
|
||||
}
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
StringBuilder buffer = new StringBuilder( "(" );
|
||||
for( Iterator<Item> iter = iterator(); iter.hasNext(); )
|
||||
{
|
||||
buffer.append( iter.next() );
|
||||
if ( iter.hasNext() )
|
||||
{
|
||||
buffer.append( ',' );
|
||||
}
|
||||
}
|
||||
buffer.append( ')' );
|
||||
return buffer.toString();
|
||||
}
|
||||
}
|
||||
|
||||
public ComparableVersion( String version )
|
||||
{
|
||||
parseVersion( version );
|
||||
}
|
||||
|
||||
public final void parseVersion( String version )
|
||||
{
|
||||
this.value = version;
|
||||
|
||||
items = new ListItem();
|
||||
|
||||
version = version.toLowerCase( Locale.ENGLISH );
|
||||
|
||||
ListItem list = items;
|
||||
|
||||
Stack<Item> stack = new Stack<Item>();
|
||||
stack.push( list );
|
||||
|
||||
boolean isDigit = false;
|
||||
|
||||
int startIndex = 0;
|
||||
|
||||
for ( int i = 0; i < version.length(); i++ )
|
||||
{
|
||||
char c = version.charAt( i );
|
||||
|
||||
if ( c == '.' )
|
||||
{
|
||||
if ( i == startIndex )
|
||||
{
|
||||
list.add( IntegerItem.ZERO );
|
||||
}
|
||||
else
|
||||
{
|
||||
list.add( parseItem( isDigit, version.substring( startIndex, i ) ) );
|
||||
}
|
||||
startIndex = i + 1;
|
||||
}
|
||||
else if ( c == '-' )
|
||||
{
|
||||
if ( i == startIndex )
|
||||
{
|
||||
list.add( IntegerItem.ZERO );
|
||||
}
|
||||
else
|
||||
{
|
||||
list.add( parseItem( isDigit, version.substring( startIndex, i ) ) );
|
||||
}
|
||||
startIndex = i + 1;
|
||||
|
||||
if ( isDigit )
|
||||
{
|
||||
list.normalize(); // 1.0-* = 1-*
|
||||
|
||||
if ( ( i + 1 < version.length() ) && Character.isDigit( version.charAt( i + 1 ) ) )
|
||||
{
|
||||
// new ListItem only if previous were digits and new char is a digit,
|
||||
// ie need to differentiate only 1.1 from 1-1
|
||||
list.add( list = new ListItem() );
|
||||
|
||||
stack.push( list );
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( Character.isDigit( c ) )
|
||||
{
|
||||
if ( !isDigit && i > startIndex )
|
||||
{
|
||||
list.add( new StringItem( version.substring( startIndex, i ), true ) );
|
||||
startIndex = i;
|
||||
}
|
||||
|
||||
isDigit = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( isDigit && i > startIndex )
|
||||
{
|
||||
list.add( parseItem( true, version.substring( startIndex, i ) ) );
|
||||
startIndex = i;
|
||||
}
|
||||
|
||||
isDigit = false;
|
||||
}
|
||||
}
|
||||
|
||||
if ( version.length() > startIndex )
|
||||
{
|
||||
list.add( parseItem( isDigit, version.substring( startIndex ) ) );
|
||||
}
|
||||
|
||||
while ( !stack.isEmpty() )
|
||||
{
|
||||
list = (ListItem) stack.pop();
|
||||
list.normalize();
|
||||
}
|
||||
|
||||
canonical = items.toString();
|
||||
}
|
||||
|
||||
private static Item parseItem( boolean isDigit, String buf )
|
||||
{
|
||||
return isDigit ? new IntegerItem( buf ) : new StringItem( buf, false );
|
||||
}
|
||||
|
||||
public int compareTo( ComparableVersion o )
|
||||
{
|
||||
return items.compareTo( o.items );
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
public boolean equals( Object o )
|
||||
{
|
||||
return ( o instanceof ComparableVersion ) && canonical.equals( ( (ComparableVersion) o ).canonical );
|
||||
}
|
||||
|
||||
public int hashCode()
|
||||
{
|
||||
return canonical.hashCode();
|
||||
}
|
||||
}
|
||||
+4
-13
@@ -21,9 +21,9 @@ public class SpringSecurityCoreVersion {
|
||||
* N.B. Classes are not intended to be serializable between different versions.
|
||||
* See SEC-1709 for why we still need a serial version.
|
||||
*/
|
||||
public static final long SERIAL_VERSION_UID = 400L;
|
||||
public static final long SERIAL_VERSION_UID = 320L;
|
||||
|
||||
static final String MIN_SPRING_VERSION = "4.1.0.RC2";
|
||||
static final String MIN_SPRING_VERSION = "3.2.8.RELEASE";
|
||||
|
||||
static {
|
||||
performVersionChecks();
|
||||
@@ -38,15 +38,6 @@ public class SpringSecurityCoreVersion {
|
||||
* Performs version checks
|
||||
*/
|
||||
private static void performVersionChecks() {
|
||||
performVersionChecks(MIN_SPRING_VERSION);
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform version checks with specific min Spring Version
|
||||
*
|
||||
* @param minSpringVersion
|
||||
*/
|
||||
private static void performVersionChecks(String minSpringVersion) {
|
||||
// Check Spring Compatibility
|
||||
String springVersion = SpringVersion.getVersion();
|
||||
String version = getVersion();
|
||||
@@ -56,8 +47,8 @@ public class SpringSecurityCoreVersion {
|
||||
}
|
||||
|
||||
logger.info("You are running with Spring Security Core " + version);
|
||||
if (new ComparableVersion(springVersion).compareTo(new ComparableVersion(minSpringVersion)) < 0) {
|
||||
logger.warn("**** You are advised to use Spring " + minSpringVersion +
|
||||
if (springVersion.compareTo(MIN_SPRING_VERSION) < 0) {
|
||||
logger.warn("**** You are advised to use Spring " + MIN_SPRING_VERSION +
|
||||
" or later with this version. You are running: " + springVersion);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,47 +1,47 @@
|
||||
AbstractAccessDecisionManager.accessDenied = \uc811\uadfc\uc774 \uac70\ubd80\ub418\uc5c8\uc2b5\ub2c8\ub2e4.
|
||||
AbstractLdapAuthenticationProvider.emptyPassword = \ube44\ubc00\ubc88\ud638\uac00 \ub9de\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4.
|
||||
AbstractSecurityInterceptor.authenticationNotFound = SecurityContext\uc5d0\uc11c Authentication \uac1d\uccb4\ub97c \ucc3e\uc744 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4.
|
||||
AbstractUserDetailsAuthenticationProvider.badCredentials = \uc790\uaca9 \uc99d\uba85\uc5d0 \uc2e4\ud328\ud558\uc600\uc2b5\ub2c8\ub2e4.
|
||||
AbstractUserDetailsAuthenticationProvider.credentialsExpired = \uc790\uaca9 \uc99d\uba85 \uc720\ud6a8 \uae30\uac04\uc774 \ub9cc\ub8cc\ub418\uc5c8\uc2b5\ub2c8\ub2e4.
|
||||
AbstractUserDetailsAuthenticationProvider.disabled = \uc720\ud6a8\ud558\uc9c0 \uc54a\uc740 \uc0ac\uc6a9\uc790\uc785\ub2c8\ub2e4.
|
||||
AbstractUserDetailsAuthenticationProvider.expired = \uc0ac\uc6a9\uc790 \uacc4\uc815\uc758 \uc720\ud6a8 \uae30\uac04\uc774 \ub9cc\ub8cc \ub418\uc5c8\uc2b5\ub2c8\ub2e4.
|
||||
AbstractUserDetailsAuthenticationProvider.locked = \uc0ac\uc6a9\uc790 \uacc4\uc815\uc774 \uc7a0\uaca8 \uc788\uc2b5\ub2c8\ub2e4.
|
||||
AbstractUserDetailsAuthenticationProvider.onlySupports = UsernamePasswordAuthenticationToken\ub9cc \uc9c0\uc6d0\ud569\ub2c8\ub2e4.
|
||||
AccountStatusUserDetailsChecker.credentialsExpired = \uc790\uaca9 \uc99d\uba85 \uc720\ud6a8 \uae30\uac04\uc774 \ub9cc\ub8cc\ub418\uc5c8\uc2b5\ub2c8\ub2e4.
|
||||
AccountStatusUserDetailsChecker.disabled = \uc720\ud6a8\ud558\uc9c0 \uc54a\uc740 \uc0ac\uc6a9\uc790\uc785\ub2c8\ub2e4.
|
||||
AccountStatusUserDetailsChecker.expired = \uc0ac\uc6a9\uc790 \uacc4\uc815\uc758 \uc720\ud6a8 \uae30\uac04\uc774 \ub9cc\ub8cc \ub418\uc5c8\uc2b5\ub2c8\ub2e4.
|
||||
AccountStatusUserDetailsChecker.locked = \uc0ac\uc6a9\uc790 \uacc4\uc815\uc774 \uc7a0\uaca8 \uc788\uc2b5\ub2c8\ub2e4.
|
||||
AclEntryAfterInvocationProvider.noPermission = domain object {1}\uc5d0 \ub300\ud55c \uad8c\ud55c\uc774 Authentication {0}\uc5d0 \uc5c6\uc2b5\ub2c8\ub2e4.
|
||||
AnonymousAuthenticationProvider.incorrectKey = \uc81c\uacf5\ub41c AnonymousAuthenticationToken\uc5d0\ub294 \ud544\uc694\ub85c\ud558\ub294 key\uac00 \uc5c6\uc2b5\ub2c8\ub2e4.
|
||||
BindAuthenticator.badCredentials = \uc790\uaca9 \uc99d\uba85\uc5d0 \uc2e4\ud328\ud558\uc600\uc2b5\ub2c8\ub2e4.
|
||||
BindAuthenticator.emptyPassword = \ube44\ubc00\ubc88\ud638 \ud56d\ubaa9\uc774 \ube44\uc5b4 \uc788\uc2b5\ub2c8\ub2e4.
|
||||
CasAuthenticationProvider.incorrectKey = \uc81c\uacf5\ub41c CasAuthenticationToken\uc5d0\ub294 \ud544\uc694\ub85c \ud558\ub294 key\uac00 \uc5c6\uc2b5\ub2c8\ub2e4.
|
||||
CasAuthenticationProvider.noServiceTicket = \uac80\uc99d\uc744 \uc704\ud55c CAS \uc11c\ube44\uc2a4 \ud2f0\ucf13\uc744 \uc81c\uacf5\ud560 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4.
|
||||
ConcurrentSessionControlStrategy.exceededAllowed = \ucd5c\ub300 \uc138\uc158 \ud5c8\uc6a9 \uc218 {0}\uac1c\ub97c \ucd08\uacfc\ud558\uc600\uc2b5\ub2c8\ub2e4.
|
||||
DigestAuthenticationFilter.incorrectRealm = \uc751\ub2f5 realm \uc774\ub984 {0}\uacfc \uc2dc\uc2a4\ud15c realm \uc774\ub984 {1}\uc774 \uc77c\uce58\ud558\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4.
|
||||
DigestAuthenticationFilter.incorrectResponse = \uc751\ub2f5\uc774 \uc815\ud655\ud558\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4.
|
||||
DigestAuthenticationFilter.missingAuth = 'auth' QOP(quality of protection)\ub97c \uc704\ud55c digest \uac12\uc740 \ud544\uc218 \ud56d\ubaa9\uc785\ub2c8\ub2e4. \ud604\uc7ac header \uac12\uc740 {0}\uc785\ub2c8\ub2e4.
|
||||
DigestAuthenticationFilter.missingMandatory = digest \uac12\uc740 \ud544\uc218 \ud56d\ubaa9\uc785\ub2c8\ub2e4. \ud604\uc7ac header \uac12\uc740 {0}\uc785\ub2c8\ub2e4.
|
||||
DigestAuthenticationFilter.nonceCompromised = Nonce \ud1a0\ud070\uc774 \uc190\uc0c1\ub418\uc5c8\uc2b5\ub2c8\ub2e4. \ud604\uc7ac nonce \uac12\uc740 {0}\uc785\ub2c8\ub2e4.
|
||||
DigestAuthenticationFilter.nonceEncoding = Nonce \uac12\uc774 Base64\ub85c \uc778\ucf54\ub529 \ub418\uc5b4\uc788\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4. \ud604\uc7ac nonce \uac12\uc740 {0}\uc785\ub2c8\ub2e4.
|
||||
DigestAuthenticationFilter.nonceExpired = Nonce\uc758 \uc720\ud6a8 \uae30\uac04\uc774 \ub9cc\ub8cc\ub418\uc5c8\uac70\ub098 \uc2dc\uac04\uc774 \ucd08\uacfc\ub418\uc5c8\uc2b5\ub2c8\ub2e4.
|
||||
DigestAuthenticationFilter.nonceNotNumeric = Nonce \ud1a0\ud070\uc758 \uccab \uae00\uc790\ub294 \uc22b\uc790\ub85c \uc2dc\uc791\ud574\uc57c \ud569\ub2c8\ub2e4. \ud604\uc7ac nonce \uac12\uc740 {0}\uc785\ub2c8\ub2e4.
|
||||
DigestAuthenticationFilter.nonceNotTwoTokens = Nonce\ub294 \ub450 \uac1c\uc758 \ud1a0\ud070\uc744 \ub9cc\ub4e4\uc5b4\uc57c \ud569\ub2c8\ub2e4. \ud604\uc7ac nonce \uac12\uc740 {0}\uc785\ub2c8\ub2e4.
|
||||
DigestAuthenticationFilter.usernameNotFound = {0} ID\ub97c \ucc3e\uc744 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4.
|
||||
JdbcDaoImpl.noAuthority = {0} \uc0ac\uc6a9\uc790\ub294 \uad8c\ud55c\uc774 \uc5c6\uc2b5\ub2c8\ub2e4.
|
||||
JdbcDaoImpl.notFound = {0} \uc0ac\uc6a9\uc790\ub97c \ucc3e\uc744 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4.
|
||||
LdapAuthenticationProvider.badCredentials = \uc790\uaca9 \uc99d\uba85\uc5d0 \uc2e4\ud328\ud558\uc600\uc2b5\ub2c8\ub2e4.
|
||||
LdapAuthenticationProvider.credentialsExpired = \uc790\uaca9 \uc99d\uba85 \uc720\ud6a8 \uae30\uac04\uc774 \ub9cc\ub8cc\ub418\uc5c8\uc2b5\ub2c8\ub2e4.
|
||||
LdapAuthenticationProvider.disabled = \uc720\ud6a8\ud558\uc9c0 \uc54a\uc740 \uc0ac\uc6a9\uc790\uc785\ub2c8\ub2e4.
|
||||
LdapAuthenticationProvider.expired = \uc0ac\uc6a9\uc790 \uacc4\uc815\uc758 \uc720\ud6a8 \uae30\uac04\uc774 \ub9cc\ub8cc \ub418\uc5c8\uc2b5\ub2c8\ub2e4.
|
||||
LdapAuthenticationProvider.locked = \uc0ac\uc6a9\uc790 \uacc4\uc815\uc774 \uc7a0\uaca8 \uc788\uc2b5\ub2c8\ub2e4.
|
||||
LdapAuthenticationProvider.emptyUsername = ID\uc5d0 \uacf5\ubc31\uc740 \ud5c8\uc6a9\ub418\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4.
|
||||
LdapAuthenticationProvider.onlySupports = UsernamePasswordAuthenticationToken\ub9cc \uc9c0\uc6d0\ud569\ub2c8\ub2e4.
|
||||
PasswordComparisonAuthenticator.badCredentials = \uc790\uaca9 \uc99d\uba85\uc5d0 \uc2e4\ud328\ud558\uc600\uc2b5\ub2c8\ub2e4.
|
||||
PersistentTokenBasedRememberMeServices.cookieStolen = \ub85c\uadf8\uc778 \uc0c1\ud0dc \uc720\uc9c0\ub97c \uc704\ud55c \ud1a0\ud070\uc774 \uc77c\uce58\ud558\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4. \uc774\uc804\uc5d0 \uc0ac\uc6a9\ud55c \ud1a0\ud070\uc774 \ud0c0\uc778\uc73c\ub85c\ubd80\ud130 \ud0c8\ucde8 \ub2f9\ud588\uc744 \uc218 \uc788\uc2b5\ub2c8\ub2e4.
|
||||
ProviderManager.providerNotFound = {0}\uc744 \uc704\ud55c AuthenticationProvider\ub97c \ucc3e\uc744 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4.
|
||||
RememberMeAuthenticationProvider.incorrectKey = \uc81c\uacf5\ub41c RememberMeAuthenticationToken\uc5d0\ub294 \ud544\uc694\ub85c \ud558\ub294 key\uac00 \uc5c6\uc2b5\ub2c8\ub2e4.
|
||||
RunAsImplAuthenticationProvider.incorrectKey = \uc81c\uacf5\ub41c RunAsUserToken\uc5d0\ub294 \ud544\uc694\ub85c \ud558\ub294 key\uac00 \uc5c6\uc2b5\ub2c8\ub2e4.
|
||||
SubjectDnX509PrincipalExtractor.noMatching = subjectDN\: {0} \ub0b4\uc5d0 \ub9e4\uce6d\ub418\ub294 \ud328\ud134\uc774 \uc5c6\uc2b5\ub2c8\ub2e4.
|
||||
SwitchUserFilter.noCurrentUser = \uc694\uccad\ud55c \uc0ac\uc6a9\uc790\ub97c \ucc3e\uc744 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4.
|
||||
SwitchUserFilter.noOriginalAuthentication = Authentication \uac1d\uccb4\uc758 \uc6d0\ubcf8\uc744 \ucc3e\uc744 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4.
|
||||
AbstractAccessDecisionManager.accessDenied=\uC811\uADFC\uC774 \uAC70\uBD80\uB418\uC5C8\uC2B5\uB2C8\uB2E4.
|
||||
AbstractLdapAuthenticationProvider.badCredentials=\uBE44\uBC00\uBC88\uD638\uAC00 \uB9DE\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.
|
||||
AbstractSecurityInterceptor.authenticationNotFound=SecurityContext\uC5D0\uC11C Authentication \uAC1D\uCCB4\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.
|
||||
AbstractUserDetailsAuthenticationProvider.badCredentials=\uBE44\uBC00\uBC88\uD638(credential)\uAC00 \uB9DE\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.
|
||||
AbstractUserDetailsAuthenticationProvider.credentialsExpired=\uBE44\uBC00\uBC88\uD638(credential)\uC758 \uC720\uD6A8 \uAE30\uAC04\uC774 \uB9CC\uB8CC\uB418\uC5C8\uC2B5\uB2C8\uB2E4.
|
||||
AbstractUserDetailsAuthenticationProvider.disabled=\uC874\uC7AC\uD558\uC9C0 \uC54A\uB294 \uC0AC\uC6A9\uC790 \uC785\uB2C8\uB2E4.
|
||||
AbstractUserDetailsAuthenticationProvider.expired=\uC0AC\uC6A9\uC790 \uACC4\uC815\uC758 \uC720\uD6A8 \uAE30\uAC04\uC774 \uB9CC\uB8CC \uB418\uC5C8\uC2B5\uB2C8\uB2E4.
|
||||
AbstractUserDetailsAuthenticationProvider.locked=\uC0AC\uC6A9\uC790 \uACC4\uC815\uC774 \uC7A0\uACA8 \uC788\uC2B5\uB2C8\uB2E4.
|
||||
AbstractUserDetailsAuthenticationProvider.onlySupports=UsernamePasswordAuthenticationToken\uB9CC \uC9C0\uC6D0\uD569\uB2C8\uB2E4.
|
||||
AccountStatusUserDetailsChecker.credentialsExpired=\uBE44\uBC00\uBC88\uD638\uC758 \uC720\uD6A8 \uAE30\uAC04\uC774 \uB9CC\uB8CC\uB418\uC5C8\uC2B5\uB2C8\uB2E4.
|
||||
AccountStatusUserDetailsChecker.disabled=\uC0AC\uC6A9\uC790 \uACC4\uC815\uC744 \uC0AC\uC6A9\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.
|
||||
AccountStatusUserDetailsChecker.expired=\uC0AC\uC6A9\uC790 \uACC4\uC815\uC758 \uC720\uD6A8 \uAE30\uAC04\uC774 \uB9CC\uB8CC \uB418\uC5C8\uC2B5\uB2C8\uB2E4.
|
||||
AccountStatusUserDetailsChecker.locked=\uC0AC\uC6A9\uC790 \uACC4\uC815\uC774 \uC7A0\uACA8 \uC788\uC2B5\uB2C8\uB2E4.
|
||||
AclEntryAfterInvocationProvider.noPermission=Authentication {0}\uC740/\uB294 domain object {1}\uC5D0 \uB300\uD55C \uAD8C\uD55C\uC774 \uC5C6\uC2B5\uB2C8\uB2E4.
|
||||
AnonymousAuthenticationProvider.incorrectKey=\uC81C\uACF5\uB41C AnonymousAuthenticationToken\uC5D0\uB294 \uCC3E\uB294 key\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4.
|
||||
BindAuthenticator.badCredentials=\uBE44\uBC00\uBC88\uD638\uAC00 \uB9DE\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.
|
||||
BindAuthenticator.emptyPassword=\uBE44\uBC00\uBC88\uD638(credential)\uAC00 \uB9DE\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.
|
||||
CasAuthenticationProvider.incorrectKey=\uC81C\uACF5\uB41C CasAuthenticationToken\uC5D0\uB294 \uCC3E\uB294 key\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4.
|
||||
CasAuthenticationProvider.noServiceTicket=\uAC80\uC99D\uC744 \uC704\uD55C CAS \uC11C\uBE44\uC2A4 \uD2F0\uCF13\uC744 \uC81C\uACF5\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.
|
||||
ConcurrentSessionControlStrategy.exceededAllowed={0}\uC758 \uCD5C\uB300 \uC138\uC158 \uD5C8\uC6A9 \uC218\uB97C \uCD08\uACFC\uD558\uC600\uC2B5\uB2C8\uB2E4.
|
||||
DigestAuthenticationFilter.incorrectRealm=\uC751\uB2F5 realm \uC774\uB984 {0}\uC774 \uC2DC\uC2A4\uD15C realm \uC774\uB984 {1}\uACFC \uC77C\uCE58 \uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.
|
||||
DigestAuthenticationFilter.incorrectResponse=\uC751\uB2F5\uC774 \uC815\uD655\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.
|
||||
DigestAuthenticationFilter.missingAuth='auth' QOP\uB97C \uC704\uD55C \uD544\uC218 digest \uD30C\uB77C\uBBF8\uD130 \uAC12\uC774 \uB204\uB77D\uB418\uC5C8\uC2B5\uB2C8\uB2E4. \uD604\uC7AC header\uB294 {0}\uC785\uB2C8\uB2E4.
|
||||
DigestAuthenticationFilter.missingMandatory=\uD544\uC218 digest \uD30C\uB77C\uBBF8\uD130 \uAC12\uC774 \uB204\uB77D\uB418\uC5C8\uC2B5\uB2C8\uB2E4. \uD604\uC7AC header\uB294 {0}\uC785\uB2C8\uB2E4.
|
||||
DigestAuthenticationFilter.nonceCompromised=Nonce \uD1A0\uD070\uC774 \uD6FC\uC190\uB418\uC5C8\uC2B5\uB2C8\uB2E4. \uD604\uC7AC nonce\uB294 {0}\uC785\uB2C8\uB2E4.
|
||||
DigestAuthenticationFilter.nonceEncoding=Nonce\uAC00 Base64\uB85C \uC778\uCF54\uB529 \uB418\uC5B4\uC788\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4. \uD604\uC7AC nonce\uB294 {0}\uC785\uB2C8\uB2E4.
|
||||
DigestAuthenticationFilter.nonceExpired=Nonce\uC758 \uC720\uD6A8 \uAE30\uAC04\uC774 \uB9CC\uB8CC\uB418\uC5C8\uC2B5\uB2C8\uB2E4.
|
||||
DigestAuthenticationFilter.nonceNotNumeric=Nonce \uD1A0\uD070\uC758 \uCCAB \uAE00\uC790\uB294 \uC22B\uC790\uB85C \uC2DC\uC791\uD574\uC57C \uD569\uB2C8\uB2E4. \uD604\uC7AC nonce\uB294 {0}\uC785\uB2C8\uB2E4.
|
||||
DigestAuthenticationFilter.nonceNotTwoTokens=Nonce\uB294 2\uAC1C\uC758 \uD1A0\uD070\uC744 \uB9CC\uB4E4\uC5B4\uC57C \uD569\uB2C8\uB2E4. \uD604\uC7AC nonce\uB294 {0}\uC785\uB2C8\uB2E4.
|
||||
DigestAuthenticationFilter.usernameNotFound=\uC0AC\uC6A9\uC790 {0}\uC744/\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.
|
||||
JdbcDaoImpl.noAuthority=\uC0AC\uC6A9\uC790 {0}\uC740/\uB294 \uAD8C\uD55C\uC774 \uC5C6\uC2B5\uB2C8\uB2E4.
|
||||
JdbcDaoImpl.notFound=\uC0AC\uC6A9\uC790 {0}\uC744/\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.
|
||||
LdapAuthenticationProvider.badCredentials=\uBE44\uBC00\uBC88\uD638\uAC00 \uB9DE\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.
|
||||
LdapAuthenticationProvider.credentialsExpired=\uBE44\uBC00\uBC88\uD638(credential)\uC758 \uC720\uD6A8 \uAE30\uAC04\uC774 \uB9CC\uB8CC\uB418\uC5C8\uC2B5\uB2C8\uB2E4.
|
||||
LdapAuthenticationProvider.disabled=\uC0AC\uC6A9\uC790 \uACC4\uC815\uC744 \uC0AC\uC6A9\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.
|
||||
LdapAuthenticationProvider.expired=\uC0AC\uC6A9\uC790 \uACC4\uC815\uC758 \uC720\uD6A8 \uAE30\uAC04\uC774 \uB9CC\uB8CC \uB418\uC5C8\uC2B5\uB2C8\uB2E4.
|
||||
LdapAuthenticationProvider.locked=\uC0AC\uC6A9\uC790 \uACC4\uC815\uC774 \uC7A0\uACA8 \uC788\uC2B5\uB2C8\uB2E4.
|
||||
LdapAuthenticationProvider.emptyUsername=\uC0AC\uC6A9\uC790\uBA85(username)\uC5D0 \uACF5\uBC31\uC740 \uD5C8\uC6A9\uB418\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.
|
||||
LdapAuthenticationProvider.onlySupports=UsernamePasswordAuthenticationToken\uB9CC \uC9C0\uC6D0\uD569\uB2C8\uB2E4.
|
||||
PasswordComparisonAuthenticator.badCredentials=\uBE44\uBC00\uBC88\uD638\uAC00 \uB9DE\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.
|
||||
#PersistentTokenBasedRememberMeServices.cookieStolen=Invalid remember-me token (Series/token) mismatch. Implies previous cookie theft attack.
|
||||
ProviderManager.providerNotFound={0}\uC744 \uC704\uD55C AuthenticationProvider\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.
|
||||
RememberMeAuthenticationProvider.incorrectKey=\uC81C\uACF5\uB41C RememberMeAuthenticationToken\uC5D0\uB294 \uCC3E\uB294 key\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4.
|
||||
RunAsImplAuthenticationProvider.incorrectKey=\uC81C\uACF5\uB41C RunAsUserToken\uC5D0\uB294 \uCC3E\uB294 key\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4.
|
||||
SubjectDnX509PrincipalExtractor.noMatching=subjectDN\: {0}\uC5D0\uC11C \uB9E4\uCE6D\uB418\uB294 \uD328\uD134\uC774 \uC5C6\uC2B5\uB2C8\uB2E4.
|
||||
SwitchUserFilter.noCurrentUser=\uC0AC\uC6A9\uC790\uAC00 \uC874\uC7AC\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.
|
||||
SwitchUserFilter.noOriginalAuthentication=Authentication\uC758 \uC6D0\uBCF8\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.
|
||||
|
||||
+3
-3
@@ -34,7 +34,6 @@ import org.springframework.security.authentication.AuthenticationServiceExceptio
|
||||
import org.springframework.security.authentication.BadCredentialsException;
|
||||
import org.springframework.security.authentication.CredentialsExpiredException;
|
||||
import org.springframework.security.authentication.DisabledException;
|
||||
import org.springframework.security.authentication.InternalAuthenticationServiceException;
|
||||
import org.springframework.security.authentication.LockedException;
|
||||
import org.springframework.security.authentication.TestingAuthenticationToken;
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||
@@ -173,8 +172,9 @@ public class DaoAuthenticationProviderTests extends TestCase {
|
||||
|
||||
try {
|
||||
provider.authenticate(token);
|
||||
fail("Should have thrown InternalAuthenticationServiceException");
|
||||
} catch (InternalAuthenticationServiceException expected) {
|
||||
fail("Should have thrown AuthenticationServiceException");
|
||||
} catch (AuthenticationServiceException expected) {
|
||||
assertTrue(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
-10
@@ -15,8 +15,6 @@
|
||||
|
||||
package org.springframework.security.authentication.dao.salt;
|
||||
|
||||
import static org.fest.assertions.Assertions.assertThat;
|
||||
|
||||
import org.springframework.security.authentication.dao.SystemWideSaltSource;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
@@ -71,12 +69,4 @@ public class SystemWideSaltSourceTests extends TestCase {
|
||||
saltSource.afterPropertiesSet();
|
||||
assertEquals("helloWorld", saltSource.getSalt(null));
|
||||
}
|
||||
|
||||
// SEC-2173
|
||||
public void testToString() {
|
||||
String systemWideSalt = "helloWorld";
|
||||
SystemWideSaltSource saltSource = new SystemWideSaltSource();
|
||||
saltSource.setSystemWideSalt(systemWideSalt);
|
||||
assertThat(saltSource.toString()).isEqualTo(systemWideSalt);
|
||||
}
|
||||
}
|
||||
|
||||
+1
-19
@@ -34,7 +34,6 @@ import org.powermock.core.classloader.annotations.PrepareForTest;
|
||||
import org.powermock.modules.junit4.PowerMockRunner;
|
||||
import org.powermock.reflect.Whitebox;
|
||||
import org.springframework.core.SpringVersion;
|
||||
import org.springframework.test.util.ReflectionTestUtils;
|
||||
|
||||
/**
|
||||
* Checks that the embedded version information is up to date.
|
||||
@@ -121,7 +120,7 @@ public class SpringSecurityCoreVersionTests {
|
||||
public void noWarnIfSpringVersionLarger() throws Exception {
|
||||
spy(SpringSecurityCoreVersion.class);
|
||||
spy(SpringVersion.class);
|
||||
when(SpringSecurityCoreVersion.getVersion()).thenReturn("4.0.0.RELEASE");
|
||||
when(SpringSecurityCoreVersion.getVersion()).thenReturn("3.2.0.RELEASE");
|
||||
when(SpringVersion.getVersion()).thenReturn("4.0.0.RELEASE");
|
||||
|
||||
performChecks();
|
||||
@@ -129,20 +128,6 @@ public class SpringSecurityCoreVersionTests {
|
||||
verify(logger, never()).warn(any());
|
||||
}
|
||||
|
||||
// SEC-2697
|
||||
@Test
|
||||
public void noWarnIfSpringPatchVersionDoubleDigits() throws Exception {
|
||||
String minSpringVersion = "3.2.8.RELEASE";
|
||||
spy(SpringSecurityCoreVersion.class);
|
||||
spy(SpringVersion.class);
|
||||
when(SpringSecurityCoreVersion.getVersion()).thenReturn("3.2.0.RELEASE");
|
||||
when(SpringVersion.getVersion()).thenReturn("3.2.10.RELEASE");
|
||||
|
||||
performChecks(minSpringVersion);
|
||||
|
||||
verify(logger, never()).warn(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void noLoggingIfPropertySet() throws Exception {
|
||||
spy(SpringSecurityCoreVersion.class);
|
||||
@@ -164,7 +149,4 @@ public class SpringSecurityCoreVersionTests {
|
||||
Whitebox.invokeMethod(SpringSecurityCoreVersion.class, "performVersionChecks");
|
||||
}
|
||||
|
||||
private void performChecks(String minSpringVersion) throws Exception {
|
||||
Whitebox.invokeMethod(SpringSecurityCoreVersion.class, "performVersionChecks", minSpringVersion);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
Implementation-Title: org.springframework.security.core
|
||||
Implementation-Version: ${version}
|
||||
Bundle-SymbolicName: org.springframework.security.core
|
||||
Bundle-Name: Spring Security Core
|
||||
Bundle-Vendor: SpringSource
|
||||
Bundle-Version: ${version}
|
||||
Bundle-ManifestVersion: 2
|
||||
Ignored-Existing-Headers:
|
||||
Import-Package,
|
||||
Export-Package
|
||||
Import-Template:
|
||||
org.aopalliance.*;version="${aopAllianceRange}",
|
||||
org.aspectj.*;version="${aspectjRange}";resolution:=optional,
|
||||
org.apache.commons.logging.*;version="${cloggingRange}",
|
||||
org.springframework.aop.*;version="${springRange}";resolution:=optional,
|
||||
org.springframework.beans.*;version="${springRange}",
|
||||
org.springframework.cache.*;version="${springRange}";resolution:=optional,
|
||||
org.springframework.context.*;version="${springRange}",
|
||||
org.springframework.core.*;version="${springRange}",
|
||||
org.springframework.expression.*;version="${springRange}";resolution:=optional,
|
||||
org.springframework.dao.*;version="${springRange}";resolution:=optional,
|
||||
org.springframework.jdbc.*;version="${springRange}";resolution:=optional,
|
||||
org.springframework.scheduling.*;version="${springRange}";resolution:=optional,
|
||||
org.springframework.transaction.*;version="${springRange}";resolution:=optional,
|
||||
org.springframework.util;version="${springRange}",
|
||||
net.sf.ehcache.*;version="${ehcacheRange}";resolution:=optional,
|
||||
javax.annotation.security.*;version="0";resolution:=optional,
|
||||
javax.crypto.*;version="0";resolution:=optional,
|
||||
javax.security.auth.*;version="0";resolution:=optional,
|
||||
javax.naming.*;version="0";resolution:=optional
|
||||
@@ -4,7 +4,7 @@
|
||||
// isJdk6 = jdkVersion >= '1.6'
|
||||
int maxAESKeySize = javax.crypto.Cipher.getMaxAllowedKeyLength('AES')
|
||||
|
||||
configure(project.tasks.withType(Test)) {
|
||||
configure([test,spring4Test]) {
|
||||
if (maxAESKeySize < 256) {
|
||||
println "AES keysize limited to $maxAESKeySize, skipping EncryptorsTests"
|
||||
exclude '**/EncryptorsTests.class'
|
||||
|
||||
+4
-10
@@ -4,7 +4,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-crypto</artifactId>
|
||||
<version>4.0.0.M2</version>
|
||||
<version>3.2.3.RELEASE</version>
|
||||
<name>spring-security-crypto</name>
|
||||
<description>spring-security-crypto</description>
|
||||
<url>http://spring.io/spring-security</url>
|
||||
@@ -42,17 +42,11 @@
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>spring-milestone</id>
|
||||
<url>https://repo.spring.io/milestone</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-core</artifactId>
|
||||
<version>4.1.0.RC2</version>
|
||||
<version>3.2.8.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
@@ -77,7 +71,7 @@
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.11</version>
|
||||
<version>4.10</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@@ -101,7 +95,7 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-test</artifactId>
|
||||
<version>4.1.0.RC2</version>
|
||||
<version>3.2.8.RELEASE</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
Implementation-Title: org.springframework.security.crypto
|
||||
Implementation-Version: ${version}
|
||||
Bundle-SymbolicName: org.springframework.security.crypto
|
||||
Bundle-Name: Spring Security Crypto
|
||||
Bundle-Vendor: SpringSource
|
||||
Bundle-Version: ${version}
|
||||
Bundle-ManifestVersion: 2
|
||||
Ignored-Existing-Headers:
|
||||
Import-Package,
|
||||
Export-Package
|
||||
Import-Template:
|
||||
org.apache.commons.logging.*;version="${cloggingRange}",
|
||||
javax.crypto.*;version="0"
|
||||
@@ -1,5 +0,0 @@
|
||||
dependencies {
|
||||
compile project(':spring-security-core'),
|
||||
"org.springframework.data:spring-data-commons:$springDataCommonsVersion"
|
||||
|
||||
}
|
||||
-120
@@ -1,120 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-data</artifactId>
|
||||
<version>4.0.0.M2</version>
|
||||
<name>spring-security-data</name>
|
||||
<description>spring-security-data</description>
|
||||
<url>http://spring.io/spring-security</url>
|
||||
<organization>
|
||||
<name>spring.io</name>
|
||||
<url>http://spring.io/</url>
|
||||
</organization>
|
||||
<licenses>
|
||||
<license>
|
||||
<name>The Apache Software License, Version 2.0</name>
|
||||
<url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
|
||||
<distribution>repo</distribution>
|
||||
</license>
|
||||
</licenses>
|
||||
<developers>
|
||||
<developer>
|
||||
<id>rwinch</id>
|
||||
<name>Rob Winch</name>
|
||||
<email>rwinch@gopivotal.com</email>
|
||||
</developer>
|
||||
</developers>
|
||||
<scm>
|
||||
<connection>scm:git:git://github.com/spring-projects/spring-security</connection>
|
||||
<developerConnection>scm:git:git://github.com/spring-projects/spring-security</developerConnection>
|
||||
<url>https://github.com/spring-projects/spring-security</url>
|
||||
</scm>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<source>1.7</source>
|
||||
<target>1.7</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>spring-milestone</id>
|
||||
<url>https://repo.spring.io/milestone</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-commons</artifactId>
|
||||
<version>1.9.0.RC1</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-core</artifactId>
|
||||
<version>4.0.0.M2</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-core</artifactId>
|
||||
<version>4.1.0.RC2</version>
|
||||
<scope>compile</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>commons-logging</artifactId>
|
||||
<groupId>commons-logging</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-logging</groupId>
|
||||
<artifactId>commons-logging</artifactId>
|
||||
<version>1.1.1</version>
|
||||
<scope>compile</scope>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ch.qos.logback</groupId>
|
||||
<artifactId>logback-classic</artifactId>
|
||||
<version>0.9.29</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.11</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.easytesting</groupId>
|
||||
<artifactId>fest-assert</artifactId>
|
||||
<version>1.4</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-core</artifactId>
|
||||
<version>1.9.5</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>jcl-over-slf4j</artifactId>
|
||||
<version>1.7.5</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-test</artifactId>
|
||||
<version>4.1.0.RC2</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
-117
@@ -1,117 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package org.springframework.security.data.repository.query;
|
||||
|
||||
import org.springframework.data.repository.query.spi.EvaluationContextExtension;
|
||||
import org.springframework.data.repository.query.spi.EvaluationContextExtensionSupport;
|
||||
import org.springframework.data.repository.query.spi.Function;
|
||||
import org.springframework.security.access.expression.SecurityExpressionRoot;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.context.SecurityContext;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* By defining this object as a Bean, Spring Security is exposed as SpEL expressions for creating Spring Data
|
||||
* queries.
|
||||
* </p>
|
||||
*
|
||||
* <p>With Java based configuration, we can define the bean using the following:</p>
|
||||
*
|
||||
* <p>For example, if you return a UserDetails that extends the following User object:</p>
|
||||
*
|
||||
* <pre>
|
||||
* @Entity
|
||||
* public class User {
|
||||
* @GeneratedValue(strategy = GenerationType.AUTO)
|
||||
* @Id
|
||||
* private Long id;
|
||||
*
|
||||
* ...
|
||||
* </pre>
|
||||
*
|
||||
* <p>And you have a Message object that looks like the following:</p>
|
||||
*
|
||||
* <pre>
|
||||
* @Entity
|
||||
* public class Message {
|
||||
* @Id
|
||||
* @GeneratedValue(strategy = GenerationType.AUTO)
|
||||
* private Long id;
|
||||
*
|
||||
* @OneToOne
|
||||
* private User to;
|
||||
*
|
||||
* ...
|
||||
* </pre>
|
||||
*
|
||||
* You can use the following {@code Query} annotation to search for only messages that are to the current user:
|
||||
*
|
||||
* <pre>
|
||||
* @Repository
|
||||
* public interface SecurityMessageRepository extends MessageRepository {
|
||||
*
|
||||
* @Query("select m from Message m where m.to.id = ?#{ principal?.id }")
|
||||
* List<Message> findAll();
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* This works because the principal in this instance is a User which has an id field on it.
|
||||
*
|
||||
* @since 4.0
|
||||
* @author Rob Winch
|
||||
*/
|
||||
public class SecurityEvaluationContextExtension extends EvaluationContextExtensionSupport {
|
||||
private Authentication authentication;
|
||||
|
||||
/**
|
||||
* Creates a new instance that uses the current {@link Authentication} found on the
|
||||
* {@link org.springframework.security.core.context.SecurityContextHolder}.
|
||||
*/
|
||||
public SecurityEvaluationContextExtension() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new instance that always uses the same {@link Authentication} object.
|
||||
*
|
||||
* @param authentication the {@link Authentication} to use
|
||||
*/
|
||||
public SecurityEvaluationContextExtension(Authentication authentication) {
|
||||
this.authentication = authentication;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getExtensionId() {
|
||||
return "security";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getRootObject() {
|
||||
Authentication authentication = getAuthentication();
|
||||
return new SecurityExpressionRoot(authentication) {};
|
||||
}
|
||||
|
||||
private Authentication getAuthentication() {
|
||||
if(authentication != null) {
|
||||
return authentication;
|
||||
}
|
||||
|
||||
SecurityContext context = SecurityContextHolder.getContext();
|
||||
return context.getAuthentication();
|
||||
}
|
||||
}
|
||||
-75
@@ -1,75 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package org.springframework.security.data.repository.query;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.security.access.expression.SecurityExpressionRoot;
|
||||
import org.springframework.security.authentication.TestingAuthenticationToken;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
|
||||
import static org.fest.assertions.Assertions.assertThat;
|
||||
|
||||
public class SecurityEvaluationContextExtensionTests {
|
||||
SecurityEvaluationContextExtension securityExtension;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
securityExtension = new SecurityEvaluationContextExtension();
|
||||
}
|
||||
|
||||
@After
|
||||
public void cleanup() {
|
||||
SecurityContextHolder.clearContext();
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void getRootObjectSecurityContextHolderAuthenticationNull() {
|
||||
getRoot().getAuthentication();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getRootObjectSecurityContextHolderAuthentication() {
|
||||
TestingAuthenticationToken authentication = new TestingAuthenticationToken("user", "password", "ROLE_USER");
|
||||
SecurityContextHolder.getContext().setAuthentication(authentication);
|
||||
|
||||
assertThat(getRoot().getAuthentication()).isSameAs(authentication);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getRootObjectExplicitAuthenticationOverridesSecurityContextHolder() {
|
||||
TestingAuthenticationToken explicit = new TestingAuthenticationToken("explicit", "password", "ROLE_EXPLICIT");
|
||||
securityExtension = new SecurityEvaluationContextExtension(explicit);
|
||||
|
||||
TestingAuthenticationToken authentication = new TestingAuthenticationToken("user", "password", "ROLE_USER");
|
||||
SecurityContextHolder.getContext().setAuthentication(authentication);
|
||||
|
||||
assertThat(getRoot().getAuthentication()).isSameAs(explicit);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getRootObjectExplicitAuthentication() {
|
||||
TestingAuthenticationToken explicit = new TestingAuthenticationToken("explicit", "password", "ROLE_EXPLICIT");
|
||||
securityExtension = new SecurityEvaluationContextExtension(explicit);
|
||||
|
||||
assertThat(getRoot().getAuthentication()).isSameAs(explicit);
|
||||
}
|
||||
|
||||
private SecurityExpressionRoot getRoot() {
|
||||
return (SecurityExpressionRoot) securityExtension.getRootObject();
|
||||
}
|
||||
}
|
||||
@@ -26,6 +26,7 @@ project('manual') {
|
||||
numbered: '',
|
||||
'spring-security-version' : project.version,
|
||||
'spring-version' : springVersion,
|
||||
'spring4-version' : spring4Version,
|
||||
revnumber : project.version
|
||||
]
|
||||
]
|
||||
|
||||
@@ -77,7 +77,7 @@ public class RootConfiguration {
|
||||
|
||||
The `@ComponentScan` is loading all configuration within the same package (and child packages) as `RootConfiguration`. Since <<security-config-java,SecurityConfig>> is in this package, it will be loaded with our existing setup and there is nothing more to do.
|
||||
|
||||
NOTE: Had <<security-config-java,SecurityConfig>> not been loaded, we could have used an `@Import(SecurityConfig.class)` above the class definition of <<root-configuration-java,RootConfiguration>> or added <<security-config-java,SecurityConfig>> as one of the results for `getRootConfigClasses()`.
|
||||
NOTE: Had <<security-config-java,SecurityConfig>> not been loaded, we could have used an `@Import(SecurityConfig)` above the class definition of <<root-configuration-java,RootConfiguration>> or added <<security-config-java,SecurityConfig>> as one of the results for `getRootConfigClasses()`.
|
||||
|
||||
include::{hello-include-dir}/exploring-the-secured-application.asc[]
|
||||
|
||||
|
||||
@@ -198,9 +198,9 @@ If you are using a milestone or release candidate version, you will need to ensu
|
||||
----
|
||||
|
||||
[[maven-bom]]
|
||||
===== Spring Framework Bom
|
||||
===== Using Spring 4 and Maven
|
||||
|
||||
Spring Security builds against Spring Framework {spring-version}, but should work with 4.0.x. The problem that many users will have is that Spring Security's transitive dependencies resolve Spring Framework {spring-version} which can cause strange classpath problems.
|
||||
Spring Security builds against Spring Framework {spring-version}, but is also tested against Spring Framework {spring4-version}. This means you can use Spring Security {spring-security-version} with Spring Framework {spring4-version}. The problem that many users will have is that Spring Security's transitive dependencies resolve Spring Framework {spring-version} causing all sorts of strange classpath problems.
|
||||
|
||||
One (tedious) way to circumvent this issue would be to include all the Spring Framework modules in a http://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html#Dependency_Management[<dependencyManagement>] section of your pom. An alternative approach is to include the `spring-framework-bom` within your `<dependencyManagement>` section of your `pom.xml` as shown below:
|
||||
|
||||
@@ -213,7 +213,7 @@ One (tedious) way to circumvent this issue would be to include all the Spring Fr
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-framework-bom</artifactId>
|
||||
<version>{spring-version}</version>
|
||||
<version>{spring4-version}</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
@@ -221,7 +221,7 @@ One (tedious) way to circumvent this issue would be to include all the Spring Fr
|
||||
</dependencyManagement>
|
||||
----
|
||||
|
||||
This will ensure that all the transitive dependencies of Spring Security use the Spring {spring-version} modules.
|
||||
This will ensure that all the transitive dependencies of Spring Security use the Spring {spring4-version} modules.
|
||||
|
||||
NOTE: This approach uses Maven's "bill of materials" (BOM) concept and is only available in Maven 2.0.9+. For additional details about how dependencies are resolved refer to http://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html[Maven's Introduction to the Dependency Mechanism documentation].
|
||||
|
||||
@@ -274,9 +274,9 @@ repositories {
|
||||
----
|
||||
|
||||
[[gradle-resolutionStrategy]]
|
||||
===== Using Spring 4.0.x and Gradle
|
||||
===== Using Spring 4 and Gradle
|
||||
|
||||
By default Gradle will use the newest version when resolving transitive versions. This means that often times no additional work is necessary when running Spring Security {spring-security-version} with Spring Framework {spring-version}. However, at times there can be issues that come up so it is best to mitigate this using http://www.gradle.org/docs/current/dsl/org.gradle.api.artifacts.ResolutionStrategy.html[Gradle's ResolutionStrategy] as shown below:
|
||||
By default Gradle will use the newest version when resolving transitive versions. This means that often times no additional work is necessary when running Spring Security {spring-security-version} with Spring Framework {spring4-version}. However, at times there can be issues that come up so it is best to mitigate this using http://www.gradle.org/docs/current/dsl/org.gradle.api.artifacts.ResolutionStrategy.html[Gradle's ResolutionStrategy] as shown below:
|
||||
|
||||
.build.gradle
|
||||
[source,groovy]
|
||||
@@ -285,13 +285,13 @@ By default Gradle will use the newest version when resolving transitive versions
|
||||
configurations.all {
|
||||
resolutionStrategy.eachDependency { DependencyResolveDetails details ->
|
||||
if (details.requested.group == 'org.springframework') {
|
||||
details.useVersion '{spring-version}'
|
||||
details.useVersion '{spring4-version}'
|
||||
}
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
This will ensure that all the transitive dependencies of Spring Security use the Spring {spring-version} modules.
|
||||
This will ensure that all the transitive dependencies of Spring Security use the Spring {spring4-version} modules.
|
||||
|
||||
NOTE: This example uses Gradle 1.9, but may need modifications to work in future versions of Gradle since this is an incubating feature within Gradle.
|
||||
|
||||
@@ -691,7 +691,7 @@ public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception
|
||||
|
||||
==== LDAP Authentication
|
||||
|
||||
You can find the updates to suppport LDAP based authentication. The https://github.com/spring-projects/spring-security/tree/master/samples/ldap-jc[ldap-jc sample] provides a complete example of using LDAP based authentication.
|
||||
You can find the updates to suppport LDAP based authentication. The https://github.com/spring-projects/spring-security/tree/master/samples/lda-jc[ldap-jc sample] provides a complete example of using LDAP based authentication.
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@@ -809,7 +809,7 @@ public class MultiHttpSecurityConfig {
|
||||
[[jc-method]]
|
||||
=== Method Security
|
||||
|
||||
From version 2.0 onwards Spring Security has improved support substantially for adding security to your service layer methods. It provides support for JSR-250 annotation security as well as the framework���s original @Secured annotation. From 3.0 you can also make use of new <<el-access,expression-based annotations>>. You can apply security to a single bean, using the intercept-methods element to decorate the bean declaration, or you can secure multiple beans across the entire service layer using the AspectJ style pointcuts.
|
||||
From version 2.0 onwards Spring Security has improved support substantially for adding security to your service layer methods. It provides support for JSR-250 annotation security as well as the framework’s original @Secured annotation. From 3.0 you can also make use of new <<el-access,expression-based annotations>>. You can apply security to a single bean, using the intercept-methods element to decorate the bean declaration, or you can secure multiple beans across the entire service layer using the AspectJ style pointcuts.
|
||||
|
||||
==== EnableGlobalMethodSecurity
|
||||
|
||||
@@ -824,7 +824,7 @@ public class MethodSecurityConfig {
|
||||
}
|
||||
----
|
||||
|
||||
Adding an annotation to a method (on an class or interface) would then limit the access to that method accordingly. Spring Security���s native annotation support defines a set of attributes for the method. These will be passed to the AccessDecisionManager for it to make the actual decision:
|
||||
Adding an annotation to a method (on an class or interface) would then limit the access to that method accordingly. Spring Security’s native annotation support defines a set of attributes for the method. These will be passed to the AccessDecisionManager for it to make the actual decision:
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@@ -852,7 +852,7 @@ public class MethodSecurityConfig {
|
||||
}
|
||||
----
|
||||
|
||||
These are standards-based and allow simple role-based constraints to be applied but do not have the power Spring Security���s native annotations. To use the new expression-based syntax, you would use
|
||||
These are standards-based and allow simple role-based constraints to be applied but do not have the power Spring Security’s native annotations. To use the new expression-based syntax, you would use
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@@ -2078,7 +2078,7 @@ Each supported secure object type has its own interceptor class, which is a subc
|
||||
|
||||
[[tech-intro-config-attributes]]
|
||||
===== What are Configuration Attributes?
|
||||
A "configuration attribute" can be thought of as a String that has special meaning to the classes used by `AbstractSecurityInterceptor`. They are represented by the interface `ConfigAttribute` within the framework. They may be simple role names or have more complex meaning, depending on the how sophisticated the `AccessDecisionManager` implementation is. The `AbstractSecurityInterceptor` is configured with a `SecurityMetadataSource` which it uses to look up the attributes for a secure object. Usually this configuration will be hidden from the user. Configuration attributes will be entered as annotations on secured methods or as access attributes on secured URLs. For example, when we saw something like `<intercept-url pattern='/secure/**' access='ROLE_A,ROLE_B'/>` in the namespace introduction, this is saying that the configuration attributes `ROLE_A` and `ROLE_B` apply to web requests matching the given pattern. In practice, with the default `AccessDecisionManager` configuration, this means that anyone who has a `GrantedAuthority` matching either of these two attributes will be allowed access. Strictly speaking though, they are just attributes and the interpretation is dependent on the `AccessDecisionManager` implementation. The use of the prefix `ROLE_` is a marker to indicate that these attributes are roles and should be consumed by Spring Security's`RoleVoter`. This is only relevant when a voter-based `AccessDecisionManager` is in use. We'll see how the `AccessDecisionManager` is implemented in the <<authz-arch,authorization chapter>>.
|
||||
A "configuration attribute" can be thought of as a String that has special meaning to the classes used by`AbstractSecurityInterceptor`. They are represented by the interface `ConfigAttribute` within the framework. They may be simple role names or have more complex meaning, depending on the how sophisticated the `AccessDecisionManager` implementation is. The `AbstractSecurityInterceptor` is configured with a `SecurityMetadataSource` which it uses to look up the attributes for a secure object. Usually this configuration will be hidden from the user. Configuration attributes will be entered as annotations on secured methods or as access attributes on secured URLs. For example, when we saw something like `<intercept-url pattern='/secure/**' access='ROLE_A,ROLE_B'/>` in the namespace introduction, this is saying that the configuration attributes `ROLE_A` and `ROLE_B` apply to web requests matching the given pattern. In practice, with the default `AccessDecisionManager` configuration, this means that anyone who has a `GrantedAuthority` matching either of these two attributes will be allowed access. Strictly speaking though, they are just attributes and the interpretation is dependent on the `AccessDecisionManager` implementation. The use of the prefix `ROLE_` is a marker to indicate that these attributes are roles and should be consumed by Spring Security's`RoleVoter`. This is only relevant when a voter-based `AccessDecisionManager` is in use. We'll see how the `AccessDecisionManager` is implemented in the <<authz-arch,authorization chapter>>.
|
||||
|
||||
|
||||
===== RunAsManager
|
||||
@@ -2936,7 +2936,7 @@ The beans required in an application context to enable remember-me services are
|
||||
</bean>
|
||||
|
||||
<bean id="rememberMeAuthenticationProvider" class=
|
||||
"org.springframework.security.authentication.RememberMeAuthenticationProvider">
|
||||
"org.springframework.security.authentication.rememberme.RememberMeAuthenticationProvider">
|
||||
<property name="key" value="springRocks"/>
|
||||
</bean>
|
||||
----
|
||||
@@ -5559,9 +5559,7 @@ The next step is to specify `serviceProperties` and the `authenticationDetailsSo
|
||||
<property name="serviceProperties" ref="serviceProperties"/>
|
||||
<property name="authenticationDetailsSource">
|
||||
<bean class=
|
||||
"org.springframework.security.cas.web.authentication.ServiceAuthenticationDetailsSource">
|
||||
<constructor-arg ref="serviceProperties"/>
|
||||
</bean>
|
||||
"org.springframework.security.cas.web.authentication.ServiceAuthenticationDetailsSource"/>
|
||||
</property>
|
||||
</bean>
|
||||
----
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
version=4.0.0.M2
|
||||
version=3.2.3.RELEASE
|
||||
|
||||
+26
-46
@@ -1,7 +1,6 @@
|
||||
import org.gradle.plugins.ide.eclipse.model.SourceFolder
|
||||
|
||||
apply plugin: 'java'
|
||||
apply plugin: 'groovy'
|
||||
apply plugin: 'javadocHotfix'
|
||||
apply plugin: 'eclipse-wtp'
|
||||
apply plugin: 'propdeps'
|
||||
@@ -12,58 +11,33 @@ apply plugin: 'propdeps-eclipse'
|
||||
sourceCompatibility = 1.5
|
||||
targetCompatibility = 1.5
|
||||
|
||||
ext.ehcacheVersion = '2.6.5'
|
||||
ext.ehcacheVersion = '1.6.2'
|
||||
ext.aspectjVersion = '1.6.10'
|
||||
ext.apacheDsVersion = '1.5.5'
|
||||
ext.jstlVersion = '1.2.1'
|
||||
ext.jstlVersion = '1.2'
|
||||
ext.jettyVersion = '6.1.26'
|
||||
ext.hsqlVersion = '2.3.1'
|
||||
ext.slf4jVersion = '1.7.5'
|
||||
ext.logbackVersion = '0.9.29'
|
||||
ext.cglibVersion = '2.2'
|
||||
ext.powerMockVersion = '1.5.1'
|
||||
ext.servletApiVersion = '3.0.1'
|
||||
ext.servletApiVersion = '7.0.33'
|
||||
ext.seleniumVersion = '2.33.0'
|
||||
ext.groovyVersion = '2.0.5'
|
||||
ext.spockVersion = '0.7-groovy-2.0'
|
||||
ext.gebVersion = '0.9.0'
|
||||
ext.thymeleafVersion = '2.1.3.RELEASE'
|
||||
ext.springDataJpaVersion = '1.7.0.RC1'
|
||||
ext.springDataCommonsVersion = '1.9.0.RC1'
|
||||
|
||||
ext.spockDependencies = [
|
||||
dependencies.create("org.spockframework:spock-spring:$spockVersion") {
|
||||
exclude group: 'junit', module: 'junit-dep'
|
||||
},
|
||||
dependencies.create("org.spockframework:spock-core:$spockVersion") {
|
||||
exclude group: 'junit', module: 'junit-dep'
|
||||
}
|
||||
]
|
||||
|
||||
ext.gebDependencies = spockDependencies + [
|
||||
"org.seleniumhq.selenium:selenium-htmlunit-driver:$seleniumVersion",
|
||||
"org.gebish:geb-spock:$gebVersion",
|
||||
'commons-httpclient:commons-httpclient:3.1',
|
||||
"org.codehaus.groovy:groovy:$groovyVersion"
|
||||
]
|
||||
ext.thymeleafVersion = '2.1.2.RELEASE'
|
||||
|
||||
ext.powerMockDependencies = [
|
||||
"org.powermock:powermock-core:$powerMockVersion",
|
||||
"org.powermock:powermock-api-support:$powerMockVersion",
|
||||
"org.powermock:powermock-module-junit4-common:$powerMockVersion",
|
||||
"org.powermock:powermock-module-junit4:$powerMockVersion",
|
||||
dependencies.create("org.powermock:powermock-api-mockito:$powerMockVersion") {
|
||||
exclude group: 'org.mockito', module: 'mockito-all'
|
||||
},
|
||||
"org.powermock:powermock-api-mockito:$powerMockVersion",
|
||||
"org.powermock:powermock-reflect:$powerMockVersion"
|
||||
]
|
||||
|
||||
ext.jstlDependencies = [
|
||||
"javax.servlet.jsp.jstl:javax.servlet.jsp.jstl-api:$jstlVersion",
|
||||
"org.apache.taglibs:taglibs-standard-jstlel:1.2.1"
|
||||
]
|
||||
|
||||
ext.apachedsDependencies = [
|
||||
ext.apacheds_libs = [
|
||||
"org.apache.directory.server:apacheds-core:$apacheDsVersion",
|
||||
"org.apache.directory.server:apacheds-core-entry:$apacheDsVersion",
|
||||
"org.apache.directory.server:apacheds-protocol-shared:$apacheDsVersion",
|
||||
@@ -72,6 +46,22 @@ ext.apachedsDependencies = [
|
||||
'org.apache.directory.shared:shared-ldap:0.9.15'
|
||||
]
|
||||
|
||||
ext.bundlorProperties = [
|
||||
version: version,
|
||||
secRange: "[$version, 3.3.0)",
|
||||
springRange: "[$springVersion, 3.3.0)",
|
||||
aspectjRange: '[1.6.0, 1.8.0)',
|
||||
casRange: '[3.1.1, 3.2.0)',
|
||||
cloggingRange: '[1.0.4, 2.0.0)',
|
||||
ehcacheRange: '[1.4.1, 2.5.0)',
|
||||
openid4javaRange: '[0.9.5, 1.0.0)',
|
||||
springLdapRange: '[1.3.0,1.4.0)',
|
||||
apacheDSRange: '[1.5.5, 1.6)',
|
||||
apacheDSSharedRange: '[0.9.15, 1.0)',
|
||||
ldapSdkRange: '[4.1, 5.0)',
|
||||
aopAllianceRange: '[1.0.0, 2.0.0)'
|
||||
]
|
||||
|
||||
// Integration test setup
|
||||
configurations {
|
||||
integrationTestCompile {
|
||||
@@ -85,7 +75,6 @@ configurations {
|
||||
sourceSets {
|
||||
integrationTest {
|
||||
java.srcDir file('src/integration-test/java')
|
||||
groovy.srcDirs file('src/integration-test/groovy')
|
||||
resources.srcDir file('src/integration-test/resources')
|
||||
compileClasspath = sourceSets.main.output + sourceSets.test.output + configurations.integrationTestCompile
|
||||
runtimeClasspath = output + compileClasspath + configurations.integrationTestRuntime
|
||||
@@ -97,10 +86,6 @@ task integrationTest(type: Test, dependsOn: jar) {
|
||||
logging.captureStandardOutput(LogLevel.INFO)
|
||||
classpath = sourceSets.integrationTest.runtimeClasspath
|
||||
maxParallelForks = 1
|
||||
reports {
|
||||
html.destination = project.file("$project.buildDir/reports/integration-tests/")
|
||||
junitXml.destination = project.file("$project.buildDir/integration-test-results/")
|
||||
}
|
||||
}
|
||||
project.conf2ScopeMappings.addMapping(MavenPlugin.TEST_COMPILE_PRIORITY + 1, project.configurations.getByName("integrationTestCompile"), Conf2ScopeMappingContainer.TEST)
|
||||
project.conf2ScopeMappings.addMapping(MavenPlugin.TEST_COMPILE_PRIORITY + 2, project.configurations.getByName("integrationTestRuntime"), Conf2ScopeMappingContainer.TEST)
|
||||
@@ -113,7 +98,7 @@ dependencies {
|
||||
exclude(group: 'commons-logging', module: 'commons-logging')
|
||||
}
|
||||
|
||||
testCompile 'junit:junit:4.11',
|
||||
testCompile 'junit:junit:4.10',
|
||||
'org.mockito:mockito-core:1.9.5',
|
||||
"org.springframework:spring-test:$springVersion",
|
||||
'org.easytesting:fest-assert:1.4'
|
||||
@@ -123,7 +108,7 @@ dependencies {
|
||||
"ch.qos.logback:logback-classic:$logbackVersion"
|
||||
}
|
||||
|
||||
[configurations.runtime, configurations.default, configurations.testCompile]*.exclude(module: 'commons-logging')
|
||||
[configurations.runtime, configurations.default]*.exclude(module: 'commons-logging')
|
||||
|
||||
configurations.all {
|
||||
resolutionStrategy.eachDependency { DependencyResolveDetails details ->
|
||||
@@ -135,8 +120,8 @@ configurations.all {
|
||||
|
||||
[compileJava, compileTestJava]*.options*.encoding = 'UTF-8'
|
||||
|
||||
project.tasks.matching { it instanceof Test && it.name != 'integrationTest' }.all {
|
||||
jvmArgs = ['-ea', '-Xmx500m', '-XX:MaxPermSize=256M']
|
||||
test {
|
||||
jvmArgs = ['-ea', '-Xmx500m', '-XX:MaxPermSize=128M']
|
||||
maxParallelForks = guessMaxForks()
|
||||
logging.captureStandardOutput(LogLevel.INFO)
|
||||
}
|
||||
@@ -214,11 +199,6 @@ project.eclipseClasspath.doFirst {
|
||||
}
|
||||
}
|
||||
|
||||
project.idea.module {
|
||||
scopes.TEST.plus += [project.configurations.integrationTestRuntime]
|
||||
testSourceDirs += sourceSets.integrationTest.resources.srcDirs
|
||||
}
|
||||
|
||||
task javadocJar(type: Jar) {
|
||||
classifier = 'javadoc'
|
||||
from javadoc
|
||||
|
||||
@@ -11,11 +11,7 @@ if(!snapshotBuild) {
|
||||
}
|
||||
|
||||
def verifyNoDependenciesMatchingVersion(def pattern) {
|
||||
def dependencies = configurations.all*.allDependencies*.findAll { d ->
|
||||
def ignored = 'io.spring.platform:platform-versions'
|
||||
def groupAndName = "$d.group:$d.name".toString()
|
||||
ignored != groupAndName && d.version?.matches(pattern)
|
||||
}.flatten().toSet().join("\n ")
|
||||
def dependencies = configurations.all*.allDependencies*.findAll { d -> d.version?.matches(pattern) }.flatten().toSet().join("\n ")
|
||||
if(dependencies) {
|
||||
throw new GradleException("${project.name} cannot have dependencies with a version that matches $pattern when its version is ${project.version}. Got\n $dependencies")
|
||||
}
|
||||
|
||||
+1
-58
@@ -1,67 +1,10 @@
|
||||
buildscript {
|
||||
repositories {
|
||||
maven { url "https://repo.spring.io/plugins-release" }
|
||||
}
|
||||
dependencies {
|
||||
classpath("org.gradle.api.plugins:gradle-tomcat-plugin:1.2.3")
|
||||
}
|
||||
}
|
||||
|
||||
apply plugin: 'tomcat'
|
||||
|
||||
dependencies {
|
||||
def tomcatVersion = '7.0.54'
|
||||
def tomcatVersion = '7.0.42'
|
||||
tomcat "org.apache.tomcat.embed:tomcat-embed-core:${tomcatVersion}",
|
||||
"org.apache.tomcat.embed:tomcat-embed-logging-juli:${tomcatVersion}"
|
||||
tomcat("org.apache.tomcat.embed:tomcat-embed-jasper:${tomcatVersion}") {
|
||||
exclude group: 'org.eclipse.jdt.core.compiler', module: 'ecj'
|
||||
}
|
||||
}
|
||||
|
||||
task integrationTomcatRun(type: org.gradle.api.plugins.tomcat.tasks.TomcatRun) {
|
||||
onlyIf { !sourceSets.integrationTest.allSource.empty }
|
||||
buildscriptClasspath = tomcatRun.buildscriptClasspath
|
||||
contextPath = tomcatRun.contextPath
|
||||
daemon = true
|
||||
tomcatClasspath = tomcatRun.tomcatClasspath
|
||||
webAppClasspath = tomcatRun.webAppClasspath
|
||||
webAppSourceDirectory = tomcatRun.webAppSourceDirectory
|
||||
doFirst {
|
||||
def mainOutputDir = project.sourceSets.main.output.classesDir
|
||||
if(mainOutputDir) {
|
||||
classesDirectory = mainOutputDir
|
||||
}
|
||||
// delay reserving ports to ensure they are still available
|
||||
def ports = reservePorts(3)
|
||||
httpPort = ports[0]
|
||||
ajpPort = ports[1]
|
||||
stopPort = ports[2]
|
||||
}
|
||||
}
|
||||
|
||||
task integrationTomcatStop(type: org.gradle.api.plugins.tomcat.tasks.TomcatStop) {
|
||||
onlyIf { !sourceSets.integrationTest.allSource.empty }
|
||||
doFirst {
|
||||
stopPort = integrationTomcatRun.stopPort
|
||||
}
|
||||
}
|
||||
|
||||
integrationTest {
|
||||
dependsOn integrationTomcatRun
|
||||
doFirst {
|
||||
def host = 'localhost:' + integrationTomcatRun.httpPort
|
||||
systemProperties['geb.build.baseUrl'] = 'http://'+host+'/' + integrationTomcatRun.contextPath + '/'
|
||||
systemProperties['geb.build.reportsDir'] = 'build/geb-reports'
|
||||
}
|
||||
finalizedBy integrationTomcatStop
|
||||
}
|
||||
|
||||
def reservePorts(int count) {
|
||||
def sockets = []
|
||||
for(int i in 1..count) {
|
||||
sockets << new ServerSocket(0)
|
||||
}
|
||||
def result = sockets*.localPort
|
||||
sockets*.close()
|
||||
result
|
||||
}
|
||||
Vendored
BIN
Binary file not shown.
+2
-2
@@ -1,6 +1,6 @@
|
||||
#Fri Jun 13 11:14:37 CDT 2014
|
||||
#Wed Dec 11 17:49:08 CST 2013
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=http\://services.gradle.org/distributions/gradle-1.12-all.zip
|
||||
distributionUrl=http\://services.gradle.org/distributions/gradle-1.10-rc-2-bin.zip
|
||||
|
||||
@@ -10,7 +10,7 @@ dependencies {
|
||||
"org.springframework:spring-beans:$springVersion"
|
||||
|
||||
testCompile project(':spring-security-web'),
|
||||
"javax.servlet:javax.servlet-api:$servletApiVersion",
|
||||
"org.apache.tomcat:tomcat-servlet-api:$servletApiVersion",
|
||||
"org.springframework:spring-web:$springVersion"
|
||||
testRuntime project(':spring-security-config'),
|
||||
"org.aspectj:aspectjweaver:$aspectjVersion"
|
||||
|
||||
+17
-23
@@ -4,7 +4,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>itest-context</artifactId>
|
||||
<version>4.0.0.M2</version>
|
||||
<version>3.2.3.RELEASE</version>
|
||||
<name>itest-context</name>
|
||||
<description>itest-context</description>
|
||||
<url>http://spring.io/spring-security</url>
|
||||
@@ -42,12 +42,6 @@
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>spring-milestone</id>
|
||||
<url>https://repo.spring.io/milestone</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>aopalliance</groupId>
|
||||
@@ -64,31 +58,31 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-core</artifactId>
|
||||
<version>4.0.0.M2</version>
|
||||
<version>3.2.3.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-aop</artifactId>
|
||||
<version>4.1.0.RC2</version>
|
||||
<version>3.2.8.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-beans</artifactId>
|
||||
<version>4.1.0.RC2</version>
|
||||
<version>3.2.8.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-context</artifactId>
|
||||
<version>4.1.0.RC2</version>
|
||||
<version>3.2.8.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-core</artifactId>
|
||||
<version>4.1.0.RC2</version>
|
||||
<version>3.2.8.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
@@ -100,7 +94,7 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-tx</artifactId>
|
||||
<version>4.1.0.RC2</version>
|
||||
<version>3.2.8.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@@ -117,15 +111,15 @@
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>javax.servlet-api</artifactId>
|
||||
<version>3.0.1</version>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.10</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.11</version>
|
||||
<groupId>org.apache.tomcat</groupId>
|
||||
<artifactId>tomcat-servlet-api</artifactId>
|
||||
<version>7.0.33</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@@ -155,25 +149,25 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-config</artifactId>
|
||||
<version>4.0.0.M2</version>
|
||||
<version>3.2.3.RELEASE</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-web</artifactId>
|
||||
<version>4.0.0.M2</version>
|
||||
<version>3.2.3.RELEASE</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-test</artifactId>
|
||||
<version>4.1.0.RC2</version>
|
||||
<version>3.2.8.RELEASE</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-web</artifactId>
|
||||
<version>4.1.0.RC2</version>
|
||||
<version>3.2.8.RELEASE</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
@@ -3,29 +3,22 @@ dependencies {
|
||||
compile "org.springframework:spring-context:$springVersion",
|
||||
"org.springframework:spring-web:$springVersion"
|
||||
|
||||
provided "javax.servlet:javax.servlet-api:$servletApiVersion"
|
||||
provided "org.apache.tomcat:tomcat-servlet-api:$servletApiVersion"
|
||||
|
||||
testCompile project(':spring-security-core'),
|
||||
project(':spring-security-web'),
|
||||
project(':spring-security-taglibs'),
|
||||
"org.springframework:spring-beans:$springVersion",
|
||||
"org.springframework:spring-webmvc:$springVersion",
|
||||
"org.mortbay.jetty:jetty:$jettyVersion",
|
||||
"org.mortbay.jetty:jetty-util:$jettyVersion",
|
||||
'net.sourceforge.jwebunit:jwebunit-core:2.2',
|
||||
"org.testng:testng:5.11:jdk15"
|
||||
testCompile ("org.mortbay.jetty:jetty:$jettyVersion") {
|
||||
exclude group: 'org.mortbay.jetty', module: 'servlet-api'
|
||||
}
|
||||
testCompile ('net.sourceforge.jwebunit:jwebunit-core:2.2') {
|
||||
exclude group: 'javax.servlet', module: 'servlet-api'
|
||||
exclude group: 'regexp', module: 'regexp'
|
||||
}
|
||||
|
||||
testRuntime project(':spring-security-config'),
|
||||
project(':spring-security-ldap'),
|
||||
"org.mortbay.jetty:jsp-2.1-jetty:$jettyVersion",
|
||||
testRuntime ('net.sourceforge.jwebunit:jwebunit-htmlunit-plugin:2.2') {
|
||||
exclude group: 'javax.servlet', module: 'servlet-api'
|
||||
}
|
||||
'net.sourceforge.jwebunit:jwebunit-htmlunit-plugin:2.2'
|
||||
}
|
||||
|
||||
integrationTest {
|
||||
|
||||
+16
-44
@@ -4,7 +4,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>itest-web</artifactId>
|
||||
<version>4.0.0.M2</version>
|
||||
<version>3.2.3.RELEASE</version>
|
||||
<name>itest-web</name>
|
||||
<description>itest-web</description>
|
||||
<url>http://spring.io/spring-security</url>
|
||||
@@ -42,23 +42,17 @@
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>spring-milestone</id>
|
||||
<url>https://repo.spring.io/milestone</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-context</artifactId>
|
||||
<version>4.1.0.RC2</version>
|
||||
<version>3.2.8.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-core</artifactId>
|
||||
<version>4.1.0.RC2</version>
|
||||
<version>3.2.8.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
@@ -70,7 +64,7 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-web</artifactId>
|
||||
<version>4.1.0.RC2</version>
|
||||
<version>3.2.8.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@@ -81,9 +75,9 @@
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>javax.servlet-api</artifactId>
|
||||
<version>3.0.1</version>
|
||||
<groupId>org.apache.tomcat</groupId>
|
||||
<artifactId>tomcat-servlet-api</artifactId>
|
||||
<version>7.0.33</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@@ -95,7 +89,7 @@
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.11</version>
|
||||
<version>4.10</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@@ -103,28 +97,12 @@
|
||||
<artifactId>jwebunit-core</artifactId>
|
||||
<version>2.2</version>
|
||||
<scope>test</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>regexp</artifactId>
|
||||
<groupId>regexp</groupId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<artifactId>servlet-api</artifactId>
|
||||
<groupId>javax.servlet</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.sourceforge.jwebunit</groupId>
|
||||
<artifactId>jwebunit-htmlunit-plugin</artifactId>
|
||||
<version>2.2</version>
|
||||
<scope>test</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>servlet-api</artifactId>
|
||||
<groupId>javax.servlet</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.easytesting</groupId>
|
||||
@@ -143,12 +121,6 @@
|
||||
<artifactId>jetty</artifactId>
|
||||
<version>6.1.26</version>
|
||||
<scope>test</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>servlet-api</artifactId>
|
||||
<groupId>org.mortbay.jetty</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mortbay.jetty</groupId>
|
||||
@@ -171,49 +143,49 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-config</artifactId>
|
||||
<version>4.0.0.M2</version>
|
||||
<version>3.2.3.RELEASE</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-core</artifactId>
|
||||
<version>4.0.0.M2</version>
|
||||
<version>3.2.3.RELEASE</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-ldap</artifactId>
|
||||
<version>4.0.0.M2</version>
|
||||
<version>3.2.3.RELEASE</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-taglibs</artifactId>
|
||||
<version>4.0.0.M2</version>
|
||||
<version>3.2.3.RELEASE</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-web</artifactId>
|
||||
<version>4.0.0.M2</version>
|
||||
<version>3.2.3.RELEASE</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-beans</artifactId>
|
||||
<version>4.1.0.RC2</version>
|
||||
<version>3.2.8.RELEASE</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-test</artifactId>
|
||||
<version>4.1.0.RC2</version>
|
||||
<version>3.2.8.RELEASE</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-webmvc</artifactId>
|
||||
<version>4.1.0.RC2</version>
|
||||
<version>3.2.8.RELEASE</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
||||
@@ -19,7 +19,6 @@ dependencies {
|
||||
exclude(group: 'org.springframework', module: 'spring-core')
|
||||
exclude(group: 'org.springframework', module: 'spring-tx')
|
||||
exclude(group: 'org.springframework', module: 'spring-beans')
|
||||
exclude(group: 'org.springframework.data', module: 'spring-data-commons')
|
||||
}
|
||||
|
||||
testCompile "org.slf4j:slf4j-api:$slf4jVersion",
|
||||
|
||||
+9
-19
@@ -4,7 +4,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-ldap</artifactId>
|
||||
<version>4.0.0.M2</version>
|
||||
<version>3.2.3.RELEASE</version>
|
||||
<name>spring-security-ldap</name>
|
||||
<description>spring-security-ldap</description>
|
||||
<url>http://spring.io/spring-security</url>
|
||||
@@ -42,17 +42,11 @@
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>spring-milestone</id>
|
||||
<url>https://repo.spring.io/milestone</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.ldap</groupId>
|
||||
<artifactId>spring-ldap-core</artifactId>
|
||||
<version>2.0.1.RELEASE</version>
|
||||
<version>1.3.2.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
@@ -63,10 +57,6 @@
|
||||
<artifactId>spring-core</artifactId>
|
||||
<groupId>org.springframework</groupId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<artifactId>spring-data-commons</artifactId>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<artifactId>commons-logging</artifactId>
|
||||
<groupId>commons-logging</groupId>
|
||||
@@ -80,25 +70,25 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-core</artifactId>
|
||||
<version>4.0.0.M2</version>
|
||||
<version>3.2.3.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-beans</artifactId>
|
||||
<version>4.1.0.RC2</version>
|
||||
<version>3.2.8.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-context</artifactId>
|
||||
<version>4.1.0.RC2</version>
|
||||
<version>3.2.8.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-core</artifactId>
|
||||
<version>4.1.0.RC2</version>
|
||||
<version>3.2.8.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
@@ -110,7 +100,7 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-tx</artifactId>
|
||||
<version>4.1.0.RC2</version>
|
||||
<version>3.2.8.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@@ -178,7 +168,7 @@
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.11</version>
|
||||
<version>4.10</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@@ -208,7 +198,7 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-test</artifactId>
|
||||
<version>4.1.0.RC2</version>
|
||||
<version>3.2.8.RELEASE</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
+1
-2
@@ -25,8 +25,7 @@ public abstract class AbstractLdapIntegrationTests {
|
||||
|
||||
@BeforeClass
|
||||
public static void createContextSource() throws Exception {
|
||||
int serverPort = ApacheDSServerIntegrationTests.getServerPort();
|
||||
contextSource = new DefaultSpringSecurityContextSource("ldap://127.0.0.1:" + serverPort + "/dc=springframework,dc=org");
|
||||
contextSource = new DefaultSpringSecurityContextSource("ldap://127.0.0.1:53389/dc=springframework,dc=org");
|
||||
// OpenLDAP configuration
|
||||
// contextSource = new DefaultSpringSecurityContextSource("ldap://127.0.0.1:22389/dc=springsource,dc=com");
|
||||
// contextSource.setUserDn("cn=admin,dc=springsource,dc=com");
|
||||
|
||||
+1
-28
@@ -1,8 +1,5 @@
|
||||
package org.springframework.security.ldap;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.ServerSocket;
|
||||
|
||||
import org.junit.*;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Suite;
|
||||
@@ -29,7 +26,6 @@ import org.springframework.security.ldap.userdetails.LdapUserDetailsManagerTests
|
||||
)
|
||||
public final class ApacheDSServerIntegrationTests {
|
||||
private static ApacheDSContainer server;
|
||||
private static Integer serverPort;
|
||||
|
||||
@BeforeClass
|
||||
public static void startServer() throws Exception {
|
||||
@@ -38,15 +34,12 @@ public final class ApacheDSServerIntegrationTests {
|
||||
// contextSource.setUserDn("cn=admin,dc=springsource,dc=com");
|
||||
// contextSource.setPassword("password");
|
||||
server = new ApacheDSContainer("dc=springframework,dc=org", "classpath:test-server.ldif");
|
||||
int port = getAvailablePort();
|
||||
server.setPort(port);
|
||||
server.setPort(53389);
|
||||
server.afterPropertiesSet();
|
||||
serverPort = port;
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void stopServer() throws Exception {
|
||||
serverPort = null;
|
||||
if (server != null) {
|
||||
server.stop();
|
||||
}
|
||||
@@ -60,12 +53,6 @@ public final class ApacheDSServerIntegrationTests {
|
||||
server.afterPropertiesSet();
|
||||
}
|
||||
|
||||
public static int getServerPort() {
|
||||
if(serverPort == null) {
|
||||
throw new IllegalStateException("The ApacheDSContainer is not currently running");
|
||||
}
|
||||
return serverPort;
|
||||
}
|
||||
/*
|
||||
@After
|
||||
public final void reloadServerDataIfDirty() throws Exception {
|
||||
@@ -118,18 +105,4 @@ public final class ApacheDSServerIntegrationTests {
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
private static int getAvailablePort() throws IOException {
|
||||
ServerSocket serverSocket = null;
|
||||
try {
|
||||
serverSocket = new ServerSocket(0);
|
||||
return serverSocket.getLocalPort();
|
||||
} finally {
|
||||
if(serverSocket != null) {
|
||||
try {
|
||||
serverSocket.close();
|
||||
} catch (IOException e) {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -71,7 +71,7 @@ public class DefaultSpringSecurityContextSourceTests extends AbstractLdapIntegra
|
||||
@Test
|
||||
public void serverUrlWithSpacesIsSupported() throws Exception {
|
||||
DefaultSpringSecurityContextSource
|
||||
contextSource = new DefaultSpringSecurityContextSource("ldap://127.0.0.1:" + ApacheDSServerIntegrationTests.getServerPort() + "/ou=space%20cadets,dc=springframework,dc=org");
|
||||
contextSource = new DefaultSpringSecurityContextSource("ldap://127.0.0.1:53389/ou=space%20cadets,dc=springframework,dc=org");
|
||||
contextSource.afterPropertiesSet();
|
||||
contextSource.getContext("uid=space cadet,ou=space cadets,dc=springframework,dc=org", "spacecadetspassword");
|
||||
}
|
||||
|
||||
+1
-66
@@ -17,8 +17,6 @@ package org.springframework.security.ldap;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.naming.Context;
|
||||
@@ -101,69 +99,6 @@ public class SpringSecurityLdapTemplateITests extends AbstractLdapIntegrationTes
|
||||
assertTrue(values.contains("submanager"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMultiAttributeRetrievalWithNullAttributeNames() {
|
||||
Set<Map<String, List<String>>> values =
|
||||
template.searchForMultipleAttributeValues(
|
||||
"ou=people",
|
||||
"(uid={0})",
|
||||
new String[]{"bob"},
|
||||
null);
|
||||
assertEquals(1, values.size());
|
||||
Map<String, List<String>> record = values.iterator().next();
|
||||
assertAttributeValue(record, "uid", "bob");
|
||||
assertAttributeValue(record, "objectclass", "top", "person", "organizationalPerson", "inetOrgPerson");
|
||||
assertAttributeValue(record, "cn", "Bob Hamilton");
|
||||
assertAttributeValue(record, "sn", "Hamilton");
|
||||
assertFalse(record.containsKey("userPassword"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMultiAttributeRetrievalWithZeroLengthAttributeNames() {
|
||||
Set<Map<String, List<String>>> values =
|
||||
template.searchForMultipleAttributeValues(
|
||||
"ou=people",
|
||||
"(uid={0})",
|
||||
new String[]{"bob"},
|
||||
new String[0]);
|
||||
assertEquals(1, values.size());
|
||||
Map<String, List<String>> record = values.iterator().next();
|
||||
assertAttributeValue(record, "uid", "bob");
|
||||
assertAttributeValue(record, "objectclass", "top", "person", "organizationalPerson", "inetOrgPerson");
|
||||
assertAttributeValue(record, "cn", "Bob Hamilton");
|
||||
assertAttributeValue(record, "sn", "Hamilton");
|
||||
assertFalse(record.containsKey("userPassword"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMultiAttributeRetrievalWithSpecifiedAttributeNames() {
|
||||
Set<Map<String, List<String>>> values =
|
||||
template.searchForMultipleAttributeValues(
|
||||
"ou=people",
|
||||
"(uid={0})",
|
||||
new String[]{"bob"},
|
||||
new String[]{
|
||||
"uid",
|
||||
"cn",
|
||||
"sn"
|
||||
});
|
||||
assertEquals(1, values.size());
|
||||
Map<String, List<String>> record = values.iterator().next();
|
||||
assertAttributeValue(record, "uid", "bob");
|
||||
assertAttributeValue(record, "cn", "Bob Hamilton");
|
||||
assertAttributeValue(record, "sn", "Hamilton");
|
||||
assertFalse(record.containsKey("userPassword"));
|
||||
assertFalse(record.containsKey("objectclass"));
|
||||
}
|
||||
|
||||
protected void assertAttributeValue(Map<String, List<String>> record, String attributeName, String... values) {
|
||||
assertTrue(record.containsKey(attributeName));
|
||||
assertEquals(values.length, record.get(attributeName).size());
|
||||
for (int i = 0; i < values.length; i++) {
|
||||
assertEquals(values[i], record.get(attributeName).get(i));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRoleSearchForMissingAttributeFailsGracefully() {
|
||||
String param = "uid=ben,ou=people,dc=springframework,dc=org";
|
||||
@@ -186,7 +121,7 @@ public class SpringSecurityLdapTemplateITests extends AbstractLdapIntegrationTes
|
||||
public void nonSpringLdapSearchCodeTestMethod() throws Exception {
|
||||
java.util.Hashtable<String, String> env = new java.util.Hashtable<String, String>();
|
||||
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
|
||||
env.put(Context.PROVIDER_URL, "ldap://localhost:" + ApacheDSServerIntegrationTests.getServerPort());
|
||||
env.put(Context.PROVIDER_URL, "ldap://localhost:53389");
|
||||
env.put(Context.SECURITY_PRINCIPAL, "");
|
||||
env.put(Context.SECURITY_CREDENTIALS, "");
|
||||
|
||||
|
||||
+1
-2
@@ -20,7 +20,6 @@ import org.junit.*;
|
||||
import org.springframework.security.authentication.BadCredentialsException;
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||
import org.springframework.security.authentication.encoding.LdapShaPasswordEncoder;
|
||||
import org.springframework.security.authentication.encoding.PasswordEncoder;
|
||||
import org.springframework.security.authentication.encoding.PlaintextPasswordEncoder;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
||||
@@ -113,7 +112,7 @@ public class PasswordComparisonAuthenticatorTests extends AbstractLdapIntegratio
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testPasswordEncoderCantBeNull() {
|
||||
authenticator.setPasswordEncoder((PasswordEncoder)null);
|
||||
authenticator.setPasswordEncoder(null);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
+10
-11
@@ -15,13 +15,12 @@
|
||||
|
||||
package org.springframework.security.ldap.search;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import javax.naming.ldap.LdapName;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.*;
|
||||
import org.springframework.dao.IncorrectResultSizeDataAccessException;
|
||||
import org.springframework.ldap.core.DirContextOperations;
|
||||
import org.springframework.ldap.core.DistinguishedName;
|
||||
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
||||
import org.springframework.security.ldap.AbstractLdapIntegrationTests;
|
||||
|
||||
@@ -33,7 +32,7 @@ import org.springframework.security.ldap.AbstractLdapIntegrationTests;
|
||||
public class FilterBasedLdapUserSearchTests extends AbstractLdapIntegrationTests {
|
||||
|
||||
@Test
|
||||
public void basicSearchSucceeds() throws Exception {
|
||||
public void basicSearchSucceeds() {
|
||||
FilterBasedLdapUserSearch locator = new FilterBasedLdapUserSearch("ou=people", "(uid={0})", getContextSource());
|
||||
locator.setSearchSubtree(false);
|
||||
locator.setSearchTimeLimit(0);
|
||||
@@ -42,25 +41,25 @@ public class FilterBasedLdapUserSearchTests extends AbstractLdapIntegrationTests
|
||||
DirContextOperations bob = locator.searchForUser("bob");
|
||||
assertEquals("bob", bob.getStringAttribute("uid"));
|
||||
|
||||
assertEquals(new LdapName("uid=bob,ou=people"), bob.getDn());
|
||||
assertEquals(new DistinguishedName("uid=bob,ou=people"), bob.getDn());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void searchForNameWithCommaSucceeds() throws Exception {
|
||||
public void searchForNameWithCommaSucceeds() {
|
||||
FilterBasedLdapUserSearch locator = new FilterBasedLdapUserSearch("ou=people", "(uid={0})", getContextSource());
|
||||
locator.setSearchSubtree(false);
|
||||
|
||||
DirContextOperations jerry = locator.searchForUser("jerry");
|
||||
assertEquals("jerry", jerry.getStringAttribute("uid"));
|
||||
|
||||
assertEquals(new LdapName("cn=mouse\\, jerry,ou=people"), jerry.getDn());
|
||||
assertEquals(new DistinguishedName("cn=mouse\\, jerry,ou=people"), jerry.getDn());
|
||||
}
|
||||
|
||||
// Try some funny business with filters.
|
||||
@Test
|
||||
public void extraFilterPartToExcludeBob() throws Exception {
|
||||
FilterBasedLdapUserSearch locator = new FilterBasedLdapUserSearch("ou=people",
|
||||
"(&(cn=*)(!(|(uid={0})(uid=rod)(uid=jerry)(uid=slashguy)(uid=javadude)(uid=groovydude)(uid=closuredude)(uid=scaladude))))", getContextSource());
|
||||
"(&(cn=*)(!(|(uid={0})(uid=rod)(uid=jerry)(uid=slashguy))))", getContextSource());
|
||||
|
||||
// Search for bob, get back ben...
|
||||
DirContextOperations ben = locator.searchForUser("bob");
|
||||
@@ -80,7 +79,7 @@ public class FilterBasedLdapUserSearchTests extends AbstractLdapIntegrationTests
|
||||
}
|
||||
|
||||
@Test
|
||||
public void subTreeSearchSucceeds() throws Exception {
|
||||
public void subTreeSearchSucceeds() {
|
||||
// Don't set the searchBase, so search from the root.
|
||||
FilterBasedLdapUserSearch locator = new FilterBasedLdapUserSearch("", "(cn={0})", getContextSource());
|
||||
locator.setSearchSubtree(true);
|
||||
@@ -88,7 +87,7 @@ public class FilterBasedLdapUserSearchTests extends AbstractLdapIntegrationTests
|
||||
DirContextOperations ben = locator.searchForUser("Ben Alex");
|
||||
assertEquals("ben", ben.getStringAttribute("uid"));
|
||||
|
||||
assertEquals(new LdapName("uid=ben,ou=people"), ben.getDn());
|
||||
assertEquals(new DistinguishedName("uid=ben,ou=people"), ben.getDn());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
+1
-29
@@ -17,11 +17,6 @@ package org.springframework.security.ldap.server;
|
||||
|
||||
import static junit.framework.Assert.fail;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.ServerSocket;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
@@ -37,10 +32,7 @@ public class ApacheDSContainerTests {
|
||||
@Test
|
||||
public void failsToStartThrowsException() throws Exception {
|
||||
ApacheDSContainer server1 = new ApacheDSContainer("dc=springframework,dc=org", "classpath:test-server.ldif");
|
||||
ApacheDSContainer server2 = new ApacheDSContainer("dc=springframework,dc=org", "classpath:missing.ldif");
|
||||
List<Integer> ports = getDefaultPorts(1);
|
||||
server1.setPort(ports.get(0));
|
||||
server2.setPort(ports.get(0));
|
||||
ApacheDSContainer server2 = new ApacheDSContainer("dc=springframework,dc=org", "classpath:test-server.ldif");
|
||||
try {
|
||||
server1.afterPropertiesSet();
|
||||
try {
|
||||
@@ -62,9 +54,6 @@ public class ApacheDSContainerTests {
|
||||
public void multipleInstancesSimultanciously() throws Exception {
|
||||
ApacheDSContainer server1 = new ApacheDSContainer("dc=springframework,dc=org", "classpath:test-server.ldif");
|
||||
ApacheDSContainer server2 = new ApacheDSContainer("dc=springframework,dc=org", "classpath:test-server.ldif");
|
||||
List<Integer> ports = getDefaultPorts(2);
|
||||
server1.setPort(ports.get(0));
|
||||
server2.setPort(ports.get(1));
|
||||
try {
|
||||
server1.afterPropertiesSet();
|
||||
server2.afterPropertiesSet();
|
||||
@@ -77,21 +66,4 @@ public class ApacheDSContainerTests {
|
||||
}catch(Throwable t) {}
|
||||
}
|
||||
}
|
||||
|
||||
private List<Integer> getDefaultPorts(int count) throws IOException {
|
||||
List<ServerSocket> connections = new ArrayList<ServerSocket>();
|
||||
List<Integer> availablePorts = new ArrayList<Integer>(count);
|
||||
try {
|
||||
for(int i=0;i<count;i++) {
|
||||
ServerSocket socket = new ServerSocket(0);
|
||||
connections.add(socket);
|
||||
availablePorts.add(socket.getLocalPort());
|
||||
}
|
||||
return availablePorts;
|
||||
} finally {
|
||||
for(ServerSocket conn : connections) {
|
||||
conn.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
-131
@@ -1,131 +0,0 @@
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.security.ldap.userdetails;
|
||||
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.ldap.core.DirContextAdapter;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.ldap.AbstractLdapIntegrationTests;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* @author Filip Hanik
|
||||
*/
|
||||
public class NestedLdapAuthoritiesPopulatorTests extends AbstractLdapIntegrationTests {
|
||||
|
||||
private NestedLdapAuthoritiesPopulator populator;
|
||||
private LdapAuthority javaDevelopers;
|
||||
private LdapAuthority groovyDevelopers;
|
||||
private LdapAuthority scalaDevelopers;
|
||||
private LdapAuthority closureDevelopers;
|
||||
private LdapAuthority jDevelopers;
|
||||
private LdapAuthority circularJavaDevelopers;
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
populator = new NestedLdapAuthoritiesPopulator(getContextSource(), "ou=jdeveloper");
|
||||
populator.setGroupSearchFilter("(member={0})");
|
||||
populator.setIgnorePartialResultException(false);
|
||||
populator.setRolePrefix("");
|
||||
populator.setSearchSubtree(true);
|
||||
populator.setConvertToUpperCase(false);
|
||||
jDevelopers = new LdapAuthority("j-developers", "cn=j-developers,ou=jdeveloper,dc=springframework,dc=org");
|
||||
javaDevelopers = new LdapAuthority("java-developers", "cn=java-developers,ou=jdeveloper,dc=springframework,dc=org");
|
||||
groovyDevelopers = new LdapAuthority("groovy-developers", "cn=groovy-developers,ou=jdeveloper,dc=springframework,dc=org");
|
||||
scalaDevelopers = new LdapAuthority("scala-developers", "cn=scala-developers,ou=jdeveloper,dc=springframework,dc=org");
|
||||
closureDevelopers = new LdapAuthority("closure-developers", "cn=closure-developers,ou=jdeveloper,dc=springframework,dc=org");
|
||||
circularJavaDevelopers = new LdapAuthority("circular-java-developers", "cn=circular-java-developers,ou=jdeveloper,dc=springframework,dc=org");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testScalaDudeJDevelopersAuthorities() {
|
||||
DirContextAdapter ctx = new DirContextAdapter("uid=scaladude,ou=people,dc=springframework,dc=org");
|
||||
Collection<GrantedAuthority> authorities = populator.getGrantedAuthorities(ctx, "scaladude");
|
||||
assertEquals(5, authorities.size());
|
||||
assertEquals(Arrays.asList(javaDevelopers, scalaDevelopers, circularJavaDevelopers, jDevelopers, groovyDevelopers), authorities);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testJavaDudeJDevelopersAuthorities() {
|
||||
DirContextAdapter ctx = new DirContextAdapter("uid=javadude,ou=people,dc=springframework,dc=org");
|
||||
Collection<GrantedAuthority> authorities = populator.getGrantedAuthorities(ctx, "javadude");
|
||||
assertEquals(3, authorities.size());
|
||||
assertEquals(Arrays.asList(javaDevelopers, circularJavaDevelopers, jDevelopers), authorities);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testScalaDudeJDevelopersAuthoritiesWithSearchLimit() {
|
||||
populator.setMaxSearchDepth(1);
|
||||
DirContextAdapter ctx = new DirContextAdapter("uid=scaladude,ou=people,dc=springframework,dc=org");
|
||||
Collection<GrantedAuthority> authorities = populator.getGrantedAuthorities(ctx, "scaladude");
|
||||
assertEquals(1, authorities.size());
|
||||
assertEquals(Arrays.asList(scalaDevelopers), authorities);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGroovyDudeJDevelopersAuthorities() {
|
||||
DirContextAdapter ctx = new DirContextAdapter("uid=groovydude,ou=people,dc=springframework,dc=org");
|
||||
Collection<GrantedAuthority> authorities = populator.getGrantedAuthorities(ctx, "groovydude");
|
||||
assertEquals(4, authorities.size());
|
||||
assertEquals(Arrays.asList(javaDevelopers, circularJavaDevelopers, jDevelopers, groovyDevelopers), authorities);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClosureDudeJDevelopersWithMembershipAsAttributeValues() {
|
||||
populator.setAttributeNames(new HashSet(Arrays.asList("member")));
|
||||
|
||||
DirContextAdapter ctx = new DirContextAdapter("uid=closuredude,ou=people,dc=springframework,dc=org");
|
||||
Collection<GrantedAuthority> authorities = populator.getGrantedAuthorities(ctx, "closuredude");
|
||||
assertEquals(5, authorities.size());
|
||||
assertEquals(Arrays.asList(closureDevelopers, javaDevelopers, circularJavaDevelopers, jDevelopers, groovyDevelopers), authorities);
|
||||
|
||||
LdapAuthority[] ldapAuthorities = authorities.toArray(new LdapAuthority[0]);
|
||||
assertEquals(5, ldapAuthorities.length);
|
||||
//closure group
|
||||
assertTrue(ldapAuthorities[0].getAttributes().containsKey("member"));
|
||||
assertNotNull(ldapAuthorities[0].getAttributes().get("member"));
|
||||
assertEquals(1, ldapAuthorities[0].getAttributes().get("member").size());
|
||||
assertEquals("uid=closuredude,ou=people,dc=springframework,dc=org", ldapAuthorities[0].getFirstAttributeValue("member"));
|
||||
|
||||
//java group
|
||||
assertTrue(ldapAuthorities[1].getAttributes().containsKey("member"));
|
||||
assertNotNull(ldapAuthorities[1].getAttributes().get("member"));
|
||||
assertEquals(3, ldapAuthorities[1].getAttributes().get("member").size());
|
||||
assertEquals(groovyDevelopers.getDn(), ldapAuthorities[1].getFirstAttributeValue("member"));
|
||||
assertEquals(
|
||||
new String[]{
|
||||
groovyDevelopers.getDn(),
|
||||
scalaDevelopers.getDn(),
|
||||
"uid=javadude,ou=people,dc=springframework,dc=org"
|
||||
},
|
||||
ldapAuthorities[1].getAttributes().get("member")
|
||||
);
|
||||
|
||||
//test non existent attribute
|
||||
assertNull(ldapAuthorities[2].getFirstAttributeValue("test"));
|
||||
assertNotNull(ldapAuthorities[2].getAttributeValues("test"));
|
||||
assertEquals(0, ldapAuthorities[2].getAttributeValues("test").size());
|
||||
//test role name
|
||||
assertEquals(jDevelopers.getAuthority(), ldapAuthorities[3].getAuthority());
|
||||
}
|
||||
}
|
||||
@@ -122,109 +122,3 @@ objectclass: groupOfNames
|
||||
cn: submanagers
|
||||
ou: submanager
|
||||
member: uid=ben,ou=people,dc=springframework,dc=org
|
||||
|
||||
#Nested groups data
|
||||
###################
|
||||
|
||||
dn: ou=jdeveloper,dc=springframework,dc=org
|
||||
objectclass: top
|
||||
objectclass: organizationalUnit
|
||||
ou: jdeveloper
|
||||
|
||||
|
||||
# javadude is part of (in a nested search)
|
||||
# circular-java-developers, java-developers, j-developers
|
||||
dn: uid=javadude,ou=people,dc=springframework,dc=org
|
||||
objectclass: top
|
||||
objectclass: person
|
||||
objectclass: organizationalPerson
|
||||
objectclass: inetOrgPerson
|
||||
cn: Java Dude
|
||||
sn: Dude
|
||||
uid: javadude
|
||||
userPassword: javadudespassword
|
||||
|
||||
# groovydude is part of (in a nested search)
|
||||
# groovy-developers, java-developers, circular-java-developers, j-developers
|
||||
dn: uid=groovydude,ou=people,dc=springframework,dc=org
|
||||
objectclass: top
|
||||
objectclass: person
|
||||
objectclass: organizationalPerson
|
||||
objectclass: inetOrgPerson
|
||||
cn: Groovy Dude
|
||||
sn: Dude
|
||||
uid: groovydude
|
||||
userPassword: groovydudespassword
|
||||
|
||||
# closuredude is part of (in a nested search)
|
||||
# closure-developers, groovy-developers, java-developers, circular-java-developers, j-developers
|
||||
dn: uid=closuredude,ou=people,dc=springframework,dc=org
|
||||
objectclass: top
|
||||
objectclass: person
|
||||
objectclass: organizationalPerson
|
||||
objectclass: inetOrgPerson
|
||||
cn: Closure Dude
|
||||
sn: Dude
|
||||
uid: closuredude
|
||||
userPassword: closuredudespassword
|
||||
|
||||
# scaladude is part of (in a nested search)
|
||||
# scala-developers, groovy-developers, java-developers, circular-java-developers, j-developers
|
||||
dn: uid=scaladude,ou=people,dc=springframework,dc=org
|
||||
objectclass: top
|
||||
objectclass: person
|
||||
objectclass: organizationalPerson
|
||||
objectclass: inetOrgPerson
|
||||
cn: Scala Dude
|
||||
sn: Dude
|
||||
uid: scaladude
|
||||
userPassword: scaladudespassword
|
||||
|
||||
dn: cn=j-developers,ou=jdeveloper,dc=springframework,dc=org
|
||||
objectclass: top
|
||||
objectclass: groupOfNames
|
||||
cn: j-developers
|
||||
ou: jdeveloper
|
||||
member: cn=java-developers,ou=jdeveloper,dc=springframework,dc=org
|
||||
|
||||
dn: cn=java-developers,ou=jdeveloper,dc=springframework,dc=org
|
||||
objectclass: top
|
||||
objectclass: groupOfNames
|
||||
cn: java-developers
|
||||
ou: jdeveloper
|
||||
member: cn=groovy-developers,ou=jdeveloper,dc=springframework,dc=org
|
||||
member: cn=scala-developers,ou=jdeveloper,dc=springframework,dc=org
|
||||
member: uid=javadude,ou=people,dc=springframework,dc=org
|
||||
|
||||
dn: cn=circular-java-developers,ou=jdeveloper,dc=springframework,dc=org
|
||||
objectclass: top
|
||||
objectclass: groupOfNames
|
||||
cn: circular-java-developers
|
||||
ou: jdeveloper
|
||||
member: cn=groovy-developers,ou=jdeveloper,dc=springframework,dc=org
|
||||
member: cn=scala-developers,ou=jdeveloper,dc=springframework,dc=org
|
||||
member: uid=javadude,ou=people,dc=springframework,dc=org
|
||||
|
||||
|
||||
dn: cn=groovy-developers,ou=jdeveloper,dc=springframework,dc=org
|
||||
objectclass: top
|
||||
objectclass: groupOfNames
|
||||
cn: groovy-developers
|
||||
ou: jdeveloper
|
||||
member: cn=closure-developers,ou=jdeveloper,dc=springframework,dc=org
|
||||
member: uid=groovydude,ou=people,dc=springframework,dc=org
|
||||
member: cn=circular-java-developers,ou=jdeveloper,dc=springframework,dc=org
|
||||
|
||||
dn: cn=closure-developers,ou=jdeveloper,dc=springframework,dc=org
|
||||
objectclass: top
|
||||
objectclass: groupOfNames
|
||||
cn: closure-developers
|
||||
ou: jdeveloper
|
||||
member: uid=closuredude,ou=people,dc=springframework,dc=org
|
||||
|
||||
dn: cn=scala-developers,ou=jdeveloper,dc=springframework,dc=org
|
||||
objectclass: top
|
||||
objectclass: groupOfNames
|
||||
cn: scala-developers
|
||||
ou: jdeveloper
|
||||
member: uid=scaladude,ou=people,dc=springframework,dc=org
|
||||
|
||||
+7
-104
@@ -30,18 +30,13 @@ import org.springframework.util.Assert;
|
||||
import javax.naming.NamingEnumeration;
|
||||
import javax.naming.NamingException;
|
||||
import javax.naming.PartialResultException;
|
||||
import javax.naming.directory.Attribute;
|
||||
import javax.naming.directory.Attributes;
|
||||
import javax.naming.directory.DirContext;
|
||||
import javax.naming.directory.SearchControls;
|
||||
import javax.naming.directory.SearchResult;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
|
||||
@@ -50,7 +45,6 @@ import java.util.Set;
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @author Luke Taylor
|
||||
* @author Filip Hanik
|
||||
* @since 2.0
|
||||
*/
|
||||
public class SpringSecurityLdapTemplate extends LdapTemplate {
|
||||
@@ -58,13 +52,6 @@ public class SpringSecurityLdapTemplate extends LdapTemplate {
|
||||
private static final Log logger = LogFactory.getLog(SpringSecurityLdapTemplate.class);
|
||||
|
||||
public static final String[] NO_ATTRS = new String[0];
|
||||
|
||||
/**
|
||||
* Every search results where a record is defined by a Map<String,String[]>
|
||||
* contains at least this key - the DN of the record itself.
|
||||
*/
|
||||
public static final String DN_KEY = "spring.security.ldap.dn";
|
||||
|
||||
private static final boolean RETURN_OBJECT = true;
|
||||
|
||||
//~ Instance fields ================================================================================================
|
||||
@@ -152,124 +139,40 @@ public class SpringSecurityLdapTemplate extends LdapTemplate {
|
||||
*/
|
||||
public Set<String> searchForSingleAttributeValues(final String base, final String filter, final Object[] params,
|
||||
final String attributeName) {
|
||||
String[] attributeNames = new String[]{attributeName};
|
||||
Set<Map<String, List<String>>> multipleAttributeValues = searchForMultipleAttributeValues(base, filter, params, attributeNames);
|
||||
Set<String> result = new HashSet<String>();
|
||||
for (Map<String, List<String>> map : multipleAttributeValues) {
|
||||
List<String> values = map.get(attributeName);
|
||||
if (values != null) {
|
||||
result.addAll(values);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs a search using the supplied filter and returns the values of each named attribute
|
||||
* found in all entries matched by the search. Note that one directory entry may have several values for the
|
||||
* attribute. Intended for role searches and similar scenarios.
|
||||
*
|
||||
* @param base the DN to search in
|
||||
* @param filter search filter to use
|
||||
* @param params the parameters to substitute in the search filter
|
||||
* @param attributeNames the attributes' values that are to be retrieved.
|
||||
*
|
||||
* @return the set of String values for each attribute found in all the matching entries.
|
||||
* The attribute name is the key for each set of values. In addition each map contains the DN as a String
|
||||
* with the key predefined key {@link #DN_KEY}.
|
||||
*/
|
||||
public Set<Map<String, List<String>>> searchForMultipleAttributeValues(final String base, final String filter, final Object[] params,
|
||||
final String[] attributeNames) {
|
||||
// Escape the params acording to RFC2254
|
||||
Object[] encodedParams = new String[params.length];
|
||||
|
||||
for (int i = 0; i < params.length; i++) {
|
||||
for (int i=0; i < params.length; i++) {
|
||||
encodedParams[i] = LdapEncoder.filterEncode(params[i].toString());
|
||||
}
|
||||
|
||||
String formattedFilter = MessageFormat.format(filter, encodedParams);
|
||||
logger.debug("Using filter: " + formattedFilter);
|
||||
|
||||
final HashSet<Map<String, List<String>>> set = new HashSet<Map<String, List<String>>>();
|
||||
final HashSet<String> set = new HashSet<String>();
|
||||
|
||||
ContextMapper roleMapper = new ContextMapper() {
|
||||
public Object mapFromContext(Object ctx) {
|
||||
DirContextAdapter adapter = (DirContextAdapter) ctx;
|
||||
Map<String, List<String>> record = new HashMap<String, List<String>>();
|
||||
if (attributeNames == null || attributeNames.length == 0) {
|
||||
try {
|
||||
for (NamingEnumeration ae = adapter.getAttributes().getAll(); ae.hasMore(); ) {
|
||||
Attribute attr = (Attribute) ae.next();
|
||||
extractStringAttributeValues(adapter, record, attr.getID());
|
||||
}
|
||||
} catch (NamingException x) {
|
||||
org.springframework.ldap.support.LdapUtils.convertLdapException(x);
|
||||
}
|
||||
String[] values = adapter.getStringAttributes(attributeName);
|
||||
if (values == null || values.length == 0) {
|
||||
logger.debug("No attribute value found for '" + attributeName + "'");
|
||||
} else {
|
||||
for (String attributeName : attributeNames) {
|
||||
extractStringAttributeValues(adapter, record, attributeName);
|
||||
}
|
||||
set.addAll(Arrays.asList(values));
|
||||
}
|
||||
record.put(DN_KEY, Arrays.asList(getAdapterDN(adapter)));
|
||||
set.add(record);
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
SearchControls ctls = new SearchControls();
|
||||
ctls.setSearchScope(searchControls.getSearchScope());
|
||||
ctls.setReturningAttributes(attributeNames != null && attributeNames.length > 0 ? attributeNames : null);
|
||||
ctls.setReturningAttributes(new String[] {attributeName});
|
||||
|
||||
search(base, formattedFilter, ctls, roleMapper);
|
||||
|
||||
return set;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the DN for the context representing this LDAP record.
|
||||
* By default this is using {@link javax.naming.Context#getNameInNamespace()}
|
||||
* instead of {@link org.springframework.ldap.core.DirContextAdapter#getDn()} since the
|
||||
* latter returns a partial DN if a base has been specified.
|
||||
* @param adapter - the Context to extract the DN from
|
||||
* @return - the String representing the full DN
|
||||
*/
|
||||
private String getAdapterDN(DirContextAdapter adapter) {
|
||||
//returns the full DN rather than the sub DN if a base is specified
|
||||
return adapter.getNameInNamespace();
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts String values for a specified attribute name and places them in the map representing the ldap record If
|
||||
* a value is not of type String, it will derive it's value from the {@link Object#toString()}
|
||||
*
|
||||
* @param adapter - the adapter that contains the values
|
||||
* @param record - the map holding the attribute names and values
|
||||
* @param attributeName - the name for which to fetch the values from
|
||||
*/
|
||||
private void extractStringAttributeValues(DirContextAdapter adapter, Map<String, List<String>> record, String attributeName) {
|
||||
Object[] values = adapter.getObjectAttributes(attributeName);
|
||||
if (values == null || values.length == 0) {
|
||||
if(logger.isDebugEnabled()) {
|
||||
logger.debug("No attribute value found for '" + attributeName + "'");
|
||||
}
|
||||
return;
|
||||
}
|
||||
List<String> svalues = new ArrayList<String>();
|
||||
for (Object o : values) {
|
||||
if (o != null) {
|
||||
if (String.class.isAssignableFrom(o.getClass())) {
|
||||
svalues.add((String) o);
|
||||
} else {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Attribute:" + attributeName + " contains a non string value of type[" + o.getClass() + "]");
|
||||
}
|
||||
svalues.add(o.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
record.put(attributeName, svalues);
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs a search, with the requirement that the search shall return a single directory entry, and uses
|
||||
* the supplied mapper to create the object from that entry.
|
||||
|
||||
+8
-52
@@ -18,7 +18,6 @@ package org.springframework.security.ldap.authentication;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.ldap.NameNotFoundException;
|
||||
import org.springframework.ldap.NamingException;
|
||||
import org.springframework.ldap.core.DirContextOperations;
|
||||
import org.springframework.ldap.core.support.BaseLdapPathContextSource;
|
||||
import org.springframework.security.authentication.BadCredentialsException;
|
||||
@@ -53,7 +52,6 @@ public final class PasswordComparisonAuthenticator extends AbstractLdapAuthentic
|
||||
|
||||
private PasswordEncoder passwordEncoder = new LdapShaPasswordEncoder();
|
||||
private String passwordAttributeName = "userPassword";
|
||||
private boolean usePasswordAttrCompare = false;
|
||||
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
@@ -97,25 +95,15 @@ public final class PasswordComparisonAuthenticator extends AbstractLdapAuthentic
|
||||
user.getDn() +"'");
|
||||
}
|
||||
|
||||
if (usePasswordAttrCompare && isPasswordAttrCompare(user, password)) {
|
||||
return user;
|
||||
} else if(isLdapPasswordCompare(user, ldapTemplate, password)) {
|
||||
return user;
|
||||
}
|
||||
throw new BadCredentialsException(messages.getMessage("PasswordComparisonAuthenticator.badCredentials",
|
||||
"Bad credentials"));
|
||||
}
|
||||
|
||||
private boolean isPasswordAttrCompare(DirContextOperations user, String password) {
|
||||
Object passwordAttrValue = user.getObjectAttribute(passwordAttributeName);
|
||||
return passwordEncoder.isPasswordValid(new String((byte[])passwordAttrValue), password, null);
|
||||
}
|
||||
|
||||
private boolean isLdapPasswordCompare(DirContextOperations user,
|
||||
SpringSecurityLdapTemplate ldapTemplate, String password) {
|
||||
String encodedPassword = passwordEncoder.encodePassword(password, null);
|
||||
byte[] passwordBytes = Utf8.encode(encodedPassword);
|
||||
return ldapTemplate.compare(user.getDn().toString(), passwordAttributeName, passwordBytes);
|
||||
|
||||
if (!ldapTemplate.compare(user.getDn().toString(), passwordAttributeName, passwordBytes)) {
|
||||
throw new BadCredentialsException(messages.getMessage("PasswordComparisonAuthenticator.badCredentials",
|
||||
"Bad credentials"));
|
||||
}
|
||||
|
||||
return user;
|
||||
}
|
||||
|
||||
public void setPasswordAttributeName(String passwordAttribute) {
|
||||
@@ -123,40 +111,8 @@ public final class PasswordComparisonAuthenticator extends AbstractLdapAuthentic
|
||||
this.passwordAttributeName = passwordAttribute;
|
||||
}
|
||||
|
||||
private void setPasswordEncoder(PasswordEncoder passwordEncoder) {
|
||||
public void setPasswordEncoder(PasswordEncoder passwordEncoder) {
|
||||
Assert.notNull(passwordEncoder, "passwordEncoder must not be null.");
|
||||
this.passwordEncoder = passwordEncoder;
|
||||
}
|
||||
|
||||
public void setPasswordEncoder(Object passwordEncoder) {
|
||||
if (passwordEncoder instanceof PasswordEncoder) {
|
||||
this.usePasswordAttrCompare = false;
|
||||
setPasswordEncoder((PasswordEncoder) passwordEncoder);
|
||||
return;
|
||||
}
|
||||
|
||||
if (passwordEncoder instanceof org.springframework.security.crypto.password.PasswordEncoder) {
|
||||
final org.springframework.security.crypto.password.PasswordEncoder delegate =
|
||||
(org.springframework.security.crypto.password.PasswordEncoder)passwordEncoder;
|
||||
setPasswordEncoder(new PasswordEncoder() {
|
||||
public String encodePassword(String rawPass, Object salt) {
|
||||
checkSalt(salt);
|
||||
return delegate.encode(rawPass);
|
||||
}
|
||||
|
||||
public boolean isPasswordValid(String encPass, String rawPass, Object salt) {
|
||||
checkSalt(salt);
|
||||
return delegate.matches(rawPass, encPass);
|
||||
}
|
||||
|
||||
private void checkSalt(Object salt) {
|
||||
Assert.isNull(salt, "Salt value must be null when used with crypto module PasswordEncoder");
|
||||
}
|
||||
});
|
||||
this.usePasswordAttrCompare = true;
|
||||
return;
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("passwordEncoder must be a PasswordEncoder instance");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,6 @@ package org.springframework.security.ldap.server;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
@@ -127,7 +126,6 @@ public class ApacheDSContainer implements InitializingBean, DisposableBean, Life
|
||||
|
||||
server = new LdapServer();
|
||||
server.setDirectoryService(service);
|
||||
// AbstractLdapIntegrationTests assume IPv4, so we specify the same here
|
||||
server.setTransports(new TcpTransport(port));
|
||||
start();
|
||||
}
|
||||
@@ -206,7 +204,7 @@ public class ApacheDSContainer implements InitializingBean, DisposableBean, Life
|
||||
try {
|
||||
importLdifs();
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Failed to import LDIF file(s)", e);
|
||||
logger.error("Failed to import LDIF file(s)", e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -264,7 +262,7 @@ public class ApacheDSContainer implements InitializingBean, DisposableBean, Life
|
||||
LdifFileLoader loader = new LdifFileLoader(service.getAdminSession(), ldifFile);
|
||||
loader.execute();
|
||||
} else {
|
||||
throw new IllegalArgumentException("More than one LDIF resource found with the supplied pattern:" + ldifResources+ " Got " + Arrays.toString(ldifs));
|
||||
throw new IllegalArgumentException("More than one LDIF resource found with the supplied pattern:" + ldifResources);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+5
-84
@@ -92,7 +92,6 @@ import java.util.Set;
|
||||
* a search of the entire subtree under <tt>groupSearchBase</tt>.
|
||||
*
|
||||
* @author Luke Taylor
|
||||
* @author Filip Hanik
|
||||
*/
|
||||
public class DefaultLdapAuthoritiesPopulator implements LdapAuthoritiesPopulator {
|
||||
//~ Static fields/initializers =====================================================================================
|
||||
@@ -106,9 +105,6 @@ public class DefaultLdapAuthoritiesPopulator implements LdapAuthoritiesPopulator
|
||||
*/
|
||||
private GrantedAuthority defaultRole;
|
||||
|
||||
/**
|
||||
* Template that will be used for searching
|
||||
*/
|
||||
private final SpringSecurityLdapTemplate ldapTemplate;
|
||||
|
||||
/**
|
||||
@@ -131,13 +127,7 @@ public class DefaultLdapAuthoritiesPopulator implements LdapAuthoritiesPopulator
|
||||
* The pattern to be used for the user search. {0} is the user's DN
|
||||
*/
|
||||
private String groupSearchFilter = "(member={0})";
|
||||
/**
|
||||
* The role prefix that will be prepended to each role name
|
||||
*/
|
||||
private String rolePrefix = "ROLE_";
|
||||
/**
|
||||
* Should we convert the role name to uppercase
|
||||
*/
|
||||
private boolean convertToUpperCase = true;
|
||||
|
||||
//~ Constructors ===================================================================================================
|
||||
@@ -153,7 +143,7 @@ public class DefaultLdapAuthoritiesPopulator implements LdapAuthoritiesPopulator
|
||||
public DefaultLdapAuthoritiesPopulator(ContextSource contextSource, String groupSearchBase) {
|
||||
Assert.notNull(contextSource, "contextSource must not be null");
|
||||
ldapTemplate = new SpringSecurityLdapTemplate(contextSource);
|
||||
getLdapTemplate().setSearchControls(getSearchControls());
|
||||
ldapTemplate.setSearchControls(searchControls);
|
||||
this.groupSearchBase = groupSearchBase;
|
||||
|
||||
if (groupSearchBase == null) {
|
||||
@@ -222,8 +212,8 @@ public class DefaultLdapAuthoritiesPopulator implements LdapAuthoritiesPopulator
|
||||
+ groupSearchFilter + " in search base '" + getGroupSearchBase() + "'");
|
||||
}
|
||||
|
||||
Set<String> userRoles = getLdapTemplate().searchForSingleAttributeValues(getGroupSearchBase(), groupSearchFilter,
|
||||
new String[]{userDn, username}, groupRoleAttribute);
|
||||
Set<String> userRoles = ldapTemplate.searchForSingleAttributeValues(getGroupSearchBase(), groupSearchFilter,
|
||||
new String[]{userDn, username}, groupRoleAttribute);
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Roles from search: " + userRoles);
|
||||
@@ -242,7 +232,7 @@ public class DefaultLdapAuthoritiesPopulator implements LdapAuthoritiesPopulator
|
||||
}
|
||||
|
||||
protected ContextSource getContextSource() {
|
||||
return getLdapTemplate().getContextSource();
|
||||
return ldapTemplate.getContextSource();
|
||||
}
|
||||
|
||||
protected String getGroupSearchBase() {
|
||||
@@ -307,75 +297,6 @@ public class DefaultLdapAuthoritiesPopulator implements LdapAuthoritiesPopulator
|
||||
* @see LdapTemplate#setIgnoreNameNotFoundException(boolean)
|
||||
*/
|
||||
public void setIgnorePartialResultException(boolean ignore) {
|
||||
getLdapTemplate().setIgnorePartialResultException(ignore);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current LDAP template.
|
||||
* Method available so that classes extending this can override the template used
|
||||
* @return the LDAP template
|
||||
* @see {@link org.springframework.security.ldap.SpringSecurityLdapTemplate}
|
||||
*/
|
||||
protected SpringSecurityLdapTemplate getLdapTemplate() {
|
||||
return ldapTemplate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the attribute name of the LDAP attribute that will be mapped to the role name
|
||||
* Method available so that classes extending this can override
|
||||
* @return the attribute name used for role mapping
|
||||
* @see {@link #setGroupRoleAttribute(String)}
|
||||
*/
|
||||
protected final String getGroupRoleAttribute() {
|
||||
return groupRoleAttribute;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the search filter configured for this populator
|
||||
* Method available so that classes extending this can override
|
||||
* @return the search filter
|
||||
* @see {@link #setGroupSearchFilter(String)}
|
||||
*/
|
||||
protected final String getGroupSearchFilter() {
|
||||
return groupSearchFilter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the role prefix used by this populator
|
||||
* Method available so that classes extending this can override
|
||||
* @return the role prefix
|
||||
* @see {@link #setRolePrefix(String)}
|
||||
*/
|
||||
protected final String getRolePrefix() {
|
||||
return rolePrefix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if role names are converted to uppercase
|
||||
* Method available so that classes extending this can override
|
||||
* @return true if role names are converted to uppercase.
|
||||
* @see {@link #setConvertToUpperCase(boolean)}
|
||||
*/
|
||||
protected final boolean isConvertToUpperCase() {
|
||||
return convertToUpperCase;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the default role
|
||||
* Method available so that classes extending this can override
|
||||
* @return the default role used
|
||||
* @see {@link #setDefaultRole(String)}
|
||||
*/
|
||||
private GrantedAuthority getDefaultRole() {
|
||||
return defaultRole;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the search controls
|
||||
* Method available so that classes extending this can override the search controls used
|
||||
* @return the search controls
|
||||
*/
|
||||
private SearchControls getSearchControls() {
|
||||
return searchControls;
|
||||
ldapTemplate.setIgnorePartialResultException(ignore);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,156 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.security.ldap.userdetails;
|
||||
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* An authority that contains at least a DN and a role name for an LDAP entry but can also contain other desired
|
||||
* attributes to be fetched during an LDAP authority search.
|
||||
*
|
||||
* @author Filip Hanik
|
||||
*/
|
||||
public class LdapAuthority implements GrantedAuthority {
|
||||
|
||||
|
||||
private String dn;
|
||||
private String role;
|
||||
private Map<String, List<String>> attributes;
|
||||
|
||||
/**
|
||||
* Constructs an LdapAuthority that has a role and a DN but no other attributes
|
||||
*
|
||||
* @param role
|
||||
* @param dn
|
||||
*/
|
||||
public LdapAuthority(String role, String dn) {
|
||||
this(role, dn, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an LdapAuthority with the given role, DN and other LDAP attributes
|
||||
*
|
||||
* @param role
|
||||
* @param dn
|
||||
* @param attributes
|
||||
*/
|
||||
public LdapAuthority(String role, String dn, Map<String, List<String>> attributes) {
|
||||
Assert.notNull(role, "role can not be null");
|
||||
Assert.notNull(dn, "dn can not be null");
|
||||
|
||||
this.role = role;
|
||||
this.dn = dn;
|
||||
this.attributes = attributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the LDAP attributes
|
||||
*
|
||||
* @return the LDAP attributes, map can be null
|
||||
*/
|
||||
public Map<String, List<String>> getAttributes() {
|
||||
return attributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the DN for this LDAP authority
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getDn() {
|
||||
return dn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the values for a specific attribute
|
||||
*
|
||||
* @param name the attribute name
|
||||
* @return a String array, never null but may be zero length
|
||||
*/
|
||||
public List<String> getAttributeValues(String name) {
|
||||
List<String> result = null;
|
||||
if (attributes != null) {
|
||||
result = attributes.get(name);
|
||||
}
|
||||
if (result == null) {
|
||||
result = Collections.emptyList();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the first attribute value for a specified attribute
|
||||
*
|
||||
* @param name
|
||||
* @return the first attribute value for a specified attribute, may be null
|
||||
*/
|
||||
public String getFirstAttributeValue(String name) {
|
||||
List<String> result = getAttributeValues(name);
|
||||
if (result.isEmpty()) {
|
||||
return null;
|
||||
} else {
|
||||
return result.get(0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public String getAuthority() {
|
||||
return role;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares the LdapAuthority based on {@link #getAuthority()} and {@link #getDn()} values {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (!(o instanceof LdapAuthority)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
LdapAuthority that = (LdapAuthority) o;
|
||||
|
||||
if (!dn.equals(that.dn)) {
|
||||
return false;
|
||||
}
|
||||
return role.equals(that.role);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = dn.hashCode();
|
||||
result = 31 * result + (role != null ? role.hashCode() : 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "LdapAuthority{" +
|
||||
"dn='" + dn + '\'' +
|
||||
", role='" + role + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
-258
@@ -1,258 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.security.ldap.userdetails;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.ldap.core.ContextSource;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.ldap.SpringSecurityLdapTemplate;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* A LDAP authority populator that can recursively search static nested groups. <p>An example of nested groups can be
|
||||
* <pre>
|
||||
* #Nested groups data
|
||||
*
|
||||
* dn: uid=javadude,ou=people,dc=springframework,dc=org
|
||||
* objectclass: top
|
||||
* objectclass: person
|
||||
* objectclass: organizationalPerson
|
||||
* objectclass: inetOrgPerson
|
||||
* cn: Java Dude
|
||||
* sn: Dude
|
||||
* uid: javadude
|
||||
* userPassword: javadudespassword
|
||||
*
|
||||
* dn: uid=groovydude,ou=people,dc=springframework,dc=org
|
||||
* objectclass: top
|
||||
* objectclass: person
|
||||
* objectclass: organizationalPerson
|
||||
* objectclass: inetOrgPerson
|
||||
* cn: Groovy Dude
|
||||
* sn: Dude
|
||||
* uid: groovydude
|
||||
* userPassword: groovydudespassword
|
||||
*
|
||||
* dn: uid=closuredude,ou=people,dc=springframework,dc=org
|
||||
* objectclass: top
|
||||
* objectclass: person
|
||||
* objectclass: organizationalPerson
|
||||
* objectclass: inetOrgPerson
|
||||
* cn: Closure Dude
|
||||
* sn: Dude
|
||||
* uid: closuredude
|
||||
* userPassword: closuredudespassword
|
||||
*
|
||||
* dn: uid=scaladude,ou=people,dc=springframework,dc=org
|
||||
* objectclass: top
|
||||
* objectclass: person
|
||||
* objectclass: organizationalPerson
|
||||
* objectclass: inetOrgPerson
|
||||
* cn: Scala Dude
|
||||
* sn: Dude
|
||||
* uid: scaladude
|
||||
* userPassword: scaladudespassword
|
||||
*
|
||||
* dn: cn=j-developers,ou=jdeveloper,dc=springframework,dc=org
|
||||
* objectclass: top
|
||||
* objectclass: groupOfNames
|
||||
* cn: j-developers
|
||||
* ou: jdeveloper
|
||||
* member: cn=java-developers,ou=groups,dc=springframework,dc=org
|
||||
*
|
||||
* dn: cn=java-developers,ou=jdeveloper,dc=springframework,dc=org
|
||||
* objectclass: top
|
||||
* objectclass: groupOfNames
|
||||
* cn: java-developers
|
||||
* ou: jdeveloper
|
||||
* member: cn=groovy-developers,ou=groups,dc=springframework,dc=org
|
||||
* member: cn=scala-developers,ou=groups,dc=springframework,dc=org
|
||||
* member: uid=javadude,ou=people,dc=springframework,dc=org
|
||||
*
|
||||
* dn: cn=groovy-developers,ou=jdeveloper,dc=springframework,dc=org
|
||||
* objectclass: top
|
||||
* objectclass: groupOfNames
|
||||
* cn: java-developers
|
||||
* ou: jdeveloper
|
||||
* member: cn=closure-developers,ou=groups,dc=springframework,dc=org
|
||||
* member: uid=groovydude,ou=people,dc=springframework,dc=org
|
||||
*
|
||||
* dn: cn=closure-developers,ou=jdeveloper,dc=springframework,dc=org
|
||||
* objectclass: top
|
||||
* objectclass: groupOfNames
|
||||
* cn: java-developers
|
||||
* ou: jdeveloper
|
||||
* member: uid=closuredude,ou=people,dc=springframework,dc=org
|
||||
*
|
||||
* dn: cn=scala-developers,ou=jdeveloper,dc=springframework,dc=org
|
||||
* objectclass: top
|
||||
* objectclass: groupOfNames
|
||||
* cn: java-developers
|
||||
* ou: jdeveloper
|
||||
* member: uid=scaladude,ou=people,dc=springframework,dc=org * </pre>
|
||||
* </pre>
|
||||
* </p>
|
||||
*
|
||||
* @author Filip Hanik
|
||||
*/
|
||||
|
||||
public class NestedLdapAuthoritiesPopulator extends DefaultLdapAuthoritiesPopulator {
|
||||
private static final Log logger = LogFactory.getLog(NestedLdapAuthoritiesPopulator.class);
|
||||
|
||||
/**
|
||||
* The attribute names to retrieve for each LDAP group
|
||||
*/
|
||||
private Set<String> attributeNames;
|
||||
|
||||
/**
|
||||
* Maximum search depth - represents the number of recursive searches performed
|
||||
*/
|
||||
private int maxSearchDepth = 10;
|
||||
|
||||
/**
|
||||
* Constructor for group search scenarios. <tt>userRoleAttributes</tt> may still be set as a property.
|
||||
*
|
||||
* @param contextSource supplies the contexts used to search for user roles.
|
||||
* @param groupSearchBase if this is an empty string the search will be performed from the root DN of the
|
||||
*/
|
||||
public NestedLdapAuthoritiesPopulator(ContextSource contextSource, String groupSearchBase) {
|
||||
super(contextSource, groupSearchBase);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Set<GrantedAuthority> getGroupMembershipRoles(String userDn, String username) {
|
||||
if (getGroupSearchBase() == null) {
|
||||
return new HashSet<GrantedAuthority>();
|
||||
}
|
||||
|
||||
Set<GrantedAuthority> authorities = new HashSet<GrantedAuthority>();
|
||||
|
||||
performNestedSearch(userDn, username, authorities, getMaxSearchDepth());
|
||||
|
||||
return authorities;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs the nested group search
|
||||
*
|
||||
* @param userDn - the userDN to search for, will become the group DN for subsequent searches
|
||||
* @param username - the username of the user
|
||||
* @param authorities - the authorities set that will be populated, must not be null
|
||||
* @param depth - the depth remaining, when 0 recursion will end
|
||||
*/
|
||||
private void performNestedSearch(String userDn, String username, Set<GrantedAuthority> authorities, int depth) {
|
||||
if (depth == 0) {
|
||||
//back out of recursion
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Search aborted, max depth reached," +
|
||||
" for roles for user '" + username + "', DN = " + "'" + userDn + "', with filter "
|
||||
+ getGroupSearchFilter() + " in search base '" + getGroupSearchBase() + "'");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Searching for roles for user '" + username + "', DN = " + "'" + userDn + "', with filter "
|
||||
+ getGroupSearchFilter() + " in search base '" + getGroupSearchBase() + "'");
|
||||
}
|
||||
|
||||
if (getAttributeNames() == null) {
|
||||
setAttributeNames(new HashSet<String>());
|
||||
}
|
||||
if (StringUtils.hasText(getGroupRoleAttribute()) && !getAttributeNames().contains(getGroupRoleAttribute())) {
|
||||
getAttributeNames().add(getGroupRoleAttribute());
|
||||
}
|
||||
|
||||
Set<Map<String, List<String>>> userRoles = getLdapTemplate().searchForMultipleAttributeValues(
|
||||
getGroupSearchBase(),
|
||||
getGroupSearchFilter(),
|
||||
new String[]{userDn, username},
|
||||
getAttributeNames().toArray(new String[getAttributeNames().size()]));
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Roles from search: " + userRoles);
|
||||
}
|
||||
|
||||
for (Map<String, List<String>> record : userRoles) {
|
||||
boolean circular = false;
|
||||
String dn = record.get(SpringSecurityLdapTemplate.DN_KEY).get(0);
|
||||
List<String> roleValues = record.get(getGroupRoleAttribute());
|
||||
Set<String> roles = new HashSet<String>();
|
||||
if(roleValues != null) {
|
||||
roles.addAll(roleValues);
|
||||
}
|
||||
for (String role : roles) {
|
||||
if (isConvertToUpperCase()) {
|
||||
role = role.toUpperCase();
|
||||
}
|
||||
role = getRolePrefix() + role;
|
||||
//if the group already exist, we will not search for it's parents again.
|
||||
//this prevents a forever loop for a misconfigured ldap directory
|
||||
circular = circular | (!authorities.add(new LdapAuthority(role, dn, record)));
|
||||
}
|
||||
String roleName = roles.size() > 0 ? roles.iterator().next() : dn;
|
||||
if (!circular) {
|
||||
performNestedSearch(dn, roleName, authorities, (depth - 1));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the attribute names that this populator has been configured to retrieve Value can be null, represents
|
||||
* fetch all attributes
|
||||
*
|
||||
* @return the attribute names or null for all
|
||||
*/
|
||||
private Set<String> getAttributeNames() {
|
||||
return attributeNames;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the attribute names to retrieve for each ldap groups. Null means retrieve all
|
||||
*
|
||||
* @param attributeNames - the names of the LDAP attributes to retrieve
|
||||
*/
|
||||
public void setAttributeNames(Set<String> attributeNames) {
|
||||
this.attributeNames = attributeNames;
|
||||
}
|
||||
|
||||
/**
|
||||
* How far should a nested search go. Depth is calculated in the number of levels we search up for parent groups.
|
||||
*
|
||||
* @return the max search depth, default is 10
|
||||
*/
|
||||
private int getMaxSearchDepth() {
|
||||
return maxSearchDepth;
|
||||
}
|
||||
|
||||
/**
|
||||
* How far should a nested search go. Depth is calculated in the number of levels we search up for parent groups.
|
||||
*
|
||||
* @param maxSearchDepth the max search depth
|
||||
*/
|
||||
public void setMaxSearchDepth(int maxSearchDepth) {
|
||||
this.maxSearchDepth = maxSearchDepth;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
-54
@@ -1,54 +0,0 @@
|
||||
package org.springframework.security.ldap.userdetails;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.security.ldap.SpringSecurityLdapTemplate;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
||||
/**
|
||||
* @author Filip Hanik
|
||||
*/
|
||||
public class LdapAuthorityTests {
|
||||
|
||||
public static final String DN = "cn=filip,ou=Users,dc=test,dc=com";
|
||||
LdapAuthority authority;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
Map<String, List<String>> attributes = new HashMap<String, List<String>>();
|
||||
attributes.put(SpringSecurityLdapTemplate.DN_KEY, Arrays.asList(DN));
|
||||
attributes.put("mail", Arrays.asList("filip@ldap.test.org", "filip@ldap.test2.org"));
|
||||
authority = new LdapAuthority("testRole", DN, attributes);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetDn() throws Exception {
|
||||
assertEquals(DN, authority.getDn());
|
||||
assertNotNull(authority.getAttributeValues(SpringSecurityLdapTemplate.DN_KEY));
|
||||
assertEquals(1, authority.getAttributeValues(SpringSecurityLdapTemplate.DN_KEY).size());
|
||||
assertEquals(DN, authority.getFirstAttributeValue(SpringSecurityLdapTemplate.DN_KEY));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetAttributes() throws Exception {
|
||||
assertNotNull(authority.getAttributes());
|
||||
assertNotNull(authority.getAttributeValues("mail"));
|
||||
assertEquals(2, authority.getAttributeValues("mail").size());
|
||||
assertEquals("filip@ldap.test.org", authority.getFirstAttributeValue("mail"));
|
||||
assertEquals("filip@ldap.test.org", authority.getAttributeValues("mail").get(0));
|
||||
assertEquals("filip@ldap.test2.org", authority.getAttributeValues("mail").get(1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetAuthority() throws Exception {
|
||||
assertNotNull(authority.getAuthority());
|
||||
assertEquals("testRole", authority.getAuthority());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
Implementation-Title: org.springframework.security.ldap
|
||||
Implementation-Version: ${version}
|
||||
Bundle-SymbolicName: org.springframework.security.ldap
|
||||
Bundle-Name: Spring Security LDAP
|
||||
Bundle-Vendor: SpringSource
|
||||
Bundle-Version: ${version}
|
||||
Bundle-ManifestVersion: 2
|
||||
Ignored-Existing-Headers:
|
||||
Import-Package,
|
||||
Export-Package
|
||||
Import-Template:
|
||||
org.apache.commons.logging.*;version="${cloggingRange}",
|
||||
org.apache.directory.server.*;version="${apacheDSRange}";resolution:=optional,
|
||||
org.apache.directory.shared.ldap.*;version="${apacheDSSharedRange}";resolution:=optional,
|
||||
org.springframework.ldap.*;version="${springLdapRange}",
|
||||
org.springframework.security.core.*;version="${secRange}",
|
||||
org.springframework.security.crypto.*;version="${secRange}",
|
||||
org.springframework.security.authentication.*;version="${secRange}",
|
||||
org.springframework.security.provisioning.*;version="${secRange}",
|
||||
org.springframework.security.util;version="${secRange}",
|
||||
org.springframework.beans.*;version="${springRange}",
|
||||
org.springframework.context.*;version="${springRange}",
|
||||
org.springframework.core.io.*;version="${springRange}",
|
||||
org.springframework.dao.*;version="${springRange}";resolution:=optional,
|
||||
org.springframework.util.*;version="${springRange}",
|
||||
javax.naming.*;version="0";resolution:=optional,
|
||||
netscape.ldap.ber.stream;version="${ldapSdkRange}";resolution:=optional
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user