Compare commits
58 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 081f0c4d94 | |||
| 247f54dc41 | |||
| 017e9834bd | |||
| 49719480a8 | |||
| f3edaa673a | |||
| f99fe36e02 | |||
| 546d44d6e7 | |||
| 901a4e183a | |||
| 72d08a2a5f | |||
| 2ac51c9c7f | |||
| b64cdb5765 | |||
| aa31f1f695 | |||
| 8353984733 | |||
| c31bdb6390 | |||
| 168f4b8f70 | |||
| 9c03571bbb | |||
| 4c79107e01 | |||
| 3f543d0fbd | |||
| 08104eb06c | |||
| b54d350e54 | |||
| b5e0886bde | |||
| 38492a5794 | |||
| b7541d56d0 | |||
| 7a7ce11ebb | |||
| 028854b936 | |||
| aa5df61eff | |||
| 6df5b76f24 | |||
| c8ed130008 | |||
| d39f3385b6 | |||
| 6bec625e68 | |||
| 666e356ebc | |||
| fc516b55a6 | |||
| bb834bccf6 | |||
| 09436649cc | |||
| f94399cff9 | |||
| 94fb1893de | |||
| 3185876a7d | |||
| 2cb38ae115 | |||
| 24fcb6c45a | |||
| a9024de734 | |||
| fd9f57eb5f | |||
| 7259759f8d | |||
| 14e5e06ae0 | |||
| 697daeab7c | |||
| f97f38fd57 | |||
| a853d38076 | |||
| f0a9421aa4 | |||
| 36f4f7d081 | |||
| 07d1c7c5eb | |||
| d2c28c58e2 | |||
| 14a656186d | |||
| 2a197c72eb | |||
| ab5af87953 | |||
| 23294c4c57 | |||
| eb2870bf82 | |||
| 9fa42117f7 | |||
| cf3d6e7167 | |||
| 08f0b57243 |
+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]
|
||||
|
||||
+3
-9
@@ -3,7 +3,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-acl</artifactId>
|
||||
<version>4.2.0.RC1</version>
|
||||
<version>4.2.2.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.3.RELEASE</version>
|
||||
<version>4.3.5.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.0.RC1</version>
|
||||
<version>4.2.2.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@@ -151,12 +151,6 @@
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>spring-milestone</id>
|
||||
<url>https://repo.spring.io/milestone</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
|
||||
+7
-4
@@ -16,18 +16,20 @@
|
||||
|
||||
package org.springframework.security.acls.domain;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.security.access.AccessDeniedException;
|
||||
import org.springframework.security.acls.model.Acl;
|
||||
import org.springframework.security.acls.model.Sid;
|
||||
import org.springframework.security.acls.model.SidRetrievalStrategy;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.core.authority.AuthorityUtils;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Default implementation of {@link AclAuthorizationStrategy}.
|
||||
* <p>
|
||||
@@ -118,7 +120,8 @@ public class AclAuthorizationStrategyImpl implements AclAuthorizationStrategy {
|
||||
}
|
||||
|
||||
// Iterate this principal's authorities to determine right
|
||||
if (authentication.getAuthorities().contains(requiredAuthority)) {
|
||||
Set<String> authorities = AuthorityUtils.authorityListToSet(authentication.getAuthorities());
|
||||
if (authorities.contains(requiredAuthority.getAuthority())) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
+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();
|
||||
|
||||
|
||||
+72
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright 2002-2016 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.acls.domain;
|
||||
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.runners.MockitoJUnitRunner;
|
||||
import org.springframework.security.acls.model.Acl;
|
||||
import org.springframework.security.authentication.TestingAuthenticationToken;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Rob Winch
|
||||
*
|
||||
*/
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class AclAuthorizationStrategyImplTests {
|
||||
@Mock
|
||||
Acl acl;
|
||||
GrantedAuthority authority;
|
||||
AclAuthorizationStrategyImpl strategy;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
authority = new SimpleGrantedAuthority("ROLE_AUTH");
|
||||
TestingAuthenticationToken authentication = new TestingAuthenticationToken("foo", "bar", Arrays.asList(authority));
|
||||
authentication.setAuthenticated(true);
|
||||
SecurityContextHolder.getContext().setAuthentication(authentication);
|
||||
}
|
||||
|
||||
@After
|
||||
public void cleanup() {
|
||||
SecurityContextHolder.clearContext();
|
||||
}
|
||||
|
||||
// gh-4085
|
||||
@Test
|
||||
public void securityCheckWhenCustomAuthorityThenNameIsUsed() {
|
||||
strategy = new AclAuthorizationStrategyImpl(new CustomAuthority());
|
||||
strategy.securityCheck(acl, AclAuthorizationStrategy.CHANGE_GENERAL);
|
||||
}
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
class CustomAuthority implements GrantedAuthority {
|
||||
@Override
|
||||
public String getAuthority() {
|
||||
return authority.getAuthority();
|
||||
}
|
||||
}
|
||||
}
|
||||
+3
-9
@@ -3,7 +3,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-aspects</artifactId>
|
||||
<version>4.2.0.RC1</version>
|
||||
<version>4.2.2.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.3.RELEASE</version>
|
||||
<version>4.3.5.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.0.RC1</version>
|
||||
<version>4.2.2.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@@ -130,12 +130,6 @@
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>spring-milestone</id>
|
||||
<url>https://repo.spring.io/milestone</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
|
||||
+10
-5
@@ -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.3.RELEASE'
|
||||
ext.springLdapVersion = '2.2.0.RC1'
|
||||
ext.springVersion = '4.3.5.RELEASE'
|
||||
ext.springLdapVersion = '2.2.0.RELEASE'
|
||||
|
||||
group = 'org.springframework.security'
|
||||
|
||||
@@ -114,7 +115,11 @@ configure(coreModuleProjects) {
|
||||
dependencyManagement {
|
||||
springIoTestRuntime {
|
||||
imports {
|
||||
mavenBom "io.spring.platform:platform-bom:${springIoVersion}"
|
||||
mavenBom("io.spring.platform:platform-bom:${springIoVersion}") {
|
||||
bomProperties([
|
||||
'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)
|
||||
}
|
||||
|
||||
+1
-1
@@ -9,7 +9,7 @@ dependencies {
|
||||
"org.jasig.cas.client:cas-client-core:$casClientVersion"
|
||||
|
||||
optional "net.sf.ehcache:ehcache:$ehcacheVersion",
|
||||
"com.fasterxml.jackson.core:jackson-databind:$jacksonDatavindVersion"
|
||||
"com.fasterxml.jackson.core:jackson-databind:$jacksonDatabindVersion"
|
||||
|
||||
testCompile "org.skyscreamer:jsonassert:$jsonassertVersion"
|
||||
|
||||
|
||||
+5
-11
@@ -3,7 +3,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-cas</artifactId>
|
||||
<version>4.2.0.RC1</version>
|
||||
<version>4.2.2.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.3.RELEASE</version>
|
||||
<version>4.3.5.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.0.RC1</version>
|
||||
<version>4.2.2.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-web</artifactId>
|
||||
<version>4.2.0.RC1</version>
|
||||
<version>4.2.2.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.3</version>
|
||||
<version>2.8.4</version>
|
||||
<scope>compile</scope>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
@@ -155,12 +155,6 @@
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>spring-milestone</id>
|
||||
<url>https://repo.spring.io/milestone</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
|
||||
@@ -36,7 +36,7 @@ import java.util.Map;
|
||||
*
|
||||
* @author Jitendra Singh
|
||||
* @see CasJackson2Module
|
||||
* @see org.springframework.security.jackson2.SecurityJacksonModules
|
||||
* @see org.springframework.security.jackson2.SecurityJackson2Modules
|
||||
* @since 4.2
|
||||
*/
|
||||
@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY)
|
||||
|
||||
+1
-1
@@ -33,7 +33,7 @@ import java.util.Map;
|
||||
*
|
||||
* @author Jitendra Singh
|
||||
* @see CasJackson2Module
|
||||
* @see org.springframework.security.jackson2.SecurityJacksonModules
|
||||
* @see org.springframework.security.jackson2.SecurityJackson2Modules
|
||||
* @since 4.2
|
||||
*/
|
||||
@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY)
|
||||
|
||||
+1
-1
@@ -42,7 +42,7 @@ import java.util.Collection;
|
||||
*
|
||||
* @author Jitendra Singh
|
||||
* @see CasJackson2Module
|
||||
* @see org.springframework.security.jackson2.SecurityJacksonModules
|
||||
* @see org.springframework.security.jackson2.SecurityJackson2Modules
|
||||
* @since 4.2
|
||||
*/
|
||||
@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY)
|
||||
|
||||
@@ -22,7 +22,7 @@ import com.fasterxml.jackson.databind.module.SimpleModule;
|
||||
import org.jasig.cas.client.authentication.AttributePrincipalImpl;
|
||||
import org.jasig.cas.client.validation.AssertionImpl;
|
||||
import org.springframework.security.cas.authentication.CasAuthenticationToken;
|
||||
import org.springframework.security.jackson2.SecurityJacksonModules;
|
||||
import org.springframework.security.jackson2.SecurityJackson2Modules;
|
||||
|
||||
/**
|
||||
* Jackson module for spring-security-cas. This module register {@link AssertionImplMixin},
|
||||
@@ -34,10 +34,10 @@ import org.springframework.security.jackson2.SecurityJacksonModules;
|
||||
* ObjectMapper mapper = new ObjectMapper();
|
||||
* mapper.registerModule(new CasJackson2Module());
|
||||
* </pre>
|
||||
* <b>Note: use {@link SecurityJacksonModules#getModules(ClassLoader)} to get list of all security modules on the classpath.</b>
|
||||
* <b>Note: use {@link SecurityJackson2Modules#getModules(ClassLoader)} to get list of all security modules on the classpath.</b>
|
||||
*
|
||||
* @author Jitendra Singh.
|
||||
* @see org.springframework.security.jackson2.SecurityJacksonModules
|
||||
* @see org.springframework.security.jackson2.SecurityJackson2Modules
|
||||
* @since 4.2
|
||||
*/
|
||||
public class CasJackson2Module extends SimpleModule {
|
||||
@@ -48,7 +48,7 @@ public class CasJackson2Module extends SimpleModule {
|
||||
|
||||
@Override
|
||||
public void setupModule(SetupContext context) {
|
||||
SecurityJacksonModules.enableDefaultTyping((ObjectMapper) context.getOwner());
|
||||
SecurityJackson2Modules.enableDefaultTyping((ObjectMapper) context.getOwner());
|
||||
context.setMixInAnnotations(AssertionImpl.class, AssertionImplMixin.class);
|
||||
context.setMixInAnnotations(AttributePrincipalImpl.class, AttributePrincipalImplMixin.class);
|
||||
context.setMixInAnnotations(CasAuthenticationToken.class, CasAuthenticationTokenMixin.class);
|
||||
|
||||
+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) + "=[^&]*");
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -36,7 +36,7 @@ import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
||||
import org.springframework.security.core.userdetails.User;
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
import org.springframework.security.jackson2.SecurityJacksonModules;
|
||||
import org.springframework.security.jackson2.SecurityJackson2Modules;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@@ -103,7 +103,7 @@ public class CasAuthenticationTokenMixinTests {
|
||||
public void setup() {
|
||||
mapper = new ObjectMapper();
|
||||
ClassLoader loader = getClass().getClassLoader();
|
||||
mapper.registerModules(SecurityJacksonModules.getModules(loader));
|
||||
mapper.registerModules(SecurityJackson2Modules.getModules(loader));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
+10
-16
@@ -3,7 +3,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-config</artifactId>
|
||||
<version>4.2.0.RC1</version>
|
||||
<version>4.2.2.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.3.RELEASE</version>
|
||||
<version>4.3.5.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.0.RC1</version>
|
||||
<version>4.2.2.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@@ -97,28 +97,28 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-ldap</artifactId>
|
||||
<version>4.2.0.RC1</version>
|
||||
<version>4.2.2.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-messaging</artifactId>
|
||||
<version>4.2.0.RC1</version>
|
||||
<version>4.2.2.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-openid</artifactId>
|
||||
<version>4.2.0.RC1</version>
|
||||
<version>4.2.2.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-web</artifactId>
|
||||
<version>4.2.0.RC1</version>
|
||||
<version>4.2.2.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
@@ -359,19 +359,19 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework.ldap</groupId>
|
||||
<artifactId>spring-ldap-core</artifactId>
|
||||
<version>2.2.0.RC1</version>
|
||||
<version>2.2.0.RELEASE</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-aspects</artifactId>
|
||||
<version>4.2.0.RC1</version>
|
||||
<version>4.2.2.RELEASE</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-cas</artifactId>
|
||||
<version>4.2.0.RC1</version>
|
||||
<version>4.2.2.RELEASE</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@@ -390,12 +390,6 @@
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>spring-milestone</id>
|
||||
<url>https://repo.spring.io/milestone</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
|
||||
+2
-2
@@ -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);
|
||||
@@ -221,7 +221,7 @@ public final class SecurityNamespaceHandler implements NamespaceHandler {
|
||||
private boolean matchesVersionInternal(Element element) {
|
||||
String schemaLocation = element.getAttributeNS(
|
||||
"http://www.w3.org/2001/XMLSchema-instance", "schemaLocation");
|
||||
return schemaLocation.matches("(?m).*spring-security-4\\.1.*.xsd.*")
|
||||
return schemaLocation.matches("(?m).*spring-security-4\\.2.*.xsd.*")
|
||||
|| schemaLocation.matches("(?m).*spring-security.xsd.*")
|
||||
|| !schemaLocation.matches("(?m).*spring-security.*");
|
||||
}
|
||||
|
||||
+69
@@ -28,6 +28,7 @@ import org.springframework.security.config.annotation.web.configuration.WebSecur
|
||||
import org.springframework.security.web.header.HeaderWriter;
|
||||
import org.springframework.security.web.header.HeaderWriterFilter;
|
||||
import org.springframework.security.web.header.writers.*;
|
||||
import org.springframework.security.web.header.writers.ReferrerPolicyHeaderWriter.ReferrerPolicy;
|
||||
import org.springframework.security.web.header.writers.frameoptions.XFrameOptionsHeaderWriter;
|
||||
import org.springframework.security.web.header.writers.frameoptions.XFrameOptionsHeaderWriter.XFrameOptionsMode;
|
||||
import org.springframework.security.web.util.matcher.RequestMatcher;
|
||||
@@ -56,6 +57,7 @@ import org.springframework.util.Assert;
|
||||
* @author Rob Winch
|
||||
* @author Tim Ysewyn
|
||||
* @author Joe Grandja
|
||||
* @author Eddú Meléndez
|
||||
* @since 3.2
|
||||
*/
|
||||
public class HeadersConfigurer<H extends HttpSecurityBuilder<H>> extends
|
||||
@@ -78,6 +80,8 @@ public class HeadersConfigurer<H extends HttpSecurityBuilder<H>> extends
|
||||
|
||||
private final ContentSecurityPolicyConfig contentSecurityPolicy = new ContentSecurityPolicyConfig();
|
||||
|
||||
private final ReferrerPolicyConfig referrerPolicy = new ReferrerPolicyConfig();
|
||||
|
||||
/**
|
||||
* Creates a new instance
|
||||
*
|
||||
@@ -770,6 +774,7 @@ public class HeadersConfigurer<H extends HttpSecurityBuilder<H>> extends
|
||||
addIfNotNull(writers, frameOptions.writer);
|
||||
addIfNotNull(writers, hpkp.writer);
|
||||
addIfNotNull(writers, contentSecurityPolicy.writer);
|
||||
addIfNotNull(writers, referrerPolicy.writer);
|
||||
writers.addAll(headerWriters);
|
||||
return writers;
|
||||
}
|
||||
@@ -779,4 +784,68 @@ public class HeadersConfigurer<H extends HttpSecurityBuilder<H>> extends
|
||||
values.add(value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Allows configuration for <a href="https://www.w3.org/TR/referrer-policy/">Referrer Policy</a>.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* Configuration is provided to the {@link ReferrerPolicyHeaderWriter} which support the writing
|
||||
* of the header as detailed in the W3C Technical Report:
|
||||
* </p>
|
||||
* <ul>
|
||||
* <li>Referrer-Policy</li>
|
||||
* </ul>
|
||||
*
|
||||
* <p>Default value is:</p>
|
||||
*
|
||||
* <pre>
|
||||
* Referrer-Policy: no-referrer
|
||||
* </pre>
|
||||
*
|
||||
* @see ReferrerPolicyHeaderWriter
|
||||
* @since 4.2
|
||||
* @return the ReferrerPolicyConfig for additional configuration
|
||||
*/
|
||||
public ReferrerPolicyConfig referrerPolicy() {
|
||||
this.referrerPolicy.writer = new ReferrerPolicyHeaderWriter();
|
||||
return this.referrerPolicy;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Allows configuration for <a href="https://www.w3.org/TR/referrer-policy/">Referrer Policy</a>.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* Configuration is provided to the {@link ReferrerPolicyHeaderWriter} which support the writing
|
||||
* of the header as detailed in the W3C Technical Report:
|
||||
* </p>
|
||||
* <ul>
|
||||
* <li>Referrer-Policy</li>
|
||||
* </ul>
|
||||
*
|
||||
* @see ReferrerPolicyHeaderWriter
|
||||
* @since 4.2
|
||||
* @return the ReferrerPolicyConfig for additional configuration
|
||||
* @throws IllegalArgumentException if policy is null or empty
|
||||
*/
|
||||
public ReferrerPolicyConfig referrerPolicy(ReferrerPolicy policy) {
|
||||
this.referrerPolicy.writer = new ReferrerPolicyHeaderWriter(policy);
|
||||
return this.referrerPolicy;
|
||||
}
|
||||
|
||||
public final class ReferrerPolicyConfig {
|
||||
|
||||
private ReferrerPolicyHeaderWriter writer;
|
||||
|
||||
private ReferrerPolicyConfig() {
|
||||
}
|
||||
|
||||
public HeadersConfigurer<H> and() {
|
||||
return HeadersConfigurer.this;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
+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);
|
||||
|
||||
+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");
|
||||
|
||||
|
||||
+22
@@ -31,6 +31,7 @@ import org.springframework.beans.factory.xml.BeanDefinitionParser;
|
||||
import org.springframework.beans.factory.xml.ParserContext;
|
||||
import org.springframework.security.web.header.HeaderWriterFilter;
|
||||
import org.springframework.security.web.header.writers.*;
|
||||
import org.springframework.security.web.header.writers.ReferrerPolicyHeaderWriter.ReferrerPolicy;
|
||||
import org.springframework.security.web.header.writers.frameoptions.RegExpAllowFromStrategy;
|
||||
import org.springframework.security.web.header.writers.frameoptions.StaticAllowFromStrategy;
|
||||
import org.springframework.security.web.header.writers.frameoptions.WhiteListedAllowFromStrategy;
|
||||
@@ -45,6 +46,7 @@ import org.w3c.dom.Node;
|
||||
*
|
||||
* @author Marten Deinum
|
||||
* @author Tim Ysewyn
|
||||
* @author Eddú Meléndez
|
||||
* @since 3.2
|
||||
*/
|
||||
public class HeadersBeanDefinitionParser implements BeanDefinitionParser {
|
||||
@@ -82,6 +84,7 @@ public class HeadersBeanDefinitionParser implements BeanDefinitionParser {
|
||||
private static final String GENERIC_HEADER_ELEMENT = "header";
|
||||
|
||||
private static final String CONTENT_SECURITY_POLICY_ELEMENT = "content-security-policy";
|
||||
private static final String REFERRER_POLICY_ELEMENT = "referrer-policy";
|
||||
|
||||
private static final String ALLOW_FROM = "ALLOW-FROM";
|
||||
|
||||
@@ -109,6 +112,8 @@ public class HeadersBeanDefinitionParser implements BeanDefinitionParser {
|
||||
|
||||
parseContentSecurityPolicyElement(disabled, element, parserContext);
|
||||
|
||||
parseReferrerPolicyElement(element, parserContext);
|
||||
|
||||
parseHeaderElements(element);
|
||||
|
||||
boolean noWriters = headerWriters.isEmpty();
|
||||
@@ -291,6 +296,23 @@ public class HeadersBeanDefinitionParser implements BeanDefinitionParser {
|
||||
headerWriters.add(headersWriter.getBeanDefinition());
|
||||
}
|
||||
|
||||
private void parseReferrerPolicyElement(Element element, ParserContext context) {
|
||||
Element referrerPolicyElement = (element == null) ? null : DomUtils.getChildElementByTagName(element, REFERRER_POLICY_ELEMENT);
|
||||
if (referrerPolicyElement != null) {
|
||||
addReferrerPolicy(referrerPolicyElement, context);
|
||||
}
|
||||
}
|
||||
|
||||
private void addReferrerPolicy(Element referrerPolicyElement, ParserContext context) {
|
||||
BeanDefinitionBuilder headersWriter = BeanDefinitionBuilder.genericBeanDefinition(ReferrerPolicyHeaderWriter.class);
|
||||
|
||||
String policy = referrerPolicyElement.getAttribute(ATT_POLICY);
|
||||
if (StringUtils.hasLength(policy)) {
|
||||
headersWriter.addConstructorArgValue(ReferrerPolicy.get(policy));
|
||||
}
|
||||
headerWriters.add(headersWriter.getBeanDefinition());
|
||||
}
|
||||
|
||||
private void attrNotAllowed(ParserContext context, String attrName,
|
||||
String otherAttrName, Element element) {
|
||||
context.getReaderContext().error(
|
||||
|
||||
+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);
|
||||
}
|
||||
}
|
||||
|
||||
+9
-2
@@ -547,7 +547,7 @@ concurrency-control =
|
||||
element concurrency-control {concurrency-control.attlist, empty}
|
||||
|
||||
concurrency-control.attlist &=
|
||||
## The maximum number of sessions a single authenticated user can have open at the same time. Defaults to "1". A negative value denotes unlimitted sessions.
|
||||
## The maximum number of sessions a single authenticated user can have open at the same time. Defaults to "1". A negative value denotes unlimited sessions.
|
||||
attribute max-sessions {xsd:integer}?
|
||||
concurrency-control.attlist &=
|
||||
## The URL a user will be redirected to if they attempt to use a session which has been "expired" because they have logged in again.
|
||||
@@ -753,7 +753,7 @@ csrf-options.attlist &=
|
||||
|
||||
headers =
|
||||
## Element for configuration of the HeaderWritersFilter. Enables easy setting for the X-Frame-Options, X-XSS-Protection and X-Content-Type-Options headers.
|
||||
element headers { headers-options.attlist, (cache-control? & xss-protection? & hsts? & frame-options? & content-type-options? & hpkp? & content-security-policy? & header*)}
|
||||
element headers { headers-options.attlist, (cache-control? & xss-protection? & hsts? & frame-options? & content-type-options? & hpkp? & content-security-policy? & referrer-policy? & header*)}
|
||||
headers-options.attlist &=
|
||||
## Specifies if the default headers should be disabled. Default false.
|
||||
attribute defaults-disabled {xsd:boolean}?
|
||||
@@ -824,6 +824,13 @@ csp-options.attlist &=
|
||||
## Set to true, to enable the Content-Security-Policy-Report-Only header for reporting policy violations only. Defaults to false.
|
||||
attribute report-only {xsd:boolean}?
|
||||
|
||||
referrer-policy =
|
||||
## Adds support for Referrer Policy
|
||||
element referrer-policy {referrer-options.attlist}
|
||||
referrer-options.attlist &=
|
||||
## The policies for the Referrer-Policy header.
|
||||
attribute policy {"no-referrer","no-referrer-when-downgrade","same-origin","origin","strict-origin","origin-when-cross-origin","strict-origin-when-cross-origin","unsafe-url"}?
|
||||
|
||||
cache-control =
|
||||
## Adds Cache-Control no-cache, no-store, must-revalidate, Pragma no-cache, and Expires 0 for every request
|
||||
element cache-control {cache-control.attlist}
|
||||
|
||||
+31
-1
@@ -1772,7 +1772,7 @@
|
||||
<xs:attribute name="max-sessions" type="xs:integer">
|
||||
<xs:annotation>
|
||||
<xs:documentation>The maximum number of sessions a single authenticated user can have open at the same time.
|
||||
Defaults to "1". A negative value denotes unlimitted sessions.
|
||||
Defaults to "1". A negative value denotes unlimited sessions.
|
||||
</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
@@ -2357,6 +2357,7 @@
|
||||
<xs:element ref="security:content-type-options"/>
|
||||
<xs:element ref="security:hpkp"/>
|
||||
<xs:element ref="security:content-security-policy"/>
|
||||
<xs:element ref="security:referrer-policy"/>
|
||||
<xs:element ref="security:header"/>
|
||||
</xs:choice>
|
||||
<xs:attributeGroup ref="security:headers-options.attlist"/>
|
||||
@@ -2539,6 +2540,35 @@
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
</xs:attributeGroup>
|
||||
<xs:element name="referrer-policy">
|
||||
<xs:annotation>
|
||||
<xs:documentation>Adds support for Referrer Policy
|
||||
</xs:documentation>
|
||||
</xs:annotation>
|
||||
<xs:complexType>
|
||||
<xs:attributeGroup ref="security:referrer-options.attlist"/>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:attributeGroup name="referrer-options.attlist">
|
||||
<xs:attribute name="policy">
|
||||
<xs:annotation>
|
||||
<xs:documentation>The policies for the Referrer-Policy header.
|
||||
</xs:documentation>
|
||||
</xs:annotation>
|
||||
<xs:simpleType>
|
||||
<xs:restriction base="xs:token">
|
||||
<xs:enumeration value="no-referrer"/>
|
||||
<xs:enumeration value="no-referrer-when-downgrade"/>
|
||||
<xs:enumeration value="same-origin"/>
|
||||
<xs:enumeration value="origin"/>
|
||||
<xs:enumeration value="strict-origin"/>
|
||||
<xs:enumeration value="origin-when-cross-origin"/>
|
||||
<xs:enumeration value="strict-origin-when-cross-origin"/>
|
||||
<xs:enumeration value="unsafe-url"/>
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
</xs:attribute>
|
||||
</xs:attributeGroup>
|
||||
<xs:element name="cache-control">
|
||||
<xs:annotation>
|
||||
<xs:documentation>Adds Cache-Control no-cache, no-store, must-revalidate, Pragma no-cache, and Expires 0 for
|
||||
|
||||
+44
@@ -20,12 +20,14 @@ import org.springframework.security.config.annotation.BaseSpringSpec
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity
|
||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity
|
||||
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter
|
||||
import static org.springframework.security.web.header.writers.ReferrerPolicyHeaderWriter.ReferrerPolicy
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Rob Winch
|
||||
* @author Tim Ysewyn
|
||||
* @author Joe Grandja
|
||||
* @author Eddú Meléndez
|
||||
*/
|
||||
class HeadersConfigurerTests extends BaseSpringSpec {
|
||||
|
||||
@@ -453,4 +455,46 @@ class HeadersConfigurerTests extends BaseSpringSpec {
|
||||
}
|
||||
}
|
||||
|
||||
def "headers.referrerPolicy default"() {
|
||||
setup:
|
||||
loadConfig(ReferrerPolicyDefaultConfig)
|
||||
when:
|
||||
springSecurityFilterChain.doFilter(request,response,chain)
|
||||
then:
|
||||
responseHeaders == ['Referrer-Policy': 'no-referrer']
|
||||
}
|
||||
|
||||
@EnableWebSecurity
|
||||
static class ReferrerPolicyDefaultConfig extends WebSecurityConfigurerAdapter {
|
||||
|
||||
@Override
|
||||
protected void configure(HttpSecurity http) throws Exception {
|
||||
http
|
||||
.headers()
|
||||
.defaultsDisabled()
|
||||
.referrerPolicy();
|
||||
}
|
||||
}
|
||||
|
||||
def "headers.referrerPolicy custom"() {
|
||||
setup:
|
||||
loadConfig(ReferrerPolicyCustomConfig)
|
||||
when:
|
||||
springSecurityFilterChain.doFilter(request,response,chain)
|
||||
then:
|
||||
responseHeaders == ['Referrer-Policy': 'same-origin']
|
||||
}
|
||||
|
||||
@EnableWebSecurity
|
||||
static class ReferrerPolicyCustomConfig extends WebSecurityConfigurerAdapter {
|
||||
|
||||
@Override
|
||||
protected void configure(HttpSecurity http) throws Exception {
|
||||
http
|
||||
.headers()
|
||||
.defaultsDisabled()
|
||||
.referrerPolicy(ReferrerPolicy.SAME_ORIGIN);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+32
@@ -920,6 +920,38 @@ class HttpHeadersConfigTests extends AbstractHttpConfigTests {
|
||||
assertHeaders(response, expectedHeaders)
|
||||
}
|
||||
|
||||
def 'http headers defaults : referrer-policy'() {
|
||||
setup:
|
||||
httpAutoConfig {
|
||||
'headers'('defaults-disabled':true) {
|
||||
'referrer-policy'()
|
||||
}
|
||||
}
|
||||
createAppContext()
|
||||
when:
|
||||
def hf = getFilter(HeaderWriterFilter)
|
||||
MockHttpServletResponse response = new MockHttpServletResponse()
|
||||
hf.doFilter(new MockHttpServletRequest(), response, new MockFilterChain())
|
||||
then:
|
||||
assertHeaders(response, ['Referrer-Policy': 'no-referrer'])
|
||||
}
|
||||
|
||||
def 'http headers defaults : referrer-policy same-origin'() {
|
||||
setup:
|
||||
httpAutoConfig {
|
||||
'headers'('defaults-disabled':true) {
|
||||
'referrer-policy'('policy': 'same-origin')
|
||||
}
|
||||
}
|
||||
createAppContext()
|
||||
when:
|
||||
def hf = getFilter(HeaderWriterFilter)
|
||||
MockHttpServletResponse response = new MockHttpServletResponse()
|
||||
hf.doFilter(new MockHttpServletRequest(), response, new MockFilterChain())
|
||||
then:
|
||||
assertHeaders(response, ['Referrer-Policy': 'same-origin'])
|
||||
}
|
||||
|
||||
def assertHeaders(MockHttpServletResponse response, Map<String,String> expected) {
|
||||
assert response.headerNames == expected.keySet()
|
||||
expected.each { headerName, value ->
|
||||
|
||||
+1
-1
@@ -444,7 +444,7 @@ public class AbstractSecurityWebSocketMessageBrokerConfigurerTests {
|
||||
// @formatter:on
|
||||
|
||||
@Bean
|
||||
public SecurityExpressionHandler<Message<Object>> messageSecurityExpressionHandler() {
|
||||
public static SecurityExpressionHandler<Message<Object>> messageSecurityExpressionHandler() {
|
||||
return new DefaultMessageSecurityExpressionHandler<Object>() {
|
||||
@Override
|
||||
protected SecurityExpressionOperations createSecurityExpressionRoot(
|
||||
|
||||
+1
-1
@@ -40,7 +40,7 @@ public class InMemoryXmlApplicationContext extends AbstractXmlApplicationContext
|
||||
+ "http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-";
|
||||
static final String BEANS_CLOSE = "</b:beans>\n";
|
||||
|
||||
static final String SPRING_SECURITY_VERSION = "4.1";
|
||||
static final String SPRING_SECURITY_VERSION = "4.2";
|
||||
|
||||
Resource inMemoryXml;
|
||||
|
||||
|
||||
+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);
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -25,7 +25,7 @@ dependencies {
|
||||
"org.aspectj:aspectjrt:$aspectjVersion",
|
||||
"org.springframework:spring-jdbc:$springVersion",
|
||||
"org.springframework:spring-tx:$springVersion",
|
||||
"com.fasterxml.jackson.core:jackson-databind:$jacksonDatavindVersion"
|
||||
"com.fasterxml.jackson.core:jackson-databind:$jacksonDatabindVersion"
|
||||
|
||||
included cryptoProject
|
||||
|
||||
|
||||
+3
-9
@@ -3,7 +3,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-core</artifactId>
|
||||
<version>4.2.0.RC1</version>
|
||||
<version>4.2.2.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.3.RELEASE</version>
|
||||
<version>4.3.5.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.3</version>
|
||||
<version>2.8.4</version>
|
||||
<scope>compile</scope>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
@@ -294,12 +294,6 @@
|
||||
</exclusions>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>spring-milestone</id>
|
||||
<url>https://repo.spring.io/milestone</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
|
||||
+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;
|
||||
}
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ public class SpringSecurityCoreVersion {
|
||||
*/
|
||||
public static final long SERIAL_VERSION_UID = 420L;
|
||||
|
||||
static final String MIN_SPRING_VERSION = "4.3.3.RELEASE";
|
||||
static final String MIN_SPRING_VERSION = "4.3.5.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;
|
||||
}
|
||||
|
||||
+1
-1
@@ -35,7 +35,7 @@ import java.util.Collection;
|
||||
*
|
||||
* @author Jitendra Singh
|
||||
* @see CoreJackson2Module
|
||||
* @see SecurityJacksonModules
|
||||
* @see SecurityJackson2Modules
|
||||
* @since 4.2
|
||||
*/
|
||||
@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY)
|
||||
|
||||
@@ -38,12 +38,13 @@ import java.util.Collections;
|
||||
* ObjectMapper mapper = new ObjectMapper();
|
||||
* mapper.registerModule(new CoreJackson2Module());
|
||||
* </pre>
|
||||
* <b>Note: use {@link SecurityJacksonModules#getModules(ClassLoader)} to get list of all security modules.</b>
|
||||
* <b>Note: use {@link SecurityJackson2Modules#getModules(ClassLoader)} to get list of all security modules.</b>
|
||||
*
|
||||
* @author Jitendra Singh.
|
||||
* @see SecurityJacksonModules
|
||||
* @see SecurityJackson2Modules
|
||||
* @since 4.2
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public class CoreJackson2Module extends SimpleModule {
|
||||
|
||||
public CoreJackson2Module() {
|
||||
@@ -52,7 +53,7 @@ public class CoreJackson2Module extends SimpleModule {
|
||||
|
||||
@Override
|
||||
public void setupModule(SetupContext context) {
|
||||
SecurityJacksonModules.enableDefaultTyping((ObjectMapper) context.getOwner());
|
||||
SecurityJackson2Modules.enableDefaultTyping((ObjectMapper) context.getOwner());
|
||||
context.setMixInAnnotations(AnonymousAuthenticationToken.class, AnonymousAuthenticationTokenMixin.class);
|
||||
context.setMixInAnnotations(RememberMeAuthenticationToken.class, RememberMeAuthenticationTokenMixin.class);
|
||||
context.setMixInAnnotations(SimpleGrantedAuthority.class, SimpleGrantedAuthorityMixin.class);
|
||||
|
||||
+1
-1
@@ -41,7 +41,7 @@ import java.util.Collection;
|
||||
*
|
||||
* @author Jitendra Singh
|
||||
* @see CoreJackson2Module
|
||||
* @see SecurityJacksonModules
|
||||
* @see SecurityJackson2Modules
|
||||
* @since 4.2
|
||||
*/
|
||||
@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY)
|
||||
|
||||
+4
-4
@@ -34,7 +34,7 @@ import java.util.List;
|
||||
* <p>
|
||||
* <pre>
|
||||
* ObjectMapper mapper = new ObjectMapper();
|
||||
* mapper.registerModules(SecurityJacksonModules.getModules());
|
||||
* mapper.registerModules(SecurityJackson2Modules.getModules());
|
||||
* </pre>
|
||||
* Above code is equivalent to
|
||||
* <p>
|
||||
@@ -49,16 +49,16 @@ import java.util.List;
|
||||
* @author Jitendra Singh.
|
||||
* @since 4.2
|
||||
*/
|
||||
public final class SecurityJacksonModules {
|
||||
public final class SecurityJackson2Modules {
|
||||
|
||||
private static final Log logger = LogFactory.getLog(SecurityJacksonModules.class);
|
||||
private static final Log logger = LogFactory.getLog(SecurityJackson2Modules.class);
|
||||
private static final List<String> securityJackson2ModuleClasses = Arrays.asList(
|
||||
"org.springframework.security.jackson2.CoreJackson2Module",
|
||||
"org.springframework.security.cas.jackson2.CasJackson2Module",
|
||||
"org.springframework.security.web.jackson2.WebJackson2Module"
|
||||
);
|
||||
|
||||
private SecurityJacksonModules() {
|
||||
private SecurityJackson2Modules() {
|
||||
}
|
||||
|
||||
public static void enableDefaultTyping(ObjectMapper mapper) {
|
||||
+1
-1
@@ -28,7 +28,7 @@ import com.fasterxml.jackson.annotation.*;
|
||||
* </pre>
|
||||
* @author Jitendra Singh
|
||||
* @see CoreJackson2Module
|
||||
* @see SecurityJacksonModules
|
||||
* @see SecurityJackson2Modules
|
||||
* @since 4.2
|
||||
*/
|
||||
@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY)
|
||||
|
||||
@@ -34,7 +34,7 @@ import java.util.Set;
|
||||
* @author Jitendra Singh
|
||||
* @see UnmodifiableSetDeserializer
|
||||
* @see CoreJackson2Module
|
||||
* @see SecurityJacksonModules
|
||||
* @see SecurityJackson2Modules
|
||||
* @since 4.2
|
||||
*/
|
||||
@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY)
|
||||
|
||||
@@ -37,7 +37,7 @@ import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
|
||||
* @author Jitendra Singh
|
||||
* @see UserDeserializer
|
||||
* @see CoreJackson2Module
|
||||
* @see SecurityJacksonModules
|
||||
* @see SecurityJackson2Modules
|
||||
* @since 4.2
|
||||
*/
|
||||
@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY)
|
||||
|
||||
+1
-1
@@ -37,7 +37,7 @@ import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
|
||||
* </pre>
|
||||
* @author Jitendra Singh
|
||||
* @see CoreJackson2Module
|
||||
* @see SecurityJacksonModules
|
||||
* @see SecurityJackson2Modules
|
||||
* @since 4.2
|
||||
*/
|
||||
@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY, property = "@class")
|
||||
|
||||
+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;
|
||||
}
|
||||
|
||||
+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"));
|
||||
|
||||
@@ -33,7 +33,7 @@ public abstract class AbstractMixinTests {
|
||||
public void setup() {
|
||||
mapper = new ObjectMapper();
|
||||
ClassLoader loader = getClass().getClassLoader();
|
||||
mapper.registerModules(SecurityJacksonModules.getModules(loader));
|
||||
mapper.registerModules(SecurityJackson2Modules.getModules(loader));
|
||||
}
|
||||
|
||||
User createDefaultUser() {
|
||||
|
||||
+2
-8
@@ -3,7 +3,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-crypto</artifactId>
|
||||
<version>4.2.0.RC1</version>
|
||||
<version>4.2.2.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.3.RELEASE</version>
|
||||
<version>4.3.5.RELEASE</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
@@ -92,12 +92,6 @@
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>spring-milestone</id>
|
||||
<url>https://repo.spring.io/milestone</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
|
||||
@@ -532,8 +532,9 @@ public class BCrypt {
|
||||
* @param password the password to hash
|
||||
* @param salt the salt to hash with (perhaps generated using BCrypt.gensalt)
|
||||
* @return the hashed password
|
||||
* @throws IllegalArgumentException if invalid salt is passed
|
||||
*/
|
||||
public static String hashpw(String password, String salt) {
|
||||
public static String hashpw(String password, String salt) throws IllegalArgumentException {
|
||||
BCrypt B;
|
||||
String real_salt;
|
||||
byte passwordb[], saltb[], hashed[];
|
||||
@@ -541,6 +542,10 @@ public class BCrypt {
|
||||
int rounds, off = 0;
|
||||
StringBuilder rs = new StringBuilder();
|
||||
|
||||
if (salt == null) {
|
||||
throw new IllegalArgumentException("salt cannot be null");
|
||||
}
|
||||
|
||||
int saltLength = salt.length();
|
||||
|
||||
if (saltLength < 28) {
|
||||
|
||||
+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);
|
||||
|
||||
@@ -14,10 +14,11 @@
|
||||
|
||||
package org.springframework.security.crypto.bcrypt;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.junit.Test;
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* JUnit unit tests for BCrypt routines
|
||||
@@ -271,6 +272,11 @@ public class BCryptTests {
|
||||
assertThat(BCrypt.gensalt(31).startsWith("$2a$31$")).isTrue();
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void hashpwFailsWhenSaltIsNull() {
|
||||
BCrypt.hashpw("password", null);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void hashpwFailsWhenSaltSpecifiesTooFewRounds() {
|
||||
BCrypt.hashpw("password", "$2a$03$......................");
|
||||
|
||||
+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";
|
||||
|
||||
+3
-9
@@ -3,7 +3,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-data</artifactId>
|
||||
<version>4.2.0.RC1</version>
|
||||
<version>4.2.2.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.3.RELEASE</version>
|
||||
<version>4.3.5.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.0.RC1</version>
|
||||
<version>4.2.2.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@@ -108,12 +108,6 @@
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>spring-milestone</id>
|
||||
<url>https://repo.spring.io/milestone</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ To use it, register the `JacksonJacksonModules.getModules(ClassLoader)` as http:
|
||||
----
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
ClassLoader loader = getClass().getClassLoader();
|
||||
List<Module> modules = SecurityJacksonModules.getModules(loader);
|
||||
List<Module> modules = SecurityJackson2Modules.getModules(loader);
|
||||
mapper.registerModules(modules);
|
||||
|
||||
// ... use ObjectMapper as normally ...
|
||||
|
||||
@@ -7,5 +7,5 @@ Without proper configuration, the application server will not know that the load
|
||||
|
||||
To fix this you can use https://tools.ietf.org/html/rfc7239[RFC 7239] to specify that a load balancer is being used.
|
||||
To make the application aware of this, you need to either configure your application server aware of the X-Forwarded headers.
|
||||
For example Tomcat uses the https://tomcat.apache.org/tomcat-8.0-doc/api/org/apache/catalina/valves/RemoteIpValve.html[RempteIpValve] and Jetty uses http://download.eclipse.org/jetty/stable-9/apidocs/org/eclipse/jetty/server/ForwardedRequestCustomizer.html[ForwardedRequestCustomizer].
|
||||
Alternatively, Spring 4.3+ users can leverage https://github.com/spring-projects/spring-framework/blob/v4.3.3.RELEASE/spring-web/src/main/java/org/springframework/web/filter/ForwardedHeaderFilter.java[ForwardedHeaderFilter].
|
||||
For example Tomcat uses the https://tomcat.apache.org/tomcat-8.0-doc/api/org/apache/catalina/valves/RemoteIpValve.html[RemoteIpValve] and Jetty uses http://download.eclipse.org/jetty/stable-9/apidocs/org/eclipse/jetty/server/ForwardedRequestCustomizer.html[ForwardedRequestCustomizer].
|
||||
Alternatively, Spring 4.3+ users can leverage https://github.com/spring-projects/spring-framework/blob/v4.3.3.RELEASE/spring-web/src/main/java/org/springframework/web/filter/ForwardedHeaderFilter.java[ForwardedHeaderFilter].
|
||||
|
||||
@@ -11,7 +11,7 @@ To use the Spring Security test support, you must include `spring-security-test-
|
||||
[[test-method]]
|
||||
== Testing Method Security
|
||||
|
||||
This section demonstrates how to use Spring Security's Test support to test method based security.
|
||||
This section demonstrates how to use Spring Security's Test support to test method based security.
|
||||
We first introduce a `MessageService` that requires the user to be authenticated in order to access it.
|
||||
|
||||
[source,java]
|
||||
@@ -49,10 +49,10 @@ public class WithMockUserTests {
|
||||
|
||||
This is a basic example of how to setup Spring Security Test. The highlights are:
|
||||
|
||||
<1> `@RunWith` instructs the spring-test module that it should create an ApplicationContext This is no different than using the existing Spring Test support. For additional information, refer to the http://docs.spring.io/spring-framework/docs/4.0.x/spring-framework-reference/htmlsingle/#integration-testing-annotations-standard[Spring Reference]
|
||||
<1> `@RunWith` instructs the spring-test module that it should create an `ApplicationContext`. This is no different than using the existing Spring Test support. For additional information, refer to the http://docs.spring.io/spring-framework/docs/4.0.x/spring-framework-reference/htmlsingle/#integration-testing-annotations-standard[Spring Reference]
|
||||
<2> `@ContextConfiguration` instructs the spring-test the configuration to use to create the `ApplicationContext`. Since no configuration is specified, the default configuration locations will be tried. This is no different than using the existing Spring Test support. For additional information, refer to the http://docs.spring.io/spring-framework/docs/4.0.x/spring-framework-reference/htmlsingle/#testcontext-ctx-management[Spring Reference]
|
||||
|
||||
NOTE: Spring Security hooks into Spring Test support using the `WithSecurityContextTestExecutionListener` which will ensure our tests are ran with the correct user.
|
||||
NOTE: Spring Security hooks into Spring Test support using the `WithSecurityContextTestExecutionListener` which will ensure our tests are ran with the correct user.
|
||||
It does this by populating the `SecurityContextHolder` prior to running our tests.
|
||||
After the test is done, it will clear out the `SecurityContextHolder`.
|
||||
If you only need Spring Security related support, you can replace `@ContextConfiguration` with `@SecurityTestExecutionListeners`.
|
||||
@@ -73,7 +73,7 @@ public void getMessageUnauthenticated() {
|
||||
|
||||
The question is "How could we most easily run the test as a specific user?"
|
||||
The answer is to use `@WithMockUser`.
|
||||
The following test will be ran as a user with the username "user", the password "password", and the roles "ROLE_USER".
|
||||
The following test will be run as a user with the username "user", the password "password", and the roles "ROLE_USER".
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@@ -291,7 +291,7 @@ final class WithUserDetailsSecurityContextFactory
|
||||
|
||||
public SecurityContext createSecurityContext(WithUserDetails withUser) {
|
||||
String username = withUser.value();
|
||||
Assert.hasLength(username, "value() must be non empty String");
|
||||
Assert.hasLength(username, "value() must be non-empty String");
|
||||
UserDetails principal = userDetailsService.loadUserByUsername(username);
|
||||
Authentication authentication = new UsernamePasswordAuthenticationToken(principal, principal.getPassword(), principal.getAuthorities());
|
||||
SecurityContext context = SecurityContextHolder.createEmptyContext();
|
||||
@@ -386,7 +386,7 @@ import static org.springframework.security.test.web.servlet.request.SecurityMock
|
||||
[[test-mockmvc-csrf]]
|
||||
==== Testing with CSRF Protection
|
||||
|
||||
When testing any non safe HTTP methods and using Spring Security's CSRF protection, you must be sure to include a valid CSRF Token in the request.
|
||||
When testing any non-safe HTTP methods and using Spring Security's CSRF protection, you must be sure to include a valid CSRF Token in the request.
|
||||
To specify a valid CSRF token as a request parameter using the following:
|
||||
|
||||
[source,java]
|
||||
|
||||
@@ -93,7 +93,7 @@ public class WebSocketSecurityConfig extends AbstractSecurityWebSocketMessageBro
|
||||
|
||||
This will ensure that:
|
||||
|
||||
<1> Any message without a destination (i.e. anything other that Message type of MESSAGE or SUBSCRIBE) will require the user to be authenticated
|
||||
<1> Any message without a destination (i.e. anything other than Message type of MESSAGE or SUBSCRIBE) will require the user to be authenticated
|
||||
<2> Anyone can subscribe to /user/queue/errors
|
||||
<3> Any message that has a destination starting with "/app/" will be require the user to have the role ROLE_USER
|
||||
<4> Any message that starts with "/user/" or "/topic/friends/" that is of type SUBSCRIBE will require ROLE_USER
|
||||
@@ -162,7 +162,7 @@ It is also is important to understand how destinations are transformed.
|
||||
|
||||
Consider a chat application.
|
||||
|
||||
* User's can send messages to a specific user by sending a message to the destination of "/app/chat".
|
||||
* Users can send messages to a specific user by sending a message to the destination of "/app/chat".
|
||||
* The application sees the message, ensures that the "from" attribute is specified as the current user (we cannot trust the client).
|
||||
* The application then sends the message to the recipient using `SimpMessageSendingOperations.convertAndSendToUser("toUser", "/queue/messages", message)`.
|
||||
* The message gets turned into the destination of "/queue/user/messages-<sessionid>"
|
||||
@@ -200,7 +200,7 @@ The Same Origin Policy ensures that evil.com cannot read or write data to bank.c
|
||||
|
||||
With WebSockets the Same Origin Policy does not apply.
|
||||
In fact, unless bank.com explicitly forbids it, evil.com can read and write data on behalf of the user.
|
||||
This means that anything the user can do over the websocket (i.e. transfer money), evil.com can do on that users behalf.
|
||||
This means that anything the user can do over the webSocket (i.e. transfer money), evil.com can do on that users behalf.
|
||||
|
||||
Since SockJS tries to emulate WebSockets it also bypasses the Same Origin Policy.
|
||||
This means developers need to explicitly protect their applications from external domains when using SockJS.
|
||||
@@ -246,7 +246,7 @@ public class CsrfController {
|
||||
}
|
||||
----
|
||||
|
||||
The javascript can make a REST call to the endpoint and use the response to populate the headerName and the token.
|
||||
The JavaScript can make a REST call to the endpoint and use the response to populate the headerName and the token.
|
||||
|
||||
We can now include the token in our Stomp client.
|
||||
For example:
|
||||
@@ -397,4 +397,4 @@ For example:
|
||||
</b:bean>
|
||||
</b:constructor-arg>
|
||||
</b:bean>
|
||||
----
|
||||
----
|
||||
|
||||
@@ -58,7 +58,7 @@ At an authentication level, Spring Security supports a wide range of authenticat
|
||||
|
||||
* Authentication based on pre-established request headers (such as Computer Associates Siteminder)
|
||||
|
||||
* JA-SIG Central Authentication Service (otherwise known as CAS, which is a popular open source single sign-on system)
|
||||
* Jasig Central Authentication Service (otherwise known as CAS, which is a popular open source single sign-on system)
|
||||
|
||||
* Transparent authentication context propagation for Remote Method Invocation (RMI) and HttpInvoker (a Spring remoting protocol)
|
||||
|
||||
@@ -70,11 +70,11 @@ At an authentication level, Spring Security supports a wide range of authenticat
|
||||
|
||||
* Java Authentication and Authorization Service (JAAS)
|
||||
|
||||
* JEE container autentication (so you can still use Container Managed Authentication if desired)
|
||||
* Java EE container authentication (so you can still use Container Managed Authentication if desired)
|
||||
|
||||
* Kerberos
|
||||
|
||||
* Java Open Source Single Sign On (JOSSO) *
|
||||
* Java Open Source Single Sign-On (JOSSO) *
|
||||
|
||||
* OpenNMS Network Management Platform *
|
||||
|
||||
@@ -108,7 +108,7 @@ At an authentication level, Spring Security supports a wide range of authenticat
|
||||
|
||||
Many independent software vendors (ISVs) adopt Spring Security because of this significant choice of flexible authentication models. Doing so allows them to quickly integrate their solutions with whatever their end clients need, without undertaking a lot of engineering or requiring the client to change their environment. If none of the above authentication mechanisms suit your needs, Spring Security is an open platform and it is quite simple to write your own authentication mechanism. Many corporate users of Spring Security need to integrate with "legacy" systems that don't follow any particular security standards, and Spring Security is happy to "play nicely" with such systems.
|
||||
|
||||
Irrespective of the authentication mechanism, Spring Security provides a deep set of authorization capabilities. There are three main areas of interest - authorizing web requests, authorizing whether methods can be invoked, and authorizing access to individual domain object instances. To help you understand the differences, consider the authorization capabilities found in the Servlet Specification web pattern security, EJB Container Managed Security and file system security respectively. Spring Security provides deep capabilities in all of these important areas, which we'll explore later in this reference guide.
|
||||
Irrespective of the authentication mechanism, Spring Security provides a deep set of authorization capabilities. There are three main areas of interest: authorizing web requests, authorizing whether methods can be invoked and authorizing access to individual domain object instances. To help you understand the differences, consider the authorization capabilities found in the Servlet Specification web pattern security, EJB Container Managed Security and file system security respectively. Spring Security provides deep capabilities in all of these important areas, which we'll explore later in this reference guide.
|
||||
|
||||
|
||||
[[history]]
|
||||
@@ -299,7 +299,7 @@ NOTE: This example uses Gradle 1.9, but may need modifications to work in future
|
||||
|
||||
[[modules]]
|
||||
==== Project Modules
|
||||
In Spring Security 3.0, the codebase has been sub-divided into separate jars which more clearly separate different functionaltiy areas and third-party dependencies. If you are using Maven to build your project, then these are the modules you will add to your `pom.xml`. Even if you're not using Maven, we'd recommend that you consult the `pom.xml` files to get an idea of third-party dependencies and versions. Alternatively, a good idea is to examine the libraries that are included in the sample applications.
|
||||
In Spring Security 3.0, the codebase has been sub-divided into separate jars which more clearly separate different functionality areas and third-party dependencies. If you are using Maven to build your project, then these are the modules you will add to your `pom.xml`. Even if you're not using Maven, we'd recommend that you consult the `pom.xml` files to get an idea of third-party dependencies and versions. Alternatively, a good idea is to examine the libraries that are included in the sample applications.
|
||||
|
||||
|
||||
[[spring-security-core]]
|
||||
@@ -378,17 +378,18 @@ This will give you access to the entire project history (including all releases
|
||||
== What's New in Spring Security 4.2
|
||||
|
||||
Among other things, Spring Security 4.2 brings early support for Spring Framework 5.
|
||||
There were https://github.com/spring-projects/spring-security/milestone/86?closed=1[50+ M1 issues] and https://github.com/spring-projects/spring-security/milestone/91?closed=1[20+ RC1 issues] closed.
|
||||
You can find the change logs for https://github.com/spring-projects/spring-security/milestone/86?closed=1[4.2.0.M1], https://github.com/spring-projects/spring-security/milestone/91?closed=1[4.2.0.RC1], https://github.com/spring-projects/spring-security/milestone/92?closed=1[4.2.0.RELEASE] which closes over 80 issues.
|
||||
The overwhelming majority of these features were contributed by the community.
|
||||
Below you can find the highlights of this release.
|
||||
|
||||
=== Web Improvements
|
||||
|
||||
* https://github.com/spring-projects/spring-security/pull/3812[#3812] - <<jackson,Jackson Support>>
|
||||
* https://github.com/spring-projects/spring-security/pull/4116[#4116] - <<headers-referrer,Referrer Policy>>
|
||||
* https://github.com/spring-projects/spring-security/pull/3938[#3938] - Add <<request-matching,HTTP response splitting prevention>>
|
||||
* https://github.com/spring-projects/spring-security/issues/3949[#3949] - Add <<mvc-authentication-principal,bean reference support to @AuthenticationPrincipal>>.
|
||||
* https://github.com/spring-projects/spring-security/pull/3978[#3978] - Support for Standford WebAuth and Shibboleth using the newly added http://docs.spring.io/spring-security/site/docs/4.2.x-SNAPSHOT/apidocs/org/springframework/security/web/authentication/preauth/RequestAttributeAuthenticationFilter.html[RequestAttributeAuthenticationFilter].
|
||||
https://github.com/spring-projects/spring-security/issues/4076[#4076] - Document <<appendix-proxy-server,Proxy Server>> Configuration
|
||||
* https://github.com/spring-projects/spring-security/issues/4076[#4076] - Document <<appendix-proxy-server,Proxy Server>> Configuration
|
||||
* https://github.com/spring-projects/spring-security/issues/3795[#3795] - `ConcurrentSessionFilter` supports `InvalidSessionStrategy`
|
||||
* https://github.com/spring-projects/spring-security/pull/3904[#3904] - Add `CompositeLogoutHandler`
|
||||
|
||||
@@ -397,7 +398,7 @@ https://github.com/spring-projects/spring-security/issues/4076[#4076] - Document
|
||||
* https://github.com/spring-projects/spring-security/pull/3956[#3956] - Central configuration of the http://docs.spring.io/spring-security/site/migrate/current/3-to-4/html5/migrate-3-to-4-jc.html#m3to4-role-prefixing[default role prefix]. See the issue for details.
|
||||
* https://github.com/spring-projects/spring-security/issues/4102[#4102] - Custom default configuration in `WebSecurityConfigurerAdapter`. See <<jc-custom-dsls>>
|
||||
* https://github.com/spring-projects/spring-security/issues/3899[#3899] - <<nsa-concurrency-control-max-sessions,concurrency-control@max-sessions>> supports unlimited sessions.
|
||||
* https://github.com/spring-projects/spring-security/issues/3899[#4097] - <<nsa-intercept-url-request-matcher-ref,intercept-url@request-matcher-ref>> adds more powerful request matching support to the XML namespace.
|
||||
* https://github.com/spring-projects/spring-security/issues/4097[#4097] - <<nsa-intercept-url-request-matcher-ref,intercept-url@request-matcher-ref>> adds more powerful request matching support to the XML namespace.
|
||||
* https://github.com/spring-projects/spring-security/issues/3990[#3990] - Support for constructing `RoleHierarchy` from `Map` (i.e. `yml`)
|
||||
* https://github.com/spring-projects/spring-security/pull/4062[#4062] - Custom cookiePath to `CookieCsrfTokenRepository`
|
||||
* https://github.com/spring-projects/spring-security/issues/3794[#3794] - Allow configuration of `InvalidSessionStrategy` on `SessionManagementConfigurer`
|
||||
@@ -445,7 +446,7 @@ If you are looking to get started with Spring Security, the best place to start
|
||||
[[jc]]
|
||||
== Java Configuration
|
||||
|
||||
General support for http://docs.spring.io/spring/docs/3.1.x/spring-framework-reference/html/beans.html#beans-java[Java Configuration] was added to Spring framework in Spring 3.1. Since Spring Security 3.2 there has been Spring Security Java Configuration support which enables users to easily configure Spring Security without the use of any XML.
|
||||
General support for http://docs.spring.io/spring/docs/3.1.x/spring-framework-reference/html/beans.html#beans-java[Java Configuration] was added to Spring Framework in Spring 3.1. Since Spring Security 3.2 there has been Spring Security Java Configuration support which enables users to easily configure Spring Security without the use of any XML.
|
||||
|
||||
If you are familiar with the <<ns-config>> then you should find quite a few similarities between it and the Security Java Configuration support.
|
||||
|
||||
@@ -681,25 +682,21 @@ protected void configure(HttpSecurity http) throws Exception {
|
||||
|
||||
<1> There are multiple children to the `http.authorizeRequests()` method each matcher is considered in the order they were declared.
|
||||
<2> We specified multiple URL patterns that any user can access. Specifically, any user can access a request if the URL starts with "/resources/", equals "/signup", or equals "/about".
|
||||
<3> Any URL that starts with "/admin/" will be resticted to users who have the role "ROLE_ADMIN". You will notice that since we are invoking the `hasRole` method we do not need to specify the "ROLE_" prefix.
|
||||
<3> Any URL that starts with "/admin/" will be restricted to users who have the role "ROLE_ADMIN". You will notice that since we are invoking the `hasRole` method we do not need to specify the "ROLE_" prefix.
|
||||
<4> Any URL that starts with "/db/" requires the user to have both "ROLE_ADMIN" and "ROLE_DBA". You will notice that since we are using the `hasRole` expression we do not need to specify the "ROLE_" prefix.
|
||||
<5> Any URL that has not already been matched on only requires that the user be authenticated
|
||||
|
||||
[[jc-logout]]
|
||||
=== Handling Logouts
|
||||
|
||||
When using the
|
||||
`{security-api-url}org/springframework/security/config/annotation/web/configuration/WebSecurityConfigurerAdapter.html[WebSecurityConfigurerAdapter]`,
|
||||
logout capabilities are automatically applied. The default is that accessing the
|
||||
URL `/logout` will log the user out by:
|
||||
When using the `{security-api-url}org/springframework/security/config/annotation/web/configuration/WebSecurityConfigurerAdapter.html[WebSecurityConfigurerAdapter]`, logout capabilities are automatically applied. The default is that accessing the URL `/logout` will log the user out by:
|
||||
|
||||
- Invalidating the HTTP Session
|
||||
- Cleaning up any RememberMe authentication that was configured
|
||||
- Clearing the `SecurityContextHolder`
|
||||
- Redirect to `/login?logout`
|
||||
|
||||
Similar to configuring login capabilities, however, you also have various options
|
||||
to further customize your logout requirements:
|
||||
Similar to configuring login capabilities, however, you also have various options to further customize your logout requirements:
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@@ -721,7 +718,7 @@ protected void configure(HttpSecurity http) throws Exception {
|
||||
<2> The URL that triggers log out to occur (default is `/logout`). If CSRF protection is enabled (default), then the request must also be a POST. For more information, please consult the {security-api-url}org/springframework/security/config/annotation/web/configurers/LogoutConfigurer.html#logoutUrl-java.lang.String-[JavaDoc].
|
||||
<3> The URL to redirect to after logout has occurred. The default is `/login?logout`. For more information, please consult the {security-api-url}org/springframework/security/config/annotation/web/configurers/LogoutConfigurer.html#logoutSuccessUrl-java.lang.String-[JavaDoc].
|
||||
<4> Let's you specify a custom `LogoutSuccessHandler`. If this is specified, `logoutSuccessUrl()` is ignored. For more information, please consult the {security-api-url}org/springframework/security/config/annotation/web/configurers/LogoutConfigurer.html#logoutSuccessHandler-org.springframework.security.web.authentication.logout.LogoutSuccessHandler-[JavaDoc].
|
||||
<5> Specify whether to invalidate the `HttpSession` at the time of logout. This is *true* by default. Configures the `SecurityContextLogoutHandler` under the covers. For more information, please consult the {security-api-url}org/springframework/security/config/annotation/web/configurers/LogoutConfigurer.html#invalidateHttpSession-boolean-[JavaDoc].
|
||||
<5> Specify whether to invalidate the `HttpSession` at the time of logout. This is *true* by default. Configures the `SecurityContextLogoutHandler` under the covers. For more information, please consult the {security-api-url}org/springframework/security/config/annotation/web/configurers/LogoutConfigurer.html#invalidateHttpSession-boolean-[JavaDoc].
|
||||
<6> Adds a `LogoutHandler`. `SecurityContextLogoutHandler` is added as the last `LogoutHandler` by default.
|
||||
<7> Allows specifying the names of cookies to be removed on logout success. This is a shortcut for adding a `CookieClearingLogoutHandler` explicitly.
|
||||
|
||||
@@ -742,7 +739,7 @@ covers when using the fluent API.
|
||||
|
||||
Generally, `{security-api-url}org/springframework/security/web/authentication/logout/LogoutHandler.html[LogoutHandler]`
|
||||
implementations indicate classes that are able to participate in logout handling.
|
||||
They are expected to be invoked to perform necessary cleanup. As such they should
|
||||
They are expected to be invoked to perform necessary clean-up. As such they should
|
||||
not throw exceptions. Various implementations are provided:
|
||||
|
||||
- {security-api-url}org/springframework/security/web/authentication/rememberme/PersistentTokenBasedRememberMeServices.html[PersistentTokenBasedRememberMeServices]
|
||||
@@ -797,10 +794,10 @@ a status code 200 will be returned by default.
|
||||
|
||||
Thus far we have only taken a look at the most basic authentication configuration. Let's take a look at a few slightly more advanced options for configuring authentication.
|
||||
|
||||
[[jc-authentication-inmememory]]
|
||||
==== In Memory Authentication
|
||||
[[jc-authentication-inmemory]]
|
||||
==== In-Memory Authentication
|
||||
|
||||
We have already seen an example of configuring in memory authentication for a single user. Below is an example to configure multiple users:
|
||||
We have already seen an example of configuring in-memory authentication for a single user. Below is an example to configure multiple users:
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@@ -816,7 +813,7 @@ public UserDetailsService userDetailsService() throws Exception {
|
||||
[[jc-authentication-jdbc]]
|
||||
==== JDBC Authentication
|
||||
|
||||
You can find the updates to suppport JDBC based authentication. The example below assumes that you have already defined a `DataSource` within your application. The https://github.com/spring-projects/spring-security/tree/master/samples/javaconfig/jdbc[jdbc-javaconfig] sample provides a complete example of using JDBC based authentication.
|
||||
You can find the updates to support JDBC based authentication. The example below assumes that you have already defined a `DataSource` within your application. The https://github.com/spring-projects/spring-security/tree/master/samples/javaconfig/jdbc[jdbc-javaconfig] sample provides a complete example of using JDBC based authentication.
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@@ -836,7 +833,7 @@ public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception
|
||||
|
||||
==== LDAP Authentication
|
||||
|
||||
You can find the updates to suppport LDAP based authentication. The https://github.com/spring-projects/spring-security/tree/master/samples/javaconfig/ldap[ldap-javaconfig] sample provides a complete example of using LDAP based authentication.
|
||||
You can find the updates to support LDAP based authentication. The https://github.com/spring-projects/spring-security/tree/master/samples/javaconfig/ldap[ldap-javaconfig] sample provides a complete example of using LDAP based authentication.
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@@ -1012,7 +1009,7 @@ public class MethodSecurityConfig {
|
||||
}
|
||||
----
|
||||
|
||||
Adding an annotation to a method (on an class or interface) would then limit the access to that method accordingly. Spring Security's native annotation support defines a set of attributes for the method. These will be passed to the AccessDecisionManager for it to make the actual decision:
|
||||
Adding an annotation to a method (on a class or interface) would then limit the access to that method accordingly. Spring Security's native annotation support defines a set of attributes for the method. These will be passed to the AccessDecisionManager for it to make the actual decision:
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@@ -1082,13 +1079,13 @@ public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration {
|
||||
}
|
||||
----
|
||||
|
||||
For additional information about methods that can be overriden, refer to the `GlobalMethodSecurityConfiguration` Javadoc.
|
||||
For additional information about methods that can be overridden, refer to the `GlobalMethodSecurityConfiguration` Javadoc.
|
||||
|
||||
=== Post Processing Configured Objects
|
||||
|
||||
Spring Security's Java Configuration does not expose every property of every object that it configures. This simplifies the configuration for a majority of users. Afterall, if every property was exposed, users could use standard bean configuration.
|
||||
|
||||
While there are good reasons to not directly expose every property, users may still need more advanced configuration options. To address this Spring Security introduces the concept of an `ObjectPostProcessor` which can used to modify or replace many of the Object instances created by the Java Configuration. For example, if you wanted to configure the `filterSecurityPublishAuthorizationSuccess` property on `FilterSecurityInterceptor` you could use the following:
|
||||
While there are good reasons to not directly expose every property, users may still need more advanced configuration options. To address this Spring Security introduces the concept of an `ObjectPostProcessor` which can be used to modify or replace many of the Object instances created by the Java Configuration. For example, if you wanted to configure the `filterSecurityPublishAuthorizationSuccess` property on `FilterSecurityInterceptor` you could use the following:
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@@ -1199,7 +1196,7 @@ public class Config extends WebSecurityConfigurerAdapter {
|
||||
|
||||
|
||||
=== Introduction
|
||||
Namespace configuration has been available since version 2.0 of the Spring framework. It allows you to supplement the traditional Spring beans application context syntax with elements from additional XML schema. You can find more information in the Spring http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/[Reference Documentation]. A namespace element can be used simply to allow a more concise way of configuring an individual bean or, more powerfully, to define an alternative configuration syntax which more closely matches the problem domain and hides the underlying complexity from the user. A simple element may conceal the fact that multiple beans and processing steps are being added to the application context. For example, adding the following element from the security namespace to an application context will start up an embedded LDAP server for testing use within the application:
|
||||
Namespace configuration has been available since version 2.0 of the Spring Framework. It allows you to supplement the traditional Spring beans application context syntax with elements from additional XML schema. You can find more information in the Spring http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/[Reference Documentation]. A namespace element can be used simply to allow a more concise way of configuring an individual bean or, more powerfully, to define an alternative configuration syntax which more closely matches the problem domain and hides the underlying complexity from the user. A simple element may conceal the fact that multiple beans and processing steps are being added to the application context. For example, adding the following element from the security namespace to an application context will start up an embedded LDAP server for testing use within the application:
|
||||
|
||||
[source,xml]
|
||||
----
|
||||
@@ -1345,7 +1342,7 @@ The `<authentication-provider>` element creates a `DaoAuthenticationProvider` be
|
||||
|
||||
The configuration above defines two users, their passwords and their roles within the application (which will be used for access control). It is also possible to load user information from a standard properties file using the `properties` attribute on `user-service`. See the section on <<core-services-in-memory-service,in-memory authentication>> for more details on the file format. Using the `<authentication-provider>` element means that the user information will be used by the authentication manager to process authentication requests. You can have multiple `<authentication-provider>` elements to define different authentication sources and each will be consulted in turn.
|
||||
|
||||
At this point you should be able to start up your application and you will be required to log in to proceed. Try it out, or try experimenting with the"tutorial" sample application that comes with the project.
|
||||
At this point you should be able to start up your application and you will be required to log in to proceed. Try it out, or try experimenting with the "tutorial" sample application that comes with the project.
|
||||
|
||||
|
||||
[[ns-form-and-basic]]
|
||||
@@ -1491,7 +1488,7 @@ Passwords should always be encoded using a secure hashing algorithm designed for
|
||||
|
||||
|
||||
|
||||
Bcrypt is a good choice for most cases, unless you have a legacy system which forces you to use a different algorithm. If you are using a simple hashing algorithm or, even worse, storing plain text passwords, then you should consider migrating to a more secure option like bcrypt.
|
||||
bcrypt is a good choice for most cases, unless you have a legacy system which forces you to use a different algorithm. If you are using a simple hashing algorithm or, even worse, storing plain text passwords, then you should consider migrating to a more secure option like bcrypt.
|
||||
|
||||
[[ns-web-advanced]]
|
||||
=== Advanced Web Features
|
||||
@@ -1636,14 +1633,14 @@ The namespace supports http://openid.net/[OpenID] login either instead of, or in
|
||||
</http>
|
||||
----
|
||||
|
||||
You should then register yourself with an OpenID provider (such as myopenid.com), and add the user information to your in-memory `<user-service>` :
|
||||
You should then register yourself with an OpenID provider (such as myopenid.com), and add the user information to your in-memory `<user-service>`:
|
||||
|
||||
[source,xml]
|
||||
----
|
||||
<user name="http://jimi.hendrix.myopenid.com/" authorities="ROLE_USER" />
|
||||
----
|
||||
|
||||
You should be able to login using the `myopenid.com` site to authenticate. It is also possible to select a specific `UserDetailsService` bean for use OpenID by setting the `user-service-ref` attribute on the `openid-login` element. See the previous section on <<ns-auth-providers,authentication providers>> for more information. Note that we have omitted the password attribute from the above user configuration, since this set of user data is only being used to load the authorities for the user. A random password will be generate internally, preventing you from accidentally using this user data as an authentication source elsewhere in your configuration.
|
||||
You should be able to login using the `myopenid.com` site to authenticate. It is also possible to select a specific `UserDetailsService` bean for use OpenID by setting the `user-service-ref` attribute on the `openid-login` element. See the previous section on <<ns-auth-providers,authentication providers>> for more information. Note that we have omitted the password attribute from the above user configuration, since this set of user data is only being used to load the authorities for the user. A random password will be generated internally, preventing you from accidentally using this user data as an authentication source elsewhere in your configuration.
|
||||
|
||||
|
||||
===== Attribute Exchange
|
||||
@@ -2061,7 +2058,7 @@ We welcome your involvement in the Spring Security project. There are many ways
|
||||
|
||||
[[further-info]]
|
||||
=== Further Information
|
||||
Questions and comments on Spring Security are welcome. You can use the Spring at StackOverflow web site at http://spring.io/questions[http://spring.io/questions] to discuss Spring Security with other users of the framework. Remember to use JIRA for bug reports, as explained above.
|
||||
Questions and comments on Spring Security are welcome. You can use the Spring at Stack Overflow web site at http://spring.io/questions[http://spring.io/questions] to discuss Spring Security with other users of the framework. Remember to use JIRA for bug reports, as explained above.
|
||||
|
||||
[[overall-architecture]]
|
||||
= Architecture and Implementation
|
||||
@@ -2089,7 +2086,7 @@ In Spring Security 3.0, the contents of the `spring-security-core` jar were stri
|
||||
==== SecurityContextHolder, SecurityContext and Authentication Objects
|
||||
The most fundamental object is `SecurityContextHolder`. This is where we store details of the present security context of the application, which includes details of the principal currently using the application. By default the `SecurityContextHolder` uses a `ThreadLocal` to store these details, which means that the security context is always available to methods in the same thread of execution, even if the security context is not explicitly passed around as an argument to those methods. Using a `ThreadLocal` in this way is quite safe if care is taken to clear the thread after the present principal's request is processed. Of course, Spring Security takes care of this for you automatically so there is no need to worry about it.
|
||||
|
||||
Some applications aren't entirely suitable for using a `ThreadLocal`, because of the specific way they work with threads. For example, a Swing client might want all threads in a Java Virtual Machine to use the same security context. `SecurityContextHolder` can be configured with a strategy on startup to specify how you would like the context to be stored. For a standalone application you would use the `SecurityContextHolder.MODE_GLOBAL` strategy. Other applications might want to have threads spawned by the secure thread also assume the same security identity. This is achieved by using `SecurityContextHolder.MODE_INHERITABLETHREADLOCAL`. You can change the mode from the default `SecurityContextHolder.MODE_THREADLOCAL` in two ways. The first is to set a system property, the second is to call a static method on `SecurityContextHolder`. Most applications won't need to change from the default, but if you do, take a look at the JavaDocs for `SecurityContextHolder` to learn more.
|
||||
Some applications aren't entirely suitable for using a `ThreadLocal`, because of the specific way they work with threads. For example, a Swing client might want all threads in a Java Virtual Machine to use the same security context. `SecurityContextHolder` can be configured with a strategy on startup to specify how you would like the context to be stored. For a standalone application you would use the `SecurityContextHolder.MODE_GLOBAL` strategy. Other applications might want to have threads spawned by the secure thread also assume the same security identity. This is achieved by using `SecurityContextHolder.MODE_INHERITABLETHREADLOCAL`. You can change the mode from the default `SecurityContextHolder.MODE_THREADLOCAL` in two ways. The first is to set a system property, the second is to call a static method on `SecurityContextHolder`. Most applications won't need to change from the default, but if you do, take a look at the JavaDoc for `SecurityContextHolder` to learn more.
|
||||
|
||||
|
||||
===== Obtaining information about the current user
|
||||
@@ -2109,7 +2106,7 @@ String username = principal.toString();
|
||||
----
|
||||
|
||||
|
||||
The object returned by the call to `getContext()` is an instance of the `SecurityContext` interface. This is the object that is kept in thread-local storage. As we'll see below, most authentication mechanisms withing Spring Security return an instance of `UserDetails` as the principal.
|
||||
The object returned by the call to `getContext()` is an instance of the `SecurityContext` interface. This is the object that is kept in thread-local storage. As we'll see below, most authentication mechanisms within Spring Security return an instance of `UserDetails` as the principal.
|
||||
|
||||
|
||||
[[tech-userdetailsservice]]
|
||||
@@ -2423,7 +2420,7 @@ If you are using the namespace, an instance of `ProviderManager` is created and
|
||||
</bean>
|
||||
----
|
||||
|
||||
In the above example we have three providers. They are tried in the order shown (which is implied by the use of a `List`), with each provider able to attempt authentication, or skip authentication by simply returning `null`. If all implementations return null, the `ProviderManager` will throw a `ProviderNotFoundException`. If you're interested in learning more about chaining providers, please refer to the `ProviderManager` JavaDocs.
|
||||
In the above example we have three providers. They are tried in the order shown (which is implied by the use of a `List`), with each provider able to attempt authentication, or skip authentication by simply returning `null`. If all implementations return null, the `ProviderManager` will throw a `ProviderNotFoundException`. If you're interested in learning more about chaining providers, please refer to the `ProviderManager` Javadoc.
|
||||
|
||||
Authentication mechanisms such as a web form-login processing filter are injected with a reference to the `ProviderManager` and will call it to handle their authentication requests. The providers you require will sometimes be interchangeable with the authentication mechanisms, while at other times they will depend on a specific authentication mechanism. For example, `DaoAuthenticationProvider` and `LdapAuthenticationProvider` are compatible with any mechanism which submits a simple username/password authentication request and so will work with form-based logins or HTTP Basic authentication. On the other hand, some authentication mechanisms create an authentication request object which can only be interpreted by a single type of `AuthenticationProvider`. An example of this would be JA-SIG CAS, which uses the notion of a service ticket and so can therefore only be authenticated by a `CasAuthenticationProvider`. You needn't be too concerned about this, because if you forget to register a suitable provider, you'll simply receive a `ProviderNotFoundException` when an attempt to authenticate is made.
|
||||
|
||||
@@ -2542,7 +2539,7 @@ Password hashing is not unique to Spring Security but is a common source of conf
|
||||
A hash is "one-way" in the sense that it is very difficult (effectively impossible) to obtain the original input given the hash value, or indeed any possible input which would produce that hash value. This property makes hash values very useful for authentication purposes. They can be stored in your user database as an alternative to plaintext passwords and even if the values are compromised they do not immediately reveal a password which can be used to login. Note that this also means you have no way of recovering the password once it is encoded.
|
||||
|
||||
==== Adding Salt to a Hash
|
||||
One potential problem with the use of password hashes that it is relatively easy to get round the one-way property of the hash if a common word is used for the input. People tend to choose similar passwords and huge dictionaries of these from previously hacked sites are available online. For example, if you search for the hash value `5f4dcc3b5aa765d61d8327deb882cf99` using google, you will quickly find the original word "password". In a similar way, an attacker can build a dictionary of hashes from a standard word list and use this to lookup the original password. One way to help prevent this is to have a suitably strong password policy to try to prevent common words from being used. Another is to use a"salt" when calculating the hashes. This is an additional string of known data for each user which is combined with the password before calculating the hash. Ideally the data should be as random as possible, but in practice any salt value is usually preferable to none. Using a salt means that an attacker has to build a separate dictionary of hashes for each salt value, making the attack more complicated (but not impossible).
|
||||
One potential problem with the use of password hashes that it is relatively easy to get round the one-way property of the hash if a common word is used for the input. People tend to choose similar passwords and huge dictionaries of these from previously hacked sites are available online. For example, if you search for the hash value `5f4dcc3b5aa765d61d8327deb882cf99` using google, you will quickly find the original word "password". In a similar way, an attacker can build a dictionary of hashes from a standard word list and use this to lookup the original password. One way to help prevent this is to have a suitably strong password policy to try to prevent common words from being used. Another is to use a "salt" when calculating the hashes. This is an additional string of known data for each user which is combined with the password before calculating the hash. Ideally the data should be as random as possible, but in practice any salt value is usually preferable to none. Using a salt means that an attacker has to build a separate dictionary of hashes for each salt value, making the attack more complicated (but not impossible).
|
||||
|
||||
Bcrypt automatically generates a random salt value for each password when it is encoded, and stores it in the bcrypt string in a standard format.
|
||||
|
||||
@@ -2619,7 +2616,7 @@ Spring Security's web infrastructure should only be used by delegating to an ins
|
||||
|
||||
The namespace element `filter-chain` is used for convenience to set up the security filter chain(s) which are required within the application. footnote:[Note that you'll need to include the security namespace in your application context XML file in order to use this syntax. The older syntax which used a `filter-chain-map` is still supported, but is deprecated in favour of the constructor argument injection.]. It maps a particular URL pattern to a list of filters built up from the bean names specified in the `filters` element, and combines them in a bean of type `SecurityFilterChain`. The `pattern` attribute takes an Ant Paths and the most specific URIs should appear first footnote:[Instead of a path pattern, the `request-matcher-ref` attribute can be used to specify a `RequestMatcher` instance for more powerful matching]. At runtime the `FilterChainProxy` will locate the first URI pattern that matches the current web request and the list of filter beans specified by the `filters` attribute will be applied to that request. The filters will be invoked in the order they are defined, so you have complete control over the filter chain which is applied to a particular URL.
|
||||
|
||||
You may have noticed we have declared two `SecurityContextPersistenceFilter` s in the filter chain ( `ASC` is short for `allowSessionCreation`, a property of `SecurityContextPersistenceFilter`). As web services will never present a `jsessionid` on future requests, creating `HttpSession` s for such user agents would be wasteful. If you had a high-volume application which required maximum scalability, we recommend you use the approach shown above. For smaller applications, using a single `SecurityContextPersistenceFilter` (with its default `allowSessionCreation` as `true`) would likely be sufficient.
|
||||
You may have noticed we have declared two `SecurityContextPersistenceFilter` s in the filter chain (`ASC` is short for `allowSessionCreation`, a property of `SecurityContextPersistenceFilter`). As web services will never present a `jsessionid` on future requests, creating `HttpSession` s for such user agents would be wasteful. If you had a high-volume application which required maximum scalability, we recommend you use the approach shown above. For smaller applications, using a single `SecurityContextPersistenceFilter` (with its default `allowSessionCreation` as `true`) would likely be sufficient.
|
||||
|
||||
Note that `FilterChainProxy` does not invoke standard filter lifecycle methods on the filters it is configured with. We recommend you use Spring's application context lifecycle interfaces as an alternative, just as you would for any other Spring bean.
|
||||
|
||||
@@ -2654,7 +2651,7 @@ As mentioned above, the default strategy is to use Ant-style paths for matching
|
||||
|
||||
If for some reason, you need a more powerful matching strategy, you can use regular expressions. The strategy implementation is then `RegexRequestMatcher`. See the Javadoc for this class for more information.
|
||||
|
||||
In practice we recommend that you use method security at your service layer, to control access to your application, and do not rely entirely on the use of security constraints defined at the web-application level. URLs change and it is difficult to take account of all the possible URLs that an application might support and how requests might be manipulated. You should try and restrict yourself to using a few simple ant paths which are simple to understand. Always try to use a"deny-by-default" approach where you have a catch-all wildcard ( /** or **) defined last and denying access.
|
||||
In practice we recommend that you use method security at your service layer, to control access to your application, and do not rely entirely on the use of security constraints defined at the web-application level. URLs change and it is difficult to take account of all the possible URLs that an application might support and how requests might be manipulated. You should try and restrict yourself to using a few simple ant paths which are simple to understand. Always try to use a "deny-by-default" approach where you have a catch-all wildcard ( /** or **) defined last and denying access.
|
||||
|
||||
Security defined at the service layer is much more robust and harder to bypass, so you should always take advantage of Spring Security's method security options.
|
||||
|
||||
@@ -2771,7 +2768,7 @@ The `AuthenticationEntryPoint` will be called if the user requests a secure HTTP
|
||||
==== AccessDeniedHandler
|
||||
What happens if a user is already authenticated and they try to access a protected resource? In normal usage, this shouldn't happen because the application workflow should be restricted to operations to which a user has access. For example, an HTML link to an administration page might be hidden from users who do not have an admin role. You can't rely on hiding links for security though, as there's always a possibility that a user will just enter the URL directly in an attempt to bypass the restrictions. Or they might modify a RESTful URL to change some of the argument values. Your application must be protected against these scenarios or it will definitely be insecure. You will typically use simple web layer security to apply constraints to basic URLs and use more specific method-based security on your service layer interfaces to really nail down what is permissible.
|
||||
|
||||
If an `AccessDeniedException` is thrown and a user has already been authenticated, then this means that an operation has been attempted for which they don't have enough permissions. In this case, `ExceptionTranslationFilter` will invoke a second strategy, the `AccessDeniedHandler`. By default, an `AccessDeniedHandlerImpl` is used, which just sends a 403 (Forbidden) response to the client. Alternatively you can configure an instance explicitly (as in the above example) and set an error page URL which it will forwards the request to footnote:[
|
||||
If an `AccessDeniedException` is thrown and a user has already been authenticated, then this means that an operation has been attempted for which they don't have enough permissions. In this case, `ExceptionTranslationFilter` will invoke a second strategy, the `AccessDeniedHandler`. By default, an `AccessDeniedHandlerImpl` is used, which just sends a 403 (Forbidden) response to the client. Alternatively you can configure an instance explicitly (as in the above example) and set an error page URL which it will forwards the request to footnote:[
|
||||
We use a forward so that the SecurityContextHolder still contains details of the principal, which may be useful for displaying to the user. In old releases of Spring Security we relied upon the servlet container to handle a 403 error message, which lacked this useful contextual information.
|
||||
]. This can be a simple "access denied" page, such as a JSP, or it could be a more complex handler such as an MVC controller. And of course, you can implement the interface yourself and use your own implementation.
|
||||
|
||||
@@ -2780,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.
|
||||
|
||||
@@ -2817,7 +2814,7 @@ void saveContext(SecurityContext context, HttpServletRequest request,
|
||||
|
||||
The `HttpRequestResponseHolder` is simply a container for the incoming request and response objects, allowing the implementation to replace these with wrapper classes. The returned contents will be passed to the filter chain.
|
||||
|
||||
The default implementation is `HttpSessionSecurityContextRepository`, which stores the security context as an `HttpSession` attribute footnote:[In Spring Security 2.0 and earlier, this filter was called `HttpSessionContextIntegrationFilter` and performed all the work of storing the context was performed by the filter itself. If you were familiar with this class, then most of the configuration options which were available can now be found on `HttpSessionSecurityContextRepository`.]. The most important configuration parameter for this implementation is the `allowSessionCreation` property, which defaults to `true`, thus allowing the class to create a session if it needs one to store the security context for an authenticated user (it won't create one unless authentication has taken place and the contents of the security context have changed). If you don't want a session to be created, then you can set this property to `false`:
|
||||
The default implementation is `HttpSessionSecurityContextRepository`, which stores the security context as an `HttpSession` attribute footnote:[In Spring Security 2.0 and earlier, this filter was called `HttpSessionContextIntegrationFilter` and performed all the work of storing the context was performed by the filter itself. If you were familiar with this class, then most of the configuration options which were available can now be found on `HttpSessionSecurityContextRepository`.]. The most important configuration parameter for this implementation is the `allowSessionCreation` property, which defaults to `true`, thus allowing the class to create a session if it needs one to store the security context for an authenticated user (it won't create one unless authentication has taken place and the contents of the security context have changed). If you don't want a session to be created, then you can set this property to `false`:
|
||||
|
||||
[source,xml]
|
||||
----
|
||||
@@ -2836,7 +2833,7 @@ Alternatively you could provide an instance of `NullSecurityContextRepository`,
|
||||
|
||||
[[form-login-filter]]
|
||||
=== UsernamePasswordAuthenticationFilter
|
||||
We've now seen the three main filters which are always present in a Spring Security web configuration. These are also the three which are automatically created by the namespace `<http>` element and cannot be substituted with alternatives. The only thing that's missing now is an actual authentication mechanism, something that will allow a user to authenticate. This filter is the most commonly used authentication filter and the one that is most often customized footnote:[For historical reasons, prior to Spring Security 3.0, this filter was called `AuthenticationProcessingFilter` and the entry point was called `AuthenticationProcessingFilterEntryPoint`. Since the framework now supports many different forms of authentication, they have both been given more specific names in 3.0.]. It also provides the implementation used by the `<form-login>` element from the namespace. There are three stages required to configure it.
|
||||
We've now seen the three main filters which are always present in a Spring Security web configuration. These are also the three which are automatically created by the namespace `<http>` element and cannot be substituted with alternatives. The only thing that's missing now is an actual authentication mechanism, something that will allow a user to authenticate. This filter is the most commonly used authentication filter and the one that is most often customized footnote:[For historical reasons, prior to Spring Security 3.0, this filter was called `AuthenticationProcessingFilter` and the entry point was called `AuthenticationProcessingFilterEntryPoint`. Since the framework now supports many different forms of authentication, they have both been given more specific names in 3.0.]. It also provides the implementation used by the `<form-login>` element from the namespace. There are three stages required to configure it.
|
||||
|
||||
* Configure a `LoginUrlAuthenticationEntryPoint` with the URL of the login page, just as we did above, and set it on the `ExceptionTranslationFilter`.
|
||||
* Implement the login page (using a JSP or MVC controller).
|
||||
@@ -2855,7 +2852,7 @@ The login form simply contains `username` and `password` input fields, and posts
|
||||
|
||||
[[form-login-flow-handling]]
|
||||
==== Application Flow on Authentication Success and Failure
|
||||
The filter calls the configured `AuthenticationManager` to process each authentication request. The destination following a successful authentication or an authentication failure is controlled by the `AuthenticationSuccessHandler` and `AuthenticationFailureHandler` strategy interfaces, respectively. The filter has properties which allow you to set these so you can customize the behaviour completely footnote:[In versions prior to 3.0, the application flow at this point had evolved to a stage was controlled by a mix of properties on this class and strategy plugins. The decision was made for 3.0 to refactor the code to make these two strategies entirely responsible.]. Some standard implementations are supplied such as `SimpleUrlAuthenticationSuccessHandler`, `SavedRequestAwareAuthenticationSuccessHandler`, `SimpleUrlAuthenticationFailureHandler`, `ExceptionMappingAuthenticationFailureHandler` and `DelegatingAuthenticationFailureHandler`. Have a look at the Javadoc for these classes and also for `AbstractAuthenticationProcessingFilter` to get an overview of how they work and the supported features.
|
||||
The filter calls the configured `AuthenticationManager` to process each authentication request. The destination following a successful authentication or an authentication failure is controlled by the `AuthenticationSuccessHandler` and `AuthenticationFailureHandler` strategy interfaces, respectively. The filter has properties which allow you to set these so you can customize the behaviour completely footnote:[In versions prior to 3.0, the application flow at this point had evolved to a stage was controlled by a mix of properties on this class and strategy plugins. The decision was made for 3.0 to refactor the code to make these two strategies entirely responsible.]. Some standard implementations are supplied such as `SimpleUrlAuthenticationSuccessHandler`, `SavedRequestAwareAuthenticationSuccessHandler`, `SimpleUrlAuthenticationFailureHandler`, `ExceptionMappingAuthenticationFailureHandler` and `DelegatingAuthenticationFailureHandler`. Have a look at the Javadoc for these classes and also for `AbstractAuthenticationProcessingFilter` to get an overview of how they work and the supported features.
|
||||
|
||||
If authentication is successful, the resulting `Authentication` object will be placed into the `SecurityContextHolder`. The configured `AuthenticationSuccessHandler` will then be called to either redirect or forward the user to the appropriate destination. By default a `SavedRequestAwareAuthenticationSuccessHandler` is used, which means that the user will be redirected to the original destination they requested before they were asked to login.
|
||||
|
||||
@@ -3002,7 +2999,7 @@ Next you need to ensure that your springSecurityFilterChain is setup for process
|
||||
|
||||
That's it! Now Spring Security will ensure that your SecurityContext is propagated on asynchronous requests too.
|
||||
|
||||
So how does it work? If you are not really interested, feel free to skip the remainder of this section, otherwise read on. Most of this is built into the Servlet specification, but there is a little bit of tweaking that Spring Security does to ensure things work with asynchronous requests properly. Prior to Spring Security 3.2, the SecurityContext from the SecurityContextHolder was automatically saved as soon as the HttpServletResponse was committed. This can cause issues in a Async environment. For example, consider the following:
|
||||
So how does it work? If you are not really interested, feel free to skip the remainder of this section, otherwise read on. Most of this is built into the Servlet specification, but there is a little bit of tweaking that Spring Security does to ensure things work with asynchronous requests properly. Prior to Spring Security 3.2, the SecurityContext from the SecurityContextHolder was automatically saved as soon as the HttpServletResponse was committed. This can cause issues in an Async environment. For example, consider the following:
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@@ -3037,7 +3034,7 @@ The http://docs.oracle.com/javaee/7/api/javax/servlet/http/HttpServletRequest.ht
|
||||
|
||||
[[basic]]
|
||||
== Basic and Digest Authentication
|
||||
Basic and digest authentiation are alternative authentication mechanisms which are popular in web applications. Basic authentication is often used with stateless clients which pass their credentials on each request. It's quite common to use it in combination with form-based authentication where an application is used through both a browser-based user interface and as a web-service. However, basic authentication transmits the password as plain text so it should only really be used over an encrypted transport layer such as HTTPS.
|
||||
Basic and digest authentication are alternative authentication mechanisms which are popular in web applications. Basic authentication is often used with stateless clients which pass their credentials on each request. It's quite common to use it in combination with form-based authentication where an application is used through both a browser-based user interface and as a web-service. However, basic authentication transmits the password as plain text so it should only really be used over an encrypted transport layer such as HTTPS.
|
||||
|
||||
[[basic-processing-filter]]
|
||||
=== BasicAuthenticationFilter
|
||||
@@ -3068,14 +3065,14 @@ If the authentication event was successful, or authentication was not attempted
|
||||
|
||||
[[digest-processing-filter]]
|
||||
=== DigestAuthenticationFilter
|
||||
`DigestAuthenticationFilter` is capable of processing digest authentication credentials presented in HTTP headers. Digest Authentication attempts to solve many of the weaknesses of Basic authentication, specifically by ensuring credentials are never sent in clear text across the wire. Many user agents support Digest Authentication, including FireFox and Internet Explorer. The standard governing HTTP Digest Authentication is defined by RFC 2617, which updates an earlier version of the Digest Authentication standard prescribed by RFC 2069. Most user agents implement RFC 2617. Spring Security's `DigestAuthenticationFilter` is compatible with the "`auth`" quality of protection (`qop`) prescribed by RFC 2617, which also provides backward compatibility with RFC 2069. Digest Authentication is a more attractive option if you need to use unencrypted HTTP (i.e. no TLS/HTTPS) and wish to maximise security of the authentication process. Indeed Digest Authentication is a mandatory requirement for the WebDAV protocol, as noted by RFC 2518 Section 17.1.
|
||||
`DigestAuthenticationFilter` is capable of processing digest authentication credentials presented in HTTP headers. Digest Authentication attempts to solve many of the weaknesses of Basic authentication, specifically by ensuring credentials are never sent in clear text across the wire. Many user agents support Digest Authentication, including Mozilla Firefox and Internet Explorer. The standard governing HTTP Digest Authentication is defined by RFC 2617, which updates an earlier version of the Digest Authentication standard prescribed by RFC 2069. Most user agents implement RFC 2617. Spring Security's `DigestAuthenticationFilter` is compatible with the "`auth`" quality of protection (`qop`) prescribed by RFC 2617, which also provides backward compatibility with RFC 2069. Digest Authentication is a more attractive option if you need to use unencrypted HTTP (i.e. no TLS/HTTPS) and wish to maximise security of the authentication process. Indeed Digest Authentication is a mandatory requirement for the WebDAV protocol, as noted by RFC 2518 Section 17.1.
|
||||
|
||||
[NOTE]
|
||||
====
|
||||
You should not use Digest in modern applications because it is not considered secure.
|
||||
The most obvious problem is that you must store your passwords in plaintext, encrpted, or an MD5 format.
|
||||
The most obvious problem is that you must store your passwords in plaintext, encrypted, or an MD5 format.
|
||||
All of these storage formats are considered insecure.
|
||||
Instead, you should use a one way adaptive password hash (i.e. BCrypt, PBKDF2, SCrypt, etc).
|
||||
Instead, you should use a one way adaptive password hash (i.e. bCrypt, PBKDF2, SCrypt, etc).
|
||||
====
|
||||
|
||||
Central to Digest Authentication is a "nonce". This is a value the server generates. Spring Security's nonce adopts the following format:
|
||||
@@ -3091,7 +3088,7 @@ The `DigestAuthenticatonEntryPoint` has a property specifying the `key` used for
|
||||
|
||||
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.
|
||||
|
||||
Because of the more complex implementation of Digest Authentication, there are often user agent issues. For example, Internet Explorer fails to present an "`opaque`" token on subsequent requests in the same session. Spring Security filters therefore encapsulate all state information into the "`nonce`" token instead. In our testing, Spring Security's implementation works reliably with FireFox and Internet Explorer, correctly handling nonce timeouts etc.
|
||||
Because of the more complex implementation of Digest Authentication, there are often user agent issues. For example, Internet Explorer fails to present an "`opaque`" token on subsequent requests in the same session. Spring Security filters therefore encapsulate all state information into the "`nonce`" token instead. In our testing, Spring Security's implementation works reliably with Mozilla Firefox and Internet Explorer, correctly handling nonce timeouts etc.
|
||||
|
||||
|
||||
[[digest-config]]
|
||||
@@ -3115,7 +3112,7 @@ Now that we've reviewed the theory, let's see how to use it. To implement HTTP D
|
||||
</bean>
|
||||
----
|
||||
|
||||
The configured `UserDetailsService` is needed because `DigestAuthenticationFilter` must have direct access to the clear text password of a user. Digest Authentication will NOT work if you are using encoded passwords in your DAO footnote:[It is possible to encode the password in the format HEX( MD5(username:realm:password) ) provided the `DigestAuthenticationFilter.passwordAlreadyEncoded` is set to `true`. However, other password encodings will not work with digest authentication.]. The DAO collaborator, along with the `UserCache`, are typically shared directly with a `DaoAuthenticationProvider`. The `authenticationEntryPoint` property must be `DigestAuthenticationEntryPoint`, so that `DigestAuthenticationFilter` can obtain the correct `realmName` and `key` for digest calculations.
|
||||
The configured `UserDetailsService` is needed because `DigestAuthenticationFilter` must have direct access to the clear text password of a user. Digest Authentication will NOT work if you are using encoded passwords in your DAO footnote:[It is possible to encode the password in the format HEX( MD5(username:realm:password) ) provided the `DigestAuthenticationFilter.passwordAlreadyEncoded` is set to `true`. However, other password encodings will not work with digest authentication.]. The DAO collaborator, along with the `UserCache`, are typically shared directly with a `DaoAuthenticationProvider`. The `authenticationEntryPoint` property must be `DigestAuthenticationEntryPoint`, so that `DigestAuthenticationFilter` can obtain the correct `realmName` and `key` for digest calculations.
|
||||
|
||||
Like `BasicAuthenticationFilter`, if authentication is successful an `Authentication` request token will be placed into the `SecurityContextHolder`. If the authentication event was successful, or authentication was not attempted because the HTTP header did not contain a Digest Authentication request, the filter chain will continue as normal. The only time the filter chain will be interrupted is if authentication fails and the `AuthenticationEntryPoint` is called, as discussed in the previous paragraph.
|
||||
|
||||
@@ -3130,7 +3127,7 @@ Digest Authentication's RFC offers a range of additional features to further inc
|
||||
=== Overview
|
||||
Remember-me or persistent-login authentication refers to web sites being able to remember the identity of a principal between sessions. This is typically accomplished by sending a cookie to the browser, with the cookie being detected during future sessions and causing automated login to take place. Spring Security provides the necessary hooks for these operations to take place, and has two concrete remember-me implementations. One uses hashing to preserve the security of cookie-based tokens and the other uses a database or other persistent storage mechanism to store the generated tokens.
|
||||
|
||||
Note that both implemementations require a `UserDetailsService`. If you are using an authentication provider which doesn't use a `UserDetailsService` (for example, the LDAP provider) then it won't work unless you also have a `UserDetailsService` bean in your application context.
|
||||
Note that both implementations require a `UserDetailsService`. If you are using an authentication provider which doesn't use a `UserDetailsService` (for example, the LDAP provider) then it won't work unless you also have a `UserDetailsService` bean in your application context.
|
||||
|
||||
|
||||
[[remember-me-hash-token]]
|
||||
@@ -3201,7 +3198,7 @@ void loginSuccess(HttpServletRequest request, HttpServletResponse response,
|
||||
Authentication successfulAuthentication);
|
||||
----
|
||||
|
||||
Please refer to the JavaDocs for a fuller discussion on what the methods do, although note at this stage that `AbstractAuthenticationProcessingFilter` only calls the `loginFail()` and `loginSuccess()` methods. The `autoLogin()` method is called by `RememberMeAuthenticationFilter` whenever the `SecurityContextHolder` does not contain an `Authentication`. This interface therefore provides the underlying remember-me implementation with sufficient notification of authentication-related events, and delegates to the implementation whenever a candidate web request might contain a cookie and wish to be remembered. This design allows any number of remember-me implementation strategies. We've seen above that Spring Security provides two implementations. We'll look at these in turn.
|
||||
Please refer to the Javadoc for a fuller discussion on what the methods do, although note at this stage that `AbstractAuthenticationProcessingFilter` only calls the `loginFail()` and `loginSuccess()` methods. The `autoLogin()` method is called by `RememberMeAuthenticationFilter` whenever the `SecurityContextHolder` does not contain an `Authentication`. This interface therefore provides the underlying remember-me implementation with sufficient notification of authentication-related events, and delegates to the implementation whenever a candidate web request might contain a cookie and wish to be remembered. This design allows any number of remember-me implementation strategies. We've seen above that Spring Security provides two implementations. We'll look at these in turn.
|
||||
|
||||
==== TokenBasedRememberMeServices
|
||||
This implementation supports the simpler approach described in <<remember-me-hash-token>>. `TokenBasedRememberMeServices` generates a `RememberMeAuthenticationToken`, which is processed by `RememberMeAuthenticationProvider`. A `key` is shared between this authentication provider and the `TokenBasedRememberMeServices`. In addition, `TokenBasedRememberMeServices` requires A UserDetailsService from which it can retrieve the username and password for signature comparison purposes, and generate the `RememberMeAuthenticationToken` to contain the correct `GrantedAuthority` s. Some sort of logout command should be provided by the application that invalidates the cookie if the user requests this. `TokenBasedRememberMeServices` also implements Spring Security's `LogoutHandler` interface so can be used with `LogoutFilter` to have the cookie cleared automatically.
|
||||
@@ -3552,7 +3549,7 @@ As previously mentioned, this is not as secure as using a session, but in many c
|
||||
==== Logging In
|
||||
In order to protect against http://en.wikipedia.org/wiki/Cross-site_request_forgery#Forging_login_requests[forging log in requests] the log in form should be protected against CSRF attacks too. Since the `CsrfToken` is stored in HttpSession, this means an HttpSession will be created as soon as `CsrfToken` token attribute is accessed. While this sounds bad in a RESTful / stateless architecture the reality is that state is necessary to implement practical security. Without state, we have nothing we can do if a token is compromised. Practically speaking, the CSRF token is quite small in size and should have a negligible impact on our architecture.
|
||||
|
||||
A common technique to protect the log in form is by using a javascript function to obtain a valid CSRF token before the form submission. By doing this, there is no need to think about session timeouts (discussed in the previous section) because the session is created right before the form submission (assuming that <<csrf-cookie,CookieCsrfTokenRepository>> isn't configured instead), so the user can stay on the login page and submit the username/password when he wants. In order to achieve this, you can take advantage of the `CsrfTokenArgumentResolver` provided by Spring Security and expose an endpoint like it's described on <<mvc-csrf-resolver,here>>.
|
||||
A common technique to protect the log in form is by using a JavaScript function to obtain a valid CSRF token before the form submission. By doing this, there is no need to think about session timeouts (discussed in the previous section) because the session is created right before the form submission (assuming that <<csrf-cookie,CookieCsrfTokenRepository>> isn't configured instead), so the user can stay on the login page and submit the username/password when he wants. In order to achieve this, you can take advantage of the `CsrfTokenArgumentResolver` provided by Spring Security and expose an endpoint like it's described on <<mvc-csrf-resolver,here>>.
|
||||
|
||||
|
||||
[[csrf-logout]]
|
||||
@@ -3656,7 +3653,7 @@ You can also specify a custom RequestMatcher to determine which requests are pro
|
||||
== CORS
|
||||
|
||||
Spring Framework provides http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#cors[first class support for CORS].
|
||||
CORS must be processed before Spring Security because the preflight request will not contain any cookies (i.e. the `JSESSIONID`).
|
||||
CORS must be processed before Spring Security because the pre-flight request will not contain any cookies (i.e. the `JSESSIONID`).
|
||||
If the request does not contain any cookies and Spring Security is first, the request will determine the user is not authenticated (since there are no cookies in the request) and reject it.
|
||||
|
||||
The easiest way to ensure that CORS is handled first is to use the `CorsFilter`.
|
||||
@@ -3723,7 +3720,7 @@ or in XML
|
||||
[source,xml]
|
||||
----
|
||||
<http>
|
||||
<!-- Default to Spring MVC's CORS configuraiton -->
|
||||
<!-- Default to Spring MVC's CORS configuration -->
|
||||
<cors />
|
||||
...
|
||||
</http>
|
||||
@@ -4194,7 +4191,7 @@ This header is included by default. However, we can customize it if we wanted. F
|
||||
</http>
|
||||
----
|
||||
|
||||
Similarly, you can customize xss protection within Java Configuration with the following:
|
||||
Similarly, you can customize XSS protection within Java Configuration with the following:
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@@ -4365,6 +4362,58 @@ https://developer.mozilla.org/en-US/docs/Web/Security/CSP[CSP Guide - Mozilla De
|
||||
|
||||
https://www.w3.org/TR/CSP2/[W3C Candidate Recommendation]
|
||||
|
||||
[[headers-referrer]]
|
||||
==== Referrer Policy
|
||||
|
||||
https://www.w3.org/TR/referrer-policy[Referrer Policy] is a mechanism that web applications can leverage to manage the referrer field, which contains the last
|
||||
page the user was on.
|
||||
|
||||
Spring Security's approach is to use https://www.w3.org/TR/referrer-policy/[Referrer Policy] header, which provides different https://www.w3.org/TR/referrer-policy/#referrer-policies[policies]:
|
||||
|
||||
[source]
|
||||
----
|
||||
Referrer-Policy: same-origin
|
||||
----
|
||||
|
||||
The Referrer-Policy response header instructs the browser to let the destination knows the source where the user was previously.
|
||||
|
||||
[[headers-referrer-configure]]
|
||||
===== Configuring Referrer Policy
|
||||
|
||||
Spring Security *_doesn't add_* Referrer Policy header by default.
|
||||
|
||||
You can enable the Referrer-Policy header using XML configuration with the <<nsa-referrer-policy,<referrer-policy>>> element as shown below:
|
||||
|
||||
[source,xml]
|
||||
----
|
||||
<http>
|
||||
<!-- ... -->
|
||||
|
||||
<headers>
|
||||
<referrer-policy policy="same-origin" />
|
||||
</headers>
|
||||
</http>
|
||||
----
|
||||
|
||||
Similarly, you can enable the Referrer Policy header using Java configuration as shown below:
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@EnableWebSecurity
|
||||
public class WebSecurityConfig extends
|
||||
WebSecurityConfigurerAdapter {
|
||||
|
||||
@Override
|
||||
protected void configure(HttpSecurity http) throws Exception {
|
||||
http
|
||||
// ...
|
||||
.headers()
|
||||
.referrerPolicy(ReferrerPolicy.SAME_ORIGIN);
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
|
||||
[[headers-custom]]
|
||||
=== Custom Headers
|
||||
Spring Security has mechanisms to make it convenient to add the more common security headers to your application. However, it also provides hooks to enable adding custom headers.
|
||||
@@ -4512,7 +4561,7 @@ protected void configure(HttpSecurity http) throws Exception {
|
||||
|
||||
[[session-mgmt]]
|
||||
== Session Management
|
||||
HTTP session related functonality is handled by a combination of the `SessionManagementFilter` and the `SessionAuthenticationStrategy` interface, which the filter delegates to. Typical usage includes session-fixation protection attack prevention, detection of session timeouts and restrictions on how many sessions an authenticated user may have open concurrently.
|
||||
HTTP session related functionality is handled by a combination of the `SessionManagementFilter` and the `SessionAuthenticationStrategy` interface, which the filter delegates to. Typical usage includes session-fixation protection attack prevention, detection of session timeouts and restrictions on how many sessions an authenticated user may have open concurrently.
|
||||
|
||||
|
||||
=== SessionManagementFilter
|
||||
@@ -4549,7 +4598,7 @@ Note that the use of the default, `SessionFixationProtectionStrategy` may cause
|
||||
|
||||
[[concurrent-sessions]]
|
||||
=== Concurrency Control
|
||||
Spring Security is able to prevent a principal from concurrently authenticating to the same application more than a specified number of times. Many ISVs take advantage of this to enforce licensing, whilst network administrators like this feature because it helps prevent people from sharing login names. You can, for example, stop user"Batman" from logging onto the web application from two different sessions. You can either expire their previous login or you can report an error when they try to log in again, preventing the second login. Note that if you are using the second approach, a user who has not explicitly logged out (but who has just closed their browser, for example) will not be able to log in again until their original session expires.
|
||||
Spring Security is able to prevent a principal from concurrently authenticating to the same application more than a specified number of times. Many ISVs take advantage of this to enforce licensing, whilst network administrators like this feature because it helps prevent people from sharing login names. You can, for example, stop user "Batman" from logging onto the web application from two different sessions. You can either expire their previous login or you can report an error when they try to log in again, preventing the second login. Note that if you are using the second approach, a user who has not explicitly logged out (but who has just closed their browser, for example) will not be able to log in again until their original session expires.
|
||||
|
||||
Concurrency control is supported by the namespace, so please check the earlier namespace chapter for the simplest configuration. Sometimes you need to customize things though.
|
||||
|
||||
@@ -4706,7 +4755,7 @@ As explained earlier, the benefit of anonymous authentication is that all URI pa
|
||||
=== AuthenticationTrustResolver
|
||||
Rounding out the anonymous authentication discussion is the `AuthenticationTrustResolver` interface, with its corresponding `AuthenticationTrustResolverImpl` implementation. This interface provides an `isAnonymous(Authentication)` method, which allows interested classes to take into account this special type of authentication status. The `ExceptionTranslationFilter` uses this interface in processing `AccessDeniedException` s. If an `AccessDeniedException` is thrown, and the authentication is of an anonymous type, instead of throwing a 403 (forbidden) response, the filter will instead commence the `AuthenticationEntryPoint` so the principal can authenticate properly. This is a necessary distinction, otherwise principals would always be deemed "authenticated" and never be given an opportunity to login via form, basic, digest or some other normal authentication mechanism.
|
||||
|
||||
You will often see the `ROLE_ANONYMOUS` attribute in the above interceptor configuration replaced with `IS_AUTHENTICATED_ANONYMOUSLY`, which is effectively the same thing when defining access controls. This is an example of the use of the `AuthenticatedVoter` which we will see in the <<authz-authenticated-voter,authorization chapter>>. It uses an `AuthenticationTrustResolver` to process this particular configuration attribute and grant access to anonymous users. the `AuthenticatedVoter` approach is more powerful, since it allows you to differentiate between anonymous, remember-me and fully-authenticated users. If you don't need this functionality though, then you can stick with `ROLE_ANONYMOUS`, which will be processed by Spring Security's standard `RoleVoter`.
|
||||
You will often see the `ROLE_ANONYMOUS` attribute in the above interceptor configuration replaced with `IS_AUTHENTICATED_ANONYMOUSLY`, which is effectively the same thing when defining access controls. This is an example of the use of the `AuthenticatedVoter` which we will see in the <<authz-authenticated-voter,authorization chapter>>. It uses an `AuthenticationTrustResolver` to process this particular configuration attribute and grant access to anonymous users. The `AuthenticatedVoter` approach is more powerful, since it allows you to differentiate between anonymous, remember-me and fully-authenticated users. If you don't need this functionality though, then you can stick with `ROLE_ANONYMOUS`, which will be processed by Spring Security's standard `RoleVoter`.
|
||||
|
||||
include::{include-dir}/websocket.adoc[]
|
||||
|
||||
@@ -4739,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]]
|
||||
@@ -4790,7 +4839,7 @@ boolean supports(Class clazz);
|
||||
|
||||
Concrete implementations return an `int`, with possible values being reflected in the `AccessDecisionVoter` static fields `ACCESS_ABSTAIN`, `ACCESS_DENIED` and `ACCESS_GRANTED`. A voting implementation will return `ACCESS_ABSTAIN` if it has no opinion on an authorization decision. If it does have an opinion, it must return either `ACCESS_DENIED` or `ACCESS_GRANTED`.
|
||||
|
||||
There are three concrete `AccessDecisionManager` s provided with Spring Security that tally the votes. the `ConsensusBased` implementation will grant or deny access based on the consensus of non-abstain votes. Properties are provided to control behavior in the event of an equality of votes or if all votes are abstain. The `AffirmativeBased` implementation will grant access if one or more `ACCESS_GRANTED` votes were received (i.e. a deny vote will be ignored, provided there was at least one grant vote). Like the `ConsensusBased` implementation, there is a parameter that controls the behavior if all voters abstain. The `UnanimousBased` provider expects unanimous `ACCESS_GRANTED` votes in order to grant access, ignoring abstains. It will deny access if there is any `ACCESS_DENIED` vote. Like the other implementations, there is a parameter that controls the behaviour if all voters abstain.
|
||||
There are three concrete `AccessDecisionManager` s provided with Spring Security that tally the votes. The `ConsensusBased` implementation will grant or deny access based on the consensus of non-abstain votes. Properties are provided to control behavior in the event of an equality of votes or if all votes are abstain. The `AffirmativeBased` implementation will grant access if one or more `ACCESS_GRANTED` votes were received (i.e. a deny vote will be ignored, provided there was at least one grant vote). Like the `ConsensusBased` implementation, there is a parameter that controls the behavior if all voters abstain. The `UnanimousBased` provider expects unanimous `ACCESS_GRANTED` votes in order to grant access, ignoring abstains. It will deny access if there is any `ACCESS_DENIED` vote. Like the other implementations, there is a parameter that controls the behaviour if all voters abstain.
|
||||
|
||||
It is possible to implement a custom `AccessDecisionManager` that tallies votes differently. For example, votes from a particular `AccessDecisionVoter` might receive additional weighting, whilst a deny vote from a particular voter may have a veto effect.
|
||||
|
||||
@@ -4811,7 +4860,7 @@ When we've used the attribute `IS_AUTHENTICATED_ANONYMOUSLY` to grant anonymous
|
||||
|
||||
[[authz-custom-voter]]
|
||||
===== Custom Voters
|
||||
Obviously, you can also implement a custom `AccessDecisionVoter` and you can put just about any access-control logic you want in it. It might be specific to your application (business-logic related) or it might implement some security administration logic. For example, you'll find a http://spring.io/blog/2009/01/03/spring-security-customization-part-2-adjusting-secured-session-in-real-time[ blog article] on the Spring web site which describes how to use a voter to deny access in real-time to users whose accounts have been suspended.
|
||||
Obviously, you can also implement a custom `AccessDecisionVoter` and you can put just about any access-control logic you want in it. It might be specific to your application (business-logic related) or it might implement some security administration logic. For example, you'll find a http://spring.io/blog/2009/01/03/spring-security-customization-part-2-adjusting-secured-session-in-real-time[blog article] on the Spring web site which describes how to use a voter to deny access in real-time to users whose accounts have been suspended.
|
||||
|
||||
|
||||
[[authz-after-invocation-handling]]
|
||||
@@ -4853,7 +4902,7 @@ The use of a role-hierarchy allows you to configure which roles (or authorities)
|
||||
</bean>
|
||||
----
|
||||
|
||||
Here we have four roles in a hierarchy `ROLE_ADMIN => ROLE_STAFF => ROLE_USER => ROLE_GUEST`. A user who is authenticated with `ROLE_ADMIN`, will behave as if they have all four roles when security contraints are evaluated against an `AccessDecisionManager` cconfigured with the above `RoleHierarchyVoter`. The `>` symbol can be thought of as meaning "includes".
|
||||
Here we have four roles in a hierarchy `ROLE_ADMIN => ROLE_STAFF => ROLE_USER => ROLE_GUEST`. A user who is authenticated with `ROLE_ADMIN`, will behave as if they have all four roles when security constraints are evaluated against an `AccessDecisionManager` cconfigured with the above `RoleHierarchyVoter`. The `>` symbol can be thought of as meaning "includes".
|
||||
|
||||
Role hierarchies offer a convenient means of simplifying the access-control configuration data for your application and/or reducing the number of authorities which you need to assign to a user. For more complex requirements you may wish to define a logical mapping between the specific access-rights your application requires and the roles that are assigned to users, translating between the two when loading the user information.
|
||||
|
||||
@@ -4986,7 +5035,7 @@ That's it! Now you can create your beans from anywhere within your application,
|
||||
|
||||
[[el-access]]
|
||||
== Expression-Based Access Control
|
||||
Spring Security 3.0 introduced the ability to use Spring EL expressions as an authorization mechanism in addition to the simple use of configuration attributes and access-decision voters which have seen before. Expression-based access control is built on the same architecture but allows complicated boolean logic to be encapsulated in a single expression.
|
||||
Spring Security 3.0 introduced the ability to use Spring EL expressions as an authorization mechanism in addition to the simple use of configuration attributes and access-decision voters which have seen before. Expression-based access control is built on the same architecture but allows complicated Boolean logic to be encapsulated in a single expression.
|
||||
|
||||
|
||||
=== Overview
|
||||
@@ -5051,7 +5100,7 @@ The base class for expression root objects is `SecurityExpressionRoot`. This pro
|
||||
=== Web Security Expressions
|
||||
To use expressions to secure individual URLs, you would first need to set the `use-expressions` attribute in the `<http>` element to `true`.
|
||||
Spring Security will then expect the `access` attributes of the `<intercept-url>` elements to contain Spring EL expressions.
|
||||
The expressions should evaluate to a boolean, defining whether access should be allowed or not.
|
||||
The expressions should evaluate to a Boolean, defining whether access should be allowed or not.
|
||||
For example:
|
||||
|
||||
[source,xml]
|
||||
@@ -5077,7 +5126,7 @@ So if you aren't using the namespace and want to use expressions, you will have
|
||||
==== Referring to Beans in Web Security Expressions
|
||||
|
||||
If you wish to extend the expressions that are available, you can easily refer to any Spring Bean you expose.
|
||||
For example, assumming you have a Bean with the name of `webSecurity` that contains the following method signature:
|
||||
For example, assuming you have a Bean with the name of `webSecurity` that contains the following method signature:
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@@ -5320,7 +5369,7 @@ In order to remain compliant with the specification JSR-250 annotations do not s
|
||||
|
||||
[[advanced-topics]]
|
||||
= Additional Topics
|
||||
In this part we cover features which require a knowledge of previous chapters as well as some of the more advanced and less-commonly used features of the framework.
|
||||
In this part we cover features which require knowledge of previous chapters as well as some of the more advanced and less-commonly used features of the framework.
|
||||
|
||||
[[domain-acls]]
|
||||
== Domain Object Security (ACLs)
|
||||
@@ -5426,7 +5475,7 @@ aclService.updateAcl(acl);
|
||||
|
||||
|
||||
|
||||
In the example above, we're retrieving the ACL associated with the "Foo" domain object with identifier number 44. We're then adding an ACE so that a principal named "Samantha" can "administer" the object. The code fragment is relatively self-explanatory, except the insertAce method. The first argument to the insertAce method is determining at what position in the Acl the new entry will be inserted. In the example above, we're just putting the new ACE at the end of the existing ACEs. The final argument is a boolean indicating whether the ACE is granting or denying. Most of the time it will be granting (true), but if it is denying (false), the permissions are effectively being blocked.
|
||||
In the example above, we're retrieving the ACL associated with the "Foo" domain object with identifier number 44. We're then adding an ACE so that a principal named "Samantha" can "administer" the object. The code fragment is relatively self-explanatory, except the insertAce method. The first argument to the insertAce method is determining at what position in the Acl the new entry will be inserted. In the example above, we're just putting the new ACE at the end of the existing ACEs. The final argument is a Boolean indicating whether the ACE is granting or denying. Most of the time it will be granting (true), but if it is denying (false), the permissions are effectively being blocked.
|
||||
|
||||
Spring Security does not provide any special integration to automatically create, update or delete ACLs as part of your DAO or repository operations. Instead, you will need to write code like shown above for your individual domain objects. It's worth considering using AOP on your services layer to automatically integrate the ACL information with your services layer operations. We've found this quite an effective approach in the past.
|
||||
|
||||
@@ -5493,7 +5542,7 @@ X.509 authentication is covered in its <<x509,own chapter>>. Here we'll look at
|
||||
|
||||
|
||||
==== Request-Header Authentication (Siteminder)
|
||||
An external authentication system may supply information to the application by setting specific headers on the HTTP request. A well known example of this is Siteminder, which passes the username in a header called `SM_USER`. This mechanism is supported by the class `RequestHeaderAuthenticationFilter` which simply extracts the username from the header. It defaults to using the name `SM_USER` as the header name. See the Javadoc for more details.
|
||||
An external authentication system may supply information to the application by setting specific headers on the HTTP request. A well-known example of this is Siteminder, which passes the username in a header called `SM_USER`. This mechanism is supported by the class `RequestHeaderAuthenticationFilter` which simply extracts the username from the header. It defaults to using the name `SM_USER` as the header name. See the Javadoc for more details.
|
||||
|
||||
[TIP]
|
||||
====
|
||||
@@ -5746,7 +5795,7 @@ void mapUserToContext(UserDetails user, DirContextAdapter ctx);
|
||||
}
|
||||
----
|
||||
|
||||
Only the first method is relevant for authentication. If you provide an implementation of this interface and inject it into the `LdapAuthenticationProvider`, you have control over exactly how the UserDetails object is created. The first parameter is an instance of Spring LDAP's `DirContextOperations` which gives you access to the LDAP attributes which were loaded during authentication. the `username` parameter is the name used to authenticate and the final parameter is the collection of authorities loaded for the user by the configured `LdapAuthoritiesPopulator`.
|
||||
Only the first method is relevant for authentication. If you provide an implementation of this interface and inject it into the `LdapAuthenticationProvider`, you have control over exactly how the UserDetails object is created. The first parameter is an instance of Spring LDAP's `DirContextOperations` which gives you access to the LDAP attributes which were loaded during authentication. The `username` parameter is the name used to authenticate and the final parameter is the collection of authorities loaded for the user by the configured `LdapAuthoritiesPopulator`.
|
||||
|
||||
The way the context data is loaded varies slightly depending on the type of authentication you are using. With the `BindAuthenticator`, the context returned from the bind operation will be used to read the attributes, otherwise the data will be read using the standard context obtained from the configured `ContextSource` (when a search is configured to locate the user, this will be the data returned by the search object).
|
||||
|
||||
@@ -5757,7 +5806,7 @@ Active Directory supports its own non-standard authentication options, and the n
|
||||
|
||||
|
||||
==== ActiveDirectoryLdapAuthenticationProvider
|
||||
Configuring `ActiveDirectoryLdapAuthenticationProvider` is quite straightforward. You just need to supply the domain name and an LDAP URL supplying the address of the server footnote:[It is also possible to obtain the server's IP address using a DNS lookup. This is not currently supported, but hopefully will be in a future version.]. An example configuration would then look like this:
|
||||
Configuring `ActiveDirectoryLdapAuthenticationProvider` is quite straightforward. You just need to supply the domain name and an LDAP URL supplying the address of the server footnote:[It is also possible to obtain the server's IP address using a DNS lookup. This is not currently supported, but hopefully will be in a future version.]. An example configuration would then look like this:
|
||||
|
||||
[source,xml]
|
||||
----
|
||||
@@ -5793,7 +5842,7 @@ To use any of the tags, you must have the security taglib declared in your JSP:
|
||||
|
||||
[[taglibs-authorize]]
|
||||
=== The authorize Tag
|
||||
This tag is used to determine whether its contents should be evaluated or not. In Spring Security 3.0, it can be used in two ways footnote:[
|
||||
This tag is used to determine whether its contents should be evaluated or not. In Spring Security 3.0, it can be used in two ways footnote:[
|
||||
The legacy options from Spring Security 2.0 are also supported, but discouraged.
|
||||
]. The first approach uses a <<el-access-web,web-security expression>>, specified in the `access` attribute of the tag. The expression evaluation will be delegated to the `SecurityExpressionHandler<FilterInvocation>` defined in the application context (you should have web expressions enabled in your `<http>` namespace configuration to make sure this service is available). So, for example, you might have
|
||||
|
||||
@@ -5830,7 +5879,7 @@ This content will only be visible to users who are authorized to send requests t
|
||||
|
||||
To use this tag there must also be an instance of `WebInvocationPrivilegeEvaluator` in your application context. If you are using the namespace, one will automatically be registered. This is an instance of `DefaultWebInvocationPrivilegeEvaluator`, which creates a dummy web request for the supplied URL and invokes the security interceptor to see whether the request would succeed or fail. This allows you to delegate to the access-control setup you defined using `intercept-url` declarations within the `<http>` namespace configuration and saves having to duplicate the information (such as the required roles) within your JSPs. This approach can also be combined with a `method` attribute, supplying the HTTP method, for a more specific match.
|
||||
|
||||
The boolean result of evaluating the tag (whether it grants or denies access) can be stored in a page context scope variable by setting the `var` attribute to the variable name, avoiding the need for duplicating and re-evaluating the condition at other points in the page.
|
||||
The Boolean result of evaluating the tag (whether it grants or denies access) can be stored in a page context scope variable by setting the `var` attribute to the variable name, avoiding the need for duplicating and re-evaluating the condition at other points in the page.
|
||||
|
||||
|
||||
==== Disabling Tag Authorization for Testing
|
||||
@@ -5986,7 +6035,7 @@ The `DefaultJaasAuthenticationProvider` allows a JAAS `Configuration` object to
|
||||
|
||||
[[jaas-inmemoryconfiguration]]
|
||||
==== InMemoryConfiguration
|
||||
In order to make it easy to inject a `Configuration` into `DefaultJaasAuthenticationProvider`, a default in memory implementation named `InMemoryConfiguration` is provided. The implementation constructor accepts a `Map` where each key represents a login configuration name and the value represents an `Array` of `AppConfigurationEntry` s. `InMemoryConfiguration` also supports a default `Array` of `AppConfigurationEntry` objects that will be used if no mapping is found within the provided `Map`. For details, refer to the class level javadoc of `InMemoryConfiguration`.
|
||||
In order to make it easy to inject a `Configuration` into `DefaultJaasAuthenticationProvider`, a default in-memory implementation named `InMemoryConfiguration` is provided. The implementation constructor accepts a `Map` where each key represents a login configuration name and the value represents an `Array` of `AppConfigurationEntry` s. `InMemoryConfiguration` also supports a default `Array` of `AppConfigurationEntry` objects that will be used if no mapping is found within the provided `Map`. For details, refer to the class level javadoc of `InMemoryConfiguration`.
|
||||
|
||||
|
||||
[[jaas-djap-config]]
|
||||
@@ -6243,7 +6292,7 @@ The CAS protocol supports Single Logout and can be easily added to your Spring S
|
||||
</bean>
|
||||
----
|
||||
|
||||
The `logout` element logs the user out of the local application, but does not terminate the session with the CAS server or any other applications that have been logged into. The `requestSingleLogoutFilter` filter will allow the url of `/spring_security_cas_logout` to be requested to redirect the application to the configured CAS Server logout url. Then the CAS Server will send a Single Logout request to all the services that were signed into. The `singleLogoutFilter` handles the Single Logout request by looking up the `HttpSession` in a static `Map` and then invalidating it.
|
||||
The `logout` element logs the user out of the local application, but does not terminate the session with the CAS server or any other applications that have been logged into. The `requestSingleLogoutFilter` filter will allow the URL of `/spring_security_cas_logout` to be requested to redirect the application to the configured CAS Server logout URL. Then the CAS Server will send a Single Logout request to all the services that were signed into. The `singleLogoutFilter` handles the Single Logout request by looking up the `HttpSession` in a static `Map` and then invalidating it.
|
||||
|
||||
It might be confusing why both the `logout` element and the `singleLogoutFilter` are needed. It is considered best practice to logout locally first since the `SingleSignOutFilter` just stores the `HttpSession` in a static `Map` in order to call invalidate on it. With the configuration above, the flow of logout would be:
|
||||
|
||||
@@ -6365,7 +6414,7 @@ Because remoting protocols have no way of presenting themselves within the conte
|
||||
|
||||
One obvious option is to not use CAS at all for remoting protocol clients. However, this would eliminate many of the desirable features of CAS. As a middle-ground, the `CasAuthenticationProvider` uses a `StatelessTicketCache`. This is used solely for stateless clients which use a principal equal to `CasAuthenticationFilter.CAS_STATELESS_IDENTIFIER`. What happens is the `CasAuthenticationProvider` will store the resulting `CasAuthenticationToken` in the `StatelessTicketCache`, keyed on the proxy ticket. Accordingly, remoting protocol clients can present the same proxy ticket and the `CasAuthenticationProvider` will not need to contact the CAS server for validation (aside from the first request). Once authenticated, the proxy ticket could be used for URLs other than the original target service.
|
||||
|
||||
This section builds upon the previous sections to accomodate proxy ticket authentication. The first step is to specify to authenticate all artifacts as shown below.
|
||||
This section builds upon the previous sections to accommodate proxy ticket authentication. The first step is to specify to authenticate all artifacts as shown below.
|
||||
|
||||
[source,xml]
|
||||
----
|
||||
@@ -6505,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.
|
||||
|
||||
@@ -6541,7 +6590,7 @@ The Spring Security Crypto module provides support for symmetric encryption, key
|
||||
|
||||
[[spring-security-crypto-encryption]]
|
||||
=== Encryptors
|
||||
The Encryptors class provides factory methods for constructing symmetric encryptors. Using this class, you can create ByteEncryptors to encrypt data in raw byte[] form. You can also construct TextEncryptors to encrypt text strings. Encryptors are thread safe.
|
||||
The Encryptors class provides factory methods for constructing symmetric encryptors. Using this class, you can create ByteEncryptors to encrypt data in raw byte[] form. You can also construct TextEncryptors to encrypt text strings. Encryptors are thread-safe.
|
||||
|
||||
[[spring-security-crypto-encryption-bytes]]
|
||||
==== BytesEncryptor
|
||||
@@ -6584,7 +6633,7 @@ The difference between a queryable TextEncryptor and a standard TextEncryptor ha
|
||||
|
||||
[[spring-security-crypto-keygenerators]]
|
||||
=== Key Generators
|
||||
The KeyGenerators class provides a number of convenience factory methods for constructing different types of key generators. Using this class, you can create a BytesKeyGenerator to generate byte[] keys. You can also construct a StringKeyGenerator to generate string keys. KeyGenerators are thread safe.
|
||||
The KeyGenerators class provides a number of convenience factory methods for constructing different types of key generators. Using this class, you can create a BytesKeyGenerator to generate byte[] keys. You can also construct a StringKeyGenerator to generate string keys. KeyGenerators are thread-safe.
|
||||
|
||||
==== BytesKeyGenerator
|
||||
Use the KeyGenerators.secureRandom factory methods to generate a BytesKeyGenerator backed by a SecureRandom instance:
|
||||
@@ -6660,7 +6709,7 @@ assertTrue(encoder.matches("myPassword", result));
|
||||
[[concurrency]]
|
||||
== Concurrency Support
|
||||
|
||||
In most environments, Security is stored on a per `Thread` basis. This means that when work is done on a new `Thread`, the `SecurityContext` is lost. Spring Security provides some infrastructure to help make this much easier for users. Spring Security provides low level abstractions for working with Spring Security in multi threaded environments. In fact, this is what Spring Security builds on to integration with <<servletapi-start-runnable>> and <<mvc-async>>.
|
||||
In most environments, Security is stored on a per `Thread` basis. This means that when work is done on a new `Thread`, the `SecurityContext` is lost. Spring Security provides some infrastructure to help make this much easier for users. Spring Security provides low level abstractions for working with Spring Security in multi-threaded environments. In fact, this is what Spring Security builds on to integration with <<servletapi-start-runnable>> and <<mvc-async>>.
|
||||
|
||||
=== DelegatingSecurityContextRunnable
|
||||
|
||||
@@ -6785,7 +6834,7 @@ Now anytime `executor.execute(Runnable)` is executed the `SecurityContext` is fi
|
||||
|
||||
=== Spring Security Concurrency Classes
|
||||
|
||||
Refer to the Javadoc for additional integrations with both the Java concurrent APIs and the Spring Task abstractions. They are quite self explanatory once you understand the previous code.
|
||||
Refer to the Javadoc for additional integrations with both the Java concurrent APIs and the Spring Task abstractions. They are quite self-explanatory once you understand the previous code.
|
||||
|
||||
* DelegatingSecurityContextCallable
|
||||
* DelegatingSecurityContextExecutor
|
||||
@@ -6908,7 +6957,7 @@ public ModelAndView findMessagesForUser() {
|
||||
SecurityContextHolder.getContext().getAuthentication();
|
||||
CustomUser custom = (CustomUser) authentication == null ? null : authentication.getPrincipal();
|
||||
|
||||
// .. find messags for this user and return them ...
|
||||
// .. find messages for this user and return them ...
|
||||
}
|
||||
----
|
||||
|
||||
@@ -6923,7 +6972,7 @@ import org.springframework.security.core.annotation.AuthenticationPrincipal;
|
||||
@RequestMapping("/messages/inbox")
|
||||
public ModelAndView findMessagesForUser(@AuthenticationPrincipal CustomUser customUser) {
|
||||
|
||||
// .. find messags for this user and return them ...
|
||||
// .. find messages for this user and return them ...
|
||||
}
|
||||
----
|
||||
|
||||
@@ -6958,7 +7007,7 @@ public ModelAndView findMessagesForUser(@AuthenticationPrincipal(expression = "c
|
||||
----
|
||||
|
||||
We can also refer to Beans in our SpEL expressions.
|
||||
For example, the following could be used if we were using JPA to manage our Users and we wanted to modify and save a propoerty on the current user.
|
||||
For example, the following could be used if we were using JPA to manage our Users and we wanted to modify and save a property on the current user.
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@@ -6967,10 +7016,10 @@ import org.springframework.security.core.annotation.AuthenticationPrincipal;
|
||||
// ...
|
||||
|
||||
@PutMapping("/users/self")
|
||||
public ModelAndView updateName(@AuthenticationPrincipal(expression = "@jpaEntityManager.merge(#this)") CustomUser attachedCustomUser
|
||||
public ModelAndView updateName(@AuthenticationPrincipal(expression = "@jpaEntityManager.merge(#this)") CustomUser attachedCustomUser,
|
||||
@RequestParam String firstName) {
|
||||
|
||||
// change the firstName on an atached instance which will be persisted to the database
|
||||
// change the firstName on an attached instance which will be persisted to the database
|
||||
attachedCustomUser.setFirstName(firstName);
|
||||
|
||||
// ...
|
||||
@@ -6997,7 +7046,7 @@ Now that `@CurrentUser` has been specified, we can use it to signal to resolve o
|
||||
@RequestMapping("/messages/inbox")
|
||||
public ModelAndView findMessagesForUser(@CurrentUser CustomUser customUser) {
|
||||
|
||||
// .. find messags for this user and return them ...
|
||||
// .. find messages for this user and return them ...
|
||||
}
|
||||
----
|
||||
|
||||
@@ -7150,7 +7199,7 @@ By exposing the `SecurityEvaluationContextExtension` bean, all of the <<common-e
|
||||
|
||||
[[appendix-schema]]
|
||||
== Security Database Schema
|
||||
There are various database schema used by the framework and this appendix provides a single reference point to them all. You only need to provide the tables for the areas of functonality you require.
|
||||
There are various database schema used by the framework and this appendix provides a single reference point to them all. You only need to provide the tables for the areas of functionality you require.
|
||||
|
||||
DDL statements are given for the HSQLDB database. You can use these as a guideline for defining the schema for the database you are using.
|
||||
|
||||
@@ -7200,7 +7249,7 @@ create table group_members (
|
||||
);
|
||||
----
|
||||
|
||||
Remember that these tables are only required if you are using the provided JDBC `UserDetailsService` implementation. If you write your own or choose to implement `AuthenticationProvider` without a `UserDetailsService`, then you have complete freedom over how you store the data, as long as the interface contract is satisfied.
|
||||
Remember that these tables are only required if you are using the provided JDBC `UserDetailsService` implementation. If you write your own or choose to implement `AuthenticationProvider` without a `UserDetailsService`, then you have complete freedom over how you store the data, as long as the interface contract is satisfied.
|
||||
|
||||
|
||||
=== Persistent Login (Remember-Me) Schema
|
||||
@@ -7501,7 +7550,7 @@ Enables Spring Security debugging infrastructure. This will provide human-readab
|
||||
[[nsa-http]]
|
||||
==== <http>
|
||||
If you use an `<http>` element within your application, a `FilterChainProxy` bean named "springSecurityFilterChain" is created and the configuration within the element is used to build a filter chain within
|
||||
`FilterChainProxy`. As of Spring Security 3.1, additional `http` elements can be used to add extra filter chains footnote:[ See the pass:specialcharacters,macros[<<ns-web-xml,introductory chapter>>] for how to set up the mapping from your `web.xml` ].
|
||||
`FilterChainProxy`. As of Spring Security 3.1, additional `http` elements can be used to add extra filter chains footnote:[See the pass:specialcharacters,macros[<<ns-web-xml,introductory chapter>>] for how to set up the mapping from your `web.xml` ].
|
||||
Some core filters are always created in a filter chain and others will be added to the stack depending on the attributes and child elements which are present. The positions of the standard filters are fixed (see
|
||||
<<filter-stack,the filter order table>> in the namespace introduction), removing a common source of errors with previous versions of the framework when users had to configure the filter chain explicitly in the
|
||||
`FilterChainProxy` bean. You can, of course, still do this if you need full control of the configuration.
|
||||
@@ -7666,7 +7715,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]]
|
||||
@@ -7680,11 +7729,12 @@ This element allows for configuring additional (security) headers to be send wit
|
||||
|
||||
** `Cache-Control`, `Pragma`, and `Expires` - Can be set using the <<nsa-cache-control,cache-control>> element. This ensures that the browser does not cache your secured pages.
|
||||
** `Strict-Transport-Security` - Can be set using the <<nsa-hsts,hsts>> element. This ensures that the browser automatically requests HTTPS for future requests.
|
||||
** `X-Frame-Options` - Can be set using the <<nsa-frame-options,frame-options>> element. The http://en.wikipedia.org/wiki/Clickjacking#X-Frame-Options[X-Frame-Options ] header can be used to prevent clickjacking attacks.
|
||||
** `X-Frame-Options` - Can be set using the <<nsa-frame-options,frame-options>> element. The http://en.wikipedia.org/wiki/Clickjacking#X-Frame-Options[X-Frame-Options] header can be used to prevent clickjacking attacks.
|
||||
** `X-XSS-Protection` - Can be set using the <<nsa-xss-protection,xss-protection>> element. The http://en.wikipedia.org/wiki/Cross-site_scripting[X-XSS-Protection ] header can be used by browser to do basic control.
|
||||
** `X-Content-Type-Options` - Can be set using the <<nsa-content-type-options,content-type-options>> element. The http://blogs.msdn.com/b/ie/archive/2008/09/02/ie8-security-part-vi-beta-2-update.aspx[X-Content-Type-Options] header prevents Internet Explorer from MIME-sniffing a response away from the declared content-type. This also applies to Google Chrome, when downloading extensions.
|
||||
** `Public-Key-Pinning` or `Public-Key-Pinning-Report-Only` - Can be set using the <<nsa-hpkp,hpkp>> element. This allows HTTPS websites to resist impersonation by attackers using mis-issued or otherwise fraudulent certificates.
|
||||
** `Content-Security-Policy` or `Content-Security-Policy-Report-Only` - Can be set using the <<nsa-content-security-policy,content-security-policy>> element. https://www.w3.org/TR/CSP2/[Content Security Policy (CSP)] is a mechanism that web applications can leverage to mitigate content injection vulnerabilities, such as cross-site scripting (XSS).
|
||||
** `Referrer-Policy` - Can be set using the <<nsa-referrer-policy,referrer-policy>> element, https://www.w3.org/TR/referrer-policy/[Referrer-Policy] is a mechanism that web applications can leverage to manage the referrer field, which contains the last page the user was on.
|
||||
|
||||
[[nsa-headers-attributes]]
|
||||
===== <headers> Attributes
|
||||
@@ -7718,6 +7768,7 @@ Optional attribute that specifies to disable Spring Security's HTTP response hea
|
||||
* <<nsa-header,header>>
|
||||
* <<nsa-hpkp,hpkp>>
|
||||
* <<nsa-hsts,hsts>>
|
||||
* <<nsa-referrer-policy,referrer-policy>>
|
||||
* <<nsa-xss-protection,xss-protection>>
|
||||
|
||||
|
||||
@@ -7762,7 +7813,7 @@ Specifies if subdomains should be included. Default true.
|
||||
|
||||
[[nsa-hsts-max-age-seconds]]
|
||||
* **max-age-seconds**
|
||||
Specifies the maximum ammount of time the host should be considered a Known HSTS Host. Default one year.
|
||||
Specifies the maximum amount of time the host should be considered a Known HSTS Host. Default one year.
|
||||
|
||||
|
||||
[[nsa-hsts-request-matcher-ref]]
|
||||
@@ -7867,6 +7918,24 @@ Set to true, to enable the Content-Security-Policy-Report-Only header for report
|
||||
|
||||
|
||||
|
||||
[[nsa-referrer-policy]]
|
||||
==== <referrer-policy>
|
||||
When enabled adds the https://www.w3.org/TR/referrer-policy/[Referrer Policy] header to the response.
|
||||
|
||||
[[nsa-referrer-policy-attributes]]
|
||||
===== <referrer-policy> Attributes
|
||||
|
||||
[[nsa-referrer-policy-policy]]
|
||||
* **policy**
|
||||
The policy for the Referrer-Policy header. Default "no-referrer".
|
||||
|
||||
[[nsa-referrer-policy-parents]]
|
||||
===== Parent Elements of <referrer-policy>
|
||||
|
||||
* <<nsa-headers,headers>>
|
||||
|
||||
|
||||
|
||||
[[nsa-frame-options]]
|
||||
==== <frame-options>
|
||||
When enabled adds the http://tools.ietf.org/html/draft-ietf-websec-x-frame-options[X-Frame-Options header] to the response, this allows newer browsers to do some security checks and prevent http://en.wikipedia.org/wiki/Clickjacking[clickjacking] attacks.
|
||||
@@ -7938,7 +8007,7 @@ Do not include the header for http://en.wikipedia.org/wiki/Cross-site_scripting#
|
||||
|
||||
[[nsa-xss-protection-enabled]]
|
||||
* **xss-protection-enabled**
|
||||
Explicitly enable or eisable http://en.wikipedia.org/wiki/Cross-site_scripting#Non-Persistent[reflected / Type-1 Cross-Site Scripting (XSS)] protection.
|
||||
Explicitly enable or disable http://en.wikipedia.org/wiki/Cross-site_scripting#Non-Persistent[reflected / Type-1 Cross-Site Scripting (XSS)] protection.
|
||||
|
||||
|
||||
[[nsa-xss-protection-block]]
|
||||
@@ -8135,7 +8204,7 @@ Defines a reference to a Spring bean that implements `SecurityExpressionHandler`
|
||||
|
||||
[[nsa-form-login]]
|
||||
==== <form-login>
|
||||
Used to add an `UsernamePasswordAuthenticationFilter` to the filter stack and an `LoginUrlAuthenticationEntryPoint` to the application context to provide authentication on demand. This will always take precedence over other namespace-created entry points. If no attributes are supplied, a login page will be generated automatically at the URL "/login" footnote:[
|
||||
Used to add an `UsernamePasswordAuthenticationFilter` to the filter stack and an `LoginUrlAuthenticationEntryPoint` to the application context to provide authentication on demand. This will always take precedence over other namespace-created entry points. If no attributes are supplied, a login page will be generated automatically at the URL "/login" footnote:[
|
||||
This feature is really just provided for convenience and is not intended for production (where a view technology will have been chosen and can be used to render a customized login page). The class `DefaultLoginPageGeneratingFilter` is responsible for rendering the login page and will provide login forms for both normal form login and/or OpenID if required.
|
||||
] The behaviour can be customized using the <<nsa-form-login-attributes, `<form-login>` Attributes>>.
|
||||
|
||||
@@ -8164,7 +8233,7 @@ Reference to an `AuthenticationDetailsSource` which will be used by the authenti
|
||||
|
||||
[[nsa-form-login-authentication-failure-handler-ref]]
|
||||
* **authentication-failure-handler-ref**
|
||||
Can be used as an alternative to <<nsa-form-login-authentication-failure-url,authentication-failure-url>>, giving you full control over the navigation flow after an authentication failure. The value should be he name of an `AuthenticationFailureHandler` bean in the application context.
|
||||
Can be used as an alternative to <<nsa-form-login-authentication-failure-url,authentication-failure-url>>, giving you full control over the navigation flow after an authentication failure. The value should be the name of an `AuthenticationFailureHandler` bean in the application context.
|
||||
|
||||
|
||||
[[nsa-form-login-authentication-failure-url]]
|
||||
@@ -8305,7 +8374,7 @@ NOTE: This property is invalid for <<nsa-filter-security-metadata-source,filter-
|
||||
|
||||
[[nsa-intercept-url-servlet-path]]
|
||||
* **servlet-path**
|
||||
The servlet path which will be used in combination with the pattern and HTTP method to match an incoming request. This attribute is only applicable when <<nsa-http-request-matcher,request-matcher>> is 'mvc'. In addition, the value is only required in the following 2 use cases: 1) There are 2 or more `HttpServlet` 's registered in the `ServletContext` that have mappings starting with `'/'` and are different; 2) The pattern starts with the same value of a registered `HttpServlet` path, excluding the default (root) `HttpServlet` `'/'`.
|
||||
The servlet path which will be used in combination with the pattern and HTTP method to match an incoming request. This attribute is only applicable when <<nsa-http-request-matcher,request-matcher>> is 'mvc'. In addition, the value is only required in the following 2 use cases: 1) There are 2 or more `HttpServlet` 's registered in the `ServletContext` that have mappings starting with `'/'` and are different; 2) The pattern starts with the same value of a registered `HttpServlet` path, excluding the default (root) `HttpServlet` `'/'`.
|
||||
|
||||
NOTE: This property is invalid for <<nsa-filter-security-metadata-source,filter-security-metadata-source>>
|
||||
|
||||
@@ -8625,9 +8694,9 @@ The name of cookie which store the token for remember-me authentication. Default
|
||||
|
||||
[[nsa-remember-me-key]]
|
||||
* **key**
|
||||
Maps to the "key" property of `AbstractRememberMeServices`. Should be set to a unique value to ensure that remember-me cookies are only valid within the one application footnote:[
|
||||
Maps to the "key" property of `AbstractRememberMeServices`. Should be set to a unique value to ensure that remember-me cookies are only valid within the one application footnote:[
|
||||
This doesn't affect the use of `PersistentTokenBasedRememberMeServices`, where the tokens are stored on the server side.
|
||||
]. If this is not set a secure random value will be generated. Since generating secure random values can take a while, setting this value explicitly can help improve startup times when using the remember me functionality.
|
||||
]. If this is not set a secure random value will be generated. Since generating secure random values can take a while, setting this value explicitly can help improve startup times when using the remember-me functionality.
|
||||
|
||||
|
||||
[[nsa-remember-me-services-alias]]
|
||||
@@ -8884,7 +8953,7 @@ Defines the strategy use for matching incoming requests. Currently the options a
|
||||
|
||||
[[nsa-filter-security-metadata-source-use-expressions]]
|
||||
* **use-expressions**
|
||||
Enables the use of expressions in the 'access' attributes in <intercept-url> elements rather than the traditional list of configuration attributes. Defaults to 'true'. If enabled, each attribute should contain a single boolean expression. If the expression evaluates to 'true', access will be granted.
|
||||
Enables the use of expressions in the 'access' attributes in <intercept-url> elements rather than the traditional list of configuration attributes. Defaults to 'true'. If enabled, each attribute should contain a single Boolean expression. If the expression evaluates to 'true', access will be granted.
|
||||
|
||||
|
||||
[[nsa-filter-security-metadata-source-children]]
|
||||
@@ -8995,7 +9064,7 @@ This attribute allows you to define an id for the internal instance for use in y
|
||||
|
||||
[[nsa-authentication-provider]]
|
||||
==== <authentication-provider>
|
||||
Unless used with a `ref` attribute, this element is shorthand for configuring a <<core-services-dao-provider,DaoAuthenticationProvider>>. `DaoAuthenticationProvider` loads user information from a `UserDetailsService` and compares the username/password combination with the values supplied at login. The `UserDetailsService` instance can be defined either by using an available namespace element ( `jdbc-user-service` or by using the `user-service-ref` attribute to point to a bean defined elsewhere in the application context). You can find examples of these variations in the <<ns-auth-providers,namespace introduction>>.
|
||||
Unless used with a `ref` attribute, this element is shorthand for configuring a <<core-services-dao-provider,DaoAuthenticationProvider>>. `DaoAuthenticationProvider` loads user information from a `UserDetailsService` and compares the username/password combination with the values supplied at login. The `UserDetailsService` instance can be defined either by using an available namespace element (`jdbc-user-service` or by using the `user-service-ref` attribute to point to a bean defined elsewhere in the application context). You can find examples of these variations in the <<ns-auth-providers,namespace introduction>>.
|
||||
|
||||
|
||||
[[nsa-authentication-provider-parents]]
|
||||
@@ -9309,7 +9378,7 @@ An external `MethodSecurityMetadataSource` instance can be supplied which will t
|
||||
* **mode**
|
||||
This attribute can be set to "aspectj" to specify that AspectJ should be used instead of the default Spring AOP. Secured methods must be woven with the `AnnotationSecurityAspect` from the `spring-security-aspects` module.
|
||||
|
||||
It is important to note that AspectJ follows Java's rule that annotations on interfaces are not inherited. This means that methods that define the Security annotaitons on the interface will not be secured. Instead, you must place the Security annotation on the class when using AspectJ.
|
||||
It is important to note that AspectJ follows Java's rule that annotations on interfaces are not inherited. This means that methods that define the Security annotations on the interface will not be secured. Instead, you must place the Security annotation on the class when using AspectJ.
|
||||
|
||||
|
||||
[[nsa-global-method-security-order]]
|
||||
@@ -9372,7 +9441,7 @@ Defines a reference to a Spring bean that implements `AfterInvocationProvider`.
|
||||
|
||||
[[nsa-pre-post-annotation-handling]]
|
||||
==== <pre-post-annotation-handling>
|
||||
Allows the default expression-based mechanism for handling Spring Security's pre and post invocation annotations (@PreFilter, @PreAuthorize, @PostFilter, @PostAuthorize) to be replace entirely. Only applies if these annotations are enabled.
|
||||
Allows the default expression-based mechanism for handling Spring Security's pre and post invocation annotations (@PreFilter, @PreAuthorize, @PostFilter, @PostAuthorize) to be replaced entirely. Only applies if these annotations are enabled.
|
||||
|
||||
|
||||
[[nsa-pre-post-annotation-handling-parents]]
|
||||
@@ -9525,7 +9594,7 @@ A bean identifier, used for referring to the bean elsewhere in the context.
|
||||
|
||||
[[nsa-method-security-metadata-source-use-expressions]]
|
||||
* **use-expressions**
|
||||
Enables the use of expressions in the 'access' attributes in <intercept-url> elements rather than the traditional list of configuration attributes. Defaults to 'false'. If enabled, each attribute should contain a single boolean expression. If the expression evaluates to 'true', access will be granted.
|
||||
Enables the use of expressions in the 'access' attributes in <intercept-url> elements rather than the traditional list of configuration attributes. Defaults to 'false'. If enabled, each attribute should contain a single Boolean expression. If the expression evaluates to 'true', access will be granted.
|
||||
|
||||
|
||||
[[nsa-method-security-metadata-source-children]]
|
||||
@@ -9800,18 +9869,18 @@ The LDAP filter used to search for users (optional). For example "(uid={0})". Th
|
||||
|
||||
[[appendix-dependencies]]
|
||||
== Spring Security Dependencies
|
||||
This appendix provides a reference of the modules in Spring Security and the additional dependencies that they require in order to function in a running application. We don't include dependenices that are only used when building or testing Spring Security itself. Nor do we include transitive dependencies which are required by external dependencies.
|
||||
This appendix provides a reference of the modules in Spring Security and the additional dependencies that they require in order to function in a running application. We don't include dependencies that are only used when building or testing Spring Security itself. Nor do we include transitive dependencies which are required by external dependencies.
|
||||
|
||||
The version of Spring required is listed on the project website, so the specific versions are omitted for Spring dependencies below. Note that some of the dependencies listed as"optional" below may still be required for other non-security functionality in a Spring application. Also dependencies listed as "optional" may not actually be marked as such in the project's Maven pom files if they are used in most applications. They are"optional" only in the sense that you don't need them unless you are using the specified functionality.
|
||||
The version of Spring required is listed on the project website, so the specific versions are omitted for Spring dependencies below. Note that some of the dependencies listed as "optional" below may still be required for other non-security functionality in a Spring application. Also dependencies listed as "optional" may not actually be marked as such in the project's Maven POM files if they are used in most applications. They are "optional" only in the sense that you don't need them unless you are using the specified functionality.
|
||||
|
||||
Where a module depends on another Spring Security module, the non-optional dependencies of the module it depends on are also assumed to be required and are not listed separately.
|
||||
|
||||
|
||||
=== spring-security-core
|
||||
|
||||
The core module must be included in any project using Spring Security.
|
||||
The core module must be included in any project using Spring Security.
|
||||
|
||||
.Core Depenendencies
|
||||
.Core Dependencies
|
||||
|===
|
||||
| Dependency | Version | Description
|
||||
|
||||
@@ -9821,7 +9890,7 @@ The core module must be included in any project using Spring Security.
|
||||
|
||||
| ehcache
|
||||
| 1.6.2
|
||||
| Required if the ehcache-based user cache implementation is used (optional).
|
||||
| Required if the Ehcache-based user cache implementation is used (optional).
|
||||
|
||||
| spring-aop
|
||||
|
|
||||
@@ -9911,7 +9980,7 @@ This module is only required if you are using LDAP authentication.
|
||||
|
|
||||
| Data exception classes are required.
|
||||
|
||||
| apache-ds footnote:[The modules `apacheds-core`, `apacheds-core-entry`, `apacheds-protocol-shared`, `apacheds-protocol-ldap` and `apacheds-server-jndi` are required.
|
||||
| apache-ds footnote:[The modules `apacheds-core`, `apacheds-core-entry`, `apacheds-protocol-shared`, `apacheds-protocol-ldap` and `apacheds-server-jndi` are required.
|
||||
]
|
||||
| 1.5.5
|
||||
| Required if you are using an embedded LDAP server (optional).
|
||||
@@ -9968,7 +10037,7 @@ The ACL module.
|
||||
|
||||
| ehcache
|
||||
| 1.6.2
|
||||
| Required if the ehcache-based ACL cache implementation is used (optional if you are using your own implementation).
|
||||
| Required if the Ehcache-based ACL cache implementation is used (optional if you are using your own implementation).
|
||||
|
||||
| spring-jdbc
|
||||
|
|
||||
@@ -10000,7 +10069,7 @@ The CAS module provides integration with JA-SIG CAS.
|
||||
|
||||
| ehcache
|
||||
| 1.6.2
|
||||
| Required if you are using the ehcache-based ticket cache (optional).
|
||||
| Required if you are using the Ehcache-based ticket cache (optional).
|
||||
|===
|
||||
|
||||
=== spring-security-openid
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
version=4.2.0.RC1
|
||||
version=4.2.2.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 {
|
||||
|
||||
@@ -21,7 +21,7 @@ ext.groovyVersion = '2.4.4'
|
||||
ext.hsqlVersion = '2.3.2'
|
||||
ext.hibernateVersion = '5.0.11.Final'
|
||||
ext.hibernateValidatorVersion = '5.2.4.Final'
|
||||
ext.jacksonDatavindVersion = '2.8.3'
|
||||
ext.jacksonDatabindVersion = '2.8.4'
|
||||
ext.javaPersistenceVersion = '2.1.1'
|
||||
ext.jettyVersion = '6.1.26'
|
||||
ext.jstlVersion = '1.2.1'
|
||||
@@ -36,7 +36,7 @@ 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.springBootVersion = '1.5.0.BUILD-SNAPSHOT'
|
||||
ext.thymeleafVersion = '3.0.2.RELEASE'
|
||||
ext.jsonassertVersion = '1.3.0'
|
||||
ext.validationApiVersion = '1.1.0.Final'
|
||||
|
||||
Vendored
+1
-1
@@ -10,7 +10,7 @@ if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS=-Xmx1024M
|
||||
set GRADLE_OPTS='-Dorg.gradle.daemon=false'
|
||||
set GRADLE_OPTS="-Dorg.gradle.daemon=false"
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
|
||||
+5
-11
@@ -3,7 +3,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>itest-context</artifactId>
|
||||
<version>4.2.0.RC1</version>
|
||||
<version>4.2.2.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.3.RELEASE</version>
|
||||
<version>4.3.5.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.0.RC1</version>
|
||||
<version>4.2.2.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@@ -132,13 +132,13 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-config</artifactId>
|
||||
<version>4.2.0.RC1</version>
|
||||
<version>4.2.2.RELEASE</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-web</artifactId>
|
||||
<version>4.2.0.RC1</version>
|
||||
<version>4.2.2.RELEASE</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@@ -152,12 +152,6 @@
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>spring-milestone</id>
|
||||
<url>https://repo.spring.io/milestone</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
|
||||
+7
-13
@@ -3,7 +3,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>itest-web</artifactId>
|
||||
<version>4.2.0.RC1</version>
|
||||
<version>4.2.2.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.3.RELEASE</version>
|
||||
<version>4.3.5.RELEASE</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
@@ -98,31 +98,31 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-config</artifactId>
|
||||
<version>4.2.0.RC1</version>
|
||||
<version>4.2.2.RELEASE</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-core</artifactId>
|
||||
<version>4.2.0.RC1</version>
|
||||
<version>4.2.2.RELEASE</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-ldap</artifactId>
|
||||
<version>4.2.0.RC1</version>
|
||||
<version>4.2.2.RELEASE</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-test</artifactId>
|
||||
<version>4.2.0.RC1</version>
|
||||
<version>4.2.2.RELEASE</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-web</artifactId>
|
||||
<version>4.2.0.RC1</version>
|
||||
<version>4.2.2.RELEASE</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@@ -141,12 +141,6 @@
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>spring-milestone</id>
|
||||
<url>https://repo.spring.io/milestone</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
|
||||
+4
-10
@@ -3,7 +3,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-ldap</artifactId>
|
||||
<version>4.2.0.RC1</version>
|
||||
<version>4.2.2.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.3.RELEASE</version>
|
||||
<version>4.3.5.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.RC1</version>
|
||||
<version>2.2.0.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.0.RC1</version>
|
||||
<version>4.2.2.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@@ -200,12 +200,6 @@
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>spring-milestone</id>
|
||||
<url>https://repo.spring.io/milestone</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Provides lifecycle services for the embedded apacheDS server defined by the supplied
|
||||
* configuration. Used by {code LdapServerBeanDefinitionParser}. An instance will be
|
||||
* configuration. Used by {@code LdapServerBeanDefinitionParser}. An instance will be
|
||||
* stored in the application context for each embedded server instance. It will start the
|
||||
* server when the context is initialized and shut it down when it is closed. It is
|
||||
* intended for temporary embedded use and will not retain changes across start/stop
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
+4
-10
@@ -3,7 +3,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-messaging</artifactId>
|
||||
<version>4.2.0.RC1</version>
|
||||
<version>4.2.2.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.3.RELEASE</version>
|
||||
<version>4.3.5.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.0.RC1</version>
|
||||
<version>4.2.2.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.0.RC1</version>
|
||||
<version>4.2.2.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
@@ -232,12 +232,6 @@
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>spring-milestone</id>
|
||||
<url>https://repo.spring.io/milestone</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
|
||||
+4
-10
@@ -3,7 +3,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-openid</artifactId>
|
||||
<version>4.2.0.RC1</version>
|
||||
<version>4.2.2.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.3.RELEASE</version>
|
||||
<version>4.3.5.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.0.RC1</version>
|
||||
<version>4.2.2.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-web</artifactId>
|
||||
<version>4.2.0.RC1</version>
|
||||
<version>4.2.2.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@@ -164,12 +164,6 @@
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>spring-milestone</id>
|
||||
<url>https://repo.spring.io/milestone</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
|
||||
@@ -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;
|
||||
|
||||
+3
-9
@@ -3,7 +3,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-remoting</artifactId>
|
||||
<version>4.2.0.RC1</version>
|
||||
<version>4.2.2.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.3.RELEASE</version>
|
||||
<version>4.3.5.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.0.RC1</version>
|
||||
<version>4.2.2.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@@ -123,12 +123,6 @@
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>spring-milestone</id>
|
||||
<url>https://repo.spring.io/milestone</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-samples-boot-helloworld</artifactId>
|
||||
<version>4.2.0.RC1</version>
|
||||
<version>4.2.2.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.3.RELEASE</version>
|
||||
<version>4.3.5.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.0.RC1</version>
|
||||
<version>4.2.2.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-web</artifactId>
|
||||
<version>4.2.0.RC1</version>
|
||||
<version>4.2.2.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@@ -115,7 +115,7 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-test</artifactId>
|
||||
<version>4.2.0.RC1</version>
|
||||
<version>4.2.2.RELEASE</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@@ -124,12 +124,6 @@
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>spring-milestone</id>
|
||||
<url>https://repo.spring.io/milestone</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
|
||||
+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.0.RC1</version>
|
||||
<version>4.2.2.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.3.RELEASE</version>
|
||||
<version>4.3.5.RELEASE</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
@@ -100,12 +100,6 @@
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>spring-milestone</id>
|
||||
<url>https://repo.spring.io/milestone</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
|
||||
+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.0.RC1</version>
|
||||
<version>4.2.2.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.3.RELEASE</version>
|
||||
<version>4.3.5.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.0.RC1</version>
|
||||
<version>4.2.2.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-core</artifactId>
|
||||
<version>4.2.0.RC1</version>
|
||||
<version>4.2.2.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@@ -71,7 +71,7 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-aspects</artifactId>
|
||||
<version>4.2.0.RC1</version>
|
||||
<version>4.2.2.RELEASE</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@@ -110,12 +110,6 @@
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>spring-milestone</id>
|
||||
<url>https://repo.spring.io/milestone</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-samples-javaconfig-concurrency</artifactId>
|
||||
<version>4.2.0.RC1</version>
|
||||
<version>4.2.2.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.3.RELEASE</version>
|
||||
<version>4.3.5.RELEASE</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
@@ -91,25 +91,25 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-config</artifactId>
|
||||
<version>4.2.0.RC1</version>
|
||||
<version>4.2.2.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-core</artifactId>
|
||||
<version>4.2.0.RC1</version>
|
||||
<version>4.2.2.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-samples-javaconfig-messages</artifactId>
|
||||
<version>4.2.0.RC1</version>
|
||||
<version>4.2.2.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-web</artifactId>
|
||||
<version>4.2.0.RC1</version>
|
||||
<version>4.2.2.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@@ -183,12 +183,6 @@
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>spring-milestone</id>
|
||||
<url>https://repo.spring.io/milestone</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-samples-javaconfig-data</artifactId>
|
||||
<version>4.2.0.RC1</version>
|
||||
<version>4.2.2.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.3.RELEASE</version>
|
||||
<version>4.3.5.RELEASE</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
@@ -81,13 +81,13 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-config</artifactId>
|
||||
<version>4.2.0.RC1</version>
|
||||
<version>4.2.2.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-data</artifactId>
|
||||
<version>4.2.0.RC1</version>
|
||||
<version>4.2.2.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@@ -133,12 +133,6 @@
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>spring-milestone</id>
|
||||
<url>https://repo.spring.io/milestone</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-samples-javaconfig-form</artifactId>
|
||||
<version>4.2.0.RC1</version>
|
||||
<version>4.2.2.RELEASE</version>
|
||||
<packaging>war</packaging>
|
||||
<name>spring-security-samples-javaconfig-form</name>
|
||||
<description>spring-security-samples-javaconfig-form</description>
|
||||
@@ -39,7 +39,7 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-framework-bom</artifactId>
|
||||
<version>4.3.3.RELEASE</version>
|
||||
<version>4.3.5.RELEASE</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
@@ -91,25 +91,25 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-config</artifactId>
|
||||
<version>4.2.0.RC1</version>
|
||||
<version>4.2.2.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-core</artifactId>
|
||||
<version>4.2.0.RC1</version>
|
||||
<version>4.2.2.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-samples-javaconfig-messages</artifactId>
|
||||
<version>4.2.0.RC1</version>
|
||||
<version>4.2.2.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-web</artifactId>
|
||||
<version>4.2.0.RC1</version>
|
||||
<version>4.2.2.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@@ -237,12 +237,6 @@
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>spring-milestone</id>
|
||||
<url>https://repo.spring.io/milestone</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
|
||||
@@ -18,7 +18,7 @@ dependencies {
|
||||
"javax.servlet.jsp.jstl:javax.servlet.jsp.jstl-api:$jstlVersion",
|
||||
"javax.validation:validation-api:$validationApiVersion",
|
||||
"org.hibernate:hibernate-validator:$hibernateValidatorVersion",
|
||||
"com.fasterxml.jackson.core:jackson-databind:$jacksonDatavindVersion"
|
||||
"com.fasterxml.jackson.core:jackson-databind:$jacksonDatabindVersion"
|
||||
|
||||
runtime "opensymphony:sitemesh:2.4.2",
|
||||
"cglib:cglib-nodep:$cglibVersion",
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-samples-javaconfig-hellojs</artifactId>
|
||||
<version>4.2.0.RC1</version>
|
||||
<version>4.2.2.RELEASE</version>
|
||||
<packaging>war</packaging>
|
||||
<name>spring-security-samples-javaconfig-hellojs</name>
|
||||
<description>spring-security-samples-javaconfig-hellojs</description>
|
||||
@@ -39,7 +39,7 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-framework-bom</artifactId>
|
||||
<version>4.3.3.RELEASE</version>
|
||||
<version>4.3.5.RELEASE</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
@@ -49,7 +49,7 @@
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
<version>2.8.3</version>
|
||||
<version>2.8.4</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@@ -97,25 +97,25 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-config</artifactId>
|
||||
<version>4.2.0.RC1</version>
|
||||
<version>4.2.2.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-core</artifactId>
|
||||
<version>4.2.0.RC1</version>
|
||||
<version>4.2.2.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-samples-javaconfig-messages</artifactId>
|
||||
<version>4.2.0.RC1</version>
|
||||
<version>4.2.2.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-web</artifactId>
|
||||
<version>4.2.0.RC1</version>
|
||||
<version>4.2.2.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@@ -189,12 +189,6 @@
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>spring-milestone</id>
|
||||
<url>https://repo.spring.io/milestone</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-samples-javaconfig-hellomvc</artifactId>
|
||||
<version>4.2.0.RC1</version>
|
||||
<version>4.2.2.RELEASE</version>
|
||||
<packaging>war</packaging>
|
||||
<name>spring-security-samples-javaconfig-hellomvc</name>
|
||||
<description>spring-security-samples-javaconfig-hellomvc</description>
|
||||
@@ -39,7 +39,7 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-framework-bom</artifactId>
|
||||
<version>4.3.3.RELEASE</version>
|
||||
<version>4.3.5.RELEASE</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
@@ -91,25 +91,25 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-config</artifactId>
|
||||
<version>4.2.0.RC1</version>
|
||||
<version>4.2.2.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-core</artifactId>
|
||||
<version>4.2.0.RC1</version>
|
||||
<version>4.2.2.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-samples-javaconfig-messages</artifactId>
|
||||
<version>4.2.0.RC1</version>
|
||||
<version>4.2.2.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-web</artifactId>
|
||||
<version>4.2.0.RC1</version>
|
||||
<version>4.2.2.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@@ -180,7 +180,7 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-test</artifactId>
|
||||
<version>4.2.0.RC1</version>
|
||||
<version>4.2.2.RELEASE</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@@ -189,12 +189,6 @@
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>spring-milestone</id>
|
||||
<url>https://repo.spring.io/milestone</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-samples-javaconfig-helloworld</artifactId>
|
||||
<version>4.2.0.RC1</version>
|
||||
<version>4.2.2.RELEASE</version>
|
||||
<packaging>war</packaging>
|
||||
<name>spring-security-samples-javaconfig-helloworld</name>
|
||||
<description>spring-security-samples-javaconfig-helloworld</description>
|
||||
@@ -39,7 +39,7 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-framework-bom</artifactId>
|
||||
<version>4.3.3.RELEASE</version>
|
||||
<version>4.3.5.RELEASE</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
@@ -67,13 +67,13 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-config</artifactId>
|
||||
<version>4.2.0.RC1</version>
|
||||
<version>4.2.2.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-web</artifactId>
|
||||
<version>4.2.0.RC1</version>
|
||||
<version>4.2.2.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@@ -179,12 +179,6 @@
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>spring-milestone</id>
|
||||
<url>https://repo.spring.io/milestone</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-samples-javaconfig-inmemory</artifactId>
|
||||
<version>4.2.0.RC1</version>
|
||||
<version>4.2.2.RELEASE</version>
|
||||
<packaging>war</packaging>
|
||||
<name>spring-security-samples-javaconfig-inmemory</name>
|
||||
<description>spring-security-samples-javaconfig-inmemory</description>
|
||||
@@ -39,7 +39,7 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-framework-bom</artifactId>
|
||||
<version>4.3.3.RELEASE</version>
|
||||
<version>4.3.5.RELEASE</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
@@ -91,25 +91,25 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-config</artifactId>
|
||||
<version>4.2.0.RC1</version>
|
||||
<version>4.2.2.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-core</artifactId>
|
||||
<version>4.2.0.RC1</version>
|
||||
<version>4.2.2.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-samples-javaconfig-messages</artifactId>
|
||||
<version>4.2.0.RC1</version>
|
||||
<version>4.2.2.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-web</artifactId>
|
||||
<version>4.2.0.RC1</version>
|
||||
<version>4.2.2.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@@ -180,7 +180,7 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-test</artifactId>
|
||||
<version>4.2.0.RC1</version>
|
||||
<version>4.2.2.RELEASE</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@@ -189,12 +189,6 @@
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>spring-milestone</id>
|
||||
<url>https://repo.spring.io/milestone</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-samples-javaconfig-jdbc</artifactId>
|
||||
<version>4.2.0.RC1</version>
|
||||
<version>4.2.2.RELEASE</version>
|
||||
<packaging>war</packaging>
|
||||
<name>spring-security-samples-javaconfig-jdbc</name>
|
||||
<description>spring-security-samples-javaconfig-jdbc</description>
|
||||
@@ -39,7 +39,7 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-framework-bom</artifactId>
|
||||
<version>4.3.3.RELEASE</version>
|
||||
<version>4.3.5.RELEASE</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
@@ -91,25 +91,25 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-config</artifactId>
|
||||
<version>4.2.0.RC1</version>
|
||||
<version>4.2.2.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-core</artifactId>
|
||||
<version>4.2.0.RC1</version>
|
||||
<version>4.2.2.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-samples-javaconfig-messages</artifactId>
|
||||
<version>4.2.0.RC1</version>
|
||||
<version>4.2.2.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-web</artifactId>
|
||||
<version>4.2.0.RC1</version>
|
||||
<version>4.2.2.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@@ -237,12 +237,6 @@
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>spring-milestone</id>
|
||||
<url>https://repo.spring.io/milestone</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-samples-javaconfig-ldap</artifactId>
|
||||
<version>4.2.0.RC1</version>
|
||||
<version>4.2.2.RELEASE</version>
|
||||
<packaging>war</packaging>
|
||||
<name>spring-security-samples-javaconfig-ldap</name>
|
||||
<description>spring-security-samples-javaconfig-ldap</description>
|
||||
@@ -39,7 +39,7 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-framework-bom</artifactId>
|
||||
<version>4.3.3.RELEASE</version>
|
||||
<version>4.3.5.RELEASE</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
@@ -127,31 +127,31 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-config</artifactId>
|
||||
<version>4.2.0.RC1</version>
|
||||
<version>4.2.2.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-core</artifactId>
|
||||
<version>4.2.0.RC1</version>
|
||||
<version>4.2.2.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-ldap</artifactId>
|
||||
<version>4.2.0.RC1</version>
|
||||
<version>4.2.2.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-samples-javaconfig-messages</artifactId>
|
||||
<version>4.2.0.RC1</version>
|
||||
<version>4.2.2.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-web</artifactId>
|
||||
<version>4.2.0.RC1</version>
|
||||
<version>4.2.2.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@@ -279,12 +279,6 @@
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>spring-milestone</id>
|
||||
<url>https://repo.spring.io/milestone</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-samples-javaconfig-messages</artifactId>
|
||||
<version>4.2.0.RC1</version>
|
||||
<version>4.2.2.RELEASE</version>
|
||||
<name>spring-security-samples-javaconfig-messages</name>
|
||||
<description>spring-security-samples-javaconfig-messages</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.3.RELEASE</version>
|
||||
<version>4.3.5.RELEASE</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
@@ -99,13 +99,13 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-config</artifactId>
|
||||
<version>4.2.0.RC1</version>
|
||||
<version>4.2.2.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-web</artifactId>
|
||||
<version>4.2.0.RC1</version>
|
||||
<version>4.2.2.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@@ -208,12 +208,6 @@
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>spring-milestone</id>
|
||||
<url>https://repo.spring.io/milestone</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-samples-javaconfig-openid</artifactId>
|
||||
<version>4.2.0.RC1</version>
|
||||
<version>4.2.2.RELEASE</version>
|
||||
<packaging>war</packaging>
|
||||
<name>spring-security-samples-javaconfig-openid</name>
|
||||
<description>spring-security-samples-javaconfig-openid</description>
|
||||
@@ -39,7 +39,7 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-framework-bom</artifactId>
|
||||
<version>4.3.3.RELEASE</version>
|
||||
<version>4.3.5.RELEASE</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
@@ -91,31 +91,31 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-config</artifactId>
|
||||
<version>4.2.0.RC1</version>
|
||||
<version>4.2.2.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-core</artifactId>
|
||||
<version>4.2.0.RC1</version>
|
||||
<version>4.2.2.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-openid</artifactId>
|
||||
<version>4.2.0.RC1</version>
|
||||
<version>4.2.2.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-samples-javaconfig-messages</artifactId>
|
||||
<version>4.2.0.RC1</version>
|
||||
<version>4.2.2.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-web</artifactId>
|
||||
<version>4.2.0.RC1</version>
|
||||
<version>4.2.2.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@@ -195,12 +195,6 @@
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>spring-milestone</id>
|
||||
<url>https://repo.spring.io/milestone</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-samples-javaconfig-preauth</artifactId>
|
||||
<version>4.2.0.RC1</version>
|
||||
<version>4.2.2.RELEASE</version>
|
||||
<packaging>war</packaging>
|
||||
<name>spring-security-samples-javaconfig-preauth</name>
|
||||
<description>spring-security-samples-javaconfig-preauth</description>
|
||||
@@ -39,7 +39,7 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-framework-bom</artifactId>
|
||||
<version>4.3.3.RELEASE</version>
|
||||
<version>4.3.5.RELEASE</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
@@ -91,25 +91,25 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-config</artifactId>
|
||||
<version>4.2.0.RC1</version>
|
||||
<version>4.2.2.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-core</artifactId>
|
||||
<version>4.2.0.RC1</version>
|
||||
<version>4.2.2.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-samples-javaconfig-messages</artifactId>
|
||||
<version>4.2.0.RC1</version>
|
||||
<version>4.2.2.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-web</artifactId>
|
||||
<version>4.2.0.RC1</version>
|
||||
<version>4.2.2.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@@ -183,12 +183,6 @@
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>spring-milestone</id>
|
||||
<url>https://repo.spring.io/milestone</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-samples-javaconfig-rememberme</artifactId>
|
||||
<version>4.2.0.RC1</version>
|
||||
<version>4.2.2.RELEASE</version>
|
||||
<packaging>war</packaging>
|
||||
<name>spring-security-samples-javaconfig-rememberme</name>
|
||||
<description>spring-security-samples-javaconfig-rememberme</description>
|
||||
@@ -39,7 +39,7 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-framework-bom</artifactId>
|
||||
<version>4.3.3.RELEASE</version>
|
||||
<version>4.3.5.RELEASE</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
@@ -91,25 +91,25 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-config</artifactId>
|
||||
<version>4.2.0.RC1</version>
|
||||
<version>4.2.2.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-core</artifactId>
|
||||
<version>4.2.0.RC1</version>
|
||||
<version>4.2.2.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-samples-javaconfig-messages</artifactId>
|
||||
<version>4.2.0.RC1</version>
|
||||
<version>4.2.2.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-web</artifactId>
|
||||
<version>4.2.0.RC1</version>
|
||||
<version>4.2.2.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@@ -183,12 +183,6 @@
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>spring-milestone</id>
|
||||
<url>https://repo.spring.io/milestone</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user