Compare commits
67 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| d1669b909f | |||
| cb8041ba67 | |||
| 6f74162a1f | |||
| 99a0baadfa | |||
| 1f9a0e579f | |||
| 9e7d08c9e7 | |||
| 82168faf9d | |||
| 9d0f8977a9 | |||
| 5ae615f3b4 | |||
| d2b0077392 | |||
| 092c5aecf7 | |||
| a5d56d8724 | |||
| 7c0da854da | |||
| 0f546dcb07 | |||
| cb576d16e1 | |||
| 3b4df40f47 | |||
| 6cbf71bd72 | |||
| cd63329b63 | |||
| cc7f504f96 | |||
| a094563052 | |||
| da19435f21 | |||
| be50cd8ada | |||
| 21efbb6ba7 | |||
| c7cf6fdd73 | |||
| 8129bf2ce0 | |||
| d48079eb19 | |||
| 45f1179b52 | |||
| e11dfa7578 | |||
| 6cc0f6c054 | |||
| 22ea835643 | |||
| 9f51d68e92 | |||
| 32af1884f7 | |||
| a88035196a | |||
| 0db94b1d36 | |||
| 9e8994a2b7 | |||
| 8b2faff7ad | |||
| 469bc20e6d | |||
| 947d11f433 | |||
| b3a60a83f6 | |||
| 5bc7e4171c | |||
| 80e96b0f7b | |||
| 8a458eb9e1 | |||
| d2524eadfc | |||
| db08be05ee | |||
| 081f0c4d94 | |||
| 247f54dc41 | |||
| 017e9834bd | |||
| 49719480a8 | |||
| f3edaa673a | |||
| f99fe36e02 | |||
| 546d44d6e7 | |||
| 901a4e183a | |||
| 72d08a2a5f | |||
| 2ac51c9c7f | |||
| b64cdb5765 | |||
| aa31f1f695 | |||
| 8353984733 | |||
| c31bdb6390 | |||
| 168f4b8f70 | |||
| 9c03571bbb | |||
| 4c79107e01 | |||
| 3f543d0fbd | |||
| 08104eb06c | |||
| b54d350e54 | |||
| b5e0886bde | |||
| 38492a5794 | |||
| b7541d56d0 |
+3
-1
@@ -20,4 +20,6 @@ build/
|
||||
.gradle/
|
||||
atlassian-ide-plugin.xml
|
||||
!etc/eclipse/.checkstyle
|
||||
.checkstyle
|
||||
.checkstyle
|
||||
classes/
|
||||
s101plugin.state
|
||||
|
||||
+2
-2
@@ -29,9 +29,9 @@ In the instructions below, http://vimeo.com/34436402[`./gradlew`] is invoked fro
|
||||
a cross-platform, self-contained bootstrap mechanism for the build.
|
||||
|
||||
=== Prerequisites
|
||||
http://help.github.com/set-up-git-redirect[Git] and the http://www.oracle.com/technetwork/java/javase/downloads[JDK7 build].
|
||||
http://help.github.com/set-up-git-redirect[Git] and the http://www.oracle.com/technetwork/java/javase/downloads[JDK8 build].
|
||||
|
||||
Be sure that your `JAVA_HOME` environment variable points to the `jdk1.7.0` folder extracted from the JDK download.
|
||||
Be sure that your `JAVA_HOME` environment variable points to the `jdk1.8.0` folder extracted from the JDK download.
|
||||
|
||||
=== Check out sources
|
||||
[indent=0]
|
||||
|
||||
+5
-5
@@ -3,7 +3,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-acl</artifactId>
|
||||
<version>4.2.1.RELEASE</version>
|
||||
<version>4.2.4.RELEASE</version>
|
||||
<name>spring-security-acl</name>
|
||||
<description>spring-security-acl</description>
|
||||
<url>http://spring.io/spring-security</url>
|
||||
@@ -35,7 +35,7 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-framework-bom</artifactId>
|
||||
<version>4.3.5.RELEASE</version>
|
||||
<version>4.3.12.RELEASE</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
@@ -51,7 +51,7 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-core</artifactId>
|
||||
<version>4.2.1.RELEASE</version>
|
||||
<version>4.2.4.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@@ -95,7 +95,7 @@
|
||||
<dependency>
|
||||
<groupId>net.sf.ehcache</groupId>
|
||||
<artifactId>ehcache</artifactId>
|
||||
<version>2.9.0</version>
|
||||
<version>2.10.4</version>
|
||||
<scope>compile</scope>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
@@ -132,7 +132,7 @@
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>jcl-over-slf4j</artifactId>
|
||||
<version>1.7.7</version>
|
||||
<version>1.7.25</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
||||
+6
-5
@@ -26,6 +26,8 @@ import org.springframework.security.acls.model.Acl;
|
||||
import org.springframework.security.acls.model.AclService;
|
||||
import org.springframework.security.acls.model.ObjectIdentity;
|
||||
import org.springframework.security.acls.model.ObjectIdentityRetrievalStrategy;
|
||||
import org.springframework.security.acls.model.Permission;
|
||||
import org.springframework.security.acls.model.Sid;
|
||||
import org.springframework.security.acls.model.SidRetrievalStrategy;
|
||||
import org.springframework.security.core.Authentication;
|
||||
|
||||
@@ -37,7 +39,6 @@ import org.springframework.security.core.Authentication;
|
||||
public class AclPermissionEvaluatorTests {
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void hasPermissionReturnsTrueIfAclGrantsPermission() throws Exception {
|
||||
AclService service = mock(AclService.class);
|
||||
AclPermissionEvaluator pe = new AclPermissionEvaluator(service);
|
||||
@@ -48,8 +49,8 @@ public class AclPermissionEvaluatorTests {
|
||||
pe.setSidRetrievalStrategy(mock(SidRetrievalStrategy.class));
|
||||
Acl acl = mock(Acl.class);
|
||||
|
||||
when(service.readAclById(any(ObjectIdentity.class), anyList())).thenReturn(acl);
|
||||
when(acl.isGranted(anyList(), anyList(), eq(false))).thenReturn(true);
|
||||
when(service.readAclById(any(ObjectIdentity.class), anyListOf(Sid.class))).thenReturn(acl);
|
||||
when(acl.isGranted(anyListOf(Permission.class), anyListOf(Sid.class), eq(false))).thenReturn(true);
|
||||
|
||||
assertThat(pe.hasPermission(mock(Authentication.class), new Object(), "READ")).isTrue();
|
||||
}
|
||||
@@ -68,8 +69,8 @@ public class AclPermissionEvaluatorTests {
|
||||
pe.setSidRetrievalStrategy(mock(SidRetrievalStrategy.class));
|
||||
Acl acl = mock(Acl.class);
|
||||
|
||||
when(service.readAclById(any(ObjectIdentity.class), anyList())).thenReturn(acl);
|
||||
when(acl.isGranted(anyList(), anyList(), eq(false))).thenReturn(true);
|
||||
when(service.readAclById(any(ObjectIdentity.class), anyListOf(Sid.class))).thenReturn(acl);
|
||||
when(acl.isGranted(anyListOf(Permission.class), anyListOf(Sid.class), eq(false))).thenReturn(true);
|
||||
|
||||
assertThat(pe.hasPermission(mock(Authentication.class), new Object(), "write")).isTrue();
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2017 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.
|
||||
@@ -61,14 +61,14 @@ public class AuditLoggerTests {
|
||||
public void nonAuditableAceIsIgnored() {
|
||||
AccessControlEntry ace = mock(AccessControlEntry.class);
|
||||
logger.logIfNeeded(true, ace);
|
||||
assertThat(bytes.size()).isEqualTo(0);
|
||||
assertThat(bytes.size()).isZero();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void successIsNotLoggedIfAceDoesntRequireSuccessAudit() throws Exception {
|
||||
when(ace.isAuditSuccess()).thenReturn(false);
|
||||
logger.logIfNeeded(true, ace);
|
||||
assertThat(bytes.size()).isEqualTo(0);
|
||||
assertThat(bytes.size()).isZero();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -76,20 +76,20 @@ public class AuditLoggerTests {
|
||||
when(ace.isAuditSuccess()).thenReturn(true);
|
||||
|
||||
logger.logIfNeeded(true, ace);
|
||||
assertThat(bytes.toString().startsWith("GRANTED due to ACE")).isTrue();
|
||||
assertThat(bytes.toString()).startsWith("GRANTED due to ACE");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void failureIsntLoggedIfAceDoesntRequireFailureAudit() throws Exception {
|
||||
when(ace.isAuditFailure()).thenReturn(false);
|
||||
logger.logIfNeeded(false, ace);
|
||||
assertThat(bytes.size()).isEqualTo(0);
|
||||
assertThat(bytes.size()).isZero();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void failureIsLoggedIfAceRequiresFailureAudit() throws Exception {
|
||||
when(ace.isAuditFailure()).thenReturn(true);
|
||||
logger.logIfNeeded(false, ace);
|
||||
assertThat(bytes.toString().startsWith("DENIED due to ACE")).isTrue();
|
||||
assertThat(bytes.toString()).startsWith("DENIED due to ACE");
|
||||
}
|
||||
}
|
||||
|
||||
+6
-6
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2017 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.
|
||||
@@ -137,9 +137,9 @@ public class ObjectIdentityImplTests {
|
||||
|
||||
String string = "SOME_STRING";
|
||||
assertThat(string).isNotSameAs(obj);
|
||||
assertThat(obj.equals(null)).isFalse();
|
||||
assertThat(obj.equals("DIFFERENT_OBJECT_TYPE")).isFalse();
|
||||
assertThat(obj.equals(new ObjectIdentityImpl(DOMAIN_CLASS, Long.valueOf(2)))).isFalse();
|
||||
assertThat(obj).isNotNull();
|
||||
assertThat(obj).isNotEqualTo("DIFFERENT_OBJECT_TYPE");
|
||||
assertThat(obj).isNotEqualTo(new ObjectIdentityImpl(DOMAIN_CLASS, Long.valueOf(2)));
|
||||
assertThat(obj).isNotEqualTo(new ObjectIdentityImpl(
|
||||
"org.springframework.security.acls.domain.ObjectIdentityImplTests$MockOtherIdDomainObject",
|
||||
Long.valueOf(1)));
|
||||
@@ -151,7 +151,7 @@ public class ObjectIdentityImplTests {
|
||||
public void hashcodeIsDifferentForDifferentJavaTypes() throws Exception {
|
||||
ObjectIdentity obj = new ObjectIdentityImpl(Object.class, Long.valueOf(1));
|
||||
ObjectIdentity obj2 = new ObjectIdentityImpl(String.class, Long.valueOf(1));
|
||||
assertThat(obj.hashCode() == obj2.hashCode()).isFalse();
|
||||
assertThat(obj.hashCode()).isNotEqualTo(obj2.hashCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -175,7 +175,7 @@ public class ObjectIdentityImplTests {
|
||||
public void stringAndNumericIdsAreNotEqual() throws Exception {
|
||||
ObjectIdentity obj = new ObjectIdentityImpl(Object.class, "1000");
|
||||
ObjectIdentity obj2 = new ObjectIdentityImpl(Object.class, Long.valueOf(1000));
|
||||
assertThat(obj.equals(obj2)).isFalse();
|
||||
assertThat(obj).isNotEqualTo(obj2);
|
||||
}
|
||||
|
||||
// ~ Inner Classes
|
||||
|
||||
+4
-4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2017 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.
|
||||
@@ -104,17 +104,17 @@ public class SpringCacheBasedAclCacheTests {
|
||||
// Try to evict an entry that doesn't exist
|
||||
myCache.evictFromCache(Long.valueOf(3));
|
||||
myCache.evictFromCache(new ObjectIdentityImpl(TARGET_CLASS, Long.valueOf(102)));
|
||||
assertThat(4).isEqualTo(realCache.size());
|
||||
assertThat(realCache).hasSize(4);
|
||||
|
||||
myCache.evictFromCache(Long.valueOf(1));
|
||||
assertThat(2).isEqualTo(realCache.size());
|
||||
assertThat(realCache).hasSize(2);
|
||||
|
||||
// Check the second object inserted
|
||||
assertThat(acl2).isEqualTo(myCache.getFromCache(Long.valueOf(2)));
|
||||
assertThat(acl2).isEqualTo(myCache.getFromCache(identity2));
|
||||
|
||||
myCache.evictFromCache(identity2);
|
||||
assertThat(0).isEqualTo(realCache.size());
|
||||
assertThat(realCache).isEmpty();
|
||||
}
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
|
||||
+5
-5
@@ -3,7 +3,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-aspects</artifactId>
|
||||
<version>4.2.1.RELEASE</version>
|
||||
<version>4.2.4.RELEASE</version>
|
||||
<name>spring-security-aspects</name>
|
||||
<description>spring-security-aspects</description>
|
||||
<url>http://spring.io/spring-security</url>
|
||||
@@ -35,7 +35,7 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-framework-bom</artifactId>
|
||||
<version>4.3.5.RELEASE</version>
|
||||
<version>4.3.12.RELEASE</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
@@ -45,7 +45,7 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-core</artifactId>
|
||||
<version>4.2.1.RELEASE</version>
|
||||
<version>4.2.4.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@@ -79,7 +79,7 @@
|
||||
<dependency>
|
||||
<groupId>org.aspectj</groupId>
|
||||
<artifactId>aspectjrt</artifactId>
|
||||
<version>1.8.4</version>
|
||||
<version>1.8.12</version>
|
||||
<scope>compile</scope>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
@@ -116,7 +116,7 @@
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>jcl-over-slf4j</artifactId>
|
||||
<version>1.7.7</version>
|
||||
<version>1.7.25</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
||||
+12
-6
@@ -1,15 +1,16 @@
|
||||
buildscript {
|
||||
repositories {
|
||||
maven { url "https://repo.spring.io/plugins-release" }
|
||||
maven { url "https://repo.spring.io/plugins-snapshot" }
|
||||
}
|
||||
dependencies {
|
||||
classpath("org.springframework.build.gradle:propdeps-plugin:0.0.7")
|
||||
classpath("io.spring.gradle:spring-io-plugin:0.0.5.RELEASE")
|
||||
classpath("io.spring.gradle:spring-io-plugin:0.0.6.RELEASE")
|
||||
classpath("com.bmuschko:gradle-tomcat-plugin:2.2.4")
|
||||
classpath('me.champeau.gradle:gradle-javadoc-hotfix-plugin:0.1')
|
||||
classpath('org.asciidoctor:asciidoctor-gradle-plugin:1.5.1')
|
||||
classpath("io.spring.gradle:docbook-reference-plugin:0.3.1")
|
||||
classpath("org.springframework.boot:spring-boot-gradle-plugin:1.4.0.RELEASE")
|
||||
classpath("org.springframework.boot:spring-boot-gradle-plugin:1.5.0.BUILD-SNAPSHOT")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,8 +28,8 @@ allprojects {
|
||||
|
||||
ext.releaseBuild = version.endsWith('RELEASE')
|
||||
ext.snapshotBuild = version.endsWith('SNAPSHOT')
|
||||
ext.springVersion = '4.3.5.RELEASE'
|
||||
ext.springLdapVersion = '2.2.0.RELEASE'
|
||||
ext.springVersion = '4.3.12.RELEASE'
|
||||
ext.springLdapVersion = '2.3.2.RELEASE'
|
||||
|
||||
group = 'org.springframework.security'
|
||||
|
||||
@@ -105,7 +106,7 @@ configure(coreModuleProjects) {
|
||||
apply plugin: 'emma'
|
||||
apply plugin: 'spring-io'
|
||||
|
||||
ext.springIoVersion = project.hasProperty('platformVersion') ? platformVersion : 'Athens-BUILD-SNAPSHOT'
|
||||
ext.springIoVersion = project.hasProperty('platformVersion') ? platformVersion : 'Brussels-SR1'
|
||||
|
||||
configurations {
|
||||
jacoco //Configuration Group used by Sonar to provide Code Coverage using JaCoCo
|
||||
@@ -114,7 +115,12 @@ configure(coreModuleProjects) {
|
||||
dependencyManagement {
|
||||
springIoTestRuntime {
|
||||
imports {
|
||||
mavenBom "io.spring.platform:platform-bom:${springIoVersion}"
|
||||
mavenBom("io.spring.platform:platform-bom:${springIoVersion}") {
|
||||
bomProperties([
|
||||
'assertj.version': '2.2.0',
|
||||
'mockito.version': '1.10.19'
|
||||
])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,12 +4,13 @@ import org.gradle.api.Project
|
||||
import org.gradle.api.Plugin
|
||||
import org.gradle.api.tasks.TaskAction
|
||||
import org.gradle.api.logging.LogLevel
|
||||
import org.gradle.api.file.FileCollection
|
||||
import org.gradle.api.file.*
|
||||
import org.gradle.api.tasks.SourceSet
|
||||
import org.gradle.api.DefaultTask
|
||||
import org.gradle.api.GradleException
|
||||
|
||||
import org.gradle.api.plugins.JavaPlugin
|
||||
import org.gradle.api.tasks.compile.JavaCompile
|
||||
import org.gradle.plugins.ide.eclipse.GenerateEclipseProject
|
||||
import org.gradle.plugins.ide.eclipse.GenerateEclipseClasspath
|
||||
import org.gradle.plugins.ide.eclipse.EclipsePlugin
|
||||
@@ -41,28 +42,25 @@ class AspectJPlugin implements Plugin<Project> {
|
||||
project.configurations.create('aspectpath')
|
||||
}
|
||||
|
||||
project.tasks.create(name: 'compileAspect', overwrite: true, description: 'Compiles AspectJ Source', type: Ajc) {
|
||||
dependsOn project.configurations*.getTaskDependencyFromProjectDependency(true, "compileJava")
|
||||
project.tasks.withType(JavaCompile) { javaCompileTask ->
|
||||
def javaCompileTaskName = javaCompileTask.name
|
||||
def ajCompileTask = project.tasks.create(name: javaCompileTaskName + 'Aspect', overwrite: true, description: 'Compiles AspectJ Source', type: Ajc) {
|
||||
inputs.files(javaCompileTask.inputs.files)
|
||||
inputs.properties(javaCompileTask.inputs.properties)
|
||||
|
||||
sourceRoots.addAll(project.sourceSets.main.java.srcDirs)
|
||||
if(javaCompileTaskName.contains("Test")) {
|
||||
sourceRoots.addAll(project.sourceSets.test.java.srcDirs)
|
||||
}
|
||||
compileClasspath = javaCompileTask.classpath
|
||||
destinationDir = javaCompileTask.destinationDir
|
||||
aspectPath = project.configurations.aspectpath
|
||||
}
|
||||
|
||||
javaCompileTask.deleteAllActions()
|
||||
javaCompileTask.dependsOn ajCompileTask
|
||||
|
||||
dependsOn project.processResources
|
||||
sourceSet = project.sourceSets.main
|
||||
inputs.files(sourceSet.allSource)
|
||||
outputs.dir(sourceSet.output.classesDir)
|
||||
aspectPath = project.configurations.aspectpath
|
||||
}
|
||||
project.tasks.compileJava.deleteAllActions()
|
||||
project.tasks.compileJava.dependsOn project.tasks.compileAspect
|
||||
|
||||
|
||||
project.tasks.create(name: 'compileTestAspect', overwrite: true, description: 'Compiles AspectJ Test Source', type: Ajc) {
|
||||
dependsOn project.processTestResources, project.compileJava, project.jar
|
||||
sourceSet = project.sourceSets.test
|
||||
inputs.files(sourceSet.allSource)
|
||||
outputs.dir(sourceSet.output.classesDir)
|
||||
aspectPath = project.files(project.configurations.aspectpath, project.jar.archivePath)
|
||||
}
|
||||
project.tasks.compileTestJava.deleteAllActions()
|
||||
project.tasks.compileTestJava.dependsOn project.tasks.compileTestAspect
|
||||
|
||||
project.tasks.withType(GenerateEclipseProject) {
|
||||
project.eclipse.project.file.whenMerged { p ->
|
||||
@@ -91,7 +89,9 @@ class AspectJPlugin implements Plugin<Project> {
|
||||
}
|
||||
|
||||
class Ajc extends DefaultTask {
|
||||
SourceSet sourceSet
|
||||
Set<File> sourceRoots = []
|
||||
FileCollection compileClasspath
|
||||
File destinationDir
|
||||
FileCollection aspectPath
|
||||
|
||||
Ajc() {
|
||||
@@ -103,15 +103,18 @@ class Ajc extends DefaultTask {
|
||||
logger.info("="*30)
|
||||
logger.info("="*30)
|
||||
logger.info("Running ajc ...")
|
||||
logger.info("classpath: ${sourceSet.compileClasspath.asPath}")
|
||||
logger.info("srcDirs $sourceSet.java.srcDirs")
|
||||
logger.info("classpath: ${compileClasspath?.files}")
|
||||
logger.info("srcDirs ${sourceRoots}")
|
||||
ant.taskdef(resource: "org/aspectj/tools/ant/taskdefs/aspectjTaskdefs.properties", classpath: project.configurations.ajtools.asPath)
|
||||
ant.iajc(classpath: sourceSet.compileClasspath.asPath, fork: 'true', destDir: sourceSet.output.classesDir.absolutePath,
|
||||
if(sourceRoots.empty) {
|
||||
return
|
||||
}
|
||||
ant.iajc(classpath: compileClasspath.asPath, fork: 'true', destDir: destinationDir.absolutePath,
|
||||
source: project.convention.plugins.java.sourceCompatibility,
|
||||
target: project.convention.plugins.java.targetCompatibility,
|
||||
aspectPath: aspectPath.asPath, sourceRootCopyFilter: '**/*.java', showWeaveInfo: 'true') {
|
||||
sourceroots {
|
||||
sourceSet.java.srcDirs.each {
|
||||
sourceRoots.each {
|
||||
logger.info(" sourceRoot $it")
|
||||
pathelement(location: it.absolutePath)
|
||||
}
|
||||
|
||||
+8
-8
@@ -3,7 +3,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-cas</artifactId>
|
||||
<version>4.2.1.RELEASE</version>
|
||||
<version>4.2.4.RELEASE</version>
|
||||
<name>spring-security-cas</name>
|
||||
<description>spring-security-cas</description>
|
||||
<url>http://spring.io/spring-security</url>
|
||||
@@ -35,7 +35,7 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-framework-bom</artifactId>
|
||||
<version>4.3.5.RELEASE</version>
|
||||
<version>4.3.12.RELEASE</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
@@ -51,13 +51,13 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-core</artifactId>
|
||||
<version>4.2.1.RELEASE</version>
|
||||
<version>4.2.4.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-web</artifactId>
|
||||
<version>4.2.1.RELEASE</version>
|
||||
<version>4.2.4.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@@ -89,7 +89,7 @@
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
<version>2.8.4</version>
|
||||
<version>2.8.10</version>
|
||||
<scope>compile</scope>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
@@ -103,7 +103,7 @@
|
||||
<dependency>
|
||||
<groupId>net.sf.ehcache</groupId>
|
||||
<artifactId>ehcache</artifactId>
|
||||
<version>2.9.0</version>
|
||||
<version>2.10.4</version>
|
||||
<scope>compile</scope>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
@@ -140,13 +140,13 @@
|
||||
<dependency>
|
||||
<groupId>org.skyscreamer</groupId>
|
||||
<artifactId>jsonassert</artifactId>
|
||||
<version>1.3.0</version>
|
||||
<version>1.4.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>jcl-over-slf4j</artifactId>
|
||||
<version>1.7.7</version>
|
||||
<version>1.7.25</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
||||
+1
-1
@@ -132,7 +132,7 @@ final class DefaultServiceAuthenticationDetails extends WebAuthenticationDetails
|
||||
* @return
|
||||
*/
|
||||
static Pattern createArtifactPattern(String artifactParameterName) {
|
||||
Assert.hasLength(artifactParameterName);
|
||||
Assert.hasLength(artifactParameterName, "artifactParameterName is expected to have a length");
|
||||
return Pattern.compile("&?" + Pattern.quote(artifactParameterName) + "=[^&]*");
|
||||
}
|
||||
|
||||
|
||||
+3
-6
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2017 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.
|
||||
@@ -57,10 +57,7 @@ public class GrantedAuthorityFromAssertionAttributesUserDetailsServiceTests {
|
||||
assertion, "ticket");
|
||||
UserDetails user = uds.loadUserDetails(token);
|
||||
Set<String> roles = AuthorityUtils.authorityListToSet(user.getAuthorities());
|
||||
assertThat(roles.size()).isEqualTo(4);
|
||||
assertThat(roles).contains("role_a1");
|
||||
assertThat(roles).contains("role_a2");
|
||||
assertThat(roles).contains("role_b");
|
||||
assertThat(roles).contains("role_c");
|
||||
assertThat(roles).containsOnly(
|
||||
"role_a1", "role_a2", "role_b", "role_c");
|
||||
}
|
||||
}
|
||||
|
||||
+14
-14
@@ -3,7 +3,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-config</artifactId>
|
||||
<version>4.2.1.RELEASE</version>
|
||||
<version>4.2.4.RELEASE</version>
|
||||
<name>spring-security-config</name>
|
||||
<description>spring-security-config</description>
|
||||
<url>http://spring.io/spring-security</url>
|
||||
@@ -35,7 +35,7 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-framework-bom</artifactId>
|
||||
<version>4.3.5.RELEASE</version>
|
||||
<version>4.3.12.RELEASE</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
@@ -51,7 +51,7 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-core</artifactId>
|
||||
<version>4.2.1.RELEASE</version>
|
||||
<version>4.2.4.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@@ -90,35 +90,35 @@
|
||||
<dependency>
|
||||
<groupId>org.aspectj</groupId>
|
||||
<artifactId>aspectjweaver</artifactId>
|
||||
<version>1.8.4</version>
|
||||
<version>1.8.12</version>
|
||||
<scope>compile</scope>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-ldap</artifactId>
|
||||
<version>4.2.1.RELEASE</version>
|
||||
<version>4.2.4.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-messaging</artifactId>
|
||||
<version>4.2.1.RELEASE</version>
|
||||
<version>4.2.4.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-openid</artifactId>
|
||||
<version>4.2.1.RELEASE</version>
|
||||
<version>4.2.4.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-web</artifactId>
|
||||
<version>4.2.1.RELEASE</version>
|
||||
<version>4.2.4.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
@@ -245,7 +245,7 @@
|
||||
<dependency>
|
||||
<groupId>org.hibernate</groupId>
|
||||
<artifactId>hibernate-entitymanager</artifactId>
|
||||
<version>5.0.11.Final</version>
|
||||
<version>5.0.12.Final</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@@ -317,7 +317,7 @@
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>jcl-over-slf4j</artifactId>
|
||||
<version>1.7.7</version>
|
||||
<version>1.7.25</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@@ -347,7 +347,7 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-jpa</artifactId>
|
||||
<version>1.10.2.RELEASE</version>
|
||||
<version>1.11.8.RELEASE</version>
|
||||
<scope>test</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
@@ -359,19 +359,19 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework.ldap</groupId>
|
||||
<artifactId>spring-ldap-core</artifactId>
|
||||
<version>2.2.0.RELEASE</version>
|
||||
<version>2.3.2.RELEASE</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-aspects</artifactId>
|
||||
<version>4.2.1.RELEASE</version>
|
||||
<version>4.2.4.RELEASE</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-cas</artifactId>
|
||||
<version>4.2.1.RELEASE</version>
|
||||
<version>4.2.4.RELEASE</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
||||
+1
-1
@@ -86,7 +86,7 @@ public final class SecurityNamespaceHandler implements NamespaceHandler {
|
||||
if (!namespaceMatchesVersion(element)) {
|
||||
pc.getReaderContext()
|
||||
.fatal("You cannot use a spring-security-2.0.xsd or spring-security-3.0.xsd or spring-security-3.1.xsd schema or spring-security-3.2.xsd schema or spring-security-4.0.xsd schema "
|
||||
+ "with Spring Security 4.1. Please update your schema declarations to the 4.1 schema.",
|
||||
+ "with Spring Security 4.2. Please update your schema declarations to the 4.2 schema.",
|
||||
element);
|
||||
}
|
||||
String name = pc.getDelegate().getLocalName(element);
|
||||
|
||||
+9
-2
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package org.springframework.security.config.annotation.web;
|
||||
|
||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.security.config.annotation.ObjectPostProcessor;
|
||||
@@ -42,6 +43,8 @@ import java.util.List;
|
||||
* @since 3.2
|
||||
*/
|
||||
public abstract class AbstractRequestMatcherRegistry<C> {
|
||||
private static final String HANDLER_MAPPING_INTROSPECTOR_BEAN_NAME = "mvcHandlerMappingIntrospector";
|
||||
|
||||
private static final RequestMatcher ANY_REQUEST = AnyRequestMatcher.INSTANCE;
|
||||
|
||||
private ApplicationContext context;
|
||||
@@ -160,8 +163,12 @@ public abstract class AbstractRequestMatcherRegistry<C> {
|
||||
String... mvcPatterns) {
|
||||
boolean isServlet30 = ClassUtils.isPresent("javax.servlet.ServletRegistration", getClass().getClassLoader());
|
||||
ObjectPostProcessor<Object> opp = this.context.getBean(ObjectPostProcessor.class);
|
||||
HandlerMappingIntrospector introspector = new HandlerMappingIntrospector(
|
||||
this.context);
|
||||
if(!this.context.containsBean(HANDLER_MAPPING_INTROSPECTOR_BEAN_NAME)) {
|
||||
throw new NoSuchBeanDefinitionException("A Bean named " + HANDLER_MAPPING_INTROSPECTOR_BEAN_NAME +" of type " + HandlerMappingIntrospector.class.getName()
|
||||
+ " is required to use MvcRequestMatcher. Please ensure Spring Security & Spring MVC are configured in a shared ApplicationContext.");
|
||||
}
|
||||
HandlerMappingIntrospector introspector = this.context.getBean(HANDLER_MAPPING_INTROSPECTOR_BEAN_NAME,
|
||||
HandlerMappingIntrospector.class);
|
||||
List<MvcRequestMatcher> matchers = new ArrayList<MvcRequestMatcher>(
|
||||
mvcPatterns.length);
|
||||
for (String mvcPattern : mvcPatterns) {
|
||||
|
||||
+2
-2
@@ -47,7 +47,7 @@ import org.springframework.security.web.access.WebInvocationPrivilegeEvaluator;
|
||||
import org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler;
|
||||
import org.springframework.security.web.access.intercept.FilterSecurityInterceptor;
|
||||
import org.springframework.security.web.debug.DebugFilter;
|
||||
import org.springframework.security.web.firewall.DefaultHttpFirewall;
|
||||
import org.springframework.security.web.firewall.StrictHttpFirewall;
|
||||
import org.springframework.security.web.firewall.HttpFirewall;
|
||||
import org.springframework.security.web.servlet.util.matcher.MvcRequestMatcher;
|
||||
import org.springframework.security.web.util.matcher.RequestMatcher;
|
||||
@@ -159,7 +159,7 @@ public final class WebSecurity extends
|
||||
|
||||
/**
|
||||
* Allows customizing the {@link HttpFirewall}. The default is
|
||||
* {@link DefaultHttpFirewall}.
|
||||
* {@link StrictHttpFirewall}.
|
||||
*
|
||||
* @param httpFirewall the custom {@link HttpFirewall}
|
||||
* @return the {@link WebSecurity} for further customizations
|
||||
|
||||
+9
-3
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package org.springframework.security.config.annotation.web.configurers;
|
||||
|
||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.security.config.annotation.web.HttpSecurityBuilder;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
@@ -98,7 +99,9 @@ public class CorsConfigurer<H extends HttpSecurityBuilder<H>>
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
static class MvcCorsFilter {
|
||||
private static final String HANDLER_MAPPING_INTROSPECTOR_BEAN_NAME = "mvcHandlerMappingIntrospector";
|
||||
/**
|
||||
* This needs to be isolated into a separate class as Spring MVC is an optional
|
||||
* dependency and will potentially cause ClassLoading issues
|
||||
@@ -106,9 +109,12 @@ public class CorsConfigurer<H extends HttpSecurityBuilder<H>>
|
||||
* @return
|
||||
*/
|
||||
private static CorsFilter getMvcCorsFilter(ApplicationContext context) {
|
||||
HandlerMappingIntrospector mappingIntrospector = new HandlerMappingIntrospector(
|
||||
context);
|
||||
if(!context.containsBean(HANDLER_MAPPING_INTROSPECTOR_BEAN_NAME)) {
|
||||
throw new NoSuchBeanDefinitionException(HANDLER_MAPPING_INTROSPECTOR_BEAN_NAME, "A Bean named " + HANDLER_MAPPING_INTROSPECTOR_BEAN_NAME +" of type " + HandlerMappingIntrospector.class.getName()
|
||||
+ " is required to use MvcRequestMatcher. Please ensure Spring Security & Spring MVC are configured in a shared ApplicationContext.");
|
||||
}
|
||||
HandlerMappingIntrospector mappingIntrospector = context.getBean(HANDLER_MAPPING_INTROSPECTOR_BEAN_NAME, HandlerMappingIntrospector.class);
|
||||
return new CorsFilter(mappingIntrospector);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -481,7 +481,7 @@ final class AuthenticationConfigBuilder {
|
||||
SimpleAttributes2GrantedAuthoritiesMapper.class));
|
||||
|
||||
String roles = jeeElt.getAttribute(ATT_MAPPABLE_ROLES);
|
||||
Assert.state(StringUtils.hasText(roles));
|
||||
Assert.hasLength(roles, "roles is expected to have length");
|
||||
BeanDefinitionBuilder rolesBuilder = BeanDefinitionBuilder
|
||||
.rootBeanDefinition(StringUtils.class);
|
||||
rolesBuilder.addConstructorArgValue(roles);
|
||||
|
||||
+3
-6
@@ -15,17 +15,16 @@
|
||||
*/
|
||||
package org.springframework.security.config.http;
|
||||
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
import org.springframework.beans.BeanMetadataElement;
|
||||
import org.springframework.beans.factory.BeanCreationException;
|
||||
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
|
||||
import org.springframework.beans.factory.config.RuntimeBeanReference;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.support.RootBeanDefinition;
|
||||
import org.springframework.beans.factory.xml.ParserContext;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.filter.CorsFilter;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
/**
|
||||
* Parser for the {@code CorsFilter}.
|
||||
@@ -71,8 +70,6 @@ public class CorsBeanDefinitionParser {
|
||||
return null;
|
||||
}
|
||||
|
||||
BeanDefinitionBuilder configurationSourceBldr = BeanDefinitionBuilder.rootBeanDefinition(HANDLER_MAPPING_INTROSPECTOR);
|
||||
configurationSourceBldr.setAutowireMode(AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR);
|
||||
return configurationSourceBldr.getBeanDefinition();
|
||||
return new RootBeanDefinition(HandlerMappingIntrospectorFactoryBean.class);
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -194,7 +194,7 @@ public class FilterInvocationSecurityMetadataSourceParser implements BeanDefinit
|
||||
logger.info("Creating access control expression attribute '" + access
|
||||
+ "' for " + path);
|
||||
// The single expression will be parsed later by the
|
||||
// ExpressionFilterInvocationSecurityMetadataSource
|
||||
// ExpressionBasedFilterInvocationSecurityMetadataSource
|
||||
attributeBuilder.addConstructorArgValue(new String[] { access });
|
||||
attributeBuilder.setFactoryMethod("createList");
|
||||
|
||||
|
||||
+19
-3
@@ -17,6 +17,8 @@
|
||||
package org.springframework.security.config.http;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.FactoryBean;
|
||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.web.servlet.handler.HandlerMappingIntrospector;
|
||||
@@ -28,12 +30,22 @@ import org.springframework.web.servlet.handler.HandlerMappingIntrospector;
|
||||
* @author Rob Winch
|
||||
* @since 4.1.1
|
||||
*/
|
||||
class HandlerMappingIntrospectorFactoryBean implements ApplicationContextAware {
|
||||
class HandlerMappingIntrospectorFactoryBean implements FactoryBean<HandlerMappingIntrospector>, ApplicationContextAware {
|
||||
private static final String HANDLER_MAPPING_INTROSPECTOR_BEAN_NAME = "mvcHandlerMappingIntrospector";
|
||||
|
||||
private ApplicationContext context;
|
||||
|
||||
HandlerMappingIntrospector createHandlerMappingIntrospector() {
|
||||
return new HandlerMappingIntrospector(this.context);
|
||||
public HandlerMappingIntrospector getObject() {
|
||||
if(!this.context.containsBean(HANDLER_MAPPING_INTROSPECTOR_BEAN_NAME)) {
|
||||
throw new NoSuchBeanDefinitionException(HANDLER_MAPPING_INTROSPECTOR_BEAN_NAME, "A Bean named " + HANDLER_MAPPING_INTROSPECTOR_BEAN_NAME +" of type " + HandlerMappingIntrospector.class.getName()
|
||||
+ " is required to use MvcRequestMatcher. Please ensure Spring Security & Spring MVC are configured in a shared ApplicationContext.");
|
||||
}
|
||||
return this.context.getBean(HANDLER_MAPPING_INTROSPECTOR_BEAN_NAME, HandlerMappingIntrospector.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> getObjectType() {
|
||||
return HandlerMappingIntrospector.class;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -48,4 +60,8 @@ class HandlerMappingIntrospectorFactoryBean implements ApplicationContextAware {
|
||||
this.context = applicationContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSingleton() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,8 +37,7 @@ public enum MatcherType {
|
||||
ant(AntPathRequestMatcher.class), regex(RegexRequestMatcher.class), ciRegex(
|
||||
RegexRequestMatcher.class), mvc(MvcRequestMatcher.class);
|
||||
|
||||
private static final String HANDLER_MAPPING_INTROSPECTOR_BEAN_NAME = "org.springframework.web.servlet.handler.HandlerMappingIntrospector";
|
||||
private static final String HANDLER_MAPPING_INTROSPECTOR_FACTORY_BEAN_NAME = "org.springframework.security.config.http.HandlerMappingIntrospectorFactoryBean";
|
||||
private static final String HANDLER_MAPPING_INTROSPECTOR_BEAN_NAME = "mvcHandlerMappingIntrospector";
|
||||
|
||||
private static final String ATT_MATCHER_TYPE = "request-matcher";
|
||||
|
||||
@@ -61,18 +60,7 @@ public enum MatcherType {
|
||||
.rootBeanDefinition(type);
|
||||
|
||||
if (this == mvc) {
|
||||
if (!pc.getRegistry().isBeanNameInUse(HANDLER_MAPPING_INTROSPECTOR_BEAN_NAME)) {
|
||||
BeanDefinitionBuilder hmifb = BeanDefinitionBuilder
|
||||
.rootBeanDefinition(HandlerMappingIntrospectorFactoryBean.class);
|
||||
pc.getRegistry().registerBeanDefinition(HANDLER_MAPPING_INTROSPECTOR_FACTORY_BEAN_NAME,
|
||||
hmifb.getBeanDefinition());
|
||||
|
||||
RootBeanDefinition hmi = new RootBeanDefinition(HANDLER_MAPPING_INTROSPECTOR_BEAN_NAME);
|
||||
hmi.setFactoryBeanName(HANDLER_MAPPING_INTROSPECTOR_FACTORY_BEAN_NAME);
|
||||
hmi.setFactoryMethodName("createHandlerMappingIntrospector");
|
||||
pc.getRegistry().registerBeanDefinition(HANDLER_MAPPING_INTROSPECTOR_BEAN_NAME, hmi);
|
||||
}
|
||||
matcherBldr.addConstructorArgReference(HANDLER_MAPPING_INTROSPECTOR_BEAN_NAME);
|
||||
matcherBldr.addConstructorArgValue(new RootBeanDefinition(HandlerMappingIntrospectorFactoryBean.class));
|
||||
}
|
||||
|
||||
matcherBldr.addConstructorArgValue(path);
|
||||
|
||||
+1
-1
@@ -163,7 +163,7 @@ final class ProtectPointcutPostProcessor implements BeanPostProcessor {
|
||||
}
|
||||
|
||||
public void setPointcutMap(Map<String, List<ConfigAttribute>> map) {
|
||||
Assert.notEmpty(map);
|
||||
Assert.notEmpty(map, "configAttributes cannot be empty");
|
||||
for (String expression : map.keySet()) {
|
||||
List<ConfigAttribute> value = map.get(expression);
|
||||
addPointcut(expression, value);
|
||||
|
||||
+8
-8
@@ -255,8 +255,8 @@ public final class WebSocketMessageBrokerSecurityBeanDefinitionParser implements
|
||||
for (String beanName : beanNames) {
|
||||
BeanDefinition bd = registry.getBeanDefinition(beanName);
|
||||
String beanClassName = bd.getBeanClassName();
|
||||
if (beanClassName.equals(SimpAnnotationMethodMessageHandler.class
|
||||
.getName()) || beanClassName.equals(WEB_SOCKET_AMMH_CLASS_NAME)) {
|
||||
if (SimpAnnotationMethodMessageHandler.class.getName().equals(beanClassName) ||
|
||||
WEB_SOCKET_AMMH_CLASS_NAME.equals(beanClassName)) {
|
||||
PropertyValue current = bd.getPropertyValues().getPropertyValue(
|
||||
CUSTOM_ARG_RESOLVERS_PROP);
|
||||
ManagedList<Object> argResolvers = new ManagedList<Object>();
|
||||
@@ -275,16 +275,16 @@ public final class WebSocketMessageBrokerSecurityBeanDefinitionParser implements
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (beanClassName
|
||||
.equals("org.springframework.web.socket.server.support.WebSocketHttpRequestHandler")) {
|
||||
else if ("org.springframework.web.socket.server.support.WebSocketHttpRequestHandler"
|
||||
.equals(beanClassName)) {
|
||||
addCsrfTokenHandshakeInterceptor(bd);
|
||||
}
|
||||
else if (beanClassName
|
||||
.equals("org.springframework.web.socket.sockjs.transport.TransportHandlingSockJsService")) {
|
||||
else if ("org.springframework.web.socket.sockjs.transport.TransportHandlingSockJsService"
|
||||
.equals(beanClassName)) {
|
||||
addCsrfTokenHandshakeInterceptor(bd);
|
||||
}
|
||||
else if (beanClassName
|
||||
.equals("org.springframework.web.socket.sockjs.transport.handler.DefaultSockJsService")) {
|
||||
else if ("org.springframework.web.socket.sockjs.transport.handler.DefaultSockJsService"
|
||||
.equals(beanClassName)) {
|
||||
addCsrfTokenHandshakeInterceptor(bd);
|
||||
}
|
||||
}
|
||||
|
||||
+7
-11
@@ -15,6 +15,9 @@
|
||||
*/
|
||||
package org.springframework.security.config.annotation.web.configurers
|
||||
|
||||
import org.springframework.beans.factory.BeanCreationException
|
||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException
|
||||
|
||||
import javax.servlet.http.HttpServletResponse
|
||||
|
||||
import org.springframework.context.annotation.Bean
|
||||
@@ -36,19 +39,12 @@ import org.springframework.web.servlet.config.annotation.EnableWebMvc
|
||||
*/
|
||||
class CorsConfigurerTests extends BaseSpringSpec {
|
||||
|
||||
def "HandlerMappingIntrospector default"() {
|
||||
setup:
|
||||
loadConfig(DefaultCorsConfig)
|
||||
def "No MVC throws meaningful error"() {
|
||||
when:
|
||||
addCors()
|
||||
springSecurityFilterChain.doFilter(request,response,chain)
|
||||
loadConfig(DefaultCorsConfig)
|
||||
then:
|
||||
responseHeaders == ['X-Content-Type-Options':'nosniff',
|
||||
'X-Frame-Options':'DENY',
|
||||
'Cache-Control': 'no-cache, no-store, max-age=0, must-revalidate',
|
||||
'Expires' : '0',
|
||||
'Pragma':'no-cache',
|
||||
'X-XSS-Protection' : '1; mode=block']
|
||||
BeanCreationException success = thrown()
|
||||
success.message.contains("Please ensure Spring Security & Spring MVC are configured in a shared ApplicationContext")
|
||||
}
|
||||
|
||||
@EnableWebSecurity
|
||||
|
||||
+6
-11
@@ -12,6 +12,8 @@
|
||||
*/
|
||||
package org.springframework.security.config.http
|
||||
|
||||
import org.springframework.beans.factory.BeanCreationException
|
||||
|
||||
import javax.servlet.http.HttpServletResponse
|
||||
|
||||
import org.springframework.http.*
|
||||
@@ -38,24 +40,17 @@ class HttpCorsConfigTests extends AbstractHttpConfigTests {
|
||||
chain = new MockFilterChain()
|
||||
}
|
||||
|
||||
def "HandlerMappingIntrospector default"() {
|
||||
setup:
|
||||
def "No MVC throws meaningful error"() {
|
||||
when:
|
||||
xml.http('entry-point-ref' : 'ep') {
|
||||
'cors'()
|
||||
'intercept-url'(pattern:'/**', access: 'authenticated')
|
||||
}
|
||||
bean('ep', Http403ForbiddenEntryPoint)
|
||||
createAppContext()
|
||||
when:
|
||||
addCors()
|
||||
springSecurityFilterChain.doFilter(request,response,chain)
|
||||
then:
|
||||
responseHeaders == ['X-Content-Type-Options':'nosniff',
|
||||
'X-Frame-Options':'DENY',
|
||||
'Cache-Control': 'no-cache, no-store, max-age=0, must-revalidate',
|
||||
'Expires' : '0',
|
||||
'Pragma':'no-cache',
|
||||
'X-XSS-Protection' : '1; mode=block']
|
||||
BeanCreationException success = thrown()
|
||||
success.message.contains("Please ensure Spring Security & Spring MVC are configured in a shared ApplicationContext")
|
||||
}
|
||||
|
||||
def "HandlerMappingIntrospector explicit"() {
|
||||
|
||||
+1
@@ -252,6 +252,7 @@ class InterceptUrlConfigTests extends AbstractHttpConfigTests {
|
||||
'http-basic'()
|
||||
'intercept-url'(pattern: '/user/{un}/**', access: "#un == 'user'")
|
||||
}
|
||||
xml.'mvc:annotation-driven'()
|
||||
createWebAppContext(servletContext)
|
||||
when: 'user can access'
|
||||
request.servletPath = '/user/user/abc'
|
||||
|
||||
+4
@@ -38,6 +38,7 @@ import org.springframework.security.web.FilterChainProxy;
|
||||
import org.springframework.security.web.SecurityFilterChain;
|
||||
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
|
||||
import org.springframework.security.web.context.SecurityContextPersistenceFilter;
|
||||
import org.springframework.security.web.firewall.DefaultHttpFirewall;
|
||||
import org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter;
|
||||
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
|
||||
import org.springframework.security.web.util.matcher.AnyRequestMatcher;
|
||||
@@ -80,6 +81,7 @@ public class FilterChainProxyConfigTests {
|
||||
public void normalOperationWithNewConfig() throws Exception {
|
||||
FilterChainProxy filterChainProxy = appCtx.getBean("newFilterChainProxy",
|
||||
FilterChainProxy.class);
|
||||
filterChainProxy.setFirewall(new DefaultHttpFirewall());
|
||||
checkPathAndFilterOrder(filterChainProxy);
|
||||
doNormalOperation(filterChainProxy);
|
||||
}
|
||||
@@ -88,6 +90,7 @@ public class FilterChainProxyConfigTests {
|
||||
public void normalOperationWithNewConfigRegex() throws Exception {
|
||||
FilterChainProxy filterChainProxy = appCtx.getBean("newFilterChainProxyRegex",
|
||||
FilterChainProxy.class);
|
||||
filterChainProxy.setFirewall(new DefaultHttpFirewall());
|
||||
checkPathAndFilterOrder(filterChainProxy);
|
||||
doNormalOperation(filterChainProxy);
|
||||
}
|
||||
@@ -96,6 +99,7 @@ public class FilterChainProxyConfigTests {
|
||||
public void normalOperationWithNewConfigNonNamespace() throws Exception {
|
||||
FilterChainProxy filterChainProxy = appCtx.getBean(
|
||||
"newFilterChainProxyNonNamespace", FilterChainProxy.class);
|
||||
filterChainProxy.setFirewall(new DefaultHttpFirewall());
|
||||
checkPathAndFilterOrder(filterChainProxy);
|
||||
doNormalOperation(filterChainProxy);
|
||||
}
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2017 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.
|
||||
@@ -299,7 +299,7 @@ public class MessageSecurityMetadataSourceRegistryTests {
|
||||
if (attrs == null) {
|
||||
return null;
|
||||
}
|
||||
assertThat(attrs.size()).isEqualTo(1);
|
||||
assertThat(attrs).hasSize(1);
|
||||
return attrs.iterator().next().toString();
|
||||
}
|
||||
}
|
||||
+4
-7
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2017 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.
|
||||
@@ -65,8 +65,7 @@ public class FilterSecurityMetadataSourceBeanDefinitionParserTests {
|
||||
.getBean("fids");
|
||||
Collection<ConfigAttribute> cad = fids
|
||||
.getAttributes(createFilterInvocation("/anything", "GET"));
|
||||
assertThat(cad).isNotNull();
|
||||
assertThat(cad.contains(new SecurityConfig("ROLE_A"))).isTrue();
|
||||
assertThat(cad).contains(new SecurityConfig("ROLE_A"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -80,7 +79,7 @@ public class FilterSecurityMetadataSourceBeanDefinitionParserTests {
|
||||
ConfigAttribute[] cad = fids
|
||||
.getAttributes(createFilterInvocation("/anything", "GET"))
|
||||
.toArray(new ConfigAttribute[0]);
|
||||
assertThat(cad.length).isEqualTo(1);
|
||||
assertThat(cad).hasSize(1);
|
||||
assertThat(cad[0].toString()).isEqualTo("hasRole('ROLE_A')");
|
||||
}
|
||||
|
||||
@@ -98,9 +97,7 @@ public class FilterSecurityMetadataSourceBeanDefinitionParserTests {
|
||||
.getBean("fids");
|
||||
Collection<ConfigAttribute> cad = fids
|
||||
.getAttributes(createFilterInvocation("/secure", "GET"));
|
||||
assertThat(cad).isNotNull();
|
||||
assertThat(cad).hasSize(1);
|
||||
assertThat(cad.contains(new SecurityConfig("ROLE_A"))).isTrue();
|
||||
assertThat(cad).containsExactly(new SecurityConfig("ROLE_A"));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2017 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.
|
||||
@@ -108,7 +108,7 @@ public class GlobalMethodSecurityBeanDefinitionParserTests {
|
||||
|
||||
// SEC-1213. Check the order
|
||||
Advisor[] advisors = ((Advised) target).getAdvisors();
|
||||
assertThat(advisors.length).isEqualTo(1);
|
||||
assertThat(advisors).hasSize(1);
|
||||
assertThat(((MethodSecurityMetadataSourceAdvisor) advisors[0]).getOrder()).isEqualTo(1001);
|
||||
}
|
||||
|
||||
@@ -308,7 +308,7 @@ public class GlobalMethodSecurityBeanDefinitionParserTests {
|
||||
target = (BusinessService) appContext.getBean("target");
|
||||
Object[] arg = new String[] { "joe", "bob", "sam" };
|
||||
Object[] result = target.methodReturningAnArray(arg);
|
||||
assertThat(result.length).isEqualTo(1);
|
||||
assertThat(result).hasSize(1);
|
||||
assertThat(result[0]).isEqualTo("bob");
|
||||
}
|
||||
|
||||
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2017 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.
|
||||
@@ -66,11 +66,11 @@ public class InterceptMethodsBeanDefinitionDecoratorTests implements
|
||||
@Test
|
||||
public void targetDoesntLoseApplicationListenerInterface() {
|
||||
assertThat(appContext.getBeansOfType(ApplicationListener.class)).hasSize(1);
|
||||
assertThat(appContext.getBeanNamesForType(ApplicationListener.class).length).isEqualTo(1);
|
||||
assertThat(appContext.getBeanNamesForType(ApplicationListener.class)).hasSize(1);
|
||||
appContext.publishEvent(new AuthenticationSuccessEvent(
|
||||
new TestingAuthenticationToken("user", "")));
|
||||
|
||||
assertThat(target instanceof ApplicationListener<?>).isTrue();
|
||||
assertThat(target).isInstanceOf(ApplicationListener.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* 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.config.websocket;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||
import org.springframework.beans.factory.support.GenericBeanDefinition;
|
||||
import org.springframework.beans.factory.support.SimpleBeanDefinitionRegistry;
|
||||
|
||||
public class MessageSecurityPostProcessorTest {
|
||||
|
||||
private WebSocketMessageBrokerSecurityBeanDefinitionParser.MessageSecurityPostProcessor postProcessor =
|
||||
new WebSocketMessageBrokerSecurityBeanDefinitionParser.MessageSecurityPostProcessor("id", false);
|
||||
|
||||
@Test
|
||||
public void handlesBeansWithoutClass() {
|
||||
BeanDefinitionRegistry registry = new SimpleBeanDefinitionRegistry();
|
||||
registry.registerBeanDefinition("beanWithoutClass", new GenericBeanDefinition());
|
||||
postProcessor.postProcessBeanDefinitionRegistry(registry);
|
||||
}
|
||||
}
|
||||
+7
-7
@@ -3,7 +3,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-core</artifactId>
|
||||
<version>4.2.1.RELEASE</version>
|
||||
<version>4.2.4.RELEASE</version>
|
||||
<name>spring-security-core</name>
|
||||
<description>spring-security-core</description>
|
||||
<url>http://spring.io/spring-security</url>
|
||||
@@ -35,7 +35,7 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-framework-bom</artifactId>
|
||||
<version>4.3.5.RELEASE</version>
|
||||
<version>4.3.12.RELEASE</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
@@ -82,7 +82,7 @@
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
<version>2.8.4</version>
|
||||
<version>2.8.10</version>
|
||||
<scope>compile</scope>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
@@ -103,14 +103,14 @@
|
||||
<dependency>
|
||||
<groupId>net.sf.ehcache</groupId>
|
||||
<artifactId>ehcache</artifactId>
|
||||
<version>2.9.0</version>
|
||||
<version>2.10.4</version>
|
||||
<scope>compile</scope>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.aspectj</groupId>
|
||||
<artifactId>aspectjrt</artifactId>
|
||||
<version>1.8.4</version>
|
||||
<version>1.8.12</version>
|
||||
<scope>compile</scope>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
@@ -261,7 +261,7 @@
|
||||
<dependency>
|
||||
<groupId>org.skyscreamer</groupId>
|
||||
<artifactId>jsonassert</artifactId>
|
||||
<version>1.3.0</version>
|
||||
<version>1.4.0</version>
|
||||
<scope>test</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
@@ -273,7 +273,7 @@
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>jcl-over-slf4j</artifactId>
|
||||
<version>1.7.7</version>
|
||||
<version>1.7.25</version>
|
||||
<scope>test</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
|
||||
+1
-1
@@ -49,7 +49,7 @@ public class SecuredAnnotationSecurityMetadataSource extends
|
||||
|
||||
public SecuredAnnotationSecurityMetadataSource(
|
||||
AnnotationMetadataExtractor annotationMetadataExtractor) {
|
||||
Assert.notNull(annotationMetadataExtractor);
|
||||
Assert.notNull(annotationMetadataExtractor, "annotationMetadataExtractor cannot be null");
|
||||
annotationExtractor = annotationMetadataExtractor;
|
||||
annotationType = (Class<? extends Annotation>) GenericTypeResolver
|
||||
.resolveTypeArgument(annotationExtractor.getClass(),
|
||||
|
||||
+1
-1
@@ -41,7 +41,7 @@ public class RememberMeAuthenticationProvider implements AuthenticationProvider,
|
||||
private String key;
|
||||
|
||||
public RememberMeAuthenticationProvider(String key) {
|
||||
Assert.hasLength(key);
|
||||
Assert.hasLength(key, "key must have a length");
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -45,7 +45,7 @@ public class InteractiveAuthenticationSuccessEvent extends AbstractAuthenticatio
|
||||
public InteractiveAuthenticationSuccessEvent(Authentication authentication,
|
||||
Class<?> generatedBy) {
|
||||
super(authentication);
|
||||
Assert.notNull(generatedBy);
|
||||
Assert.notNull(generatedBy, "generatedBy cannot be null");
|
||||
this.generatedBy = generatedBy;
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -20,8 +20,8 @@ import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.context.event.SmartApplicationListener;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
||||
/**
|
||||
* Used for delegating to a number of SmartApplicationListener instances. This is useful
|
||||
@@ -32,7 +32,7 @@ import java.util.List;
|
||||
*/
|
||||
public final class DelegatingApplicationListener implements
|
||||
ApplicationListener<ApplicationEvent> {
|
||||
private List<SmartApplicationListener> listeners = new ArrayList<SmartApplicationListener>();
|
||||
private List<SmartApplicationListener> listeners = new CopyOnWriteArrayList<SmartApplicationListener>();
|
||||
|
||||
public void onApplicationEvent(ApplicationEvent event) {
|
||||
if (event == null) {
|
||||
|
||||
@@ -40,7 +40,7 @@ public class SpringSecurityCoreVersion {
|
||||
*/
|
||||
public static final long SERIAL_VERSION_UID = 420L;
|
||||
|
||||
static final String MIN_SPRING_VERSION = "4.3.5.RELEASE";
|
||||
static final String MIN_SPRING_VERSION = "4.3.12.RELEASE";
|
||||
|
||||
static {
|
||||
performVersionChecks();
|
||||
|
||||
+2
-1
@@ -17,6 +17,7 @@
|
||||
package org.springframework.security.core.context;
|
||||
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
|
||||
@@ -93,7 +94,7 @@ public class SecurityContextHolder {
|
||||
}
|
||||
|
||||
private static void initialize() {
|
||||
if ((strategyName == null) || "".equals(strategyName)) {
|
||||
if (!StringUtils.hasText(strategyName)) {
|
||||
// Set default
|
||||
strategyName = MODE_THREADLOCAL;
|
||||
}
|
||||
|
||||
+12
-2
@@ -48,13 +48,23 @@ public class SessionRegistryImpl implements SessionRegistry,
|
||||
protected final Log logger = LogFactory.getLog(SessionRegistryImpl.class);
|
||||
|
||||
/** <principal:Object,SessionIdSet> */
|
||||
private final ConcurrentMap<Object, Set<String>> principals = new ConcurrentHashMap<Object, Set<String>>();
|
||||
private final ConcurrentMap<Object, Set<String>> principals;
|
||||
/** <sessionId:Object,SessionInformation> */
|
||||
private final Map<String, SessionInformation> sessionIds = new ConcurrentHashMap<String, SessionInformation>();
|
||||
private final Map<String, SessionInformation> sessionIds;
|
||||
|
||||
// ~ Methods
|
||||
// ========================================================================================================
|
||||
|
||||
public SessionRegistryImpl() {
|
||||
this.principals = new ConcurrentHashMap<Object, Set<String>>();
|
||||
this.sessionIds = new ConcurrentHashMap<String, SessionInformation>();
|
||||
}
|
||||
|
||||
public SessionRegistryImpl(ConcurrentMap<Object, Set<String>> principals,Map<String, SessionInformation> sessionIds) {
|
||||
this.principals=principals;
|
||||
this.sessionIds=sessionIds;
|
||||
}
|
||||
|
||||
public List<Object> getAllPrincipals() {
|
||||
return new ArrayList<Object>(principals.keySet());
|
||||
}
|
||||
|
||||
+117
-8
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2015-2016 the original author or authors.
|
||||
* Copyright 2015-2017 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.
|
||||
@@ -16,17 +16,18 @@
|
||||
|
||||
package org.springframework.security.jackson2;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JacksonAnnotation;
|
||||
import com.fasterxml.jackson.annotation.JsonTypeInfo;
|
||||
import com.fasterxml.jackson.databind.Module;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.jsontype.TypeResolverBuilder;
|
||||
import com.fasterxml.jackson.databind.*;
|
||||
import com.fasterxml.jackson.databind.cfg.MapperConfig;
|
||||
import com.fasterxml.jackson.databind.jsontype.*;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.core.annotation.AnnotationUtils;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* This utility class will find all the SecurityModules in classpath.
|
||||
@@ -65,7 +66,7 @@ public final class SecurityJackson2Modules {
|
||||
if(mapper != null) {
|
||||
TypeResolverBuilder<?> typeBuilder = mapper.getDeserializationConfig().getDefaultTyper(null);
|
||||
if (typeBuilder == null) {
|
||||
mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);
|
||||
mapper.setDefaultTyping(createWhitelistedDefaultTyping());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -103,4 +104,112 @@ public final class SecurityJackson2Modules {
|
||||
}
|
||||
return modules;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a TypeResolverBuilder that performs whitelisting.
|
||||
* @return a TypeResolverBuilder that performs whitelisting.
|
||||
*/
|
||||
private static TypeResolverBuilder<? extends TypeResolverBuilder> createWhitelistedDefaultTyping() {
|
||||
TypeResolverBuilder<? extends TypeResolverBuilder> result = new WhitelistTypeResolverBuilder(ObjectMapper.DefaultTyping.NON_FINAL);
|
||||
result = result.init(JsonTypeInfo.Id.CLASS, null);
|
||||
result = result.inclusion(JsonTypeInfo.As.PROPERTY);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* An implementation of {@link ObjectMapper.DefaultTypeResolverBuilder} that overrides the {@link TypeIdResolver}
|
||||
* with {@link WhitelistTypeIdResolver}.
|
||||
* @author Rob Winch
|
||||
*/
|
||||
static class WhitelistTypeResolverBuilder extends ObjectMapper.DefaultTypeResolverBuilder {
|
||||
|
||||
public WhitelistTypeResolverBuilder(ObjectMapper.DefaultTyping defaultTyping) {
|
||||
super(defaultTyping);
|
||||
}
|
||||
|
||||
protected TypeIdResolver idResolver(MapperConfig<?> config,
|
||||
JavaType baseType, Collection<NamedType> subtypes, boolean forSer, boolean forDeser) {
|
||||
TypeIdResolver result = super.idResolver(config, baseType, subtypes, forSer, forDeser);
|
||||
return new WhitelistTypeIdResolver(result);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A {@link TypeIdResolver} that delegates to an existing implementation and throws an IllegalStateException if the
|
||||
* class being looked up is not whitelisted, does not provide an explicit mixin, and is not annotated with Jackson
|
||||
* mappings. See https://github.com/spring-projects/spring-security/issues/4370
|
||||
*/
|
||||
static class WhitelistTypeIdResolver implements TypeIdResolver {
|
||||
private static final Set<String> WHITELIST_CLASS_NAMES = Collections.unmodifiableSet(new HashSet(Arrays.asList(
|
||||
"java.util.ArrayList",
|
||||
"java.util.Collections$EmptyMap",
|
||||
"java.util.Date",
|
||||
"java.util.TreeMap",
|
||||
"java.util.HashMap",
|
||||
"org.springframework.security.core.context.SecurityContextImpl"
|
||||
)));
|
||||
|
||||
private final TypeIdResolver delegate;
|
||||
|
||||
WhitelistTypeIdResolver(TypeIdResolver delegate) {
|
||||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(JavaType baseType) {
|
||||
delegate.init(baseType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String idFromValue(Object value) {
|
||||
return delegate.idFromValue(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String idFromValueAndType(Object value, Class<?> suggestedType) {
|
||||
return delegate.idFromValueAndType(value, suggestedType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String idFromBaseType() {
|
||||
return delegate.idFromBaseType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public JavaType typeFromId(DatabindContext context, String id) throws IOException {
|
||||
DeserializationConfig config = (DeserializationConfig) context.getConfig();
|
||||
JavaType result = delegate.typeFromId(context, id);
|
||||
String className = result.getRawClass().getName();
|
||||
if(isWhitelisted(className)) {
|
||||
return delegate.typeFromId(context, id);
|
||||
}
|
||||
boolean isExplicitMixin = config.findMixInClassFor(result.getRawClass()) != null;
|
||||
if(isExplicitMixin) {
|
||||
return result;
|
||||
}
|
||||
JacksonAnnotation jacksonAnnotation = AnnotationUtils.findAnnotation(result.getRawClass(), JacksonAnnotation.class);
|
||||
if(jacksonAnnotation != null) {
|
||||
return result;
|
||||
}
|
||||
throw new IllegalArgumentException("The class with " + id + " and name of " + className + " is not whitelisted. " +
|
||||
"If you believe this class is safe to deserialize, please provide an explicit mapping using Jackson annotations or by providing a Mixin. " +
|
||||
"If the serialization is only done by a trusted source, you can also enable default typing. " +
|
||||
"See https://github.com/spring-projects/spring-security/issues/4370 for details");
|
||||
}
|
||||
|
||||
private boolean isWhitelisted(String id) {
|
||||
return WHITELIST_CLASS_NAMES.contains(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescForKnownTypeIds() {
|
||||
return delegate.getDescForKnownTypeIds();
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonTypeInfo.Id getMechanism() {
|
||||
return delegate.getMechanism();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -50,10 +50,10 @@ class UnmodifiableSetDeserializer extends JsonDeserializer<Set> {
|
||||
Iterator<JsonNode> nodeIterator = arrayNode.iterator();
|
||||
while (nodeIterator.hasNext()) {
|
||||
JsonNode elementNode = nodeIterator.next();
|
||||
resultSet.add(mapper.readValue(elementNode.toString(), Object.class));
|
||||
resultSet.add(mapper.readValue(elementNode.traverse(mapper), Object.class));
|
||||
}
|
||||
} else {
|
||||
resultSet.add(mapper.readValue(node.toString(), Object.class));
|
||||
resultSet.add(mapper.readValue(node.traverse(mapper), Object.class));
|
||||
}
|
||||
}
|
||||
return Collections.unmodifiableSet(resultSet);
|
||||
|
||||
+20
-8
@@ -16,6 +16,9 @@
|
||||
|
||||
package org.springframework.security.jackson2;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
@@ -24,12 +27,9 @@ import com.fasterxml.jackson.databind.JsonDeserializer;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.node.MissingNode;
|
||||
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.core.userdetails.User;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Custom deserializer for {@link UsernamePasswordAuthenticationToken}. At the time of deserialization
|
||||
@@ -40,6 +40,7 @@ import java.util.List;
|
||||
* you can also registered it with your own mixin class.
|
||||
*
|
||||
* @author Jitendra Singh
|
||||
* @author Greg Turnquist
|
||||
* @see UsernamePasswordAuthenticationTokenMixin
|
||||
* @since 4.2
|
||||
*/
|
||||
@@ -62,20 +63,31 @@ class UsernamePasswordAuthenticationTokenDeserializer extends JsonDeserializer<U
|
||||
JsonNode principalNode = readJsonNode(jsonNode, "principal");
|
||||
Object principal = null;
|
||||
if(principalNode.isObject()) {
|
||||
principal = mapper.readValue(principalNode.toString(), new TypeReference<User>() {});
|
||||
principal = mapper.readValue(principalNode.traverse(mapper), Object.class);
|
||||
} else {
|
||||
principal = principalNode.asText();
|
||||
}
|
||||
Object credentials = readJsonNode(jsonNode, "credentials").asText();
|
||||
JsonNode credentialsNode = readJsonNode(jsonNode, "credentials");
|
||||
Object credentials;
|
||||
if (credentialsNode.isNull()) {
|
||||
credentials = null;
|
||||
} else {
|
||||
credentials = credentialsNode.asText();
|
||||
}
|
||||
List<GrantedAuthority> authorities = mapper.readValue(
|
||||
readJsonNode(jsonNode, "authorities").toString(), new TypeReference<List<GrantedAuthority>>() {
|
||||
readJsonNode(jsonNode, "authorities").traverse(mapper), new TypeReference<List<GrantedAuthority>>() {
|
||||
});
|
||||
if (authenticated) {
|
||||
token = new UsernamePasswordAuthenticationToken(principal, credentials, authorities);
|
||||
} else {
|
||||
token = new UsernamePasswordAuthenticationToken(principal, credentials);
|
||||
}
|
||||
token.setDetails(readJsonNode(jsonNode, "details"));
|
||||
JsonNode detailsNode = readJsonNode(jsonNode, "details");
|
||||
if (detailsNode.isNull()) {
|
||||
token.setDetails(null);
|
||||
} else {
|
||||
token.setDetails(detailsNode);
|
||||
}
|
||||
return token;
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -76,7 +76,7 @@ public class InMemoryUserDetailsManager implements UserDetailsManager {
|
||||
}
|
||||
|
||||
public void createUser(UserDetails user) {
|
||||
Assert.isTrue(!userExists(user.getUsername()));
|
||||
Assert.isTrue(!userExists(user.getUsername()), "user should not exist");
|
||||
|
||||
users.put(user.getUsername().toLowerCase(), new MutableUser(user));
|
||||
}
|
||||
@@ -86,7 +86,7 @@ public class InMemoryUserDetailsManager implements UserDetailsManager {
|
||||
}
|
||||
|
||||
public void updateUser(UserDetails user) {
|
||||
Assert.isTrue(userExists(user.getUsername()));
|
||||
Assert.isTrue(userExists(user.getUsername()), "user should exist");
|
||||
|
||||
users.put(user.getUsername().toLowerCase(), new MutableUser(user));
|
||||
}
|
||||
|
||||
+35
-35
@@ -258,15 +258,15 @@ public class JdbcUserDetailsManager extends JdbcDaoImpl implements UserDetailsMa
|
||||
}
|
||||
|
||||
public List<String> findUsersInGroup(String groupName) {
|
||||
Assert.hasText(groupName);
|
||||
Assert.hasText(groupName, "groupName should have text");
|
||||
return getJdbcTemplate().queryForList(findUsersInGroupSql,
|
||||
new String[] { groupName }, String.class);
|
||||
}
|
||||
|
||||
public void createGroup(final String groupName,
|
||||
final List<GrantedAuthority> authorities) {
|
||||
Assert.hasText(groupName);
|
||||
Assert.notNull(authorities);
|
||||
Assert.hasText(groupName, "groupName should have text");
|
||||
Assert.notNull(authorities, "authorities cannot be null");
|
||||
|
||||
logger.debug("Creating new group '" + groupName + "' with authorities "
|
||||
+ AuthorityUtils.authorityListToSet(authorities));
|
||||
@@ -289,7 +289,7 @@ public class JdbcUserDetailsManager extends JdbcDaoImpl implements UserDetailsMa
|
||||
|
||||
public void deleteGroup(String groupName) {
|
||||
logger.debug("Deleting group '" + groupName + "'");
|
||||
Assert.hasText(groupName);
|
||||
Assert.hasText(groupName, "groupName should have text");
|
||||
|
||||
final int id = findGroupId(groupName);
|
||||
PreparedStatementSetter groupIdPSS = new PreparedStatementSetter() {
|
||||
@@ -304,16 +304,16 @@ public class JdbcUserDetailsManager extends JdbcDaoImpl implements UserDetailsMa
|
||||
|
||||
public void renameGroup(String oldName, String newName) {
|
||||
logger.debug("Changing group name from '" + oldName + "' to '" + newName + "'");
|
||||
Assert.hasText(oldName);
|
||||
Assert.hasText(newName);
|
||||
Assert.hasText(oldName,"oldName should have text");;
|
||||
Assert.hasText(newName,"newName should have text");;
|
||||
|
||||
getJdbcTemplate().update(renameGroupSql, newName, oldName);
|
||||
}
|
||||
|
||||
public void addUserToGroup(final String username, final String groupName) {
|
||||
logger.debug("Adding user '" + username + "' to group '" + groupName + "'");
|
||||
Assert.hasText(username);
|
||||
Assert.hasText(groupName);
|
||||
Assert.hasText(username,"username should have text");;
|
||||
Assert.hasText(groupName,"groupName should have text");;
|
||||
|
||||
final int id = findGroupId(groupName);
|
||||
getJdbcTemplate().update(insertGroupMemberSql, new PreparedStatementSetter() {
|
||||
@@ -328,8 +328,8 @@ public class JdbcUserDetailsManager extends JdbcDaoImpl implements UserDetailsMa
|
||||
|
||||
public void removeUserFromGroup(final String username, final String groupName) {
|
||||
logger.debug("Removing user '" + username + "' to group '" + groupName + "'");
|
||||
Assert.hasText(username);
|
||||
Assert.hasText(groupName);
|
||||
Assert.hasText(username,"username should have text");;
|
||||
Assert.hasText(groupName,"groupName should have text");;
|
||||
|
||||
final int id = findGroupId(groupName);
|
||||
|
||||
@@ -345,7 +345,7 @@ public class JdbcUserDetailsManager extends JdbcDaoImpl implements UserDetailsMa
|
||||
|
||||
public List<GrantedAuthority> findGroupAuthorities(String groupName) {
|
||||
logger.debug("Loading authorities for group '" + groupName + "'");
|
||||
Assert.hasText(groupName);
|
||||
Assert.hasText(groupName,"groupName should have text");;
|
||||
|
||||
return getJdbcTemplate().query(groupAuthoritiesSql, new String[] { groupName },
|
||||
new RowMapper<GrantedAuthority>() {
|
||||
@@ -361,8 +361,8 @@ public class JdbcUserDetailsManager extends JdbcDaoImpl implements UserDetailsMa
|
||||
public void removeGroupAuthority(String groupName, final GrantedAuthority authority) {
|
||||
logger.debug("Removing authority '" + authority + "' from group '" + groupName
|
||||
+ "'");
|
||||
Assert.hasText(groupName);
|
||||
Assert.notNull(authority);
|
||||
Assert.hasText(groupName,"groupName should have text");
|
||||
Assert.notNull(authority, "authority cannot be null");
|
||||
|
||||
final int id = findGroupId(groupName);
|
||||
|
||||
@@ -377,8 +377,8 @@ public class JdbcUserDetailsManager extends JdbcDaoImpl implements UserDetailsMa
|
||||
|
||||
public void addGroupAuthority(final String groupName, final GrantedAuthority authority) {
|
||||
logger.debug("Adding authority '" + authority + "' to group '" + groupName + "'");
|
||||
Assert.hasText(groupName);
|
||||
Assert.notNull(authority);
|
||||
Assert.hasText(groupName,"groupName should have text");;
|
||||
Assert.notNull(authority, "authority cannot be null");
|
||||
|
||||
final int id = findGroupId(groupName);
|
||||
getJdbcTemplate().update(insertGroupAuthoritySql, new PreparedStatementSetter() {
|
||||
@@ -398,102 +398,102 @@ public class JdbcUserDetailsManager extends JdbcDaoImpl implements UserDetailsMa
|
||||
}
|
||||
|
||||
public void setCreateUserSql(String createUserSql) {
|
||||
Assert.hasText(createUserSql);
|
||||
Assert.hasText(createUserSql,"createUserSql should have text");;
|
||||
this.createUserSql = createUserSql;
|
||||
}
|
||||
|
||||
public void setDeleteUserSql(String deleteUserSql) {
|
||||
Assert.hasText(deleteUserSql);
|
||||
Assert.hasText(deleteUserSql,"deleteUserSql should have text");;
|
||||
this.deleteUserSql = deleteUserSql;
|
||||
}
|
||||
|
||||
public void setUpdateUserSql(String updateUserSql) {
|
||||
Assert.hasText(updateUserSql);
|
||||
Assert.hasText(updateUserSql,"updateUserSql should have text");;
|
||||
this.updateUserSql = updateUserSql;
|
||||
}
|
||||
|
||||
public void setCreateAuthoritySql(String createAuthoritySql) {
|
||||
Assert.hasText(createAuthoritySql);
|
||||
Assert.hasText(createAuthoritySql,"createAuthoritySql should have text");;
|
||||
this.createAuthoritySql = createAuthoritySql;
|
||||
}
|
||||
|
||||
public void setDeleteUserAuthoritiesSql(String deleteUserAuthoritiesSql) {
|
||||
Assert.hasText(deleteUserAuthoritiesSql);
|
||||
Assert.hasText(deleteUserAuthoritiesSql,"deleteUserAuthoritiesSql should have text");;
|
||||
this.deleteUserAuthoritiesSql = deleteUserAuthoritiesSql;
|
||||
}
|
||||
|
||||
public void setUserExistsSql(String userExistsSql) {
|
||||
Assert.hasText(userExistsSql);
|
||||
Assert.hasText(userExistsSql,"userExistsSql should have text");;
|
||||
this.userExistsSql = userExistsSql;
|
||||
}
|
||||
|
||||
public void setChangePasswordSql(String changePasswordSql) {
|
||||
Assert.hasText(changePasswordSql);
|
||||
Assert.hasText(changePasswordSql,"changePasswordSql should have text");;
|
||||
this.changePasswordSql = changePasswordSql;
|
||||
}
|
||||
|
||||
public void setFindAllGroupsSql(String findAllGroupsSql) {
|
||||
Assert.hasText(findAllGroupsSql);
|
||||
Assert.hasText(findAllGroupsSql,"findAllGroupsSql should have text");;
|
||||
this.findAllGroupsSql = findAllGroupsSql;
|
||||
}
|
||||
|
||||
public void setFindUsersInGroupSql(String findUsersInGroupSql) {
|
||||
Assert.hasText(findUsersInGroupSql);
|
||||
Assert.hasText(findUsersInGroupSql,"findUsersInGroupSql should have text");;
|
||||
this.findUsersInGroupSql = findUsersInGroupSql;
|
||||
}
|
||||
|
||||
public void setInsertGroupSql(String insertGroupSql) {
|
||||
Assert.hasText(insertGroupSql);
|
||||
Assert.hasText(insertGroupSql,"insertGroupSql should have text");;
|
||||
this.insertGroupSql = insertGroupSql;
|
||||
}
|
||||
|
||||
public void setFindGroupIdSql(String findGroupIdSql) {
|
||||
Assert.hasText(findGroupIdSql);
|
||||
Assert.hasText(findGroupIdSql,"findGroupIdSql should have text");;
|
||||
this.findGroupIdSql = findGroupIdSql;
|
||||
}
|
||||
|
||||
public void setInsertGroupAuthoritySql(String insertGroupAuthoritySql) {
|
||||
Assert.hasText(insertGroupAuthoritySql);
|
||||
Assert.hasText(insertGroupAuthoritySql,"insertGroupAuthoritySql should have text");;
|
||||
this.insertGroupAuthoritySql = insertGroupAuthoritySql;
|
||||
}
|
||||
|
||||
public void setDeleteGroupSql(String deleteGroupSql) {
|
||||
Assert.hasText(deleteGroupSql);
|
||||
Assert.hasText(deleteGroupSql,"deleteGroupSql should have text");;
|
||||
this.deleteGroupSql = deleteGroupSql;
|
||||
}
|
||||
|
||||
public void setDeleteGroupAuthoritiesSql(String deleteGroupAuthoritiesSql) {
|
||||
Assert.hasText(deleteGroupAuthoritiesSql);
|
||||
Assert.hasText(deleteGroupAuthoritiesSql,"deleteGroupAuthoritiesSql should have text");;
|
||||
this.deleteGroupAuthoritiesSql = deleteGroupAuthoritiesSql;
|
||||
}
|
||||
|
||||
public void setDeleteGroupMembersSql(String deleteGroupMembersSql) {
|
||||
Assert.hasText(deleteGroupMembersSql);
|
||||
Assert.hasText(deleteGroupMembersSql,"deleteGroupMembersSql should have text");;
|
||||
this.deleteGroupMembersSql = deleteGroupMembersSql;
|
||||
}
|
||||
|
||||
public void setRenameGroupSql(String renameGroupSql) {
|
||||
Assert.hasText(renameGroupSql);
|
||||
Assert.hasText(renameGroupSql,"renameGroupSql should have text");;
|
||||
this.renameGroupSql = renameGroupSql;
|
||||
}
|
||||
|
||||
public void setInsertGroupMemberSql(String insertGroupMemberSql) {
|
||||
Assert.hasText(insertGroupMemberSql);
|
||||
Assert.hasText(insertGroupMemberSql,"insertGroupMemberSql should have text");;
|
||||
this.insertGroupMemberSql = insertGroupMemberSql;
|
||||
}
|
||||
|
||||
public void setDeleteGroupMemberSql(String deleteGroupMemberSql) {
|
||||
Assert.hasText(deleteGroupMemberSql);
|
||||
Assert.hasText(deleteGroupMemberSql,"deleteGroupMemberSql should have text");;
|
||||
this.deleteGroupMemberSql = deleteGroupMemberSql;
|
||||
}
|
||||
|
||||
public void setGroupAuthoritiesSql(String groupAuthoritiesSql) {
|
||||
Assert.hasText(groupAuthoritiesSql);
|
||||
Assert.hasText(groupAuthoritiesSql,"groupAuthoritiesSql should have text");;
|
||||
this.groupAuthoritiesSql = groupAuthoritiesSql;
|
||||
}
|
||||
|
||||
public void setDeleteGroupAuthoritySql(String deleteGroupAuthoritySql) {
|
||||
Assert.hasText(deleteGroupAuthoritySql);
|
||||
Assert.hasText(deleteGroupAuthoritySql,"deleteGroupAuthoritySql should have text");;
|
||||
this.deleteGroupAuthoritySql = deleteGroupAuthoritySql;
|
||||
}
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@ public class InMemoryResource extends AbstractResource {
|
||||
}
|
||||
|
||||
public InMemoryResource(byte[] source, String description) {
|
||||
Assert.notNull(source);
|
||||
Assert.notNull(source, "source cannot be null");
|
||||
this.source = source;
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
+6
-6
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2017 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.
|
||||
@@ -56,7 +56,7 @@ public class Jsr250MethodSecurityMetadataSourceTests {
|
||||
@Test
|
||||
public void methodWithRolesAllowedHasCorrectAttribute() throws Exception {
|
||||
ConfigAttribute[] accessAttributes = findAttributes("adminMethod");
|
||||
assertThat(accessAttributes.length).isEqualTo(1);
|
||||
assertThat(accessAttributes).hasSize(1);
|
||||
assertThat(accessAttributes[0].toString()).isEqualTo("ROLE_ADMIN");
|
||||
}
|
||||
|
||||
@@ -95,7 +95,7 @@ public class Jsr250MethodSecurityMetadataSourceTests {
|
||||
this.mds.setDefaultRolePrefix("CUSTOMPREFIX_");
|
||||
|
||||
ConfigAttribute[] accessAttributes = findAttributes("adminMethod");
|
||||
assertThat(accessAttributes.length).isEqualTo(1);
|
||||
assertThat(accessAttributes).hasSize(1);
|
||||
assertThat(accessAttributes[0].toString()).isEqualTo("CUSTOMPREFIX_ADMIN");
|
||||
}
|
||||
|
||||
@@ -104,7 +104,7 @@ public class Jsr250MethodSecurityMetadataSourceTests {
|
||||
this.mds.setDefaultRolePrefix("");
|
||||
|
||||
ConfigAttribute[] accessAttributes = findAttributes("adminMethod");
|
||||
assertThat(accessAttributes.length).isEqualTo(1);
|
||||
assertThat(accessAttributes).hasSize(1);
|
||||
assertThat(accessAttributes[0].toString()).isEqualTo("ADMIN");
|
||||
}
|
||||
|
||||
@@ -113,14 +113,14 @@ public class Jsr250MethodSecurityMetadataSourceTests {
|
||||
this.mds.setDefaultRolePrefix(null);
|
||||
|
||||
ConfigAttribute[] accessAttributes = findAttributes("adminMethod");
|
||||
assertThat(accessAttributes.length).isEqualTo(1);
|
||||
assertThat(accessAttributes).hasSize(1);
|
||||
assertThat(accessAttributes[0].toString()).isEqualTo("ADMIN");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void alreadyHasDefaultPrefix() throws Exception {
|
||||
ConfigAttribute[] accessAttributes = findAttributes("roleAdminMethod");
|
||||
assertThat(accessAttributes.length).isEqualTo(1);
|
||||
assertThat(accessAttributes).hasSize(1);
|
||||
assertThat(accessAttributes[0].toString()).isEqualTo("ROLE_ADMIN");
|
||||
}
|
||||
|
||||
|
||||
+10
-13
@@ -137,8 +137,6 @@ public class SecuredAnnotationSecurityMetadataSourceTests {
|
||||
Collection<ConfigAttribute> attrs = this.mds.findAttributes(method,
|
||||
BusinessService.class);
|
||||
|
||||
assertThat(attrs).isNotNull();
|
||||
|
||||
// expect 2 attributes
|
||||
assertThat(attrs).hasSize(2);
|
||||
|
||||
@@ -147,7 +145,7 @@ public class SecuredAnnotationSecurityMetadataSourceTests {
|
||||
|
||||
// should have 2 SecurityConfigs
|
||||
for (ConfigAttribute sc : attrs) {
|
||||
assertThat(sc instanceof SecurityConfig).isTrue();
|
||||
assertThat(sc).isInstanceOf(SecurityConfig.class);
|
||||
|
||||
if (sc.getAttribute().equals("ROLE_USER")) {
|
||||
user = true;
|
||||
@@ -158,7 +156,7 @@ public class SecuredAnnotationSecurityMetadataSourceTests {
|
||||
}
|
||||
|
||||
// expect to have ROLE_USER and ROLE_ADMIN
|
||||
assertThat(user && admin).isTrue();
|
||||
assertThat(user).isEqualTo(admin).isTrue();
|
||||
}
|
||||
|
||||
// SEC-1491
|
||||
@@ -168,8 +166,7 @@ public class SecuredAnnotationSecurityMetadataSourceTests {
|
||||
new CustomSecurityAnnotationMetadataExtractor());
|
||||
Collection<ConfigAttribute> attrs = mds.findAttributes(
|
||||
CustomAnnotatedService.class);
|
||||
assertThat(attrs).hasSize(1);
|
||||
assertThat(attrs.toArray()[0]).isEqualTo(SecurityEnum.ADMIN);
|
||||
assertThat(attrs).containsOnly(SecurityEnum.ADMIN);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -181,8 +178,8 @@ public class SecuredAnnotationSecurityMetadataSourceTests {
|
||||
ConfigAttribute[] attrs = mds.getAttributes(annotatedAtClassLevel).toArray(
|
||||
new ConfigAttribute[0]);
|
||||
|
||||
assertThat(attrs.length).isEqualTo(1);
|
||||
assertThat(attrs[0].getAttribute()).isEqualTo("CUSTOM");
|
||||
assertThat(attrs).hasSize(1);
|
||||
assertThat(attrs).extracting("attribute").containsOnly("CUSTOM");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -194,8 +191,8 @@ public class SecuredAnnotationSecurityMetadataSourceTests {
|
||||
ConfigAttribute[] attrs = mds.getAttributes(annotatedAtInterfaceLevel).toArray(
|
||||
new ConfigAttribute[0]);
|
||||
|
||||
assertThat(attrs.length).isEqualTo(1);
|
||||
assertThat(attrs[0].getAttribute()).isEqualTo("CUSTOM");
|
||||
assertThat(attrs).hasSize(1);
|
||||
assertThat(attrs).extracting("attribute").containsOnly("CUSTOM");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -206,15 +203,15 @@ public class SecuredAnnotationSecurityMetadataSourceTests {
|
||||
ConfigAttribute[] attrs = mds.getAttributes(annotatedAtMethodLevel).toArray(
|
||||
new ConfigAttribute[0]);
|
||||
|
||||
assertThat(attrs.length).isEqualTo(1);
|
||||
assertThat(attrs[0].getAttribute()).isEqualTo("CUSTOM");
|
||||
assertThat(attrs).hasSize(1);
|
||||
assertThat(attrs).extracting("attribute").containsOnly("CUSTOM");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void proxyFactoryInterfaceAttributesFound() throws Exception {
|
||||
MockMethodInvocation mi = MethodInvocationFactory.createSec2150MethodInvocation();
|
||||
Collection<ConfigAttribute> attributes = mds.getAttributes(mi);
|
||||
assertThat(attributes.size()).isEqualTo(1);
|
||||
assertThat(attributes).hasSize(1);
|
||||
assertThat(attributes).extracting("attribute").containsOnly("ROLE_PERSON");
|
||||
}
|
||||
|
||||
|
||||
+11
-11
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2017 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.
|
||||
@@ -89,7 +89,7 @@ public class PrePostAnnotationSecurityMetadataSourceTests {
|
||||
ConfigAttribute[] attrs = mds.getAttributes(voidImpl1).toArray(
|
||||
new ConfigAttribute[0]);
|
||||
|
||||
assertThat(attrs.length).isEqualTo(1);
|
||||
assertThat(attrs).hasSize(1);
|
||||
assertThat(attrs[0] instanceof PreInvocationExpressionAttribute).isTrue();
|
||||
PreInvocationExpressionAttribute pre = (PreInvocationExpressionAttribute) attrs[0];
|
||||
assertThat(pre.getAuthorizeExpression()).isNotNull();
|
||||
@@ -102,7 +102,7 @@ public class PrePostAnnotationSecurityMetadataSourceTests {
|
||||
ConfigAttribute[] attrs = mds.getAttributes(voidImpl2).toArray(
|
||||
new ConfigAttribute[0]);
|
||||
|
||||
assertThat(attrs.length).isEqualTo(1);
|
||||
assertThat(attrs).hasSize(1);
|
||||
assertThat(attrs[0] instanceof PreInvocationExpressionAttribute).isTrue();
|
||||
PreInvocationExpressionAttribute pre = (PreInvocationExpressionAttribute) attrs[0];
|
||||
assertThat(pre.getAuthorizeExpression().getExpressionString()).isEqualTo("someExpression");
|
||||
@@ -115,7 +115,7 @@ public class PrePostAnnotationSecurityMetadataSourceTests {
|
||||
ConfigAttribute[] attrs = mds.getAttributes(voidImpl3).toArray(
|
||||
new ConfigAttribute[0]);
|
||||
|
||||
assertThat(attrs.length).isEqualTo(1);
|
||||
assertThat(attrs).hasSize(1);
|
||||
assertThat(attrs[0] instanceof PreInvocationExpressionAttribute).isTrue();
|
||||
PreInvocationExpressionAttribute pre = (PreInvocationExpressionAttribute) attrs[0];
|
||||
assertThat(pre.getAuthorizeExpression().getExpressionString()).isEqualTo("permitAll");
|
||||
@@ -128,7 +128,7 @@ public class PrePostAnnotationSecurityMetadataSourceTests {
|
||||
ConfigAttribute[] attrs = mds.getAttributes(listImpl1).toArray(
|
||||
new ConfigAttribute[0]);
|
||||
|
||||
assertThat(attrs.length).isEqualTo(2);
|
||||
assertThat(attrs).hasSize(2);
|
||||
assertThat(attrs[0] instanceof PreInvocationExpressionAttribute).isTrue();
|
||||
assertThat(attrs[1] instanceof PostInvocationExpressionAttribute).isTrue();
|
||||
PreInvocationExpressionAttribute pre = (PreInvocationExpressionAttribute) attrs[0];
|
||||
@@ -143,7 +143,7 @@ public class PrePostAnnotationSecurityMetadataSourceTests {
|
||||
ConfigAttribute[] attrs = mds.getAttributes(notherListImpl1).toArray(
|
||||
new ConfigAttribute[0]);
|
||||
|
||||
assertThat(attrs.length).isEqualTo(1);
|
||||
assertThat(attrs).hasSize(1);
|
||||
assertThat(attrs[0] instanceof PreInvocationExpressionAttribute).isTrue();
|
||||
PreInvocationExpressionAttribute pre = (PreInvocationExpressionAttribute) attrs[0];
|
||||
assertThat(pre.getFilterExpression()).isNotNull();
|
||||
@@ -157,7 +157,7 @@ public class PrePostAnnotationSecurityMetadataSourceTests {
|
||||
ConfigAttribute[] attrs = mds.getAttributes(notherListImpl2).toArray(
|
||||
new ConfigAttribute[0]);
|
||||
|
||||
assertThat(attrs.length).isEqualTo(1);
|
||||
assertThat(attrs).hasSize(1);
|
||||
assertThat(attrs[0] instanceof PreInvocationExpressionAttribute).isTrue();
|
||||
PreInvocationExpressionAttribute pre = (PreInvocationExpressionAttribute) attrs[0];
|
||||
assertThat(pre.getFilterExpression()).isNotNull();
|
||||
@@ -171,7 +171,7 @@ public class PrePostAnnotationSecurityMetadataSourceTests {
|
||||
ConfigAttribute[] attrs = mds.getAttributes(annotatedAtClassLevel).toArray(
|
||||
new ConfigAttribute[0]);
|
||||
|
||||
assertThat(attrs.length).isEqualTo(1);
|
||||
assertThat(attrs).hasSize(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -179,7 +179,7 @@ public class PrePostAnnotationSecurityMetadataSourceTests {
|
||||
ConfigAttribute[] attrs = mds.getAttributes(annotatedAtInterfaceLevel).toArray(
|
||||
new ConfigAttribute[0]);
|
||||
|
||||
assertThat(attrs.length).isEqualTo(1);
|
||||
assertThat(attrs).hasSize(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -187,14 +187,14 @@ public class PrePostAnnotationSecurityMetadataSourceTests {
|
||||
ConfigAttribute[] attrs = mds.getAttributes(annotatedAtMethodLevel).toArray(
|
||||
new ConfigAttribute[0]);
|
||||
|
||||
assertThat(attrs.length).isEqualTo(1);
|
||||
assertThat(attrs).hasSize(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void proxyFactoryInterfaceAttributesFound() throws Exception {
|
||||
MockMethodInvocation mi = MethodInvocationFactory.createSec2150MethodInvocation();
|
||||
Collection<ConfigAttribute> attributes = mds.getAttributes(mi);
|
||||
assertThat(attributes.size()).isEqualTo(1);
|
||||
assertThat(attributes).hasSize(1);
|
||||
Expression expression = (Expression) ReflectionTestUtils.getField(attributes
|
||||
.iterator().next(), "authorizeExpression");
|
||||
assertThat(expression.getExpressionString()).isEqualTo("hasRole('ROLE_PERSON')");
|
||||
|
||||
+1
-1
@@ -74,7 +74,7 @@ public abstract class HierarchicalRolesTestHelper {
|
||||
List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>(roles.length);
|
||||
|
||||
for (final String role : roles) {
|
||||
// Use non GrantedAuthorityImpl (SEC-863)
|
||||
// Use non SimpleGrantedAuthority (SEC-863)
|
||||
authorities.add(new GrantedAuthority() {
|
||||
public String getAuthority() {
|
||||
return role;
|
||||
|
||||
+7
-1
@@ -28,10 +28,16 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
* @author Joe Grandja
|
||||
*/
|
||||
public class RoleHierarchyUtilsTests {
|
||||
private static final String EOL = System.lineSeparator();
|
||||
|
||||
@Test
|
||||
public void roleHierarchyFromMapWhenMapValidThenConvertsCorrectly() throws Exception {
|
||||
String expectedRoleHierarchy = "ROLE_A > ROLE_B\nROLE_A > ROLE_C\nROLE_B > ROLE_D\nROLE_C > ROLE_D\n";
|
||||
// @formatter:off
|
||||
String expectedRoleHierarchy = "ROLE_A > ROLE_B" + EOL +
|
||||
"ROLE_A > ROLE_C" + EOL +
|
||||
"ROLE_B > ROLE_D" + EOL +
|
||||
"ROLE_C > ROLE_D" + EOL;
|
||||
// @formatter:on
|
||||
|
||||
Map<String, List<String>> roleHierarchyMap = new TreeMap<String, List<String>>();
|
||||
roleHierarchyMap.put("ROLE_A", asList("ROLE_B", "ROLE_C"));
|
||||
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2017 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.
|
||||
@@ -181,12 +181,12 @@ public class TestHelperTests {
|
||||
public void testCreateAuthorityList() {
|
||||
List<GrantedAuthority> authorities1 = HierarchicalRolesTestHelper
|
||||
.createAuthorityList("ROLE_A");
|
||||
assertThat(1).isEqualTo(authorities1.size());
|
||||
assertThat(authorities1).hasSize(1);
|
||||
assertThat(authorities1.get(0).getAuthority()).isEqualTo("ROLE_A");
|
||||
|
||||
List<GrantedAuthority> authorities2 = HierarchicalRolesTestHelper
|
||||
.createAuthorityList("ROLE_A", "ROLE_C");
|
||||
assertThat(2).isEqualTo(authorities2.size());
|
||||
assertThat(authorities2).hasSize(2);
|
||||
assertThat(authorities2.get(0).getAuthority()).isEqualTo("ROLE_A");
|
||||
assertThat(authorities2.get(1).getAuthority()).isEqualTo("ROLE_C");
|
||||
}
|
||||
|
||||
+1
-1
@@ -87,7 +87,7 @@ public class AbstractAccessDecisionManagerTests {
|
||||
list.add(voter);
|
||||
list.add(denyVoter);
|
||||
MockDecisionManagerImpl mock = new MockDecisionManagerImpl(list);
|
||||
assertThat(mock.getDecisionVoters().size()).isEqualTo(list.size());
|
||||
assertThat(mock.getDecisionVoters()).hasSize(list.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
+4
-4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2017 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.
|
||||
@@ -48,7 +48,7 @@ public class DefaultSecurityParameterNameDiscovererTests {
|
||||
List<ParameterNameDiscoverer> discoverers = (List<ParameterNameDiscoverer>) ReflectionTestUtils
|
||||
.getField(discoverer, "parameterNameDiscoverers");
|
||||
|
||||
assertThat(discoverers.size()).isEqualTo(2);
|
||||
assertThat(discoverers).hasSize(2);
|
||||
|
||||
ParameterNameDiscoverer annotationDisc = discoverers.get(0);
|
||||
assertThat(annotationDisc).isInstanceOf(AnnotationParameterNameDiscoverer.class);
|
||||
@@ -68,7 +68,7 @@ public class DefaultSecurityParameterNameDiscovererTests {
|
||||
List<ParameterNameDiscoverer> discoverers = (List<ParameterNameDiscoverer>) ReflectionTestUtils
|
||||
.getField(discoverer, "parameterNameDiscoverers");
|
||||
|
||||
assertThat(discoverers.size()).isEqualTo(3);
|
||||
assertThat(discoverers).hasSize(3);
|
||||
assertThat(discoverers.get(0)).isInstanceOf(
|
||||
LocalVariableTableParameterNameDiscoverer.class);
|
||||
|
||||
@@ -78,7 +78,7 @@ public class DefaultSecurityParameterNameDiscovererTests {
|
||||
annotationDisc, "annotationClassesToUse");
|
||||
assertThat(annotationsToUse).containsOnly(P.class.getName());
|
||||
|
||||
assertThat(discoverers.get(2).getClass()).isEqualTo(
|
||||
assertThat(discoverers.get(2)).isInstanceOf(
|
||||
DefaultParameterNameDiscoverer.class);
|
||||
}
|
||||
}
|
||||
+135
@@ -0,0 +1,135 @@
|
||||
/*
|
||||
* Copyright 2015-2017 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.jackson2;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonAutoDetect;
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreType;
|
||||
import com.fasterxml.jackson.annotation.JsonTypeInfo;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
import java.util.HashMap;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.fail;
|
||||
|
||||
/**
|
||||
* @author Rob Winch
|
||||
* @since 5.0
|
||||
*/
|
||||
public class SecurityJackson2ModulesTests {
|
||||
private ObjectMapper mapper;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
mapper = new ObjectMapper();
|
||||
SecurityJackson2Modules.enableDefaultTyping(mapper);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void readValueWhenNotWhitelistedOrMappedThenThrowsException() throws Exception {
|
||||
String content = "{\"@class\":\"org.springframework.security.jackson2.SecurityJackson2ModulesTests$NotWhitelisted\",\"property\":\"bar\"}";
|
||||
try {
|
||||
mapper.readValue(content, Object.class);
|
||||
fail("Expected Exception");
|
||||
} catch(RuntimeException e) {
|
||||
assertThat(e).hasMessageContaining("whitelisted");
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void readValueWhenExplicitDefaultTypingAfterSecuritySetupThenReadsAsSpecificType() throws Exception {
|
||||
mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);
|
||||
String content = "{\"@class\":\"org.springframework.security.jackson2.SecurityJackson2ModulesTests$NotWhitelisted\",\"property\":\"bar\"}";
|
||||
|
||||
assertThat(mapper.readValue(content, Object.class)).isInstanceOf(NotWhitelisted.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void readValueWhenExplicitDefaultTypingBeforeSecuritySetupThenReadsAsSpecificType() throws Exception {
|
||||
mapper = new ObjectMapper();
|
||||
mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);
|
||||
SecurityJackson2Modules.enableDefaultTyping(mapper);
|
||||
String content = "{\"@class\":\"org.springframework.security.jackson2.SecurityJackson2ModulesTests$NotWhitelisted\",\"property\":\"bar\"}";
|
||||
|
||||
assertThat(mapper.readValue(content, Object.class)).isInstanceOf(NotWhitelisted.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void readValueWhenAnnotatedThenReadsAsSpecificType() throws Exception {
|
||||
String content = "{\"@class\":\"org.springframework.security.jackson2.SecurityJackson2ModulesTests$NotWhitelistedButAnnotated\",\"property\":\"bar\"}";
|
||||
|
||||
assertThat(mapper.readValue(content, Object.class)).isInstanceOf(NotWhitelistedButAnnotated.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void readValueWhenMixinProvidedThenReadsAsSpecificType() throws Exception {
|
||||
mapper.addMixIn(NotWhitelisted.class, NotWhitelistedMixin.class);
|
||||
String content = "{\"@class\":\"org.springframework.security.jackson2.SecurityJackson2ModulesTests$NotWhitelisted\",\"property\":\"bar\"}";
|
||||
|
||||
assertThat(mapper.readValue(content, Object.class)).isInstanceOf(NotWhitelisted.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void readValueWhenHashMapThenReadsAsSpecificType() throws Exception {
|
||||
mapper.addMixIn(NotWhitelisted.class, NotWhitelistedMixin.class);
|
||||
String content = "{\"@class\":\"java.util.HashMap\"}";
|
||||
|
||||
assertThat(mapper.readValue(content, Object.class)).isInstanceOf(HashMap.class);
|
||||
}
|
||||
|
||||
@Target({ ElementType.TYPE, ElementType.ANNOTATION_TYPE })
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
public @interface NotJacksonAnnotation {}
|
||||
|
||||
@NotJacksonAnnotation
|
||||
static class NotWhitelisted {
|
||||
private String property = "bar";
|
||||
|
||||
public String getProperty() {
|
||||
return property;
|
||||
}
|
||||
|
||||
public void setProperty(String property) {
|
||||
}
|
||||
}
|
||||
|
||||
@JsonIgnoreType(false)
|
||||
static class NotWhitelistedButAnnotated {
|
||||
private String property = "bar";
|
||||
|
||||
public String getProperty() {
|
||||
return property;
|
||||
}
|
||||
|
||||
public void setProperty(String property) {
|
||||
}
|
||||
}
|
||||
|
||||
@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY)
|
||||
@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY, getterVisibility = JsonAutoDetect.Visibility.NONE,
|
||||
isGetterVisibility = JsonAutoDetect.Visibility.NONE)
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
abstract class NotWhitelistedMixin {
|
||||
|
||||
}
|
||||
}
|
||||
+64
-1
@@ -17,20 +17,24 @@
|
||||
package org.springframework.security.jackson2;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonClassDescription;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import org.json.JSONException;
|
||||
import org.junit.Test;
|
||||
import org.skyscreamer.jsonassert.JSONAssert;
|
||||
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
||||
import org.springframework.security.core.userdetails.User;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
|
||||
/**
|
||||
* @author Jitendra Singh
|
||||
* @author Greg Turnquist
|
||||
* @since 4.2
|
||||
*/
|
||||
public class UsernamePasswordAuthenticationTokenMixinTests extends AbstractMixinTests {
|
||||
@@ -49,6 +53,20 @@ public class UsernamePasswordAuthenticationTokenMixinTests extends AbstractMixin
|
||||
public static final String AUTHENTICATED_STRINGPRINCIPAL_JSON = AUTHENTICATED_JSON.replace( UserDeserializerTests.USER_JSON, "\"admin\"");
|
||||
// @formatter:on
|
||||
|
||||
// @formatter:off
|
||||
private static final String NON_USER_PRINCIPAL_JSON = "{"
|
||||
+ "\"@class\": \"org.springframework.security.jackson2.UsernamePasswordAuthenticationTokenMixinTests$NonUserPrincipal\", "
|
||||
+ "\"username\": \"admin\""
|
||||
+ "}";
|
||||
// @formatter:on
|
||||
|
||||
// @formatter:off
|
||||
private static final String AUTHENTICATED_NON_USER_PRINCIPAL_JSON = AUTHENTICATED_JSON
|
||||
.replace(UserDeserializerTests.USER_JSON, NON_USER_PRINCIPAL_JSON)
|
||||
.replaceAll(UserDeserializerTests.USER_PASSWORD, "null")
|
||||
.replace(SimpleGrantedAuthorityMixinTests.AUTHORITIES_ARRAYLIST_JSON, SimpleGrantedAuthorityMixinTests.NO_AUTHORITIES_ARRAYLIST_JSON);
|
||||
// @formatter:on
|
||||
|
||||
// @formatter:off
|
||||
private static final String UNAUTHENTICATED_STRINGPRINCIPAL_JSON = AUTHENTICATED_STRINGPRINCIPAL_JSON
|
||||
.replace("\"authenticated\": true, ", "\"authenticated\": false, ")
|
||||
@@ -115,9 +133,54 @@ public class UsernamePasswordAuthenticationTokenMixinTests extends AbstractMixin
|
||||
JSONAssert.assertEquals(AUTHENTICATED_JSON.replaceAll(UserDeserializerTests.USER_PASSWORD, "null"), actualJson, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void serializeAuthenticatedUsernamePasswordAuthenticationTokenMixinWithNonUserPrincipalTest() throws JsonProcessingException, JSONException {
|
||||
NonUserPrincipal principal = new NonUserPrincipal();
|
||||
principal.setUsername("admin");
|
||||
UsernamePasswordAuthenticationToken token =
|
||||
new UsernamePasswordAuthenticationToken(principal, null, new ArrayList<GrantedAuthority>());
|
||||
String actualJson = mapper.writeValueAsString(token);
|
||||
JSONAssert.assertEquals(AUTHENTICATED_NON_USER_PRINCIPAL_JSON, actualJson, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void deserializeAuthenticatedUsernamePasswordAuthenticationTokenWithNonUserPrincipalTest() throws IOException {
|
||||
UsernamePasswordAuthenticationToken token = mapper
|
||||
.readValue(AUTHENTICATED_NON_USER_PRINCIPAL_JSON, UsernamePasswordAuthenticationToken.class);
|
||||
assertThat(token).isNotNull();
|
||||
assertThat(token.getPrincipal()).isNotNull().isInstanceOf(NonUserPrincipal.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void serializingThenDeserializingWithNoCredentialsOrDetailsShouldWork() throws IOException {
|
||||
// given
|
||||
UsernamePasswordAuthenticationToken original = new UsernamePasswordAuthenticationToken("Frodo", null);
|
||||
|
||||
// when
|
||||
String serialized = this.mapper.writeValueAsString(original);
|
||||
UsernamePasswordAuthenticationToken deserialized = this.mapper.readValue(serialized, UsernamePasswordAuthenticationToken.class);
|
||||
|
||||
// then
|
||||
assertThat(deserialized).isEqualTo(original);
|
||||
}
|
||||
|
||||
|
||||
private UsernamePasswordAuthenticationToken createToken() {
|
||||
User user = createDefaultUser();
|
||||
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(user, user.getPassword(), user.getAuthorities());
|
||||
return token;
|
||||
}
|
||||
|
||||
@JsonClassDescription
|
||||
public static class NonUserPrincipal {
|
||||
private String username;
|
||||
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2017 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.
|
||||
@@ -262,7 +262,7 @@ public class JdbcUserDetailsManagerTests {
|
||||
manager.renameGroup("GROUP_0", "GROUP_X");
|
||||
|
||||
assertThat(template.queryForObject("select id from groups where group_name = 'GROUP_X'",
|
||||
Integer.class)).isEqualTo(0);
|
||||
Integer.class)).isZero();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
+3
-3
@@ -3,7 +3,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-crypto</artifactId>
|
||||
<version>4.2.1.RELEASE</version>
|
||||
<version>4.2.4.RELEASE</version>
|
||||
<name>spring-security-crypto</name>
|
||||
<description>spring-security-crypto</description>
|
||||
<url>http://spring.io/spring-security</url>
|
||||
@@ -35,7 +35,7 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-framework-bom</artifactId>
|
||||
<version>4.3.5.RELEASE</version>
|
||||
<version>4.3.12.RELEASE</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
@@ -83,7 +83,7 @@
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>jcl-over-slf4j</artifactId>
|
||||
<version>1.7.7</version>
|
||||
<version>1.7.25</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
||||
+3
-3
@@ -53,7 +53,7 @@ public class Pbkdf2PasswordEncoder implements PasswordEncoder {
|
||||
|
||||
/**
|
||||
* Constructs a PBKDF2 password encoder with no additional secret value. There will be
|
||||
* 360000 iterations and a hash width of 160. The default is based upon aiming for .5
|
||||
* {@value DEFAULT_ITERATIONS} iterations and a hash width of {@value DEFAULT_HASH_WIDTH}. The default is based upon aiming for .5
|
||||
* seconds to validate the password when this class was added.. Users should tune
|
||||
* password verification to their own systems.
|
||||
*/
|
||||
@@ -63,7 +63,7 @@ public class Pbkdf2PasswordEncoder implements PasswordEncoder {
|
||||
|
||||
/**
|
||||
* Constructs a standard password encoder with a secret value which is also included
|
||||
* in the password hash. There will be 1024 iterations and a hash width of 160.
|
||||
* in the password hash. There will be {@value DEFAULT_ITERATIONS} iterations and a hash width of {@value DEFAULT_HASH_WIDTH}.
|
||||
*
|
||||
* @param secret the secret key used in the encoding process (should not be shared)
|
||||
*/
|
||||
@@ -126,4 +126,4 @@ public class Pbkdf2PasswordEncoder implements PasswordEncoder {
|
||||
throw new IllegalStateException("Could not create hash", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2017 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.
|
||||
@@ -163,7 +163,7 @@ public class SCryptPasswordEncoder implements PasswordEncoder {
|
||||
}
|
||||
|
||||
private String digest(CharSequence rawPassword, byte[] salt) {
|
||||
byte[] derived = SCrypt.generate(Utf8.encode(rawPassword), salt, cpuCost, memoryCost, parallelization, 32);
|
||||
byte[] derived = SCrypt.generate(Utf8.encode(rawPassword), salt, cpuCost, memoryCost, parallelization, keyLength);
|
||||
|
||||
String params = Long
|
||||
.toString(((int) (Math.log(cpuCost) / Math.log(2)) << 16L) | memoryCost << 8 | parallelization, 16);
|
||||
|
||||
@@ -218,21 +218,21 @@ public class BCryptTests {
|
||||
@Test
|
||||
public void decodingCharsOutsideAsciiGivesNoResults() {
|
||||
byte[] ba = BCrypt.decode_base64("ππππππππ", 1);
|
||||
assertThat(ba.length).isEqualTo(0);
|
||||
assertThat(ba).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void decodingStopsWithFirstInvalidCharacter() {
|
||||
assertThat(BCrypt.decode_base64("....", 1).length).isEqualTo(1);
|
||||
assertThat(BCrypt.decode_base64(" ....", 1).length).isEqualTo(0);
|
||||
assertThat(BCrypt.decode_base64("....", 1)).hasSize(1);
|
||||
assertThat(BCrypt.decode_base64(" ....", 1)).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void decodingOnlyProvidesAvailableBytes() {
|
||||
assertThat(BCrypt.decode_base64("", 1).length).isEqualTo(0);
|
||||
assertThat(BCrypt.decode_base64("......", 3).length).isEqualTo(3);
|
||||
assertThat(BCrypt.decode_base64("......", 4).length).isEqualTo(4);
|
||||
assertThat(BCrypt.decode_base64("......", 5).length).isEqualTo(4);
|
||||
assertThat(BCrypt.decode_base64("", 1)).isEmpty();
|
||||
assertThat(BCrypt.decode_base64("......", 3)).hasSize(3);
|
||||
assertThat(BCrypt.decode_base64("......", 4)).hasSize(4);
|
||||
assertThat(BCrypt.decode_base64("......", 5)).hasSize(4);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -268,8 +268,8 @@ public class BCryptTests {
|
||||
|
||||
@Test
|
||||
public void genSaltGeneratesCorrectSaltPrefix() {
|
||||
assertThat(BCrypt.gensalt(4).startsWith("$2a$04$")).isTrue();
|
||||
assertThat(BCrypt.gensalt(31).startsWith("$2a$31$")).isTrue();
|
||||
assertThat(BCrypt.gensalt(4)).startsWith("$2a$04$");
|
||||
assertThat(BCrypt.gensalt(31)).startsWith("$2a$31$");
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2017 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.
|
||||
@@ -30,7 +30,7 @@ public class Utf8Tests {
|
||||
@Test
|
||||
public void utf8EncodesAndDecodesCorrectly() throws Exception {
|
||||
byte[] bytes = Utf8.encode("6048b75ed560785c");
|
||||
assertThat(bytes.length).isEqualTo(16);
|
||||
assertThat(bytes).hasSize(16);
|
||||
assertThat(Arrays.equals("6048b75ed560785c".getBytes("UTF-8"), bytes)).isTrue();
|
||||
|
||||
String decoded = Utf8.decode(bytes);
|
||||
|
||||
+5
-5
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2017 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.
|
||||
@@ -29,7 +29,7 @@ public class KeyGeneratorsTests {
|
||||
BytesKeyGenerator keyGenerator = KeyGenerators.secureRandom();
|
||||
assertThat(keyGenerator.getKeyLength()).isEqualTo(8);
|
||||
byte[] key = keyGenerator.generateKey();
|
||||
assertThat(key.length).isEqualTo(8);
|
||||
assertThat(key).hasSize(8);
|
||||
byte[] key2 = keyGenerator.generateKey();
|
||||
assertThat(Arrays.equals(key, key2)).isFalse();
|
||||
}
|
||||
@@ -39,7 +39,7 @@ public class KeyGeneratorsTests {
|
||||
BytesKeyGenerator keyGenerator = KeyGenerators.secureRandom(21);
|
||||
assertThat(keyGenerator.getKeyLength()).isEqualTo(21);
|
||||
byte[] key = keyGenerator.generateKey();
|
||||
assertThat(key.length).isEqualTo(21);
|
||||
assertThat(key).hasSize(21);
|
||||
byte[] key2 = keyGenerator.generateKey();
|
||||
assertThat(Arrays.equals(key, key2)).isFalse();
|
||||
}
|
||||
@@ -49,7 +49,7 @@ public class KeyGeneratorsTests {
|
||||
BytesKeyGenerator keyGenerator = KeyGenerators.shared(21);
|
||||
assertThat(keyGenerator.getKeyLength()).isEqualTo(21);
|
||||
byte[] key = keyGenerator.generateKey();
|
||||
assertThat(key.length).isEqualTo(21);
|
||||
assertThat(key).hasSize(21);
|
||||
byte[] key2 = keyGenerator.generateKey();
|
||||
assertThat(Arrays.equals(key, key2)).isTrue();
|
||||
}
|
||||
@@ -59,7 +59,7 @@ public class KeyGeneratorsTests {
|
||||
StringKeyGenerator keyGenerator = KeyGenerators.string();
|
||||
String hexStringKey = keyGenerator.generateKey();
|
||||
assertThat(hexStringKey.length()).isEqualTo(16);
|
||||
assertThat(Hex.decode(hexStringKey).length).isEqualTo(8);
|
||||
assertThat(Hex.decode(hexStringKey)).hasSize(8);
|
||||
String hexStringKey2 = keyGenerator.generateKey();
|
||||
assertThat(hexStringKey.equals(hexStringKey2)).isFalse();
|
||||
}
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2017 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.
|
||||
@@ -65,7 +65,7 @@ public class SCryptPasswordEncoderTests {
|
||||
|
||||
@Test
|
||||
public void samePasswordWithDifferentParams() {
|
||||
SCryptPasswordEncoder oldEncoder = new SCryptPasswordEncoder(512, 8, 4, 64, 16);
|
||||
SCryptPasswordEncoder oldEncoder = new SCryptPasswordEncoder(16384, 8, 1, 32,64);
|
||||
SCryptPasswordEncoder newEncoder = new SCryptPasswordEncoder();
|
||||
|
||||
String password = "secret";
|
||||
|
||||
+1
-1
@@ -57,7 +57,7 @@ public class EncodingUtilsTests {
|
||||
(byte) 67, (byte) 0xC0, (byte) 0xC1, (byte) 0xC2 };
|
||||
byte[] two = new byte[] { (byte) 0xFF, (byte) 65, (byte) 66 };
|
||||
byte[] subArray = EncodingUtils.subArray(bytes, 1, 4);
|
||||
assertThat(subArray.length).isEqualTo(3);
|
||||
assertThat(subArray).hasSize(3);
|
||||
assertThat(Arrays.equals(two, subArray)).isTrue();
|
||||
}
|
||||
|
||||
|
||||
+5
-5
@@ -3,7 +3,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-data</artifactId>
|
||||
<version>4.2.1.RELEASE</version>
|
||||
<version>4.2.4.RELEASE</version>
|
||||
<name>spring-security-data</name>
|
||||
<description>spring-security-data</description>
|
||||
<url>http://spring.io/spring-security</url>
|
||||
@@ -35,7 +35,7 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-framework-bom</artifactId>
|
||||
<version>4.3.5.RELEASE</version>
|
||||
<version>4.3.12.RELEASE</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
@@ -45,13 +45,13 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-commons</artifactId>
|
||||
<version>1.12.2.RELEASE</version>
|
||||
<version>1.13.8.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-core</artifactId>
|
||||
<version>4.2.1.RELEASE</version>
|
||||
<version>4.2.4.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@@ -99,7 +99,7 @@
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>jcl-over-slf4j</artifactId>
|
||||
<version>1.7.7</version>
|
||||
<version>1.7.25</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
||||
@@ -431,7 +431,7 @@ To use JDBC instead, you can implement the interface yourself, using whatever SQ
|
||||
* prefix "ROLE_" to mark attributes which are supported by Spring Security's RoleVoter.
|
||||
*/
|
||||
public GrantedAuthority mapRow(ResultSet rs, int rowNum) throws SQLException {
|
||||
return new GrantedAuthorityImpl("ROLE_" + rs.getString(1);
|
||||
return new SimpleGrantedAuthority("ROLE_" + rs.getString(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -944,7 +944,7 @@ public BCryptPasswordEncoder passwordEncoder() {
|
||||
|
||||
=== Multiple HttpSecurity
|
||||
|
||||
We can configure multiple HttpSecurity instances just as we can have multiple `<http>` blocks. The key is to extend the `WebSecurityConfigurationAdapter` multiple times. For example, the following is an example of having a different configuration for URL's that start with `/api/`.
|
||||
We can configure multiple HttpSecurity instances just as we can have multiple `<http>` blocks. The key is to extend the `WebSecurityConfigurerAdapter` multiple times. For example, the following is an example of having a different configuration for URL's that start with `/api/`.
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@@ -2777,7 +2777,7 @@ It's also possible to supply a custom `AccessDeniedHandler` when you're using th
|
||||
|
||||
[[request-caching]]
|
||||
==== SavedRequest s and the RequestCache Interface
|
||||
Another responsibility of `ExceptionTranslationFilter` responsibilities is to save the current request before invoking the `AuthenticationEntryPoint`. This allows the request to be restored after the use has authenticated (see previous overview of <<tech-intro-web-authentication,web authentication>>). A typical example would be where the user logs in with a form, and is then redirected to the original URL by the default `SavedRequestAwareAuthenticationSuccessHandler` (see <<form-login-flow-handling,below>>).
|
||||
Another responsibility of `ExceptionTranslationFilter` responsibilities is to save the current request before invoking the `AuthenticationEntryPoint`. This allows the request to be restored after the user has authenticated (see previous overview of <<tech-intro-web-authentication,web authentication>>). A typical example would be where the user logs in with a form, and is then redirected to the original URL by the default `SavedRequestAwareAuthenticationSuccessHandler` (see <<form-login-flow-handling,below>>).
|
||||
|
||||
The `RequestCache` encapsulates the functionality required for storing and retrieving `HttpServletRequest` instances. By default the `HttpSessionRequestCache` is used, which stores the request in the `HttpSession`. The `RequestCacheFilter` has the job of actually restoring the saved request from the cache when the user is redirected to the original URL.
|
||||
|
||||
@@ -2914,8 +2914,8 @@ The following section describes the Servlet 3 methods that Spring Security integ
|
||||
|
||||
|
||||
[[servletapi-authenticate]]
|
||||
==== HttpServletRequest.authenticate(HttpServletRequest,HttpServletResponse)
|
||||
The http://docs.oracle.com/javaee/6/api/javax/servlet/http/HttpServletRequest.html#authenticate%28javax.servlet.http.HttpServletResponse%29[HttpServletRequest.authenticate(HttpServletRequest,HttpServletResponse)] method can be used to ensure that a user is authenticated. If they are not authenticated, the configured AuthenticationEntryPoint will be used to request the user to authenticate (i.e. redirect to the login page).
|
||||
==== HttpServletRequest.authenticate(HttpServletResponse)
|
||||
The http://docs.oracle.com/javaee/6/api/javax/servlet/http/HttpServletRequest.html#authenticate%28javax.servlet.http.HttpServletResponse%29[HttpServletRequest.authenticate(HttpServletResponse)] method can be used to ensure that a user is authenticated. If they are not authenticated, the configured AuthenticationEntryPoint will be used to request the user to authenticate (i.e. redirect to the login page).
|
||||
|
||||
|
||||
[[servletapi-login]]
|
||||
@@ -3084,7 +3084,7 @@ expirationTime: The date and time when the nonce expires, expressed in millise
|
||||
key: A private key to prevent modification of the nonce token
|
||||
----
|
||||
|
||||
The `DigestAuthenticatonEntryPoint` has a property specifying the `key` used for generating the nonce tokens, along with a `nonceValiditySeconds` property for determining the expiration time (default 300, which equals five minutes). Whist ever the nonce is valid, the digest is computed by concatenating various strings including the username, password, nonce, URI being requested, a client-generated nonce (merely a random value which the user agent generates each request), the realm name etc, then performing an MD5 hash. Both the server and user agent perform this digest computation, resulting in different hash codes if they disagree on an included value (eg password). In Spring Security implementation, if the server-generated nonce has merely expired (but the digest was otherwise valid), the `DigestAuthenticationEntryPoint` will send a `"stale=true"` header. This tells the user agent there is no need to disturb the user (as the password and username etc is correct), but simply to try again using a new nonce.
|
||||
The `DigestAuthenticationEntryPoint` has a property specifying the `key` used for generating the nonce tokens, along with a `nonceValiditySeconds` property for determining the expiration time (default 300, which equals five minutes). Whist ever the nonce is valid, the digest is computed by concatenating various strings including the username, password, nonce, URI being requested, a client-generated nonce (merely a random value which the user agent generates each request), the realm name etc, then performing an MD5 hash. Both the server and user agent perform this digest computation, resulting in different hash codes if they disagree on an included value (eg password). In Spring Security implementation, if the server-generated nonce has merely expired (but the digest was otherwise valid), the `DigestAuthenticationEntryPoint` will send a `"stale=true"` header. This tells the user agent there is no need to disturb the user (as the password and username etc is correct), but simply to try again using a new nonce.
|
||||
|
||||
An appropriate value for the `nonceValiditySeconds` parameter of `DigestAuthenticationEntryPoint` depends on your application. Extremely secure applications should note that an intercepted authentication header can be used to impersonate the principal until the `expirationTime` contained in the nonce is reached. This is the key principle when selecting an appropriate setting, but it would be unusual for immensely secure applications to not be running over TLS/HTTPS in the first instance.
|
||||
|
||||
@@ -4788,7 +4788,7 @@ This method allows
|
||||
|
||||
An example of a "complex" `GrantedAuthority` would be an implementation that stores a list of operations and authority thresholds that apply to different customer account numbers. Representing this complex `GrantedAuthority` as a `String` would be quite difficult, and as a result the `getAuthority()` method should return `null`. This will indicate to any `AccessDecisionManager` that it will need to specifically support the `GrantedAuthority` implementation in order to understand its contents.
|
||||
|
||||
Spring Security includes one concrete `GrantedAuthority` implementation, `GrantedAuthorityImpl`. This allows any user-specified `String` to be converted into a `GrantedAuthority`. All `AuthenticationProvider` s included with the security architecture use `GrantedAuthorityImpl` to populate the `Authentication` object.
|
||||
Spring Security includes one concrete `GrantedAuthority` implementation, `SimpleGrantedAuthority`. This allows any user-specified `String` to be converted into a `GrantedAuthority`. All `AuthenticationProvider` s included with the security architecture use `SimpleGrantedAuthority` to populate the `Authentication` object.
|
||||
|
||||
|
||||
[[authz-pre-invocation]]
|
||||
@@ -5522,16 +5522,16 @@ There is an additional stage where the roles (or attributes) are mapped to Sprin
|
||||
|
||||
|
||||
==== PreAuthenticatedAuthenticationProvider
|
||||
The pre-authenticated provider has little more to do than load the `UserDetails` object for the user. It does this by delegating to a `AuthenticationUserDetailsService`. The latter is similar to the standard `UserDetailsService` but takes an `Authentication` object rather than just user name:
|
||||
The pre-authenticated provider has little more to do than load the `UserDetails` object for the user. It does this by delegating to an `AuthenticationUserDetailsService`. The latter is similar to the standard `UserDetailsService` but takes an `Authentication` object rather than just user name:
|
||||
|
||||
[source,java]
|
||||
----
|
||||
public interface AuthenticationUserDetailsService {
|
||||
UserDetails loadUserDetails(Authentication token) throws UsernameNotFoundException;
|
||||
UserDetails loadUserDetails(Authentication token) throws UsernameNotFoundException;
|
||||
}
|
||||
----
|
||||
|
||||
This interface may have also other uses but with pre-authentication it allows access to the authorities which were packaged in the `Authentication` object, as we saw in the previous section. the `PreAuthenticatedGrantedAuthoritiesUserDetailsService` class does this. Alternatively, it may delegate to a standard `UserDetailsService` via the `UserDetailsByNameServiceWrapper` implementation.
|
||||
This interface may have also other uses but with pre-authentication it allows access to the authorities which were packaged in the `Authentication` object, as we saw in the previous section. The `PreAuthenticatedGrantedAuthoritiesUserDetailsService` class does this. Alternatively, it may delegate to a standard `UserDetailsService` via the `UserDetailsByNameServiceWrapper` implementation.
|
||||
|
||||
==== Http403ForbiddenEntryPoint
|
||||
The `AuthenticationEntryPoint` was discussed in the <<tech-intro-auth-entry-point,technical overview>> chapter. Normally it is responsible for kick-starting the authentication process for an unauthenticated user (when they try to access a protected resource), but in the pre-authenticated case this doesn't apply. You would only configure the `ExceptionTranslationFilter` with an instance of this class if you aren't using pre-authentication in combination with other authentication mechanisms. It will be called if the user is rejected by the `AbstractPreAuthenticatedProcessingFilter` resulting in a null authentication. It always returns a `403`-forbidden response code if called.
|
||||
@@ -6554,7 +6554,7 @@ boolean supports(Class clazz);
|
||||
|
||||
The first method returns the `Authentication` object that should replace the existing `Authentication` object for the duration of the method invocation. If the method returns `null`, it indicates no replacement should be made. The second method is used by the `AbstractSecurityInterceptor` as part of its startup validation of configuration attributes. The `supports(Class)` method is called by a security interceptor implementation to ensure the configured `RunAsManager` supports the type of secure object that the security interceptor will present.
|
||||
|
||||
One concrete implementation of a `RunAsManager` is provided with Spring Security. The `RunAsManagerImpl` class returns a replacement `RunAsUserToken` if any `ConfigAttribute` starts with `RUN_AS_`. If any such `ConfigAttribute` is found, the replacement `RunAsUserToken` will contain the same principal, credentials and granted authorities as the original `Authentication` object, along with a new `GrantedAuthorityImpl` for each `RUN_AS_` `ConfigAttribute`. Each new `GrantedAuthorityImpl` will be prefixed with `ROLE_`, followed by the `RUN_AS` `ConfigAttribute`. For example, a `RUN_AS_SERVER` will result in the replacement `RunAsUserToken` containing a `ROLE_RUN_AS_SERVER` granted authority.
|
||||
One concrete implementation of a `RunAsManager` is provided with Spring Security. The `RunAsManagerImpl` class returns a replacement `RunAsUserToken` if any `ConfigAttribute` starts with `RUN_AS_`. If any such `ConfigAttribute` is found, the replacement `RunAsUserToken` will contain the same principal, credentials and granted authorities as the original `Authentication` object, along with a new `SimpleGrantedAuthority` for each `RUN_AS_` `ConfigAttribute`. Each new `SimpleGrantedAuthority` will be prefixed with `ROLE_`, followed by the `RUN_AS` `ConfigAttribute`. For example, a `RUN_AS_SERVER` will result in the replacement `RunAsUserToken` containing a `ROLE_RUN_AS_SERVER` granted authority.
|
||||
|
||||
The replacement `RunAsUserToken` is just like any other `Authentication` object. It needs to be authenticated by the `AuthenticationManager`, probably via delegation to a suitable `AuthenticationProvider`. The `RunAsImplAuthenticationProvider` performs such authentication. It simply accepts as valid any `RunAsUserToken` presented.
|
||||
|
||||
@@ -6640,7 +6640,7 @@ Use the KeyGenerators.secureRandom factory methods to generate a BytesKeyGenerat
|
||||
|
||||
[source,java]
|
||||
----
|
||||
KeyGenerator generator = KeyGenerators.secureRandom();
|
||||
BytesKeyGenerator generator = KeyGenerators.secureRandom();
|
||||
byte[] key = generator.generateKey();
|
||||
----
|
||||
|
||||
@@ -6865,6 +6865,64 @@ NOTE: Spring Security provides the configuration using Spring MVC's http://docs.
|
||||
Spring Security provides deep integration with how Spring MVC matches on URLs with `MvcRequestMatcher`.
|
||||
This is helpful to ensure your Security rules match the logic used to handle your requests.
|
||||
|
||||
In order to use `MvcRequestMatcher` you must place the Spring Security Configuration in the same `ApplicationContext` as your `DispatcherServlet`.
|
||||
This is necessary because Spring Security's `MvcRequestMatcher` expects a `HandlerMappingIntrospector` bean with the name of `mvcHandlerMappingIntrospector` to be registered by your Spring MVC configuration that is used to perform the matching.
|
||||
|
||||
For a `web.xml` this means that you should place your configuration in the `DispatcherServlet.xml`.
|
||||
|
||||
[source,xml]
|
||||
----
|
||||
<listener>
|
||||
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
|
||||
</listener>
|
||||
|
||||
<!-- All Spring Configuration (both MVC and Security) are in /WEB-INF/spring/ -->
|
||||
<context-param>
|
||||
<param-name>contextConfigLocation</param-name>
|
||||
<param-value>/WEB-INF/spring/*.xml</param-value>
|
||||
</context-param>
|
||||
|
||||
<servlet>
|
||||
<servlet-name>spring</servlet-name>
|
||||
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
|
||||
<!-- Load from the ContextLoaderListener -->
|
||||
<init-param>
|
||||
<param-name>contextConfigLocation</param-name>
|
||||
<param-value></param-value>
|
||||
</init-param>
|
||||
</servlet>
|
||||
|
||||
<servlet-mapping>
|
||||
<servlet-name>spring</servlet-name>
|
||||
<url-pattern>/</url-pattern>
|
||||
</servlet-mapping>
|
||||
----
|
||||
|
||||
Below `WebSecurityConfiguration` in placed in the ``DispatcherServlet``s `ApplicationContext`.
|
||||
|
||||
[source,java]
|
||||
----
|
||||
public class SecurityInitializer extends
|
||||
AbstractAnnotationConfigDispatcherServletInitializer {
|
||||
|
||||
@Override
|
||||
protected Class<?>[] getRootConfigClasses() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class<?>[] getServletConfigClasses() {
|
||||
return new Class[] { RootConfiguration.class,
|
||||
WebMvcConfiguration.class };
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String[] getServletMappings() {
|
||||
return new String[] { "/" };
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
[NOTE]
|
||||
====
|
||||
It is always recommended to provide authorization rules by matching on the `HttpServletRequest` and method security.
|
||||
@@ -7715,7 +7773,7 @@ The attributes on the `<cors>` element control the headers element.
|
||||
Optional attribute that specifies the bean name of a `CorsFilter`.
|
||||
|
||||
[[nsa-cors-configuration-source-ref]]
|
||||
* **ref**
|
||||
* **cors-configuration-source-ref**
|
||||
Optional attribute that specifies the bean name of a `CorsConfigurationSource` to be injected into a `CorsFilter` created by the XML namespace.
|
||||
|
||||
[[nsa-cors-parents]]
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
version=4.2.1.RELEASE
|
||||
version=4.2.4.RELEASE
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
apply plugin: 'spring-boot'
|
||||
apply plugin: 'org.springframework.boot'
|
||||
|
||||
sonarqube {
|
||||
skipProject = true
|
||||
|
||||
@@ -50,6 +50,8 @@ tasks["eclipseJdt"].dependsOn(eclipseJdtPrepare)
|
||||
tasks["cleanEclipse"].dependsOn(cleanEclipseJdtUi)
|
||||
tasks["eclipse"].dependsOn(eclipseCheckstyle, eclipseSettings, eclipseWstComponent)
|
||||
|
||||
task eclipseConfiguration(dependsOn: [eclipseCheckstyle, eclipseSettings, eclipseWstComponent]) {
|
||||
}
|
||||
|
||||
eclipse {
|
||||
classpath {
|
||||
|
||||
+12
-12
@@ -9,19 +9,19 @@ sourceCompatibility = 1.6
|
||||
targetCompatibility = 1.6
|
||||
|
||||
ext.apacheDsVersion = '1.5.5'
|
||||
ext.aspectjVersion = '1.8.4'
|
||||
ext.aspectjVersion = '1.8.12'
|
||||
ext.casClientVersion = '3.4.1'
|
||||
ext.cglibVersion = '3.1'
|
||||
ext.commonsCodecVersion = '1.10'
|
||||
ext.commonsCollectionsVersion = '3.2.2'
|
||||
ext.commonsLoggingVersion = '1.2'
|
||||
ext.ehcacheVersion = '2.9.0'
|
||||
ext.ehcacheVersion = '2.10.4'
|
||||
ext.gebVersion = '0.10.0'
|
||||
ext.groovyVersion = '2.4.4'
|
||||
ext.hsqlVersion = '2.3.2'
|
||||
ext.hibernateVersion = '5.0.11.Final'
|
||||
ext.hibernateValidatorVersion = '5.2.4.Final'
|
||||
ext.jacksonDatabindVersion = '2.8.4'
|
||||
ext.hibernateVersion = '5.0.12.Final'
|
||||
ext.hibernateValidatorVersion = '5.3.6.Final'
|
||||
ext.jacksonDatabindVersion = '2.8.10'
|
||||
ext.javaPersistenceVersion = '2.1.1'
|
||||
ext.jettyVersion = '6.1.26'
|
||||
ext.jstlVersion = '1.2.1'
|
||||
@@ -30,15 +30,15 @@ ext.logbackVersion = '1.1.2'
|
||||
ext.powerMockVersion = '1.6.2'
|
||||
ext.seleniumVersion = '2.44.0'
|
||||
ext.servletApiVersion = '3.1.0'
|
||||
ext.slf4jVersion = '1.7.7'
|
||||
ext.slf4jVersion = '1.7.25'
|
||||
ext.spockVersion = '0.7-groovy-2.0'
|
||||
ext.springDataCommonsVersion = '1.12.2.RELEASE'
|
||||
ext.springDataJpaVersion = '1.10.2.RELEASE'
|
||||
ext.springDataRedisVersion = '1.7.2.RELEASE'
|
||||
ext.springSessionVersion = '1.2.1.RELEASE'
|
||||
ext.springBootVersion = '1.4.0.RELEASE'
|
||||
ext.springDataCommonsVersion = '1.13.8.RELEASE'
|
||||
ext.springDataJpaVersion = '1.11.8.RELEASE'
|
||||
ext.springDataRedisVersion = '1.8.8.RELEASE'
|
||||
ext.springSessionVersion = '1.3.1.RELEASE'
|
||||
ext.springBootVersion = '1.5.8.RELEASE'
|
||||
ext.thymeleafVersion = '3.0.2.RELEASE'
|
||||
ext.jsonassertVersion = '1.3.0'
|
||||
ext.jsonassertVersion = '1.4.0'
|
||||
ext.validationApiVersion = '1.1.0.Final'
|
||||
|
||||
ext.spockDependencies = [
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>itest-context</artifactId>
|
||||
<version>4.2.1.RELEASE</version>
|
||||
<version>4.2.4.RELEASE</version>
|
||||
<name>itest-context</name>
|
||||
<description>itest-context</description>
|
||||
<url>http://spring.io/spring-security</url>
|
||||
@@ -35,7 +35,7 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-framework-bom</artifactId>
|
||||
<version>4.3.5.RELEASE</version>
|
||||
<version>4.3.12.RELEASE</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
@@ -57,7 +57,7 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-core</artifactId>
|
||||
<version>4.2.1.RELEASE</version>
|
||||
<version>4.2.4.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@@ -108,7 +108,7 @@
|
||||
<dependency>
|
||||
<groupId>org.aspectj</groupId>
|
||||
<artifactId>aspectjweaver</artifactId>
|
||||
<version>1.8.4</version>
|
||||
<version>1.8.12</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@@ -126,19 +126,19 @@
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>jcl-over-slf4j</artifactId>
|
||||
<version>1.7.7</version>
|
||||
<version>1.7.25</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-config</artifactId>
|
||||
<version>4.2.1.RELEASE</version>
|
||||
<version>4.2.4.RELEASE</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-web</artifactId>
|
||||
<version>4.2.1.RELEASE</version>
|
||||
<version>4.2.4.RELEASE</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
||||
+9
-7
@@ -28,6 +28,7 @@ import org.springframework.security.authentication.TestingAuthenticationToken;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.security.web.FilterChainProxy;
|
||||
import org.springframework.security.web.context.HttpSessionSecurityContextRepository;
|
||||
import org.springframework.security.web.firewall.RequestRejectedException;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
@@ -40,7 +41,7 @@ public class HttpPathParameterStrippingTests {
|
||||
@Autowired
|
||||
private FilterChainProxy fcp;
|
||||
|
||||
@Test
|
||||
@Test(expected = RequestRejectedException.class)
|
||||
public void securedFilterChainCannotBeBypassedByAddingPathParameters()
|
||||
throws Exception {
|
||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||
@@ -48,24 +49,25 @@ public class HttpPathParameterStrippingTests {
|
||||
request.setSession(createAuthenticatedSession("ROLE_USER"));
|
||||
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
fcp.doFilter(request, response, new MockFilterChain());
|
||||
assertThat(response.getStatus()).isEqualTo(403);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test(expected = RequestRejectedException.class)
|
||||
public void adminFilePatternCannotBeBypassedByAddingPathParameters() throws Exception {
|
||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||
request.setServletPath("/secured/admin.html;x=user.html");
|
||||
request.setSession(createAuthenticatedSession("ROLE_USER"));
|
||||
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
fcp.doFilter(request, response, new MockFilterChain());
|
||||
assertThat(response.getStatus()).isEqualTo(403);
|
||||
}
|
||||
|
||||
// Try with pathInfo
|
||||
request = new MockHttpServletRequest();
|
||||
|
||||
@Test(expected = RequestRejectedException.class)
|
||||
public void adminFilePatternCannotBeBypassedByAddingPathParametersWithPathInfo() throws Exception {
|
||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||
request.setServletPath("/secured");
|
||||
request.setPathInfo("/admin.html;x=user.html");
|
||||
request.setSession(createAuthenticatedSession("ROLE_USER"));
|
||||
response = new MockHttpServletResponse();
|
||||
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
fcp.doFilter(request, response, new MockFilterChain());
|
||||
assertThat(response.getStatus()).isEqualTo(403);
|
||||
}
|
||||
|
||||
+5
-5
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2017 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.
|
||||
@@ -45,14 +45,14 @@ public class SecurityContextHolderMTTests extends TestCase{
|
||||
assertThat(new SecurityContextHolder().toString().isTrue()
|
||||
.lastIndexOf("SecurityContextHolder[strategy='org.springframework.security.context.InheritableThreadLocalSecurityContextHolderStrategy'") != -1);
|
||||
loadStartAndWaitForThreads(true, "Main_", NUM_THREADS, false, true);
|
||||
assertThat(errors).as("Thread errors detected; review log output for details").isEqualTo(0);
|
||||
assertThat(errors).as("Thread errors detected; review log output for details").isZero();
|
||||
}
|
||||
|
||||
public void testSynchronizationGlobal() throws Exception {
|
||||
SecurityContextHolder.clearContext();
|
||||
SecurityContextHolder.setStrategyName(SecurityContextHolder.MODE_GLOBAL);
|
||||
loadStartAndWaitForThreads(true, "Main_", NUM_THREADS, true, false);
|
||||
assertThat(errors).as("Thread errors detected; review log output for details").isEqualTo(0);
|
||||
assertThat(errors).as("Thread errors detected; review log output for details").isZero();
|
||||
}
|
||||
|
||||
public void testSynchronizationInheritableThreadLocal()
|
||||
@@ -60,14 +60,14 @@ public class SecurityContextHolderMTTests extends TestCase{
|
||||
SecurityContextHolder.clearContext();
|
||||
SecurityContextHolder.setStrategyName(SecurityContextHolder.MODE_INHERITABLETHREADLOCAL);
|
||||
loadStartAndWaitForThreads(true, "Main_", NUM_THREADS, false, true);
|
||||
assertThat(errors).as("Thread errors detected; review log output for details").isEqualTo(0);
|
||||
assertThat(errors).as("Thread errors detected; review log output for details").isZero();
|
||||
}
|
||||
|
||||
public void testSynchronizationThreadLocal() throws Exception {
|
||||
SecurityContextHolder.clearContext();
|
||||
SecurityContextHolder.setStrategyName(SecurityContextHolder.MODE_THREADLOCAL);
|
||||
loadStartAndWaitForThreads(true, "Main_", NUM_THREADS, false, false);
|
||||
assertThat(errors).as("Thread errors detected; review log output for details").isEqualTo(0);
|
||||
assertThat(errors).as("Thread errors detected; review log output for details").isZero();
|
||||
}
|
||||
|
||||
private void startAndRun(Thread[] threads) {
|
||||
|
||||
+8
-8
@@ -3,7 +3,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>itest-web</artifactId>
|
||||
<version>4.2.1.RELEASE</version>
|
||||
<version>4.2.4.RELEASE</version>
|
||||
<name>itest-web</name>
|
||||
<description>itest-web</description>
|
||||
<url>http://spring.io/spring-security</url>
|
||||
@@ -35,7 +35,7 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-framework-bom</artifactId>
|
||||
<version>4.3.5.RELEASE</version>
|
||||
<version>4.3.12.RELEASE</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
@@ -92,37 +92,37 @@
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>jcl-over-slf4j</artifactId>
|
||||
<version>1.7.7</version>
|
||||
<version>1.7.25</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-config</artifactId>
|
||||
<version>4.2.1.RELEASE</version>
|
||||
<version>4.2.4.RELEASE</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-core</artifactId>
|
||||
<version>4.2.1.RELEASE</version>
|
||||
<version>4.2.4.RELEASE</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-ldap</artifactId>
|
||||
<version>4.2.1.RELEASE</version>
|
||||
<version>4.2.4.RELEASE</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-test</artifactId>
|
||||
<version>4.2.1.RELEASE</version>
|
||||
<version>4.2.4.RELEASE</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-web</artifactId>
|
||||
<version>4.2.1.RELEASE</version>
|
||||
<version>4.2.4.RELEASE</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
||||
+6
-6
@@ -3,7 +3,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-ldap</artifactId>
|
||||
<version>4.2.1.RELEASE</version>
|
||||
<version>4.2.4.RELEASE</version>
|
||||
<name>spring-security-ldap</name>
|
||||
<description>spring-security-ldap</description>
|
||||
<url>http://spring.io/spring-security</url>
|
||||
@@ -35,7 +35,7 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-framework-bom</artifactId>
|
||||
<version>4.3.5.RELEASE</version>
|
||||
<version>4.3.12.RELEASE</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
@@ -45,7 +45,7 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework.ldap</groupId>
|
||||
<artifactId>spring-ldap-core</artifactId>
|
||||
<version>2.2.0.RELEASE</version>
|
||||
<version>2.3.2.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
@@ -73,7 +73,7 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-core</artifactId>
|
||||
<version>4.2.1.RELEASE</version>
|
||||
<version>4.2.4.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@@ -185,13 +185,13 @@
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>jcl-over-slf4j</artifactId>
|
||||
<version>1.7.7</version>
|
||||
<version>1.7.25</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
<version>1.7.7</version>
|
||||
<version>1.7.25</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
||||
+1
-1
@@ -157,7 +157,7 @@ public class SpringSecurityLdapTemplateITests extends AbstractLdapIntegrationTes
|
||||
protected void assertAttributeValue(Map<String, List<String>> record,
|
||||
String attributeName, String... values) {
|
||||
assertThat(record.containsKey(attributeName)).isTrue();
|
||||
assertThat(record.get(attributeName).size()).isEqualTo(values.length);
|
||||
assertThat(record.get(attributeName)).hasSize(values.length);
|
||||
for (int i = 0; i < values.length; i++) {
|
||||
assertThat(record.get(attributeName).get(i)).isEqualTo(values[i]);
|
||||
}
|
||||
|
||||
+1
-1
@@ -122,7 +122,7 @@ public class NestedLdapAuthoritiesPopulatorTests extends AbstractLdapIntegration
|
||||
circularJavaDevelopers, jDevelopers, groovyDevelopers));
|
||||
|
||||
LdapAuthority[] ldapAuthorities = authorities.toArray(new LdapAuthority[0]);
|
||||
assertThat(ldapAuthorities.length).isEqualTo(5);
|
||||
assertThat(ldapAuthorities).hasSize(5);
|
||||
// closure group
|
||||
assertThat(ldapAuthorities[0].getAttributes().containsKey("member")).isTrue();
|
||||
assertThat(ldapAuthorities[0].getAttributes().get("member")).isNotNull();
|
||||
|
||||
@@ -157,7 +157,7 @@ public final class LdapUtils {
|
||||
* @return the root DN
|
||||
*/
|
||||
public static String parseRootDnFromUrl(String url) {
|
||||
Assert.hasLength(url);
|
||||
Assert.hasLength(url, "url must have length");
|
||||
|
||||
String urlRootDn;
|
||||
|
||||
@@ -187,7 +187,7 @@ public final class LdapUtils {
|
||||
*/
|
||||
|
||||
private static URI parseLdapUrl(String url) {
|
||||
Assert.hasLength(url);
|
||||
Assert.hasLength(url, "url must have length");
|
||||
|
||||
try {
|
||||
return new URI(url);
|
||||
|
||||
+1
-1
@@ -119,7 +119,7 @@ public abstract class AbstractLdapAuthenticator implements LdapAuthenticator,
|
||||
}
|
||||
|
||||
public void setMessageSource(MessageSource messageSource) {
|
||||
Assert.notNull("Message source must not be null");
|
||||
Assert.notNull(messageSource, "Message source must not be null");
|
||||
this.messages = new MessageSourceAccessor(messageSource);
|
||||
}
|
||||
|
||||
|
||||
@@ -159,7 +159,7 @@ public class ApacheDSContainer implements InitializingBean, DisposableBean, Life
|
||||
}
|
||||
|
||||
public void setWorkingDirectory(File workingDir) {
|
||||
Assert.notNull(workingDir);
|
||||
Assert.notNull(workingDir, "workingDir cannot be null");
|
||||
|
||||
logger.info("Setting working directory for LDAP_PROVIDER: "
|
||||
+ workingDir.getAbsolutePath());
|
||||
@@ -239,7 +239,7 @@ public class ApacheDSContainer implements InitializingBean, DisposableBean, Life
|
||||
catch (LdapNameNotFoundException e) {
|
||||
try {
|
||||
LdapDN dn = new LdapDN(root);
|
||||
Assert.isTrue(root.startsWith("dc="));
|
||||
Assert.isTrue(root.startsWith("dc="), "root must start with dc=");
|
||||
String dc = root.substring(3, root.indexOf(','));
|
||||
ServerEntry entry = service.newEntry(dn);
|
||||
entry.add("objectClass", "top", "domain", "extensibleObject");
|
||||
|
||||
+2
-2
@@ -387,7 +387,7 @@ public class LdapUserDetailsManager implements UserDetailsManager {
|
||||
}
|
||||
|
||||
public void setAttributesToRetrieve(String[] attributesToRetrieve) {
|
||||
Assert.notNull(attributesToRetrieve);
|
||||
Assert.notNull(attributesToRetrieve, "attributesToRetrieve cannot be null");
|
||||
this.attributesToRetrieve = attributesToRetrieve;
|
||||
}
|
||||
|
||||
@@ -406,7 +406,7 @@ public class LdapUserDetailsManager implements UserDetailsManager {
|
||||
* members.
|
||||
*/
|
||||
public void setGroupMemberAttributeName(String groupMemberAttributeName) {
|
||||
Assert.hasText(groupMemberAttributeName);
|
||||
Assert.hasText(groupMemberAttributeName, "groupMemberAttributeName should have text");
|
||||
this.groupMemberAttributeName = groupMemberAttributeName;
|
||||
this.groupSearchFilter = "(" + groupMemberAttributeName + "={0})";
|
||||
}
|
||||
|
||||
@@ -139,8 +139,8 @@ public class Person extends LdapUserDetailsImpl {
|
||||
|
||||
public LdapUserDetails createUserDetails() {
|
||||
Person p = (Person) super.createUserDetails();
|
||||
Assert.notNull(p.cn);
|
||||
Assert.notEmpty(p.cn);
|
||||
Assert.notNull(p.cn, "person.sn cannot be null");
|
||||
Assert.notEmpty(p.cn, "person.cn cannot be empty");
|
||||
// TODO: Check contents for null entries
|
||||
return p;
|
||||
}
|
||||
|
||||
+5
-5
@@ -3,7 +3,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-messaging</artifactId>
|
||||
<version>4.2.1.RELEASE</version>
|
||||
<version>4.2.4.RELEASE</version>
|
||||
<name>spring-security-messaging</name>
|
||||
<description>spring-security-messaging</description>
|
||||
<url>http://spring.io/spring-security</url>
|
||||
@@ -35,7 +35,7 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-framework-bom</artifactId>
|
||||
<version>4.3.5.RELEASE</version>
|
||||
<version>4.3.12.RELEASE</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
@@ -51,7 +51,7 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-core</artifactId>
|
||||
<version>4.2.1.RELEASE</version>
|
||||
<version>4.2.4.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@@ -102,7 +102,7 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-web</artifactId>
|
||||
<version>4.2.1.RELEASE</version>
|
||||
<version>4.2.4.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
@@ -199,7 +199,7 @@
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>jcl-over-slf4j</artifactId>
|
||||
<version>1.7.7</version>
|
||||
<version>1.7.25</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2017 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.
|
||||
@@ -80,7 +80,7 @@ public class ExpressionBasedMessageSecurityMetadataSourceFactoryTests {
|
||||
|
||||
Collection<ConfigAttribute> attrs = source.getAttributes(message);
|
||||
|
||||
assertThat(attrs.size()).isEqualTo(1);
|
||||
assertThat(attrs).hasSize(1);
|
||||
ConfigAttribute attr = attrs.iterator().next();
|
||||
assertThat(attr).isInstanceOf(MessageExpressionConfigAttribute.class);
|
||||
assertThat(
|
||||
@@ -94,7 +94,7 @@ public class ExpressionBasedMessageSecurityMetadataSourceFactoryTests {
|
||||
|
||||
Collection<ConfigAttribute> attrs = source.getAttributes(message);
|
||||
|
||||
assertThat(attrs.size()).isEqualTo(1);
|
||||
assertThat(attrs).hasSize(1);
|
||||
ConfigAttribute attr = attrs.iterator().next();
|
||||
assertThat(attr).isInstanceOf(MessageExpressionConfigAttribute.class);
|
||||
assertThat(
|
||||
|
||||
+5
-5
@@ -3,7 +3,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-openid</artifactId>
|
||||
<version>4.2.1.RELEASE</version>
|
||||
<version>4.2.4.RELEASE</version>
|
||||
<name>spring-security-openid</name>
|
||||
<description>spring-security-openid</description>
|
||||
<url>http://spring.io/spring-security</url>
|
||||
@@ -35,7 +35,7 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-framework-bom</artifactId>
|
||||
<version>4.3.5.RELEASE</version>
|
||||
<version>4.3.12.RELEASE</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
@@ -63,13 +63,13 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-core</artifactId>
|
||||
<version>4.2.1.RELEASE</version>
|
||||
<version>4.2.4.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-web</artifactId>
|
||||
<version>4.2.1.RELEASE</version>
|
||||
<version>4.2.4.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@@ -155,7 +155,7 @@
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>jcl-over-slf4j</artifactId>
|
||||
<version>1.7.7</version>
|
||||
<version>1.7.25</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
||||
@@ -45,7 +45,7 @@ public class OpenIDAttribute implements Serializable {
|
||||
}
|
||||
|
||||
public OpenIDAttribute(String name, String type, List<String> values) {
|
||||
Assert.notEmpty(values);
|
||||
Assert.notEmpty(values, "values cannot be empty");
|
||||
this.name = name;
|
||||
this.typeIdentifier = type;
|
||||
this.values = values;
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2017 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.
|
||||
@@ -103,7 +103,7 @@ public class OpenIDAuthenticationFilterTests {
|
||||
URI returnTo = new URI(filter.buildReturnToUrl(req));
|
||||
String query = returnTo.getRawQuery();
|
||||
assertThat(count(query, '=')).isEqualTo(1);
|
||||
assertThat(count(query, '&')).isEqualTo(0);
|
||||
assertThat(count(query, '&')).isZero();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+4
-4
@@ -3,7 +3,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-remoting</artifactId>
|
||||
<version>4.2.1.RELEASE</version>
|
||||
<version>4.2.4.RELEASE</version>
|
||||
<name>spring-security-remoting</name>
|
||||
<description>spring-security-remoting</description>
|
||||
<url>http://spring.io/spring-security</url>
|
||||
@@ -35,7 +35,7 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-framework-bom</artifactId>
|
||||
<version>4.3.5.RELEASE</version>
|
||||
<version>4.3.12.RELEASE</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
@@ -51,7 +51,7 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-core</artifactId>
|
||||
<version>4.2.1.RELEASE</version>
|
||||
<version>4.2.4.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@@ -114,7 +114,7 @@
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>jcl-over-slf4j</artifactId>
|
||||
<version>1.7.7</version>
|
||||
<version>1.7.25</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-samples-boot-helloworld</artifactId>
|
||||
<version>4.2.1.RELEASE</version>
|
||||
<version>4.2.4.RELEASE</version>
|
||||
<name>spring-security-samples-boot-helloworld</name>
|
||||
<description>spring-security-samples-boot-helloworld</description>
|
||||
<url>http://spring.io/spring-security</url>
|
||||
@@ -35,7 +35,7 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-framework-bom</artifactId>
|
||||
<version>4.3.5.RELEASE</version>
|
||||
<version>4.3.12.RELEASE</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
@@ -55,13 +55,13 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-config</artifactId>
|
||||
<version>4.2.1.RELEASE</version>
|
||||
<version>4.2.4.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-web</artifactId>
|
||||
<version>4.2.1.RELEASE</version>
|
||||
<version>4.2.4.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@@ -104,7 +104,7 @@
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>jcl-over-slf4j</artifactId>
|
||||
<version>1.7.7</version>
|
||||
<version>1.7.25</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@@ -115,7 +115,7 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-test</artifactId>
|
||||
<version>4.2.1.RELEASE</version>
|
||||
<version>4.2.4.RELEASE</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
||||
+30
-32
@@ -15,25 +15,22 @@
|
||||
*/
|
||||
package org.springframework.security.samples;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.SpringApplicationConfiguration;
|
||||
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.mock.web.MockHttpSession;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.test.context.web.WebAppConfiguration;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
import org.springframework.test.web.servlet.MvcResult;
|
||||
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
|
||||
import org.springframework.web.context.WebApplicationContext;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestBuilders.formLogin;
|
||||
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf;
|
||||
import static org.springframework.security.test.web.servlet.response.SecurityMockMvcResultMatchers.authenticated;
|
||||
import static org.springframework.security.test.web.servlet.response.SecurityMockMvcResultMatchers.unauthenticated;
|
||||
import static org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers.springSecurity;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
@@ -43,78 +40,79 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
|
||||
* @author Joe Grandja
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@SpringApplicationConfiguration(HelloWorldApplication.class)
|
||||
@WebAppConfiguration
|
||||
@SpringBootTest
|
||||
@AutoConfigureMockMvc
|
||||
public class HelloWorldApplicationTests {
|
||||
|
||||
@Autowired
|
||||
private WebApplicationContext context;
|
||||
|
||||
private MockMvc mockMvc;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
mockMvc = MockMvcBuilders
|
||||
.webAppContextSetup(context)
|
||||
.apply(springSecurity())
|
||||
.build();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void accessUnprotected() throws Exception {
|
||||
this.mockMvc.perform(get("/index")).andExpect(status().isOk());
|
||||
// @formatter:off
|
||||
this.mockMvc.perform(get("/index"))
|
||||
.andExpect(status().isOk());
|
||||
// @formatter:on
|
||||
}
|
||||
|
||||
@Test
|
||||
public void accessProtectedRedirectsToLogin() throws Exception {
|
||||
// @formatter:off
|
||||
MvcResult mvcResult = this.mockMvc.perform(get("/user/index"))
|
||||
.andExpect(status().is3xxRedirection())
|
||||
.andReturn();
|
||||
// @formatter:on
|
||||
|
||||
assertThat(mvcResult.getResponse().getRedirectedUrl()).endsWith("/login");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void loginUser() throws Exception {
|
||||
// @formatter:off
|
||||
this.mockMvc.perform(formLogin().user("user").password("password"))
|
||||
.andExpect(authenticated());
|
||||
// @formatter:on
|
||||
}
|
||||
|
||||
@Test
|
||||
public void loginInvalidUser() throws Exception {
|
||||
// @formatter:off
|
||||
this.mockMvc.perform(formLogin().user("invalid").password("invalid"))
|
||||
.andExpect(unauthenticated())
|
||||
.andExpect(status().is3xxRedirection());
|
||||
// @formatter:on
|
||||
}
|
||||
|
||||
@Test
|
||||
public void loginUserAccessProtected() throws Exception {
|
||||
// @formatter:off
|
||||
MvcResult mvcResult = this.mockMvc.perform(formLogin().user("user").password("password"))
|
||||
.andExpect(authenticated())
|
||||
.andReturn();
|
||||
.andExpect(authenticated()).andReturn();
|
||||
// @formatter:on
|
||||
|
||||
MockHttpSession httpSession = MockHttpSession.class.cast(mvcResult.getRequest().getSession(false));
|
||||
MockHttpSession httpSession = (MockHttpSession) mvcResult.getRequest().getSession(false);
|
||||
|
||||
this.mockMvc.perform(get("/user/index")
|
||||
.session(httpSession))
|
||||
// @formatter:off
|
||||
this.mockMvc.perform(get("/user/index").session(httpSession))
|
||||
.andExpect(status().isOk());
|
||||
// @formatter:on
|
||||
}
|
||||
|
||||
@Test
|
||||
public void loginUserValidateLogout() throws Exception {
|
||||
// @formatter:off
|
||||
MvcResult mvcResult = this.mockMvc.perform(formLogin().user("user").password("password"))
|
||||
.andExpect(authenticated())
|
||||
.andReturn();
|
||||
.andExpect(authenticated()).andReturn();
|
||||
// @formatter:on
|
||||
|
||||
MockHttpSession httpSession = MockHttpSession.class.cast(mvcResult.getRequest().getSession(false));
|
||||
MockHttpSession httpSession = (MockHttpSession) mvcResult.getRequest().getSession(false);
|
||||
|
||||
this.mockMvc.perform(post("/logout").with(csrf())
|
||||
.session(httpSession))
|
||||
// @formatter:off
|
||||
this.mockMvc.perform(post("/logout").with(csrf()).session(httpSession))
|
||||
.andExpect(unauthenticated());
|
||||
|
||||
this.mockMvc.perform(get("/user/index")
|
||||
.session(httpSession))
|
||||
this.mockMvc.perform(get("/user/index").session(httpSession))
|
||||
.andExpect(unauthenticated())
|
||||
.andExpect(status().is3xxRedirection());
|
||||
// @formatter:on
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-samples-boot-insecure</artifactId>
|
||||
<version>4.2.1.RELEASE</version>
|
||||
<version>4.2.4.RELEASE</version>
|
||||
<name>spring-security-samples-boot-insecure</name>
|
||||
<description>spring-security-samples-boot-insecure</description>
|
||||
<url>http://spring.io/spring-security</url>
|
||||
@@ -35,7 +35,7 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-framework-bom</artifactId>
|
||||
<version>4.3.5.RELEASE</version>
|
||||
<version>4.3.12.RELEASE</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
@@ -86,7 +86,7 @@
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>jcl-over-slf4j</artifactId>
|
||||
<version>1.7.7</version>
|
||||
<version>1.7.25</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
||||
+5
-16
@@ -15,16 +15,14 @@
|
||||
*/
|
||||
package org.springframework.security.samples;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.SpringApplicationConfiguration;
|
||||
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.test.context.web.WebAppConfiguration;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
|
||||
import org.springframework.web.context.WebApplicationContext;
|
||||
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
@@ -34,22 +32,13 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
|
||||
* @author Joe Grandja
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@SpringApplicationConfiguration(InsecureApplication.class)
|
||||
@WebAppConfiguration
|
||||
@SpringBootTest
|
||||
@AutoConfigureMockMvc
|
||||
public class InsecureApplicationTests {
|
||||
|
||||
@Autowired
|
||||
private WebApplicationContext context;
|
||||
|
||||
private MockMvc mockMvc;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
mockMvc = MockMvcBuilders
|
||||
.webAppContextSetup(context)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void accessUnprotected() throws Exception {
|
||||
this.mockMvc.perform(get("/index")).andExpect(status().isOk());
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-samples-javaconfig-aspectj</artifactId>
|
||||
<version>4.2.1.RELEASE</version>
|
||||
<version>4.2.4.RELEASE</version>
|
||||
<name>spring-security-samples-javaconfig-aspectj</name>
|
||||
<description>spring-security-samples-javaconfig-aspectj</description>
|
||||
<url>http://spring.io/spring-security</url>
|
||||
@@ -35,7 +35,7 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-framework-bom</artifactId>
|
||||
<version>4.3.5.RELEASE</version>
|
||||
<version>4.3.12.RELEASE</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
@@ -45,13 +45,13 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-config</artifactId>
|
||||
<version>4.2.1.RELEASE</version>
|
||||
<version>4.2.4.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-core</artifactId>
|
||||
<version>4.2.1.RELEASE</version>
|
||||
<version>4.2.4.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@@ -64,14 +64,14 @@
|
||||
<dependency>
|
||||
<groupId>org.aspectj</groupId>
|
||||
<artifactId>aspectjrt</artifactId>
|
||||
<version>1.8.4</version>
|
||||
<version>1.8.12</version>
|
||||
<scope>compile</scope>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-aspects</artifactId>
|
||||
<version>4.2.1.RELEASE</version>
|
||||
<version>4.2.4.RELEASE</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@@ -101,7 +101,7 @@
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>jcl-over-slf4j</artifactId>
|
||||
<version>1.7.7</version>
|
||||
<version>1.7.25</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-samples-javaconfig-concurrency</artifactId>
|
||||
<version>4.2.1.RELEASE</version>
|
||||
<version>4.2.4.RELEASE</version>
|
||||
<packaging>war</packaging>
|
||||
<name>spring-security-samples-javaconfig-concurrency</name>
|
||||
<description>spring-security-samples-javaconfig-concurrency</description>
|
||||
@@ -39,7 +39,7 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-framework-bom</artifactId>
|
||||
<version>4.3.5.RELEASE</version>
|
||||
<version>4.3.12.RELEASE</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
@@ -61,55 +61,55 @@
|
||||
<dependency>
|
||||
<groupId>org.hibernate</groupId>
|
||||
<artifactId>hibernate-validator</artifactId>
|
||||
<version>5.2.4.Final</version>
|
||||
<version>5.3.6.Final</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>jcl-over-slf4j</artifactId>
|
||||
<version>1.7.7</version>
|
||||
<version>1.7.25</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>jul-to-slf4j</artifactId>
|
||||
<version>1.7.7</version>
|
||||
<version>1.7.25</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>log4j-over-slf4j</artifactId>
|
||||
<version>1.7.7</version>
|
||||
<version>1.7.25</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
<version>1.7.7</version>
|
||||
<version>1.7.25</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-config</artifactId>
|
||||
<version>4.2.1.RELEASE</version>
|
||||
<version>4.2.4.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-core</artifactId>
|
||||
<version>4.2.1.RELEASE</version>
|
||||
<version>4.2.4.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-samples-javaconfig-messages</artifactId>
|
||||
<version>4.2.1.RELEASE</version>
|
||||
<version>4.2.4.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-web</artifactId>
|
||||
<version>4.2.1.RELEASE</version>
|
||||
<version>4.2.4.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-samples-javaconfig-data</artifactId>
|
||||
<version>4.2.1.RELEASE</version>
|
||||
<version>4.2.4.RELEASE</version>
|
||||
<name>spring-security-samples-javaconfig-data</name>
|
||||
<description>spring-security-samples-javaconfig-data</description>
|
||||
<url>http://spring.io/spring-security</url>
|
||||
@@ -35,7 +35,7 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-framework-bom</artifactId>
|
||||
<version>4.3.5.RELEASE</version>
|
||||
<version>4.3.12.RELEASE</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
@@ -57,13 +57,13 @@
|
||||
<dependency>
|
||||
<groupId>org.hibernate</groupId>
|
||||
<artifactId>hibernate-entitymanager</artifactId>
|
||||
<version>5.0.11.Final</version>
|
||||
<version>5.0.12.Final</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.hibernate</groupId>
|
||||
<artifactId>hibernate-validator</artifactId>
|
||||
<version>5.2.4.Final</version>
|
||||
<version>5.3.6.Final</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@@ -75,19 +75,19 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-jpa</artifactId>
|
||||
<version>1.10.2.RELEASE</version>
|
||||
<version>1.11.8.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-config</artifactId>
|
||||
<version>4.2.1.RELEASE</version>
|
||||
<version>4.2.4.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-data</artifactId>
|
||||
<version>4.2.1.RELEASE</version>
|
||||
<version>4.2.4.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@@ -124,7 +124,7 @@
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>jcl-over-slf4j</artifactId>
|
||||
<version>1.7.7</version>
|
||||
<version>1.7.25</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2017 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.
|
||||
@@ -63,7 +63,7 @@ public class SecurityMessageRepositoryTests {
|
||||
public void findAllOnlyToCurrentUser() {
|
||||
Long expectedId = user.getId();
|
||||
List<Message> messages = repository.findAll();
|
||||
assertThat(messages.size()).isEqualTo(3);
|
||||
assertThat(messages).hasSize(3);
|
||||
for (Message m : messages) {
|
||||
assertThat(m.getTo().getId()).isEqualTo(expectedId);
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user