SEC-2915: groovy/gradle spaces->tabs
This commit is contained in:
parent
cf9f58a4ac
commit
0a2e496a84
|
@ -1,19 +1,19 @@
|
||||||
// Acl Module build file
|
// Acl Module build file
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
compile project(':spring-security-core'),
|
compile project(':spring-security-core'),
|
||||||
springCoreDependency,
|
springCoreDependency,
|
||||||
'aopalliance:aopalliance:1.0',
|
'aopalliance:aopalliance:1.0',
|
||||||
"org.springframework:spring-aop:$springVersion",
|
"org.springframework:spring-aop:$springVersion",
|
||||||
"org.springframework:spring-context:$springVersion",
|
"org.springframework:spring-context:$springVersion",
|
||||||
"org.springframework:spring-tx:$springVersion",
|
"org.springframework:spring-tx:$springVersion",
|
||||||
"org.springframework:spring-jdbc:$springVersion"
|
"org.springframework:spring-jdbc:$springVersion"
|
||||||
|
|
||||||
optional "net.sf.ehcache:ehcache:$ehcacheVersion"
|
optional "net.sf.ehcache:ehcache:$ehcacheVersion"
|
||||||
|
|
||||||
testCompile "org.springframework:spring-beans:$springVersion",
|
testCompile "org.springframework:spring-beans:$springVersion",
|
||||||
"org.springframework:spring-context-support:$springVersion",
|
"org.springframework:spring-context-support:$springVersion",
|
||||||
"org.springframework:spring-test:$springVersion"
|
"org.springframework:spring-test:$springVersion"
|
||||||
|
|
||||||
testRuntime "org.hsqldb:hsqldb:$hsqlVersion"
|
testRuntime "org.hsqldb:hsqldb:$hsqlVersion"
|
||||||
}
|
}
|
|
@ -1,10 +1,10 @@
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
compile project(':spring-security-core'),
|
compile project(':spring-security-core'),
|
||||||
springCoreDependency,
|
springCoreDependency,
|
||||||
"org.springframework:spring-beans:$springVersion",
|
"org.springframework:spring-beans:$springVersion",
|
||||||
"org.springframework:spring-context:$springVersion"
|
"org.springframework:spring-context:$springVersion"
|
||||||
|
|
||||||
testCompile 'aopalliance:aopalliance:1.0',
|
testCompile 'aopalliance:aopalliance:1.0',
|
||||||
"org.springframework:spring-aop:$springVersion"
|
"org.springframework:spring-aop:$springVersion"
|
||||||
}
|
}
|
|
@ -5,5 +5,5 @@ generatePom.enabled = false
|
||||||
sonarRunner.skipProject = true
|
sonarRunner.skipProject = true
|
||||||
|
|
||||||
mavenBom {
|
mavenBom {
|
||||||
projects = coreModuleProjects
|
projects = coreModuleProjects
|
||||||
}
|
}
|
208
build.gradle
208
build.gradle
|
@ -1,17 +1,17 @@
|
||||||
import groovy.text.SimpleTemplateEngine
|
import groovy.text.SimpleTemplateEngine
|
||||||
|
|
||||||
buildscript {
|
buildscript {
|
||||||
repositories {
|
repositories {
|
||||||
maven { url "https://repo.spring.io/plugins-release" }
|
maven { url "https://repo.spring.io/plugins-release" }
|
||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath("org.springframework.build.gradle:propdeps-plugin:0.0.7")
|
classpath("org.springframework.build.gradle:propdeps-plugin:0.0.7")
|
||||||
classpath("org.springframework.build.gradle:spring-io-plugin:0.0.3.RELEASE")
|
classpath("org.springframework.build.gradle:spring-io-plugin:0.0.3.RELEASE")
|
||||||
classpath("org.gradle.api.plugins:gradle-tomcat-plugin:1.2.5")
|
classpath("org.gradle.api.plugins:gradle-tomcat-plugin:1.2.5")
|
||||||
classpath('me.champeau.gradle:gradle-javadoc-hotfix-plugin:0.1')
|
classpath('me.champeau.gradle:gradle-javadoc-hotfix-plugin:0.1')
|
||||||
classpath('org.asciidoctor:asciidoctor-gradle-plugin:1.5.1')
|
classpath('org.asciidoctor:asciidoctor-gradle-plugin:1.5.1')
|
||||||
classpath("io.spring.gradle:docbook-reference-plugin:0.3.0")
|
classpath("io.spring.gradle:docbook-reference-plugin:0.3.0")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
apply plugin: 'sonar-runner'
|
apply plugin: 'sonar-runner'
|
||||||
|
@ -20,38 +20,38 @@ apply plugin: 'base'
|
||||||
description = 'Spring Security'
|
description = 'Spring Security'
|
||||||
|
|
||||||
allprojects {
|
allprojects {
|
||||||
apply plugin: 'idea'
|
apply plugin: 'idea'
|
||||||
apply plugin: 'eclipse'
|
apply plugin: 'eclipse'
|
||||||
|
|
||||||
ext.releaseBuild = version.endsWith('RELEASE')
|
ext.releaseBuild = version.endsWith('RELEASE')
|
||||||
ext.snapshotBuild = version.endsWith('SNAPSHOT')
|
ext.snapshotBuild = version.endsWith('SNAPSHOT')
|
||||||
ext.springVersion = '4.1.5.RELEASE'
|
ext.springVersion = '4.1.5.RELEASE'
|
||||||
ext.springLdapVersion = '2.0.2.RELEASE'
|
ext.springLdapVersion = '2.0.2.RELEASE'
|
||||||
|
|
||||||
group = 'org.springframework.security'
|
group = 'org.springframework.security'
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
maven { url "https://repo.spring.io/libs-snapshot" }
|
maven { url "https://repo.spring.io/libs-snapshot" }
|
||||||
maven { url "https://repo.spring.io/plugins-release" }
|
maven { url "https://repo.spring.io/plugins-release" }
|
||||||
maven { url "http://repo.terracotta.org/maven2/" }
|
maven { url "http://repo.terracotta.org/maven2/" }
|
||||||
}
|
}
|
||||||
|
|
||||||
eclipse.project.name = "${project.name}-4.0.x"
|
eclipse.project.name = "${project.name}-4.0.x"
|
||||||
}
|
}
|
||||||
|
|
||||||
sonarRunner {
|
sonarRunner {
|
||||||
sonarProperties {
|
sonarProperties {
|
||||||
property "sonar.java.coveragePlugin", "jacoco"
|
property "sonar.java.coveragePlugin", "jacoco"
|
||||||
property "sonar.projectName", "Spring Security"
|
property "sonar.projectName", "Spring Security"
|
||||||
property "sonar.jacoco.reportPath", "${buildDir.name}/jacoco.exec"
|
property "sonar.jacoco.reportPath", "${buildDir.name}/jacoco.exec"
|
||||||
property "sonar.links.homepage", 'https://www.springsource.org/spring-security'
|
property "sonar.links.homepage", 'https://www.springsource.org/spring-security'
|
||||||
property "sonar.links.ci", 'https://build.springsource.org/browse/SEC-B32X'
|
property "sonar.links.ci", 'https://build.springsource.org/browse/SEC-B32X'
|
||||||
property "sonar.links.issue", 'https://jira.springsource.org/browse/SEC'
|
property "sonar.links.issue", 'https://jira.springsource.org/browse/SEC'
|
||||||
property "sonar.links.scm", 'https://github.com/SpringSource/spring-security'
|
property "sonar.links.scm", 'https://github.com/SpringSource/spring-security'
|
||||||
property "sonar.links.scm_dev", 'https://github.com/SpringSource/spring-security.git'
|
property "sonar.links.scm_dev", 'https://github.com/SpringSource/spring-security.git'
|
||||||
property "sonar.java.coveragePlugin", "jacoco"
|
property "sonar.java.coveragePlugin", "jacoco"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set up different subproject lists for individual configuration
|
// Set up different subproject lists for individual configuration
|
||||||
|
@ -62,105 +62,105 @@ ext.coreModuleProjects = javaProjects - sampleProjects - itestProjects
|
||||||
ext.aspectjProjects = [project(':spring-security-aspects'), project(':spring-security-samples-aspectj-xml'), project(':spring-security-samples-aspectj-jc')]
|
ext.aspectjProjects = [project(':spring-security-aspects'), project(':spring-security-samples-aspectj-xml'), project(':spring-security-samples-aspectj-jc')]
|
||||||
|
|
||||||
configure(allprojects - javaProjects) {
|
configure(allprojects - javaProjects) {
|
||||||
task afterEclipseImport {
|
task afterEclipseImport {
|
||||||
ext.srcFile = file('.classpath')
|
ext.srcFile = file('.classpath')
|
||||||
inputs.file srcFile
|
inputs.file srcFile
|
||||||
outputs.dir srcFile
|
outputs.dir srcFile
|
||||||
|
|
||||||
onlyIf { !srcFile.exists() }
|
onlyIf { !srcFile.exists() }
|
||||||
|
|
||||||
doLast {
|
doLast {
|
||||||
srcFile << """<?xml version="1.0" encoding="UTF-8"?>
|
srcFile << """<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<classpath>
|
<classpath>
|
||||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
|
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
|
||||||
<classpathentry kind="output" path="bin"/>
|
<classpathentry kind="output" path="bin"/>
|
||||||
</classpath>
|
</classpath>
|
||||||
"""
|
"""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
configure(subprojects - coreModuleProjects - project(':spring-security-samples-messages-jc') - project(':spring-security-bom')) {
|
configure(subprojects - coreModuleProjects - project(':spring-security-samples-messages-jc') - project(':spring-security-bom')) {
|
||||||
tasks.findByPath("artifactoryPublish")?.enabled = false
|
tasks.findByPath("artifactoryPublish")?.enabled = false
|
||||||
sonarRunner {
|
sonarRunner {
|
||||||
skipProject = true
|
skipProject = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
configure(javaProjects) {
|
configure(javaProjects) {
|
||||||
ext.TOMCAT_GRADLE = "$rootDir/gradle/tomcat.gradle"
|
ext.TOMCAT_GRADLE = "$rootDir/gradle/tomcat.gradle"
|
||||||
ext.WAR_SAMPLE_GRADLE = "$rootDir/gradle/war-sample.gradle"
|
ext.WAR_SAMPLE_GRADLE = "$rootDir/gradle/war-sample.gradle"
|
||||||
apply from: "$rootDir/gradle/javaprojects.gradle"
|
apply from: "$rootDir/gradle/javaprojects.gradle"
|
||||||
apply from: "$rootDir/gradle/release-checks.gradle"
|
apply from: "$rootDir/gradle/release-checks.gradle"
|
||||||
apply from: "$rootDir/gradle/maven-deployment.gradle"
|
apply from: "$rootDir/gradle/maven-deployment.gradle"
|
||||||
}
|
}
|
||||||
|
|
||||||
configure(coreModuleProjects) {
|
configure(coreModuleProjects) {
|
||||||
apply plugin: 'emma'
|
apply plugin: 'emma'
|
||||||
apply plugin: 'spring-io'
|
apply plugin: 'spring-io'
|
||||||
|
|
||||||
ext.springIoVersion = project.hasProperty('platformVersion') ? platformVersion : '1.1.0.BUILD-SNAPSHOT'
|
ext.springIoVersion = project.hasProperty('platformVersion') ? platformVersion : '1.1.0.BUILD-SNAPSHOT'
|
||||||
|
|
||||||
configurations {
|
configurations {
|
||||||
jacoco //Configuration Group used by Sonar to provide Code Coverage using JaCoCo
|
jacoco //Configuration Group used by Sonar to provide Code Coverage using JaCoCo
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
springIoVersions "io.spring.platform:platform-versions:${springIoVersion}@properties"
|
springIoVersions "io.spring.platform:platform-versions:${springIoVersion}@properties"
|
||||||
jacoco "org.jacoco:org.jacoco.agent:0.6.2.201302030002:runtime"
|
jacoco "org.jacoco:org.jacoco.agent:0.6.2.201302030002:runtime"
|
||||||
}
|
}
|
||||||
test {
|
test {
|
||||||
jvmArgs "-javaagent:${configurations.jacoco.asPath}=destfile=${buildDir}/jacoco.exec,includes=${project.group}.*"
|
jvmArgs "-javaagent:${configurations.jacoco.asPath}=destfile=${buildDir}/jacoco.exec,includes=${project.group}.*"
|
||||||
}
|
}
|
||||||
integrationTest {
|
integrationTest {
|
||||||
jvmArgs "-javaagent:${configurations.jacoco.asPath}=destfile=${buildDir}/jacoco.exec,includes=${project.group}.*"
|
jvmArgs "-javaagent:${configurations.jacoco.asPath}=destfile=${buildDir}/jacoco.exec,includes=${project.group}.*"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
configure (aspectjProjects) {
|
configure (aspectjProjects) {
|
||||||
apply plugin: 'java'
|
apply plugin: 'java'
|
||||||
apply plugin: 'aspectj'
|
apply plugin: 'aspectj'
|
||||||
}
|
}
|
||||||
|
|
||||||
task coreBuild {
|
task coreBuild {
|
||||||
dependsOn coreModuleProjects*.tasks*.matching { task -> task.name == 'build' }
|
dependsOn coreModuleProjects*.tasks*.matching { task -> task.name == 'build' }
|
||||||
}
|
}
|
||||||
|
|
||||||
// Task for creating the distro zip
|
// Task for creating the distro zip
|
||||||
|
|
||||||
task dist(type: Zip) {
|
task dist(type: Zip) {
|
||||||
dependsOn subprojects*.tasks*.matching { task -> task.name == 'assemble' || task.name.endsWith('Zip') || task.name.endsWith('generatePom') }
|
dependsOn subprojects*.tasks*.matching { task -> task.name == 'assemble' || task.name.endsWith('Zip') || task.name.endsWith('generatePom') }
|
||||||
classifier = 'dist'
|
classifier = 'dist'
|
||||||
|
|
||||||
evaluationDependsOn(':docs')
|
evaluationDependsOn(':docs')
|
||||||
evaluationDependsOn(':docs:manual')
|
evaluationDependsOn(':docs:manual')
|
||||||
|
|
||||||
def zipRootDir = "${project.name}-$version"
|
def zipRootDir = "${project.name}-$version"
|
||||||
into(zipRootDir) {
|
into(zipRootDir) {
|
||||||
from(rootDir) {
|
from(rootDir) {
|
||||||
include '*.adoc'
|
include '*.adoc'
|
||||||
}
|
}
|
||||||
into('docs') {
|
into('docs') {
|
||||||
with(project(':docs').apiSpec)
|
with(project(':docs').apiSpec)
|
||||||
with(project(':docs:manual').spec)
|
with(project(':docs:manual').spec)
|
||||||
with(project(':docs:guides').spec)
|
with(project(':docs:guides').spec)
|
||||||
}
|
}
|
||||||
into('dist') {
|
into('dist') {
|
||||||
from coreModuleProjects.collect {project -> project.libsDir }
|
from coreModuleProjects.collect {project -> project.libsDir }
|
||||||
}
|
}
|
||||||
sampleProjects.each { project->
|
sampleProjects.each { project->
|
||||||
into("$zipRootDir/samples/$project.name") {
|
into("$zipRootDir/samples/$project.name") {
|
||||||
from(project.projectDir) {
|
from(project.projectDir) {
|
||||||
include "src/main/**"
|
include "src/main/**"
|
||||||
include "pom.xml"
|
include "pom.xml"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
artifacts {
|
artifacts {
|
||||||
archives dist
|
archives dist
|
||||||
archives project(':docs').docsZip
|
archives project(':docs').docsZip
|
||||||
archives project(':docs').schemaZip
|
archives project(':docs').schemaZip
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,37 +1,37 @@
|
||||||
apply plugin: 'groovy'
|
apply plugin: 'groovy'
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
maven {
|
maven {
|
||||||
name = 'SpringSource Enterprise Release'
|
name = 'SpringSource Enterprise Release'
|
||||||
url = 'http://repository.springsource.com/maven/bundles/release'
|
url = 'http://repository.springsource.com/maven/bundles/release'
|
||||||
}
|
}
|
||||||
maven {
|
maven {
|
||||||
name = 'SpringSource Enterprise External'
|
name = 'SpringSource Enterprise External'
|
||||||
url = 'http://repository.springsource.com/maven/bundles/external'
|
url = 'http://repository.springsource.com/maven/bundles/external'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
compile gradleApi()
|
compile gradleApi()
|
||||||
}
|
}
|
||||||
|
|
||||||
// GAE
|
// GAE
|
||||||
dependencies {
|
dependencies {
|
||||||
compile 'com.google.appengine:appengine-tools-sdk:1.4.2'
|
compile 'com.google.appengine:appengine-tools-sdk:1.4.2'
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies{
|
dependencies{
|
||||||
compile "emma:emma:2.0.5312"
|
compile "emma:emma:2.0.5312"
|
||||||
}
|
}
|
||||||
|
|
||||||
// Trang
|
// Trang
|
||||||
dependencies {
|
dependencies {
|
||||||
compile 'com.thaiopensource:trang:20091111',
|
compile 'com.thaiopensource:trang:20091111',
|
||||||
'net.sourceforge.saxon:saxon:9.1.0.8'
|
'net.sourceforge.saxon:saxon:9.1.0.8'
|
||||||
}
|
}
|
||||||
|
|
||||||
task ide(type: Copy) {
|
task ide(type: Copy) {
|
||||||
from configurations.runtime
|
from configurations.runtime
|
||||||
into 'ide'
|
into 'ide'
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,50 +6,50 @@ import org.gradle.api.tasks.*
|
||||||
|
|
||||||
public class MavenBomTask extends DefaultTask {
|
public class MavenBomTask extends DefaultTask {
|
||||||
|
|
||||||
Set<Project> projects
|
Set<Project> projects
|
||||||
|
|
||||||
File bomFile
|
File bomFile
|
||||||
|
|
||||||
|
|
||||||
public MavenBomTask() {
|
public MavenBomTask() {
|
||||||
this.group = "Generate"
|
this.group = "Generate"
|
||||||
this.description = "Generates a Maven Build of Materials (BOM). See http://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html#Importing_Dependencies"
|
this.description = "Generates a Maven Build of Materials (BOM). See http://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html#Importing_Dependencies"
|
||||||
this.projects = project.subprojects
|
this.projects = project.subprojects
|
||||||
this.bomFile = project.file("${->project.buildDir}/maven-bom/${->project.name}-${->project.version}.txt")
|
this.bomFile = project.file("${->project.buildDir}/maven-bom/${->project.name}-${->project.version}.txt")
|
||||||
}
|
}
|
||||||
|
|
||||||
@TaskAction
|
@TaskAction
|
||||||
public void configureBom() {
|
public void configureBom() {
|
||||||
project.configurations.archives.artifacts.clear()
|
project.configurations.archives.artifacts.clear()
|
||||||
|
|
||||||
bomFile.parentFile.mkdirs()
|
bomFile.parentFile.mkdirs()
|
||||||
bomFile.write("Maven Build of Materials (BOM). See http://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html#Importing_Dependencies")
|
bomFile.write("Maven Build of Materials (BOM). See http://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html#Importing_Dependencies")
|
||||||
project.artifacts {
|
project.artifacts {
|
||||||
// work around GRADLE-2406 by attaching text artifact
|
// work around GRADLE-2406 by attaching text artifact
|
||||||
archives(bomFile)
|
archives(bomFile)
|
||||||
}
|
}
|
||||||
project.install {
|
project.install {
|
||||||
repositories.mavenInstaller {
|
repositories.mavenInstaller {
|
||||||
pom.whenConfigured {
|
pom.whenConfigured {
|
||||||
packaging = "pom"
|
packaging = "pom"
|
||||||
withXml {
|
withXml {
|
||||||
asNode().children().last() + {
|
asNode().children().last() + {
|
||||||
delegate.dependencyManagement {
|
delegate.dependencyManagement {
|
||||||
delegate.dependencies {
|
delegate.dependencies {
|
||||||
projects.sort { dep -> "$dep.group:$dep.name" }.each { p ->
|
projects.sort { dep -> "$dep.group:$dep.name" }.each { p ->
|
||||||
|
|
||||||
delegate.dependency {
|
delegate.dependency {
|
||||||
delegate.groupId(p.group)
|
delegate.groupId(p.group)
|
||||||
delegate.artifactId(p.name)
|
delegate.artifactId(p.name)
|
||||||
delegate.version(p.version)
|
delegate.version(p.version)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -22,100 +22,100 @@ import org.gradle.plugins.ide.eclipse.model.ProjectDependency
|
||||||
*/
|
*/
|
||||||
class AspectJPlugin implements Plugin<Project> {
|
class AspectJPlugin implements Plugin<Project> {
|
||||||
|
|
||||||
void apply(Project project) {
|
void apply(Project project) {
|
||||||
project.plugins.apply(JavaPlugin)
|
project.plugins.apply(JavaPlugin)
|
||||||
|
|
||||||
if (!project.hasProperty('aspectjVersion')) {
|
if (!project.hasProperty('aspectjVersion')) {
|
||||||
throw new GradleException("You must set the property 'aspectjVersion' before applying the aspectj plugin")
|
throw new GradleException("You must set the property 'aspectjVersion' before applying the aspectj plugin")
|
||||||
}
|
}
|
||||||
|
|
||||||
if (project.configurations.findByName('ajtools') == null) {
|
if (project.configurations.findByName('ajtools') == null) {
|
||||||
project.configurations.create('ajtools')
|
project.configurations.create('ajtools')
|
||||||
project.dependencies {
|
project.dependencies {
|
||||||
ajtools "org.aspectj:aspectjtools:${project.aspectjVersion}"
|
ajtools "org.aspectj:aspectjtools:${project.aspectjVersion}"
|
||||||
optional "org.aspectj:aspectjrt:${project.aspectjVersion}"
|
optional "org.aspectj:aspectjrt:${project.aspectjVersion}"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (project.configurations.findByName('aspectpath') == null) {
|
if (project.configurations.findByName('aspectpath') == null) {
|
||||||
project.configurations.create('aspectpath')
|
project.configurations.create('aspectpath')
|
||||||
}
|
}
|
||||||
|
|
||||||
project.tasks.create(name: 'compileAspect', overwrite: true, description: 'Compiles AspectJ Source', type: Ajc) {
|
project.tasks.create(name: 'compileAspect', overwrite: true, description: 'Compiles AspectJ Source', type: Ajc) {
|
||||||
dependsOn project.configurations*.getTaskDependencyFromProjectDependency(true, "compileJava")
|
dependsOn project.configurations*.getTaskDependencyFromProjectDependency(true, "compileJava")
|
||||||
|
|
||||||
dependsOn project.processResources
|
dependsOn project.processResources
|
||||||
sourceSet = project.sourceSets.main
|
sourceSet = project.sourceSets.main
|
||||||
inputs.files(sourceSet.allSource)
|
inputs.files(sourceSet.allSource)
|
||||||
outputs.dir(sourceSet.output.classesDir)
|
outputs.dir(sourceSet.output.classesDir)
|
||||||
aspectPath = project.configurations.aspectpath
|
aspectPath = project.configurations.aspectpath
|
||||||
}
|
}
|
||||||
project.tasks.compileJava.deleteAllActions()
|
project.tasks.compileJava.deleteAllActions()
|
||||||
project.tasks.compileJava.dependsOn project.tasks.compileAspect
|
project.tasks.compileJava.dependsOn project.tasks.compileAspect
|
||||||
|
|
||||||
|
|
||||||
project.tasks.create(name: 'compileTestAspect', overwrite: true, description: 'Compiles AspectJ Test Source', type: Ajc) {
|
project.tasks.create(name: 'compileTestAspect', overwrite: true, description: 'Compiles AspectJ Test Source', type: Ajc) {
|
||||||
dependsOn project.processTestResources, project.compileJava, project.jar
|
dependsOn project.processTestResources, project.compileJava, project.jar
|
||||||
sourceSet = project.sourceSets.test
|
sourceSet = project.sourceSets.test
|
||||||
inputs.files(sourceSet.allSource)
|
inputs.files(sourceSet.allSource)
|
||||||
outputs.dir(sourceSet.output.classesDir)
|
outputs.dir(sourceSet.output.classesDir)
|
||||||
aspectPath = project.files(project.configurations.aspectpath, project.jar.archivePath)
|
aspectPath = project.files(project.configurations.aspectpath, project.jar.archivePath)
|
||||||
}
|
}
|
||||||
project.tasks.compileTestJava.deleteAllActions()
|
project.tasks.compileTestJava.deleteAllActions()
|
||||||
project.tasks.compileTestJava.dependsOn project.tasks.compileTestAspect
|
project.tasks.compileTestJava.dependsOn project.tasks.compileTestAspect
|
||||||
|
|
||||||
project.tasks.withType(GenerateEclipseProject) {
|
project.tasks.withType(GenerateEclipseProject) {
|
||||||
project.eclipse.project.file.whenMerged { p ->
|
project.eclipse.project.file.whenMerged { p ->
|
||||||
p.natures.add(0, 'org.eclipse.ajdt.ui.ajnature')
|
p.natures.add(0, 'org.eclipse.ajdt.ui.ajnature')
|
||||||
p.buildCommands = [new BuildCommand('org.eclipse.ajdt.core.ajbuilder')]
|
p.buildCommands = [new BuildCommand('org.eclipse.ajdt.core.ajbuilder')]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
project.tasks.withType(GenerateEclipseClasspath) {
|
project.tasks.withType(GenerateEclipseClasspath) {
|
||||||
project.eclipse.classpath.file.whenMerged { classpath ->
|
project.eclipse.classpath.file.whenMerged { classpath ->
|
||||||
def entries = classpath.entries.findAll { it instanceof ProjectDependency}.findAll { entry ->
|
def entries = classpath.entries.findAll { it instanceof ProjectDependency}.findAll { entry ->
|
||||||
def projectPath = entry.path.replaceAll('/','')
|
def projectPath = entry.path.replaceAll('/','')
|
||||||
project.rootProject.allprojects.find{ p->
|
project.rootProject.allprojects.find{ p->
|
||||||
if(p.plugins.findPlugin(EclipsePlugin)) {
|
if(p.plugins.findPlugin(EclipsePlugin)) {
|
||||||
return p.eclipse.project.name == projectPath && p.plugins.findPlugin(AspectJPlugin)
|
return p.eclipse.project.name == projectPath && p.plugins.findPlugin(AspectJPlugin)
|
||||||
}
|
}
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
entries.each { entry->
|
entries.each { entry->
|
||||||
entry.entryAttributes.put('org.eclipse.ajdt.aspectpath','org.eclipse.ajdt.aspectpath')
|
entry.entryAttributes.put('org.eclipse.ajdt.aspectpath','org.eclipse.ajdt.aspectpath')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class Ajc extends DefaultTask {
|
class Ajc extends DefaultTask {
|
||||||
SourceSet sourceSet
|
SourceSet sourceSet
|
||||||
FileCollection aspectPath
|
FileCollection aspectPath
|
||||||
|
|
||||||
Ajc() {
|
Ajc() {
|
||||||
logging.captureStandardOutput(LogLevel.INFO)
|
logging.captureStandardOutput(LogLevel.INFO)
|
||||||
}
|
}
|
||||||
|
|
||||||
@TaskAction
|
@TaskAction
|
||||||
def compile() {
|
def compile() {
|
||||||
logger.info("="*30)
|
logger.info("="*30)
|
||||||
logger.info("="*30)
|
logger.info("="*30)
|
||||||
logger.info("Running ajc ...")
|
logger.info("Running ajc ...")
|
||||||
logger.info("classpath: ${sourceSet.compileClasspath.asPath}")
|
logger.info("classpath: ${sourceSet.compileClasspath.asPath}")
|
||||||
logger.info("srcDirs $sourceSet.java.srcDirs")
|
logger.info("srcDirs $sourceSet.java.srcDirs")
|
||||||
ant.taskdef(resource: "org/aspectj/tools/ant/taskdefs/aspectjTaskdefs.properties", classpath: project.configurations.ajtools.asPath)
|
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,
|
ant.iajc(classpath: sourceSet.compileClasspath.asPath, fork: 'true', destDir: sourceSet.output.classesDir.absolutePath,
|
||||||
source: project.convention.plugins.java.sourceCompatibility,
|
source: project.convention.plugins.java.sourceCompatibility,
|
||||||
target: project.convention.plugins.java.targetCompatibility,
|
target: project.convention.plugins.java.targetCompatibility,
|
||||||
aspectPath: aspectPath.asPath, sourceRootCopyFilter: '**/*.java', showWeaveInfo: 'true') {
|
aspectPath: aspectPath.asPath, sourceRootCopyFilter: '**/*.java', showWeaveInfo: 'true') {
|
||||||
sourceroots {
|
sourceroots {
|
||||||
sourceSet.java.srcDirs.each {
|
sourceSet.java.srcDirs.each {
|
||||||
logger.info(" sourceRoot $it")
|
logger.info(" sourceRoot $it")
|
||||||
pathelement(location: it.absolutePath)
|
pathelement(location: it.absolutePath)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,100 +15,100 @@ import com.vladium.util.XProperties;
|
||||||
*/
|
*/
|
||||||
class EmmaPlugin implements Plugin<Project> {
|
class EmmaPlugin implements Plugin<Project> {
|
||||||
|
|
||||||
void apply(Project project) {
|
void apply(Project project) {
|
||||||
Project rootProject = project.rootProject
|
Project rootProject = project.rootProject
|
||||||
def emmaMetaDataFile = "${rootProject.buildDir}/emma/emma.em"
|
def emmaMetaDataFile = "${rootProject.buildDir}/emma/emma.em"
|
||||||
def emmaCoverageFile = "${rootProject.buildDir}/emma/emma.ec"
|
def emmaCoverageFile = "${rootProject.buildDir}/emma/emma.ec"
|
||||||
|
|
||||||
if (project.configurations.findByName('emma_rt') == null) {
|
if (project.configurations.findByName('emma_rt') == null) {
|
||||||
project.configurations.create('emma_rt')
|
project.configurations.create('emma_rt')
|
||||||
project.dependencies {
|
project.dependencies {
|
||||||
emma_rt 'emma:emma:2.0.5312'
|
emma_rt 'emma:emma:2.0.5312'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
project.task('emmaInstrument') {
|
project.task('emmaInstrument') {
|
||||||
dependsOn project.classes
|
dependsOn project.classes
|
||||||
|
|
||||||
doFirst {
|
doFirst {
|
||||||
InstrProcessor processor = InstrProcessor.create ();
|
InstrProcessor processor = InstrProcessor.create ();
|
||||||
String[] classesDirPath = [project.sourceSets.main.output.classesDir.absolutePath]
|
String[] classesDirPath = [project.sourceSets.main.output.classesDir.absolutePath]
|
||||||
|
|
||||||
processor.setInstrPath(classesDirPath, false);
|
processor.setInstrPath(classesDirPath, false);
|
||||||
processor.setOutMode(InstrProcessor.OutMode.OUT_MODE_COPY);
|
processor.setOutMode(InstrProcessor.OutMode.OUT_MODE_COPY);
|
||||||
processor.setInstrOutDir("${project.buildDir}/emma/classes");
|
processor.setInstrOutDir("${project.buildDir}/emma/classes");
|
||||||
processor.setMetaOutFile(emmaMetaDataFile);
|
processor.setMetaOutFile(emmaMetaDataFile);
|
||||||
processor.setMetaOutMerge(true);
|
processor.setMetaOutMerge(true);
|
||||||
//processor.setInclExclFilter (null);
|
//processor.setInclExclFilter (null);
|
||||||
processor.run();
|
processor.run();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Modify test tasks in the project to generate coverage data
|
// Modify test tasks in the project to generate coverage data
|
||||||
project.afterEvaluate {
|
project.afterEvaluate {
|
||||||
if (project.hasProperty('coverage') && ['on','true'].contains(project.properties.coverage)) {
|
if (project.hasProperty('coverage') && ['on','true'].contains(project.properties.coverage)) {
|
||||||
project.tasks.withType(Test.class).each { task ->
|
project.tasks.withType(Test.class).each { task ->
|
||||||
task.dependsOn project.emmaInstrument
|
task.dependsOn project.emmaInstrument
|
||||||
task.configure() {
|
task.configure() {
|
||||||
jvmArgs '-Dsec.log.level=DEBUG', "-Demma.coverage.out.file=$emmaCoverageFile"
|
jvmArgs '-Dsec.log.level=DEBUG', "-Demma.coverage.out.file=$emmaCoverageFile"
|
||||||
jvmArgs '-Demma.verbosity.level=quiet'
|
jvmArgs '-Demma.verbosity.level=quiet'
|
||||||
}
|
}
|
||||||
task.doFirst {
|
task.doFirst {
|
||||||
classpath = project.files("${project.buildDir}/emma/classes") + project.configurations.emma_rt + classpath
|
classpath = project.files("${project.buildDir}/emma/classes") + project.configurations.emma_rt + classpath
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Task> reportTasks = rootProject.getTasksByName('coverageReport', false) as List;
|
List<Task> reportTasks = rootProject.getTasksByName('coverageReport', false) as List;
|
||||||
CoverageReport task;
|
CoverageReport task;
|
||||||
|
|
||||||
if (reportTasks.isEmpty()) {
|
if (reportTasks.isEmpty()) {
|
||||||
task = rootProject.tasks.create('coverageReport', CoverageReport.class);
|
task = rootProject.tasks.create('coverageReport', CoverageReport.class);
|
||||||
task.dataPath = [emmaMetaDataFile, emmaCoverageFile];
|
task.dataPath = [emmaMetaDataFile, emmaCoverageFile];
|
||||||
} else {
|
} else {
|
||||||
task = reportTasks[0];
|
task = reportTasks[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
task.modules.add(project);
|
task.modules.add(project);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class CoverageReport extends DefaultTask {
|
class CoverageReport extends DefaultTask {
|
||||||
@Input
|
@Input
|
||||||
List<Project> modules = [];
|
List<Project> modules = [];
|
||||||
|
|
||||||
@Input
|
@Input
|
||||||
String[] dataPath;
|
String[] dataPath;
|
||||||
|
|
||||||
@TaskAction
|
@TaskAction
|
||||||
void generateReport() {
|
void generateReport() {
|
||||||
def buildDir = project.rootProject.buildDir
|
def buildDir = project.rootProject.buildDir
|
||||||
|
|
||||||
if (!buildDir.exists()) {
|
if (!buildDir.exists()) {
|
||||||
throw new GradleException("No coverage data. Run gradle with -Pcoverage=on if using coverageReport");
|
throw new GradleException("No coverage data. Run gradle with -Pcoverage=on if using coverageReport");
|
||||||
}
|
}
|
||||||
|
|
||||||
ReportProcessor processor = ReportProcessor.create ();
|
ReportProcessor processor = ReportProcessor.create ();
|
||||||
processor.setDataPath(dataPath)
|
processor.setDataPath(dataPath)
|
||||||
|
|
||||||
def srcPath = []
|
def srcPath = []
|
||||||
modules.each {module->
|
modules.each {module->
|
||||||
module.sourceSets.main.java.srcDirs.each {
|
module.sourceSets.main.java.srcDirs.each {
|
||||||
srcPath.add(it.absolutePath)
|
srcPath.add(it.absolutePath)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
processor.setSourcePath(srcPath as String[]);
|
processor.setSourcePath(srcPath as String[]);
|
||||||
|
|
||||||
|
|
||||||
def types = ['txt', 'html']
|
def types = ['txt', 'html']
|
||||||
processor.setReportTypes(types as String[]);
|
processor.setReportTypes(types as String[]);
|
||||||
XProperties properties = new XProperties();
|
XProperties properties = new XProperties();
|
||||||
properties.setProperty('report.html.out.file', "$buildDir/emma/coverage.html");
|
properties.setProperty('report.html.out.file', "$buildDir/emma/coverage.html");
|
||||||
properties.setProperty('report.txt.out.file', "$buildDir/emma/coverage.txt");
|
properties.setProperty('report.txt.out.file', "$buildDir/emma/coverage.txt");
|
||||||
processor.setPropertyOverrides(properties)
|
processor.setPropertyOverrides(properties)
|
||||||
|
|
||||||
processor.run()
|
processor.run()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,23 +4,23 @@ import com.google.appengine.tools.admin.AppCfg
|
||||||
import org.gradle.api.*;
|
import org.gradle.api.*;
|
||||||
|
|
||||||
class GaePlugin implements Plugin<Project> {
|
class GaePlugin implements Plugin<Project> {
|
||||||
public void apply(Project project) {
|
public void apply(Project project) {
|
||||||
if (!project.hasProperty('appEngineSdkRoot')) {
|
if (!project.hasProperty('appEngineSdkRoot')) {
|
||||||
println "'appEngineSdkRoot' must be set in gradle.properties"
|
println "'appEngineSdkRoot' must be set in gradle.properties"
|
||||||
} else {
|
} else {
|
||||||
System.setProperty('appengine.sdk.root', project.property('appEngineSdkRoot'))
|
System.setProperty('appengine.sdk.root', project.property('appEngineSdkRoot'))
|
||||||
}
|
}
|
||||||
|
|
||||||
File explodedWar = new File(project.buildDir, "gae-exploded")
|
File explodedWar = new File(project.buildDir, "gae-exploded")
|
||||||
|
|
||||||
project.task('gaeDeploy') << {
|
project.task('gaeDeploy') << {
|
||||||
AppCfg.main("update", explodedWar.toString())
|
AppCfg.main("update", explodedWar.toString())
|
||||||
}
|
}
|
||||||
|
|
||||||
project.gaeDeploy.dependsOn project.war
|
project.gaeDeploy.dependsOn project.war
|
||||||
|
|
||||||
project.war.doLast {
|
project.war.doLast {
|
||||||
ant.unzip(src: project.war.archivePath, dest: explodedWar)
|
ant.unzip(src: project.war.archivePath, dest: explodedWar)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,44 +16,44 @@ import org.gradle.api.file.FileCollection
|
||||||
* @author Rob Winch
|
* @author Rob Winch
|
||||||
*/
|
*/
|
||||||
class TrangPlugin implements Plugin<Project> {
|
class TrangPlugin implements Plugin<Project> {
|
||||||
public void apply(Project project) {
|
public void apply(Project project) {
|
||||||
Task rncToXsd = project.tasks.create('rncToXsd', RncToXsd.class)
|
Task rncToXsd = project.tasks.create('rncToXsd', RncToXsd.class)
|
||||||
rncToXsd.description = 'Converts .rnc to .xsd'
|
rncToXsd.description = 'Converts .rnc to .xsd'
|
||||||
rncToXsd.group = 'Build'
|
rncToXsd.group = 'Build'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts .rnc files to .xsd files using trang and then applies an xsl file to cleanup the results.
|
* Converts .rnc files to .xsd files using trang and then applies an xsl file to cleanup the results.
|
||||||
*/
|
*/
|
||||||
public class RncToXsd extends DefaultTask {
|
public class RncToXsd extends DefaultTask {
|
||||||
@InputDirectory
|
@InputDirectory
|
||||||
File rncDir
|
File rncDir
|
||||||
|
|
||||||
@InputFile
|
@InputFile
|
||||||
File xslFile
|
File xslFile
|
||||||
|
|
||||||
@OutputDirectory
|
@OutputDirectory
|
||||||
File xsdDir
|
File xsdDir
|
||||||
|
|
||||||
@TaskAction
|
@TaskAction
|
||||||
public final void transform() {
|
public final void transform() {
|
||||||
String xslPath = xslFile.absolutePath
|
String xslPath = xslFile.absolutePath
|
||||||
rncDir.listFiles( { dir, file -> file.endsWith('.rnc')} as FilenameFilter).each { rncFile ->
|
rncDir.listFiles( { dir, file -> file.endsWith('.rnc')} as FilenameFilter).each { rncFile ->
|
||||||
File xsdFile = new File(xsdDir, rncFile.name.replace('.rnc', '.xsd'))
|
File xsdFile = new File(xsdDir, rncFile.name.replace('.rnc', '.xsd'))
|
||||||
String xsdOutputPath = xsdFile.absolutePath
|
String xsdOutputPath = xsdFile.absolutePath
|
||||||
new Driver().run([rncFile.absolutePath, xsdOutputPath] as String[]);
|
new Driver().run([rncFile.absolutePath, xsdOutputPath] as String[]);
|
||||||
|
|
||||||
TransformerFactory tFactory = new net.sf.saxon.TransformerFactoryImpl()
|
TransformerFactory tFactory = new net.sf.saxon.TransformerFactoryImpl()
|
||||||
Transformer transformer =
|
Transformer transformer =
|
||||||
tFactory.newTransformer(new StreamSource(xslPath))
|
tFactory.newTransformer(new StreamSource(xslPath))
|
||||||
File temp = File.createTempFile("gradle-trang-" + xsdFile.name, ".xsd")
|
File temp = File.createTempFile("gradle-trang-" + xsdFile.name, ".xsd")
|
||||||
xsdFile.withInputStream { is ->
|
xsdFile.withInputStream { is ->
|
||||||
temp << is
|
temp << is
|
||||||
}
|
}
|
||||||
StreamSource xmlSource = new StreamSource(temp)
|
StreamSource xmlSource = new StreamSource(temp)
|
||||||
transformer.transform(xmlSource, new StreamResult(xsdFile))
|
transformer.transform(xmlSource, new StreamResult(xsdFile))
|
||||||
temp.delete()
|
temp.delete()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,14 +1,14 @@
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
compile project(':spring-security-core'),
|
compile project(':spring-security-core'),
|
||||||
project(':spring-security-web'),
|
project(':spring-security-web'),
|
||||||
springCoreDependency,
|
springCoreDependency,
|
||||||
"org.springframework:spring-context:$springVersion",
|
"org.springframework:spring-context:$springVersion",
|
||||||
"org.springframework:spring-beans:$springVersion",
|
"org.springframework:spring-beans:$springVersion",
|
||||||
"org.springframework:spring-web:$springVersion",
|
"org.springframework:spring-web:$springVersion",
|
||||||
"org.jasig.cas.client:cas-client-core:$casClientVersion"
|
"org.jasig.cas.client:cas-client-core:$casClientVersion"
|
||||||
|
|
||||||
optional "net.sf.ehcache:ehcache:$ehcacheVersion"
|
optional "net.sf.ehcache:ehcache:$ehcacheVersion"
|
||||||
|
|
||||||
provided "javax.servlet:javax.servlet-api:$servletApiVersion"
|
provided "javax.servlet:javax.servlet-api:$servletApiVersion"
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,71 +8,71 @@ apply plugin: 'trang'
|
||||||
compileTestJava.dependsOn(':spring-security-core:compileTestJava')
|
compileTestJava.dependsOn(':spring-security-core:compileTestJava')
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
// NB: Don't add other compile time dependencies to the config module as this breaks tooling
|
// NB: Don't add other compile time dependencies to the config module as this breaks tooling
|
||||||
compile project(':spring-security-core'),
|
compile project(':spring-security-core'),
|
||||||
springCoreDependency,
|
springCoreDependency,
|
||||||
'aopalliance:aopalliance:1.0',
|
'aopalliance:aopalliance:1.0',
|
||||||
"org.springframework:spring-aop:$springVersion",
|
"org.springframework:spring-aop:$springVersion",
|
||||||
"org.springframework:spring-context:$springVersion",
|
"org.springframework:spring-context:$springVersion",
|
||||||
"org.springframework:spring-beans:$springVersion"
|
"org.springframework:spring-beans:$springVersion"
|
||||||
|
|
||||||
optional project(':spring-security-web'),
|
optional project(':spring-security-web'),
|
||||||
project(':spring-security-ldap'),
|
project(':spring-security-ldap'),
|
||||||
project(':spring-security-openid'),
|
project(':spring-security-openid'),
|
||||||
project(':spring-security-messaging'),
|
project(':spring-security-messaging'),
|
||||||
"org.springframework:spring-web:$springVersion",
|
"org.springframework:spring-web:$springVersion",
|
||||||
"org.springframework:spring-websocket:$springVersion",
|
"org.springframework:spring-websocket:$springVersion",
|
||||||
"org.springframework:spring-webmvc:$springVersion",
|
"org.springframework:spring-webmvc:$springVersion",
|
||||||
"org.aspectj:aspectjweaver:$aspectjVersion",
|
"org.aspectj:aspectjweaver:$aspectjVersion",
|
||||||
"org.springframework:spring-jdbc:$springVersion",
|
"org.springframework:spring-jdbc:$springVersion",
|
||||||
"org.springframework:spring-tx:$springVersion"
|
"org.springframework:spring-tx:$springVersion"
|
||||||
|
|
||||||
provided "javax.servlet:javax.servlet-api:$servletApiVersion"
|
provided "javax.servlet:javax.servlet-api:$servletApiVersion"
|
||||||
|
|
||||||
testCompile project(':spring-security-cas'),
|
testCompile project(':spring-security-cas'),
|
||||||
project(':spring-security-core').sourceSets.test.output,
|
project(':spring-security-core').sourceSets.test.output,
|
||||||
project(':spring-security-aspects'),
|
project(':spring-security-aspects'),
|
||||||
'javax.annotation:jsr250-api:1.0',
|
'javax.annotation:jsr250-api:1.0',
|
||||||
"org.springframework.ldap:spring-ldap-core:$springLdapVersion",
|
"org.springframework.ldap:spring-ldap-core:$springLdapVersion",
|
||||||
"org.springframework:spring-expression:$springVersion",
|
"org.springframework:spring-expression:$springVersion",
|
||||||
"org.springframework:spring-jdbc:$springVersion",
|
"org.springframework:spring-jdbc:$springVersion",
|
||||||
"org.springframework:spring-orm:$springVersion",
|
"org.springframework:spring-orm:$springVersion",
|
||||||
"org.springframework:spring-tx:$springVersion",
|
"org.springframework:spring-tx:$springVersion",
|
||||||
"org.slf4j:jcl-over-slf4j:$slf4jVersion",
|
"org.slf4j:jcl-over-slf4j:$slf4jVersion",
|
||||||
"org.eclipse.persistence:javax.persistence:2.0.5",
|
"org.eclipse.persistence:javax.persistence:2.0.5",
|
||||||
"org.hibernate:hibernate-entitymanager:4.1.0.Final",
|
"org.hibernate:hibernate-entitymanager:4.1.0.Final",
|
||||||
"org.codehaus.groovy:groovy-all:$groovyVersion",
|
"org.codehaus.groovy:groovy-all:$groovyVersion",
|
||||||
"org.apache.directory.server:apacheds-core:$apacheDsVersion",
|
"org.apache.directory.server:apacheds-core:$apacheDsVersion",
|
||||||
"org.apache.directory.server:apacheds-core-entry:$apacheDsVersion",
|
"org.apache.directory.server:apacheds-core-entry:$apacheDsVersion",
|
||||||
"org.apache.directory.server:apacheds-protocol-shared:$apacheDsVersion",
|
"org.apache.directory.server:apacheds-protocol-shared:$apacheDsVersion",
|
||||||
"org.apache.directory.server:apacheds-protocol-ldap:$apacheDsVersion",
|
"org.apache.directory.server:apacheds-protocol-ldap:$apacheDsVersion",
|
||||||
"org.apache.directory.server:apacheds-server-jndi:$apacheDsVersion",
|
"org.apache.directory.server:apacheds-server-jndi:$apacheDsVersion",
|
||||||
'org.apache.directory.shared:shared-ldap:0.9.15',
|
'org.apache.directory.shared:shared-ldap:0.9.15',
|
||||||
'ldapsdk:ldapsdk:4.1',
|
'ldapsdk:ldapsdk:4.1',
|
||||||
powerMockDependencies,
|
powerMockDependencies,
|
||||||
"org.hibernate:hibernate-entitymanager:3.6.10.Final",
|
"org.hibernate:hibernate-entitymanager:3.6.10.Final",
|
||||||
"org.hsqldb:hsqldb:$hsqlVersion",
|
"org.hsqldb:hsqldb:$hsqlVersion",
|
||||||
spockDependencies
|
spockDependencies
|
||||||
|
|
||||||
testCompile('org.openid4java:openid4java-nodeps:0.9.6') {
|
testCompile('org.openid4java:openid4java-nodeps:0.9.6') {
|
||||||
exclude group: 'com.google.code.guice', module: 'guice'
|
exclude group: 'com.google.code.guice', module: 'guice'
|
||||||
}
|
}
|
||||||
testCompile("org.springframework.data:spring-data-jpa:$springDataJpaVersion") {
|
testCompile("org.springframework.data:spring-data-jpa:$springDataJpaVersion") {
|
||||||
exclude group: 'org.aspectj', module: 'aspectjrt'
|
exclude group: 'org.aspectj', module: 'aspectjrt'
|
||||||
}
|
}
|
||||||
|
|
||||||
testRuntime "org.hsqldb:hsqldb:$hsqlVersion",
|
testRuntime "org.hsqldb:hsqldb:$hsqlVersion",
|
||||||
"cglib:cglib-nodep:$cglibVersion"
|
"cglib:cglib-nodep:$cglibVersion"
|
||||||
}
|
}
|
||||||
|
|
||||||
test {
|
test {
|
||||||
inputs.file file("$rootDir/docs/manual/src/docbook/appendix-namespace.xml")
|
inputs.file file("$rootDir/docs/manual/src/docbook/appendix-namespace.xml")
|
||||||
}
|
}
|
||||||
|
|
||||||
rncToXsd {
|
rncToXsd {
|
||||||
rncDir = file('src/main/resources/org/springframework/security/config/')
|
rncDir = file('src/main/resources/org/springframework/security/config/')
|
||||||
xsdDir = rncDir
|
xsdDir = rncDir
|
||||||
xslFile = new File(rncDir, 'spring-security.xsl')
|
xslFile = new File(rncDir, 'spring-security.xsl')
|
||||||
}
|
}
|
||||||
|
|
||||||
build.dependsOn rncToXsd
|
build.dependsOn rncToXsd
|
|
@ -20,65 +20,65 @@ import org.springframework.security.CollectingAppListener
|
||||||
* @author Luke Taylor
|
* @author Luke Taylor
|
||||||
*/
|
*/
|
||||||
abstract class AbstractXmlConfigTests extends Specification {
|
abstract class AbstractXmlConfigTests extends Specification {
|
||||||
AbstractXmlApplicationContext appContext;
|
AbstractXmlApplicationContext appContext;
|
||||||
Writer writer;
|
Writer writer;
|
||||||
MarkupBuilder xml;
|
MarkupBuilder xml;
|
||||||
ApplicationListener appListener;
|
ApplicationListener appListener;
|
||||||
|
|
||||||
def setup() {
|
def setup() {
|
||||||
writer = new StringWriter()
|
writer = new StringWriter()
|
||||||
xml = new MarkupBuilder(writer)
|
xml = new MarkupBuilder(writer)
|
||||||
appListener = new CollectingAppListener()
|
appListener = new CollectingAppListener()
|
||||||
}
|
}
|
||||||
|
|
||||||
def cleanup() {
|
def cleanup() {
|
||||||
if (appContext != null) {
|
if (appContext != null) {
|
||||||
appContext.close();
|
appContext.close();
|
||||||
appContext = null;
|
appContext = null;
|
||||||
}
|
}
|
||||||
SecurityContextHolder.clearContext();
|
SecurityContextHolder.clearContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
def mockBean(Class clazz, String id = clazz.simpleName) {
|
def mockBean(Class clazz, String id = clazz.simpleName) {
|
||||||
xml.'b:bean'(id: id, 'class': Mockito.class.name, 'factory-method':'mock') {
|
xml.'b:bean'(id: id, 'class': Mockito.class.name, 'factory-method':'mock') {
|
||||||
'b:constructor-arg'(value : clazz.name)
|
'b:constructor-arg'(value : clazz.name)
|
||||||
'b:constructor-arg'(value : id)
|
'b:constructor-arg'(value : id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
def bean(String name, Class clazz) {
|
def bean(String name, Class clazz) {
|
||||||
xml.'b:bean'(id: name, 'class': clazz.name)
|
xml.'b:bean'(id: name, 'class': clazz.name)
|
||||||
}
|
}
|
||||||
|
|
||||||
def bean(String name, String clazz) {
|
def bean(String name, String clazz) {
|
||||||
xml.'b:bean'(id: name, 'class': clazz)
|
xml.'b:bean'(id: name, 'class': clazz)
|
||||||
}
|
}
|
||||||
|
|
||||||
def bean(String name, String clazz, List constructorArgs) {
|
def bean(String name, String clazz, List constructorArgs) {
|
||||||
xml.'b:bean'(id: name, 'class': clazz) {
|
xml.'b:bean'(id: name, 'class': clazz) {
|
||||||
constructorArgs.each { val ->
|
constructorArgs.each { val ->
|
||||||
'b:constructor-arg'(value: val)
|
'b:constructor-arg'(value: val)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
def bean(String name, String clazz, Map properties, Map refs) {
|
def bean(String name, String clazz, Map properties, Map refs) {
|
||||||
xml.'b:bean'(id: name, 'class': clazz) {
|
xml.'b:bean'(id: name, 'class': clazz) {
|
||||||
properties.each {key, val ->
|
properties.each {key, val ->
|
||||||
'b:property'(name: key, value: val)
|
'b:property'(name: key, value: val)
|
||||||
}
|
}
|
||||||
refs.each {key, val ->
|
refs.each {key, val ->
|
||||||
'b:property'(name: key, ref: val)
|
'b:property'(name: key, ref: val)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
def createAppContext() {
|
def createAppContext() {
|
||||||
createAppContext(AUTH_PROVIDER_XML)
|
createAppContext(AUTH_PROVIDER_XML)
|
||||||
}
|
}
|
||||||
|
|
||||||
def createAppContext(String extraXml) {
|
def createAppContext(String extraXml) {
|
||||||
appContext = new InMemoryXmlApplicationContext(writer.toString() + extraXml);
|
appContext = new InMemoryXmlApplicationContext(writer.toString() + extraXml);
|
||||||
appContext.addApplicationListener(appListener);
|
appContext.addApplicationListener(appListener);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
@ -51,119 +51,119 @@ import spock.lang.Specification
|
||||||
* @author Rob Winch
|
* @author Rob Winch
|
||||||
*/
|
*/
|
||||||
abstract class BaseSpringSpec extends Specification {
|
abstract class BaseSpringSpec extends Specification {
|
||||||
@AutoCleanup
|
@AutoCleanup
|
||||||
ConfigurableApplicationContext context
|
ConfigurableApplicationContext context
|
||||||
@AutoCleanup
|
@AutoCleanup
|
||||||
ConfigurableApplicationContext oppContext
|
ConfigurableApplicationContext oppContext
|
||||||
|
|
||||||
MockHttpServletRequest request
|
MockHttpServletRequest request
|
||||||
MockHttpServletResponse response
|
MockHttpServletResponse response
|
||||||
MockFilterChain chain
|
MockFilterChain chain
|
||||||
CsrfToken csrfToken
|
CsrfToken csrfToken
|
||||||
AuthenticationManagerBuilder authenticationBldr
|
AuthenticationManagerBuilder authenticationBldr
|
||||||
|
|
||||||
def setup() {
|
def setup() {
|
||||||
authenticationBldr = createAuthenticationManagerBuilder()
|
authenticationBldr = createAuthenticationManagerBuilder()
|
||||||
setupWeb(null)
|
setupWeb(null)
|
||||||
}
|
}
|
||||||
|
|
||||||
def setupWeb(httpSession = null) {
|
def setupWeb(httpSession = null) {
|
||||||
request = new MockHttpServletRequest(method:"GET")
|
request = new MockHttpServletRequest(method:"GET")
|
||||||
if(httpSession) {
|
if(httpSession) {
|
||||||
request.session = httpSession
|
request.session = httpSession
|
||||||
}
|
}
|
||||||
response = new MockHttpServletResponse()
|
response = new MockHttpServletResponse()
|
||||||
chain = new MockFilterChain()
|
chain = new MockFilterChain()
|
||||||
setupCsrf()
|
setupCsrf()
|
||||||
}
|
}
|
||||||
|
|
||||||
def setupCsrf(csrfTokenValue="BaseSpringSpec_CSRFTOKEN",req=request,resp=response) {
|
def setupCsrf(csrfTokenValue="BaseSpringSpec_CSRFTOKEN",req=request,resp=response) {
|
||||||
csrfToken = new DefaultCsrfToken("X-CSRF-TOKEN","_csrf",csrfTokenValue)
|
csrfToken = new DefaultCsrfToken("X-CSRF-TOKEN","_csrf",csrfTokenValue)
|
||||||
new HttpSessionCsrfTokenRepository().saveToken(csrfToken, req, resp)
|
new HttpSessionCsrfTokenRepository().saveToken(csrfToken, req, resp)
|
||||||
req.setParameter(csrfToken.parameterName, csrfToken.token)
|
req.setParameter(csrfToken.parameterName, csrfToken.token)
|
||||||
}
|
}
|
||||||
|
|
||||||
def cleanup() {
|
def cleanup() {
|
||||||
SecurityContextHolder.clearContext()
|
SecurityContextHolder.clearContext()
|
||||||
}
|
}
|
||||||
|
|
||||||
def loadConfig(Class<?>... configs) {
|
def loadConfig(Class<?>... configs) {
|
||||||
context = new AnnotationConfigApplicationContext(configs)
|
context = new AnnotationConfigApplicationContext(configs)
|
||||||
context
|
context
|
||||||
}
|
}
|
||||||
|
|
||||||
def findFilter(Class<?> filter, int index = 0) {
|
def findFilter(Class<?> filter, int index = 0) {
|
||||||
filterChain(index).filters.find { filter.isAssignableFrom(it.class)}
|
filterChain(index).filters.find { filter.isAssignableFrom(it.class)}
|
||||||
}
|
}
|
||||||
|
|
||||||
def filterChain(int index=0) {
|
def filterChain(int index=0) {
|
||||||
filterChains()[index]
|
filterChains()[index]
|
||||||
}
|
}
|
||||||
|
|
||||||
def filterChains() {
|
def filterChains() {
|
||||||
context.getBean(FilterChainProxy).filterChains
|
context.getBean(FilterChainProxy).filterChains
|
||||||
}
|
}
|
||||||
|
|
||||||
Filter getSpringSecurityFilterChain() {
|
Filter getSpringSecurityFilterChain() {
|
||||||
context.getBean("springSecurityFilterChain",Filter.class)
|
context.getBean("springSecurityFilterChain",Filter.class)
|
||||||
}
|
}
|
||||||
|
|
||||||
def getResponseHeaders() {
|
def getResponseHeaders() {
|
||||||
def headers = [:]
|
def headers = [:]
|
||||||
response.headerNames.each { name ->
|
response.headerNames.each { name ->
|
||||||
headers.put(name, response.getHeaderValues(name).join(','))
|
headers.put(name, response.getHeaderValues(name).join(','))
|
||||||
}
|
}
|
||||||
return headers
|
return headers
|
||||||
}
|
}
|
||||||
|
|
||||||
AuthenticationManager authenticationManager() {
|
AuthenticationManager authenticationManager() {
|
||||||
context.getBean(AuthenticationManager)
|
context.getBean(AuthenticationManager)
|
||||||
}
|
}
|
||||||
|
|
||||||
AuthenticationManager getAuthenticationManager() {
|
AuthenticationManager getAuthenticationManager() {
|
||||||
try {
|
try {
|
||||||
authenticationManager().delegateBuilder.getObject()
|
authenticationManager().delegateBuilder.getObject()
|
||||||
} catch(NoSuchBeanDefinitionException e) {
|
} catch(NoSuchBeanDefinitionException e) {
|
||||||
} catch(MissingPropertyException e) {}
|
} catch(MissingPropertyException e) {}
|
||||||
findFilter(FilterSecurityInterceptor).authenticationManager
|
findFilter(FilterSecurityInterceptor).authenticationManager
|
||||||
}
|
}
|
||||||
|
|
||||||
List<AuthenticationProvider> authenticationProviders() {
|
List<AuthenticationProvider> authenticationProviders() {
|
||||||
List<AuthenticationProvider> providers = new ArrayList<AuthenticationProvider>()
|
List<AuthenticationProvider> providers = new ArrayList<AuthenticationProvider>()
|
||||||
AuthenticationManager authenticationManager = getAuthenticationManager()
|
AuthenticationManager authenticationManager = getAuthenticationManager()
|
||||||
while(authenticationManager?.providers) {
|
while(authenticationManager?.providers) {
|
||||||
providers.addAll(authenticationManager.providers)
|
providers.addAll(authenticationManager.providers)
|
||||||
authenticationManager = authenticationManager.parent
|
authenticationManager = authenticationManager.parent
|
||||||
}
|
}
|
||||||
providers
|
providers
|
||||||
}
|
}
|
||||||
|
|
||||||
AuthenticationProvider findAuthenticationProvider(Class<?> provider) {
|
AuthenticationProvider findAuthenticationProvider(Class<?> provider) {
|
||||||
authenticationProviders().find { provider.isAssignableFrom(it.class) }
|
authenticationProviders().find { provider.isAssignableFrom(it.class) }
|
||||||
}
|
}
|
||||||
|
|
||||||
def getCurrentAuthentication() {
|
def getCurrentAuthentication() {
|
||||||
new HttpSessionSecurityContextRepository().loadContext(new HttpRequestResponseHolder(request, response)).authentication
|
new HttpSessionSecurityContextRepository().loadContext(new HttpRequestResponseHolder(request, response)).authentication
|
||||||
}
|
}
|
||||||
|
|
||||||
def login(String username="user", String role="ROLE_USER") {
|
def login(String username="user", String role="ROLE_USER") {
|
||||||
login(new UsernamePasswordAuthenticationToken(username, null, AuthorityUtils.createAuthorityList(role)))
|
login(new UsernamePasswordAuthenticationToken(username, null, AuthorityUtils.createAuthorityList(role)))
|
||||||
}
|
}
|
||||||
|
|
||||||
def login(Authentication auth) {
|
def login(Authentication auth) {
|
||||||
HttpSessionSecurityContextRepository repo = new HttpSessionSecurityContextRepository()
|
HttpSessionSecurityContextRepository repo = new HttpSessionSecurityContextRepository()
|
||||||
HttpRequestResponseHolder requestResponseHolder = new HttpRequestResponseHolder(request, response)
|
HttpRequestResponseHolder requestResponseHolder = new HttpRequestResponseHolder(request, response)
|
||||||
repo.loadContext(requestResponseHolder)
|
repo.loadContext(requestResponseHolder)
|
||||||
repo.saveContext(new SecurityContextImpl(authentication:auth), requestResponseHolder.request, requestResponseHolder.response)
|
repo.saveContext(new SecurityContextImpl(authentication:auth), requestResponseHolder.request, requestResponseHolder.response)
|
||||||
}
|
}
|
||||||
|
|
||||||
def createAuthenticationManagerBuilder() {
|
def createAuthenticationManagerBuilder() {
|
||||||
oppContext = new AnnotationConfigApplicationContext(ObjectPostProcessorConfiguration, AuthenticationConfiguration)
|
oppContext = new AnnotationConfigApplicationContext(ObjectPostProcessorConfiguration, AuthenticationConfiguration)
|
||||||
AuthenticationManagerBuilder auth = new AuthenticationManagerBuilder(objectPostProcessor)
|
AuthenticationManagerBuilder auth = new AuthenticationManagerBuilder(objectPostProcessor)
|
||||||
auth.inMemoryAuthentication().and()
|
auth.inMemoryAuthentication().and()
|
||||||
}
|
}
|
||||||
|
|
||||||
def getObjectPostProcessor() {
|
def getObjectPostProcessor() {
|
||||||
oppContext.getBean(ObjectPostProcessor)
|
oppContext.getBean(ObjectPostProcessor)
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -5,7 +5,7 @@
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
@ -22,19 +22,19 @@ import spock.lang.Specification
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class SecurityConfigurerAdapterTests extends Specification {
|
class SecurityConfigurerAdapterTests extends Specification {
|
||||||
ConcereteSecurityConfigurerAdapter conf = new ConcereteSecurityConfigurerAdapter()
|
ConcereteSecurityConfigurerAdapter conf = new ConcereteSecurityConfigurerAdapter()
|
||||||
|
|
||||||
def "addPostProcessor closure"() {
|
def "addPostProcessor closure"() {
|
||||||
setup:
|
setup:
|
||||||
SecurityBuilder<Object> builder = Mock()
|
SecurityBuilder<Object> builder = Mock()
|
||||||
conf.addObjectPostProcessor({ List l ->
|
conf.addObjectPostProcessor({ List l ->
|
||||||
l.add("a")
|
l.add("a")
|
||||||
l
|
l
|
||||||
} as ObjectPostProcessor<List>)
|
} as ObjectPostProcessor<List>)
|
||||||
when:
|
when:
|
||||||
conf.init(builder)
|
conf.init(builder)
|
||||||
conf.configure(builder)
|
conf.configure(builder)
|
||||||
then:
|
then:
|
||||||
conf.list.contains("a")
|
conf.list.contains("a")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
@ -39,62 +39,62 @@ import spock.lang.Specification
|
||||||
@ContextConfiguration(classes=[ApplicationConfig,SecurityConfig])
|
@ContextConfiguration(classes=[ApplicationConfig,SecurityConfig])
|
||||||
@Transactional
|
@Transactional
|
||||||
class Issue50Tests extends Specification {
|
class Issue50Tests extends Specification {
|
||||||
@Autowired
|
@Autowired
|
||||||
private FilterChainProxy springSecurityFilterChain
|
private FilterChainProxy springSecurityFilterChain
|
||||||
@Autowired
|
@Autowired
|
||||||
private AuthenticationManager authenticationManager
|
private AuthenticationManager authenticationManager
|
||||||
@Autowired
|
@Autowired
|
||||||
private UserRepository userRepo
|
private UserRepository userRepo
|
||||||
|
|
||||||
def setup() {
|
def setup() {
|
||||||
SecurityContextHolder.context.authentication = new TestingAuthenticationToken("test",null,"ROLE_ADMIN")
|
SecurityContextHolder.context.authentication = new TestingAuthenticationToken("test",null,"ROLE_ADMIN")
|
||||||
}
|
}
|
||||||
|
|
||||||
def cleanup() {
|
def cleanup() {
|
||||||
SecurityContextHolder.clearContext()
|
SecurityContextHolder.clearContext()
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://github.com/SpringSource/spring-security-javaconfig/issues/50
|
// https://github.com/SpringSource/spring-security-javaconfig/issues/50
|
||||||
def "#50 - GlobalMethodSecurityConfiguration should load AuthenticationManager lazily"() {
|
def "#50 - GlobalMethodSecurityConfiguration should load AuthenticationManager lazily"() {
|
||||||
when:
|
when:
|
||||||
"Configuration Loads"
|
"Configuration Loads"
|
||||||
then: "GlobalMethodSecurityConfiguration loads AuthenticationManager lazily"
|
then: "GlobalMethodSecurityConfiguration loads AuthenticationManager lazily"
|
||||||
noExceptionThrown()
|
noExceptionThrown()
|
||||||
}
|
}
|
||||||
|
|
||||||
def "AuthenticationManager will not authenticate missing user"() {
|
def "AuthenticationManager will not authenticate missing user"() {
|
||||||
when:
|
when:
|
||||||
authenticationManager.authenticate(new UsernamePasswordAuthenticationToken("test", "password"))
|
authenticationManager.authenticate(new UsernamePasswordAuthenticationToken("test", "password"))
|
||||||
then:
|
then:
|
||||||
thrown(UsernameNotFoundException)
|
thrown(UsernameNotFoundException)
|
||||||
}
|
}
|
||||||
|
|
||||||
def "AuthenticationManager will not authenticate with invalid password"() {
|
def "AuthenticationManager will not authenticate with invalid password"() {
|
||||||
when:
|
when:
|
||||||
User user = new User(username:"test",password:"password")
|
User user = new User(username:"test",password:"password")
|
||||||
userRepo.save(user)
|
userRepo.save(user)
|
||||||
authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(user.username , "invalid"))
|
authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(user.username , "invalid"))
|
||||||
then:
|
then:
|
||||||
thrown(BadCredentialsException)
|
thrown(BadCredentialsException)
|
||||||
}
|
}
|
||||||
|
|
||||||
def "AuthenticationManager can be used to authenticate a user"() {
|
def "AuthenticationManager can be used to authenticate a user"() {
|
||||||
when:
|
when:
|
||||||
User user = new User(username:"test",password:"password")
|
User user = new User(username:"test",password:"password")
|
||||||
userRepo.save(user)
|
userRepo.save(user)
|
||||||
Authentication result = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(user.username , user.password))
|
Authentication result = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(user.username , user.password))
|
||||||
then:
|
then:
|
||||||
result.principal == user.username
|
result.principal == user.username
|
||||||
}
|
}
|
||||||
|
|
||||||
def "Global Method Security is enabled and works"() {
|
def "Global Method Security is enabled and works"() {
|
||||||
setup:
|
setup:
|
||||||
SecurityContextHolder.context.authentication = new TestingAuthenticationToken("test",null,"ROLE_USER")
|
SecurityContextHolder.context.authentication = new TestingAuthenticationToken("test",null,"ROLE_USER")
|
||||||
when:
|
when:
|
||||||
User user = new User(username:"denied",password:"password")
|
User user = new User(username:"denied",password:"password")
|
||||||
userRepo.save(user)
|
userRepo.save(user)
|
||||||
Authentication result = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(user.username , user.password))
|
Authentication result = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(user.username , user.password))
|
||||||
then:
|
then:
|
||||||
thrown(AccessDeniedException)
|
thrown(AccessDeniedException)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
@ -44,100 +44,100 @@ import org.springframework.web.context.support.AnnotationConfigWebApplicationCon
|
||||||
|
|
||||||
public class Sec2758Tests extends BaseSpringSpec {
|
public class Sec2758Tests extends BaseSpringSpec {
|
||||||
|
|
||||||
def cleanup() {
|
def cleanup() {
|
||||||
SecurityContextHolder.clearContext()
|
SecurityContextHolder.clearContext()
|
||||||
}
|
}
|
||||||
|
|
||||||
def "SEC-2758: Verify Passivity Restored with Advice from JIRA"() {
|
def "SEC-2758: Verify Passivity Restored with Advice from JIRA"() {
|
||||||
setup:
|
setup:
|
||||||
SecurityContextHolder.context.authentication = new TestingAuthenticationToken("user", "pass", "USER")
|
SecurityContextHolder.context.authentication = new TestingAuthenticationToken("user", "pass", "USER")
|
||||||
loadConfig(SecurityConfig)
|
loadConfig(SecurityConfig)
|
||||||
Service service = context.getBean(Service)
|
Service service = context.getBean(Service)
|
||||||
|
|
||||||
when:
|
when:
|
||||||
findFilter(FilterSecurityInterceptor).doFilter(new MockHttpServletRequest(), new MockHttpServletResponse(), new MockFilterChain())
|
findFilter(FilterSecurityInterceptor).doFilter(new MockHttpServletRequest(), new MockHttpServletResponse(), new MockFilterChain())
|
||||||
then:
|
then:
|
||||||
noExceptionThrown()
|
noExceptionThrown()
|
||||||
|
|
||||||
when:
|
when:
|
||||||
service.doPreAuthorize()
|
service.doPreAuthorize()
|
||||||
then:
|
then:
|
||||||
noExceptionThrown()
|
noExceptionThrown()
|
||||||
|
|
||||||
when:
|
when:
|
||||||
service.doJsr250()
|
service.doJsr250()
|
||||||
then:
|
then:
|
||||||
noExceptionThrown()
|
noExceptionThrown()
|
||||||
}
|
}
|
||||||
|
|
||||||
@EnableWebSecurity
|
@EnableWebSecurity
|
||||||
@EnableGlobalMethodSecurity(prePostEnabled=true)
|
@EnableGlobalMethodSecurity(prePostEnabled=true)
|
||||||
static class SecurityConfig extends WebSecurityConfigurerAdapter {
|
static class SecurityConfig extends WebSecurityConfigurerAdapter {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void configure(HttpSecurity http) throws Exception {
|
protected void configure(HttpSecurity http) throws Exception {
|
||||||
http
|
http
|
||||||
.authorizeRequests()
|
.authorizeRequests()
|
||||||
.anyRequest().hasAnyAuthority("USER");
|
.anyRequest().hasAnyAuthority("USER");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public void configureGlobal(AuthenticationManagerBuilder auth) {
|
public void configureGlobal(AuthenticationManagerBuilder auth) {
|
||||||
auth
|
auth
|
||||||
.inMemoryAuthentication()
|
.inMemoryAuthentication()
|
||||||
.withUser("user").password("password").authorities("USER")
|
.withUser("user").password("password").authorities("USER")
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
Service service() {
|
Service service() {
|
||||||
return new ServiceImpl()
|
return new ServiceImpl()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
static DefaultRolesPrefixPostProcessor defaultRolesPrefixPostProcessor() {
|
static DefaultRolesPrefixPostProcessor defaultRolesPrefixPostProcessor() {
|
||||||
new DefaultRolesPrefixPostProcessor()
|
new DefaultRolesPrefixPostProcessor()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Service {
|
interface Service {
|
||||||
void doPreAuthorize()
|
void doPreAuthorize()
|
||||||
void doJsr250()
|
void doJsr250()
|
||||||
}
|
}
|
||||||
|
|
||||||
static class ServiceImpl implements Service {
|
static class ServiceImpl implements Service {
|
||||||
@PreAuthorize("hasRole('USER')")
|
@PreAuthorize("hasRole('USER')")
|
||||||
void doPreAuthorize() {}
|
void doPreAuthorize() {}
|
||||||
|
|
||||||
@RolesAllowed("USER")
|
@RolesAllowed("USER")
|
||||||
void doJsr250() {}
|
void doJsr250() {}
|
||||||
}
|
}
|
||||||
|
|
||||||
static class DefaultRolesPrefixPostProcessor implements BeanPostProcessor, PriorityOrdered {
|
static class DefaultRolesPrefixPostProcessor implements BeanPostProcessor, PriorityOrdered {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object postProcessAfterInitialization(Object bean, String beanName)
|
public Object postProcessAfterInitialization(Object bean, String beanName)
|
||||||
throws BeansException {
|
throws BeansException {
|
||||||
if(bean instanceof Jsr250MethodSecurityMetadataSource) {
|
if(bean instanceof Jsr250MethodSecurityMetadataSource) {
|
||||||
((Jsr250MethodSecurityMetadataSource) bean).setDefaultRolePrefix(null);
|
((Jsr250MethodSecurityMetadataSource) bean).setDefaultRolePrefix(null);
|
||||||
}
|
}
|
||||||
if(bean instanceof DefaultMethodSecurityExpressionHandler) {
|
if(bean instanceof DefaultMethodSecurityExpressionHandler) {
|
||||||
((DefaultMethodSecurityExpressionHandler) bean).setDefaultRolePrefix(null);
|
((DefaultMethodSecurityExpressionHandler) bean).setDefaultRolePrefix(null);
|
||||||
}
|
}
|
||||||
if(bean instanceof DefaultWebSecurityExpressionHandler) {
|
if(bean instanceof DefaultWebSecurityExpressionHandler) {
|
||||||
((DefaultWebSecurityExpressionHandler) bean).setDefaultRolePrefix(null);
|
((DefaultWebSecurityExpressionHandler) bean).setDefaultRolePrefix(null);
|
||||||
}
|
}
|
||||||
return bean;
|
return bean;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object postProcessBeforeInitialization(Object bean, String beanName)
|
public Object postProcessBeforeInitialization(Object bean, String beanName)
|
||||||
throws BeansException {
|
throws BeansException {
|
||||||
return bean;
|
return bean;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getOrder() {
|
public int getOrder() {
|
||||||
return PriorityOrdered.HIGHEST_PRECEDENCE;
|
return PriorityOrdered.HIGHEST_PRECEDENCE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
@ -29,31 +29,31 @@ import spock.lang.Specification;
|
||||||
*/
|
*/
|
||||||
class RequestMatchersTests extends Specification {
|
class RequestMatchersTests extends Specification {
|
||||||
|
|
||||||
def "regexMatchers(GET,'/a.*') uses RegexRequestMatcher"() {
|
def "regexMatchers(GET,'/a.*') uses RegexRequestMatcher"() {
|
||||||
when:
|
when:
|
||||||
def matchers = regexMatchers(HttpMethod.GET, "/a.*")
|
def matchers = regexMatchers(HttpMethod.GET, "/a.*")
|
||||||
then: 'matcher is a RegexRequestMatcher'
|
then: 'matcher is a RegexRequestMatcher'
|
||||||
matchers.collect {it.class } == [RegexRequestMatcher]
|
matchers.collect {it.class } == [RegexRequestMatcher]
|
||||||
}
|
}
|
||||||
|
|
||||||
def "regexMatchers('/a.*') uses RegexRequestMatcher"() {
|
def "regexMatchers('/a.*') uses RegexRequestMatcher"() {
|
||||||
when:
|
when:
|
||||||
def matchers = regexMatchers("/a.*")
|
def matchers = regexMatchers("/a.*")
|
||||||
then: 'matcher is a RegexRequestMatcher'
|
then: 'matcher is a RegexRequestMatcher'
|
||||||
matchers.collect {it.class } == [RegexRequestMatcher]
|
matchers.collect {it.class } == [RegexRequestMatcher]
|
||||||
}
|
}
|
||||||
|
|
||||||
def "antMatchers(GET,'/a.*') uses AntPathRequestMatcher"() {
|
def "antMatchers(GET,'/a.*') uses AntPathRequestMatcher"() {
|
||||||
when:
|
when:
|
||||||
def matchers = antMatchers(HttpMethod.GET, "/a.*")
|
def matchers = antMatchers(HttpMethod.GET, "/a.*")
|
||||||
then: 'matcher is a RegexRequestMatcher'
|
then: 'matcher is a RegexRequestMatcher'
|
||||||
matchers.collect {it.class } == [AntPathRequestMatcher]
|
matchers.collect {it.class } == [AntPathRequestMatcher]
|
||||||
}
|
}
|
||||||
|
|
||||||
def "antMatchers('/a.*') uses AntPathRequestMatcher"() {
|
def "antMatchers('/a.*') uses AntPathRequestMatcher"() {
|
||||||
when:
|
when:
|
||||||
def matchers = antMatchers("/a.*")
|
def matchers = antMatchers("/a.*")
|
||||||
then: 'matcher is a AntPathRequestMatcher'
|
then: 'matcher is a AntPathRequestMatcher'
|
||||||
matchers.collect {it.class } == [AntPathRequestMatcher]
|
matchers.collect {it.class } == [AntPathRequestMatcher]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
@ -60,440 +60,440 @@ import org.springframework.security.web.util.matcher.RequestMatcher
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class NamespaceHttpTests extends BaseSpringSpec {
|
public class NamespaceHttpTests extends BaseSpringSpec {
|
||||||
def "http@access-decision-manager-ref"() {
|
def "http@access-decision-manager-ref"() {
|
||||||
setup:
|
setup:
|
||||||
AccessDecisionManagerRefConfig.ACCESS_DECISION_MGR = Mock(AccessDecisionManager)
|
AccessDecisionManagerRefConfig.ACCESS_DECISION_MGR = Mock(AccessDecisionManager)
|
||||||
AccessDecisionManagerRefConfig.ACCESS_DECISION_MGR.supports(FilterInvocation) >> true
|
AccessDecisionManagerRefConfig.ACCESS_DECISION_MGR.supports(FilterInvocation) >> true
|
||||||
AccessDecisionManagerRefConfig.ACCESS_DECISION_MGR.supports(_ as ConfigAttribute) >> true
|
AccessDecisionManagerRefConfig.ACCESS_DECISION_MGR.supports(_ as ConfigAttribute) >> true
|
||||||
when:
|
when:
|
||||||
loadConfig(AccessDecisionManagerRefConfig)
|
loadConfig(AccessDecisionManagerRefConfig)
|
||||||
then:
|
then:
|
||||||
findFilter(FilterSecurityInterceptor).accessDecisionManager == AccessDecisionManagerRefConfig.ACCESS_DECISION_MGR
|
findFilter(FilterSecurityInterceptor).accessDecisionManager == AccessDecisionManagerRefConfig.ACCESS_DECISION_MGR
|
||||||
}
|
}
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
static class AccessDecisionManagerRefConfig extends BaseWebConfig {
|
static class AccessDecisionManagerRefConfig extends BaseWebConfig {
|
||||||
static AccessDecisionManager ACCESS_DECISION_MGR
|
static AccessDecisionManager ACCESS_DECISION_MGR
|
||||||
|
|
||||||
protected void configure(HttpSecurity http) throws Exception {
|
protected void configure(HttpSecurity http) throws Exception {
|
||||||
http
|
http
|
||||||
.authorizeRequests()
|
.authorizeRequests()
|
||||||
.anyRequest().permitAll()
|
.anyRequest().permitAll()
|
||||||
.accessDecisionManager(ACCESS_DECISION_MGR)
|
.accessDecisionManager(ACCESS_DECISION_MGR)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
def "http@access-denied-page"() {
|
def "http@access-denied-page"() {
|
||||||
when:
|
when:
|
||||||
loadConfig(AccessDeniedPageConfig)
|
loadConfig(AccessDeniedPageConfig)
|
||||||
then:
|
then:
|
||||||
findFilter(ExceptionTranslationFilter).accessDeniedHandler.errorPage == "/AccessDeniedPageConfig"
|
findFilter(ExceptionTranslationFilter).accessDeniedHandler.errorPage == "/AccessDeniedPageConfig"
|
||||||
}
|
}
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
static class AccessDeniedPageConfig extends BaseWebConfig {
|
static class AccessDeniedPageConfig extends BaseWebConfig {
|
||||||
protected void configure(HttpSecurity http) throws Exception {
|
protected void configure(HttpSecurity http) throws Exception {
|
||||||
http
|
http
|
||||||
.exceptionHandling()
|
.exceptionHandling()
|
||||||
.accessDeniedPage("/AccessDeniedPageConfig")
|
.accessDeniedPage("/AccessDeniedPageConfig")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
def "http@authentication-manager-ref"() {
|
def "http@authentication-manager-ref"() {
|
||||||
when: "Specify AuthenticationManager"
|
when: "Specify AuthenticationManager"
|
||||||
loadConfig(AuthenticationManagerRefConfig)
|
loadConfig(AuthenticationManagerRefConfig)
|
||||||
then: "Populates the AuthenticationManager"
|
then: "Populates the AuthenticationManager"
|
||||||
findFilter(FilterSecurityInterceptor).authenticationManager.parent.class == CustomAuthenticationManager
|
findFilter(FilterSecurityInterceptor).authenticationManager.parent.class == CustomAuthenticationManager
|
||||||
}
|
}
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
static class AuthenticationManagerRefConfig extends BaseWebConfig {
|
static class AuthenticationManagerRefConfig extends BaseWebConfig {
|
||||||
// demo authentication-manager-ref (could be any value)
|
// demo authentication-manager-ref (could be any value)
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected AuthenticationManager authenticationManager() throws Exception {
|
protected AuthenticationManager authenticationManager() throws Exception {
|
||||||
return new CustomAuthenticationManager();
|
return new CustomAuthenticationManager();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void configure(HttpSecurity http) throws Exception {
|
protected void configure(HttpSecurity http) throws Exception {
|
||||||
http
|
http
|
||||||
.authorizeRequests()
|
.authorizeRequests()
|
||||||
.anyRequest().hasRole("USER");
|
.anyRequest().hasRole("USER");
|
||||||
}
|
}
|
||||||
|
|
||||||
static class CustomAuthenticationManager implements AuthenticationManager {
|
static class CustomAuthenticationManager implements AuthenticationManager {
|
||||||
public Authentication authenticate(Authentication authentication)
|
public Authentication authenticate(Authentication authentication)
|
||||||
throws AuthenticationException {
|
throws AuthenticationException {
|
||||||
throw new BadCredentialsException("This always fails");
|
throw new BadCredentialsException("This always fails");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Note: There is no http@auto-config equivalent in Java Config
|
// Note: There is no http@auto-config equivalent in Java Config
|
||||||
|
|
||||||
def "http@create-session=always"() {
|
def "http@create-session=always"() {
|
||||||
when:
|
when:
|
||||||
loadConfig(IfRequiredConfig)
|
loadConfig(IfRequiredConfig)
|
||||||
then:
|
then:
|
||||||
findFilter(SecurityContextPersistenceFilter).forceEagerSessionCreation == false
|
findFilter(SecurityContextPersistenceFilter).forceEagerSessionCreation == false
|
||||||
findFilter(SecurityContextPersistenceFilter).repo.allowSessionCreation == true
|
findFilter(SecurityContextPersistenceFilter).repo.allowSessionCreation == true
|
||||||
findFilter(SessionManagementFilter).securityContextRepository.allowSessionCreation == true
|
findFilter(SessionManagementFilter).securityContextRepository.allowSessionCreation == true
|
||||||
findFilter(ExceptionTranslationFilter).requestCache.class == HttpSessionRequestCache
|
findFilter(ExceptionTranslationFilter).requestCache.class == HttpSessionRequestCache
|
||||||
}
|
}
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
static class CreateSessionAlwaysConfig extends BaseWebConfig {
|
static class CreateSessionAlwaysConfig extends BaseWebConfig {
|
||||||
protected void configure(HttpSecurity http) throws Exception {
|
protected void configure(HttpSecurity http) throws Exception {
|
||||||
http
|
http
|
||||||
.sessionManagement()
|
.sessionManagement()
|
||||||
.sessionCreationPolicy(SessionCreationPolicy.ALWAYS);
|
.sessionCreationPolicy(SessionCreationPolicy.ALWAYS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
def "http@create-session=stateless"() {
|
def "http@create-session=stateless"() {
|
||||||
when:
|
when:
|
||||||
loadConfig(CreateSessionStatelessConfig)
|
loadConfig(CreateSessionStatelessConfig)
|
||||||
then:
|
then:
|
||||||
findFilter(SecurityContextPersistenceFilter).forceEagerSessionCreation == false
|
findFilter(SecurityContextPersistenceFilter).forceEagerSessionCreation == false
|
||||||
findFilter(SecurityContextPersistenceFilter).repo.class == NullSecurityContextRepository
|
findFilter(SecurityContextPersistenceFilter).repo.class == NullSecurityContextRepository
|
||||||
findFilter(SessionManagementFilter).securityContextRepository.class == NullSecurityContextRepository
|
findFilter(SessionManagementFilter).securityContextRepository.class == NullSecurityContextRepository
|
||||||
findFilter(ExceptionTranslationFilter).requestCache.class == NullRequestCache
|
findFilter(ExceptionTranslationFilter).requestCache.class == NullRequestCache
|
||||||
findFilter(RequestCacheAwareFilter).requestCache.class == NullRequestCache
|
findFilter(RequestCacheAwareFilter).requestCache.class == NullRequestCache
|
||||||
}
|
}
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
static class CreateSessionStatelessConfig extends BaseWebConfig {
|
static class CreateSessionStatelessConfig extends BaseWebConfig {
|
||||||
protected void configure(HttpSecurity http) throws Exception {
|
protected void configure(HttpSecurity http) throws Exception {
|
||||||
http
|
http
|
||||||
.sessionManagement()
|
.sessionManagement()
|
||||||
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
|
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
def "http@create-session=ifRequired"() {
|
def "http@create-session=ifRequired"() {
|
||||||
when:
|
when:
|
||||||
loadConfig(IfRequiredConfig)
|
loadConfig(IfRequiredConfig)
|
||||||
then:
|
then:
|
||||||
findFilter(SecurityContextPersistenceFilter).forceEagerSessionCreation == false
|
findFilter(SecurityContextPersistenceFilter).forceEagerSessionCreation == false
|
||||||
findFilter(SecurityContextPersistenceFilter).repo.allowSessionCreation == true
|
findFilter(SecurityContextPersistenceFilter).repo.allowSessionCreation == true
|
||||||
findFilter(SessionManagementFilter).securityContextRepository.allowSessionCreation == true
|
findFilter(SessionManagementFilter).securityContextRepository.allowSessionCreation == true
|
||||||
}
|
}
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
static class IfRequiredConfig extends BaseWebConfig {
|
static class IfRequiredConfig extends BaseWebConfig {
|
||||||
protected void configure(HttpSecurity http) throws Exception {
|
protected void configure(HttpSecurity http) throws Exception {
|
||||||
http
|
http
|
||||||
.sessionManagement()
|
.sessionManagement()
|
||||||
.sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED);
|
.sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
def "http@create-session defaults to ifRequired"() {
|
def "http@create-session defaults to ifRequired"() {
|
||||||
when:
|
when:
|
||||||
loadConfig(IfRequiredConfig)
|
loadConfig(IfRequiredConfig)
|
||||||
then:
|
then:
|
||||||
findFilter(SecurityContextPersistenceFilter).forceEagerSessionCreation == false
|
findFilter(SecurityContextPersistenceFilter).forceEagerSessionCreation == false
|
||||||
findFilter(SecurityContextPersistenceFilter).repo.allowSessionCreation == true
|
findFilter(SecurityContextPersistenceFilter).repo.allowSessionCreation == true
|
||||||
findFilter(SessionManagementFilter).securityContextRepository.allowSessionCreation == true
|
findFilter(SessionManagementFilter).securityContextRepository.allowSessionCreation == true
|
||||||
}
|
}
|
||||||
|
|
||||||
def "http@create-session=never"() {
|
def "http@create-session=never"() {
|
||||||
when:
|
when:
|
||||||
loadConfig(CreateSessionNeverConfig)
|
loadConfig(CreateSessionNeverConfig)
|
||||||
then:
|
then:
|
||||||
findFilter(SecurityContextPersistenceFilter).forceEagerSessionCreation == false
|
findFilter(SecurityContextPersistenceFilter).forceEagerSessionCreation == false
|
||||||
findFilter(SecurityContextPersistenceFilter).repo.allowSessionCreation == false
|
findFilter(SecurityContextPersistenceFilter).repo.allowSessionCreation == false
|
||||||
findFilter(SessionManagementFilter).securityContextRepository.allowSessionCreation == false
|
findFilter(SessionManagementFilter).securityContextRepository.allowSessionCreation == false
|
||||||
}
|
}
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
static class CreateSessionNeverConfig extends BaseWebConfig {
|
static class CreateSessionNeverConfig extends BaseWebConfig {
|
||||||
protected void configure(HttpSecurity http) throws Exception {
|
protected void configure(HttpSecurity http) throws Exception {
|
||||||
http
|
http
|
||||||
.sessionManagement()
|
.sessionManagement()
|
||||||
.sessionCreationPolicy(SessionCreationPolicy.NEVER);
|
.sessionCreationPolicy(SessionCreationPolicy.NEVER);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
static class DefaultCreateSessionConfig extends BaseWebConfig {
|
static class DefaultCreateSessionConfig extends BaseWebConfig {
|
||||||
protected void configure(HttpSecurity http) throws Exception {
|
protected void configure(HttpSecurity http) throws Exception {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
def "http@disable-url-rewriting = true (default for Java Config)"() {
|
def "http@disable-url-rewriting = true (default for Java Config)"() {
|
||||||
when:
|
when:
|
||||||
loadConfig(DefaultUrlRewritingConfig)
|
loadConfig(DefaultUrlRewritingConfig)
|
||||||
then:
|
then:
|
||||||
findFilter(SecurityContextPersistenceFilter).repo.disableUrlRewriting
|
findFilter(SecurityContextPersistenceFilter).repo.disableUrlRewriting
|
||||||
}
|
}
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
static class DefaultUrlRewritingConfig extends BaseWebConfig {
|
static class DefaultUrlRewritingConfig extends BaseWebConfig {
|
||||||
protected void configure(HttpSecurity http) throws Exception {
|
protected void configure(HttpSecurity http) throws Exception {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// http@disable-url-rewriting is on by default to disable it create a custom HttpSecurityContextRepository and use security-context-repository-ref
|
// http@disable-url-rewriting is on by default to disable it create a custom HttpSecurityContextRepository and use security-context-repository-ref
|
||||||
|
|
||||||
def "http@disable-url-rewriting = false"() {
|
def "http@disable-url-rewriting = false"() {
|
||||||
when:
|
when:
|
||||||
loadConfig(EnableUrlRewritingConfig)
|
loadConfig(EnableUrlRewritingConfig)
|
||||||
then:
|
then:
|
||||||
findFilter(SecurityContextPersistenceFilter).repo.disableUrlRewriting == false
|
findFilter(SecurityContextPersistenceFilter).repo.disableUrlRewriting == false
|
||||||
}
|
}
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
static class EnableUrlRewritingConfig extends BaseWebConfig {
|
static class EnableUrlRewritingConfig extends BaseWebConfig {
|
||||||
protected void configure(HttpSecurity http) throws Exception {
|
protected void configure(HttpSecurity http) throws Exception {
|
||||||
HttpSessionSecurityContextRepository repository = new HttpSessionSecurityContextRepository()
|
HttpSessionSecurityContextRepository repository = new HttpSessionSecurityContextRepository()
|
||||||
repository.disableUrlRewriting = false // explicitly configured (not necessary due to default values)
|
repository.disableUrlRewriting = false // explicitly configured (not necessary due to default values)
|
||||||
|
|
||||||
http.
|
http.
|
||||||
securityContext()
|
securityContext()
|
||||||
.securityContextRepository(repository)
|
.securityContextRepository(repository)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
def "http@entry-point-ref"() {
|
def "http@entry-point-ref"() {
|
||||||
when:
|
when:
|
||||||
loadConfig(EntryPointRefConfig)
|
loadConfig(EntryPointRefConfig)
|
||||||
then:
|
then:
|
||||||
findFilter(ExceptionTranslationFilter).authenticationEntryPoint.loginFormUrl == "/EntryPointRefConfig"
|
findFilter(ExceptionTranslationFilter).authenticationEntryPoint.loginFormUrl == "/EntryPointRefConfig"
|
||||||
}
|
}
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
static class EntryPointRefConfig extends BaseWebConfig {
|
static class EntryPointRefConfig extends BaseWebConfig {
|
||||||
protected void configure(HttpSecurity http) throws Exception {
|
protected void configure(HttpSecurity http) throws Exception {
|
||||||
http
|
http
|
||||||
.exceptionHandling()
|
.exceptionHandling()
|
||||||
.authenticationEntryPoint(new LoginUrlAuthenticationEntryPoint("/EntryPointRefConfig"))
|
.authenticationEntryPoint(new LoginUrlAuthenticationEntryPoint("/EntryPointRefConfig"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
def "http@jaas-api-provision"() {
|
def "http@jaas-api-provision"() {
|
||||||
when:
|
when:
|
||||||
loadConfig(JaasApiProvisionConfig)
|
loadConfig(JaasApiProvisionConfig)
|
||||||
then:
|
then:
|
||||||
findFilter(JaasApiIntegrationFilter)
|
findFilter(JaasApiIntegrationFilter)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
static class JaasApiProvisionConfig extends BaseWebConfig {
|
static class JaasApiProvisionConfig extends BaseWebConfig {
|
||||||
protected void configure(HttpSecurity http) throws Exception {
|
protected void configure(HttpSecurity http) throws Exception {
|
||||||
http
|
http
|
||||||
.addFilter(new JaasApiIntegrationFilter())
|
.addFilter(new JaasApiIntegrationFilter())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// http@name is not available since it can be done w/ standard bean configuration easily
|
// http@name is not available since it can be done w/ standard bean configuration easily
|
||||||
|
|
||||||
def "http@once-per-request=true"() {
|
def "http@once-per-request=true"() {
|
||||||
when:
|
when:
|
||||||
loadConfig(OncePerRequestConfig)
|
loadConfig(OncePerRequestConfig)
|
||||||
then:
|
then:
|
||||||
findFilter(FilterSecurityInterceptor).observeOncePerRequest
|
findFilter(FilterSecurityInterceptor).observeOncePerRequest
|
||||||
}
|
}
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
static class OncePerRequestConfig extends BaseWebConfig {
|
static class OncePerRequestConfig extends BaseWebConfig {
|
||||||
@Override
|
@Override
|
||||||
protected void configure(HttpSecurity http) throws Exception {
|
protected void configure(HttpSecurity http) throws Exception {
|
||||||
http
|
http
|
||||||
.authorizeRequests()
|
.authorizeRequests()
|
||||||
.anyRequest().hasRole("USER");
|
.anyRequest().hasRole("USER");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
def "http@once-per-request=false"() {
|
def "http@once-per-request=false"() {
|
||||||
when:
|
when:
|
||||||
loadConfig(OncePerRequestFalseConfig)
|
loadConfig(OncePerRequestFalseConfig)
|
||||||
then:
|
then:
|
||||||
!findFilter(FilterSecurityInterceptor).observeOncePerRequest
|
!findFilter(FilterSecurityInterceptor).observeOncePerRequest
|
||||||
}
|
}
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
static class OncePerRequestFalseConfig extends BaseWebConfig {
|
static class OncePerRequestFalseConfig extends BaseWebConfig {
|
||||||
@Override
|
@Override
|
||||||
protected void configure(HttpSecurity http) throws Exception {
|
protected void configure(HttpSecurity http) throws Exception {
|
||||||
http.
|
http.
|
||||||
authorizeRequests()
|
authorizeRequests()
|
||||||
.filterSecurityInterceptorOncePerRequest(false)
|
.filterSecurityInterceptorOncePerRequest(false)
|
||||||
.antMatchers("/users**","/sessions/**").hasRole("ADMIN")
|
.antMatchers("/users**","/sessions/**").hasRole("ADMIN")
|
||||||
.antMatchers("/signup").permitAll()
|
.antMatchers("/signup").permitAll()
|
||||||
.anyRequest().hasRole("USER");
|
.anyRequest().hasRole("USER");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
def "http@realm"() {
|
def "http@realm"() {
|
||||||
setup:
|
setup:
|
||||||
loadConfig(RealmConfig)
|
loadConfig(RealmConfig)
|
||||||
when:
|
when:
|
||||||
springSecurityFilterChain.doFilter(request,response,chain)
|
springSecurityFilterChain.doFilter(request,response,chain)
|
||||||
then:
|
then:
|
||||||
response.getHeader("WWW-Authenticate") == 'Basic realm="RealmConfig"'
|
response.getHeader("WWW-Authenticate") == 'Basic realm="RealmConfig"'
|
||||||
}
|
}
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
static class RealmConfig extends BaseWebConfig {
|
static class RealmConfig extends BaseWebConfig {
|
||||||
protected void configure(HttpSecurity http) throws Exception {
|
protected void configure(HttpSecurity http) throws Exception {
|
||||||
http
|
http
|
||||||
.authorizeRequests()
|
.authorizeRequests()
|
||||||
.anyRequest().authenticated()
|
.anyRequest().authenticated()
|
||||||
.and()
|
.and()
|
||||||
.httpBasic().realmName("RealmConfig")
|
.httpBasic().realmName("RealmConfig")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// http@request-matcher is not available (instead request matcher instances are used)
|
// http@request-matcher is not available (instead request matcher instances are used)
|
||||||
|
|
||||||
def "http@request-matcher-ref ant"() {
|
def "http@request-matcher-ref ant"() {
|
||||||
when:
|
when:
|
||||||
loadConfig(RequestMatcherAntConfig)
|
loadConfig(RequestMatcherAntConfig)
|
||||||
then:
|
then:
|
||||||
filterChain(0).requestMatcher.pattern == "/api/**"
|
filterChain(0).requestMatcher.pattern == "/api/**"
|
||||||
}
|
}
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
static class RequestMatcherAntConfig extends BaseWebConfig {
|
static class RequestMatcherAntConfig extends BaseWebConfig {
|
||||||
protected void configure(HttpSecurity http) throws Exception {
|
protected void configure(HttpSecurity http) throws Exception {
|
||||||
http
|
http
|
||||||
.antMatcher("/api/**")
|
.antMatcher("/api/**")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
def "http@request-matcher-ref regex"() {
|
def "http@request-matcher-ref regex"() {
|
||||||
when:
|
when:
|
||||||
loadConfig(RequestMatcherRegexConfig)
|
loadConfig(RequestMatcherRegexConfig)
|
||||||
then:
|
then:
|
||||||
filterChain(0).requestMatcher.class == RegexRequestMatcher
|
filterChain(0).requestMatcher.class == RegexRequestMatcher
|
||||||
filterChain(0).requestMatcher.pattern.matcher("/regex/a")
|
filterChain(0).requestMatcher.pattern.matcher("/regex/a")
|
||||||
filterChain(0).requestMatcher.pattern.matcher("/regex/b")
|
filterChain(0).requestMatcher.pattern.matcher("/regex/b")
|
||||||
!filterChain(0).requestMatcher.pattern.matcher("/regex1/b")
|
!filterChain(0).requestMatcher.pattern.matcher("/regex1/b")
|
||||||
}
|
}
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
static class RequestMatcherRegexConfig extends BaseWebConfig {
|
static class RequestMatcherRegexConfig extends BaseWebConfig {
|
||||||
protected void configure(HttpSecurity http) throws Exception {
|
protected void configure(HttpSecurity http) throws Exception {
|
||||||
http
|
http
|
||||||
.regexMatcher("/regex/.*")
|
.regexMatcher("/regex/.*")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
def "http@request-matcher-ref"() {
|
def "http@request-matcher-ref"() {
|
||||||
when:
|
when:
|
||||||
loadConfig(RequestMatcherRefConfig)
|
loadConfig(RequestMatcherRefConfig)
|
||||||
then:
|
then:
|
||||||
filterChain(0).requestMatcher.class == MyRequestMatcher
|
filterChain(0).requestMatcher.class == MyRequestMatcher
|
||||||
}
|
}
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
static class RequestMatcherRefConfig extends BaseWebConfig {
|
static class RequestMatcherRefConfig extends BaseWebConfig {
|
||||||
protected void configure(HttpSecurity http) throws Exception {
|
protected void configure(HttpSecurity http) throws Exception {
|
||||||
http
|
http
|
||||||
.requestMatcher(new MyRequestMatcher());
|
.requestMatcher(new MyRequestMatcher());
|
||||||
}
|
}
|
||||||
static class MyRequestMatcher implements RequestMatcher {
|
static class MyRequestMatcher implements RequestMatcher {
|
||||||
public boolean matches(HttpServletRequest request) {
|
public boolean matches(HttpServletRequest request) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
def "http@security=none"() {
|
def "http@security=none"() {
|
||||||
when:
|
when:
|
||||||
loadConfig(SecurityNoneConfig)
|
loadConfig(SecurityNoneConfig)
|
||||||
then:
|
then:
|
||||||
filterChain(0).requestMatcher.pattern == "/resources/**"
|
filterChain(0).requestMatcher.pattern == "/resources/**"
|
||||||
filterChain(0).filters.empty
|
filterChain(0).filters.empty
|
||||||
filterChain(1).requestMatcher.pattern == "/public/**"
|
filterChain(1).requestMatcher.pattern == "/public/**"
|
||||||
filterChain(1).filters.empty
|
filterChain(1).filters.empty
|
||||||
}
|
}
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
static class SecurityNoneConfig extends BaseWebConfig {
|
static class SecurityNoneConfig extends BaseWebConfig {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void configure(WebSecurity web)
|
public void configure(WebSecurity web)
|
||||||
throws Exception {
|
throws Exception {
|
||||||
web
|
web
|
||||||
.ignoring()
|
.ignoring()
|
||||||
.antMatchers("/resources/**","/public/**")
|
.antMatchers("/resources/**","/public/**")
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void configure(HttpSecurity http) throws Exception {}
|
protected void configure(HttpSecurity http) throws Exception {}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def "http@security-context-repository-ref"() {
|
def "http@security-context-repository-ref"() {
|
||||||
when:
|
when:
|
||||||
loadConfig(SecurityContextRepoConfig)
|
loadConfig(SecurityContextRepoConfig)
|
||||||
then:
|
then:
|
||||||
findFilter(SecurityContextPersistenceFilter).repo.class == NullSecurityContextRepository
|
findFilter(SecurityContextPersistenceFilter).repo.class == NullSecurityContextRepository
|
||||||
}
|
}
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
static class SecurityContextRepoConfig extends BaseWebConfig {
|
static class SecurityContextRepoConfig extends BaseWebConfig {
|
||||||
protected void configure(HttpSecurity http) throws Exception {
|
protected void configure(HttpSecurity http) throws Exception {
|
||||||
http
|
http
|
||||||
.securityContext()
|
.securityContext()
|
||||||
.securityContextRepository(new NullSecurityContextRepository()) // security-context-repository-ref
|
.securityContextRepository(new NullSecurityContextRepository()) // security-context-repository-ref
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
def "http@servlet-api-provision=false"() {
|
def "http@servlet-api-provision=false"() {
|
||||||
when:
|
when:
|
||||||
loadConfig(ServletApiProvisionConfig)
|
loadConfig(ServletApiProvisionConfig)
|
||||||
then:
|
then:
|
||||||
findFilter(SecurityContextHolderAwareRequestFilter) == null
|
findFilter(SecurityContextHolderAwareRequestFilter) == null
|
||||||
}
|
}
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
static class ServletApiProvisionConfig extends BaseWebConfig {
|
static class ServletApiProvisionConfig extends BaseWebConfig {
|
||||||
protected void configure(HttpSecurity http) throws Exception {
|
protected void configure(HttpSecurity http) throws Exception {
|
||||||
http.servletApi().disable()
|
http.servletApi().disable()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
def "http@servlet-api-provision defaults to true"() {
|
def "http@servlet-api-provision defaults to true"() {
|
||||||
when:
|
when:
|
||||||
loadConfig(ServletApiProvisionDefaultsConfig)
|
loadConfig(ServletApiProvisionDefaultsConfig)
|
||||||
then:
|
then:
|
||||||
findFilter(SecurityContextHolderAwareRequestFilter) != null
|
findFilter(SecurityContextHolderAwareRequestFilter) != null
|
||||||
}
|
}
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
static class ServletApiProvisionDefaultsConfig extends BaseWebConfig {
|
static class ServletApiProvisionDefaultsConfig extends BaseWebConfig {
|
||||||
protected void configure(HttpSecurity http) throws Exception {
|
protected void configure(HttpSecurity http) throws Exception {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
def "http@use-expressions=true"() {
|
def "http@use-expressions=true"() {
|
||||||
when:
|
when:
|
||||||
loadConfig(UseExpressionsConfig)
|
loadConfig(UseExpressionsConfig)
|
||||||
then:
|
then:
|
||||||
findFilter(FilterSecurityInterceptor).securityMetadataSource.class == ExpressionBasedFilterInvocationSecurityMetadataSource
|
findFilter(FilterSecurityInterceptor).securityMetadataSource.class == ExpressionBasedFilterInvocationSecurityMetadataSource
|
||||||
findFilter(FilterSecurityInterceptor).accessDecisionManager.decisionVoters.collect { it.class } == [WebExpressionVoter]
|
findFilter(FilterSecurityInterceptor).accessDecisionManager.decisionVoters.collect { it.class } == [WebExpressionVoter]
|
||||||
}
|
}
|
||||||
|
|
||||||
@EnableWebSecurity
|
@EnableWebSecurity
|
||||||
static class UseExpressionsConfig extends BaseWebConfig {
|
static class UseExpressionsConfig extends BaseWebConfig {
|
||||||
protected void configure(HttpSecurity http) throws Exception {
|
protected void configure(HttpSecurity http) throws Exception {
|
||||||
http
|
http
|
||||||
.authorizeRequests()
|
.authorizeRequests()
|
||||||
.antMatchers("/users**","/sessions/**").hasRole("USER")
|
.antMatchers("/users**","/sessions/**").hasRole("USER")
|
||||||
.antMatchers("/signup").permitAll()
|
.antMatchers("/signup").permitAll()
|
||||||
.anyRequest().hasRole("USER")
|
.anyRequest().hasRole("USER")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
def "http@use-expressions=false"() {
|
def "http@use-expressions=false"() {
|
||||||
when:
|
when:
|
||||||
loadConfig(DisableUseExpressionsConfig)
|
loadConfig(DisableUseExpressionsConfig)
|
||||||
then:
|
then:
|
||||||
findFilter(FilterSecurityInterceptor).securityMetadataSource.class == DefaultFilterInvocationSecurityMetadataSource
|
findFilter(FilterSecurityInterceptor).securityMetadataSource.class == DefaultFilterInvocationSecurityMetadataSource
|
||||||
findFilter(FilterSecurityInterceptor).accessDecisionManager.decisionVoters.collect { it.class } == [RoleVoter, AuthenticatedVoter]
|
findFilter(FilterSecurityInterceptor).accessDecisionManager.decisionVoters.collect { it.class } == [RoleVoter, AuthenticatedVoter]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
@ -24,17 +24,17 @@ import org.springframework.security.config.annotation.authentication.builders.Au
|
||||||
*/
|
*/
|
||||||
@EnableWebSecurity
|
@EnableWebSecurity
|
||||||
public abstract class BaseWebConfig extends WebSecurityConfigurerAdapter {
|
public abstract class BaseWebConfig extends WebSecurityConfigurerAdapter {
|
||||||
BaseWebConfig(boolean disableDefaults) {
|
BaseWebConfig(boolean disableDefaults) {
|
||||||
super(disableDefaults)
|
super(disableDefaults)
|
||||||
}
|
}
|
||||||
|
|
||||||
BaseWebConfig() {
|
BaseWebConfig() {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
|
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
|
||||||
auth
|
auth
|
||||||
.inMemoryAuthentication()
|
.inMemoryAuthentication()
|
||||||
.withUser("user").password("password").roles("USER").and()
|
.withUser("user").password("password").roles("USER").and()
|
||||||
.withUser("admin").password("password").roles("USER", "ADMIN");
|
.withUser("admin").password("password").roles("USER", "ADMIN");
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -5,7 +5,7 @@
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
@ -28,86 +28,86 @@ import org.springframework.security.config.annotation.authentication.builders.Au
|
||||||
|
|
||||||
public class Sec2515Tests extends BaseSpringSpec {
|
public class Sec2515Tests extends BaseSpringSpec {
|
||||||
|
|
||||||
def "SEC-2515: Prevent StackOverflow with bean graph cycle"() {
|
def "SEC-2515: Prevent StackOverflow with bean graph cycle"() {
|
||||||
when:
|
when:
|
||||||
loadConfig(StackOverflowSecurityConfig)
|
loadConfig(StackOverflowSecurityConfig)
|
||||||
then:
|
then:
|
||||||
thrown(FatalBeanException)
|
thrown(FatalBeanException)
|
||||||
}
|
}
|
||||||
|
|
||||||
@EnableWebSecurity
|
@EnableWebSecurity
|
||||||
static class StackOverflowSecurityConfig extends WebSecurityConfigurerAdapter {
|
static class StackOverflowSecurityConfig extends WebSecurityConfigurerAdapter {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Bean
|
@Bean
|
||||||
public AuthenticationManager authenticationManagerBean()
|
public AuthenticationManager authenticationManagerBean()
|
||||||
throws Exception {
|
throws Exception {
|
||||||
return super.authenticationManagerBean();
|
return super.authenticationManagerBean();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
def "Custom Name Prevent StackOverflow with bean graph cycle"() {
|
def "Custom Name Prevent StackOverflow with bean graph cycle"() {
|
||||||
when:
|
when:
|
||||||
loadConfig(StackOverflowSecurityConfig)
|
loadConfig(StackOverflowSecurityConfig)
|
||||||
then:
|
then:
|
||||||
thrown(FatalBeanException)
|
thrown(FatalBeanException)
|
||||||
}
|
}
|
||||||
|
|
||||||
@EnableWebSecurity
|
@EnableWebSecurity
|
||||||
static class CustomBeanNameStackOverflowSecurityConfig extends WebSecurityConfigurerAdapter {
|
static class CustomBeanNameStackOverflowSecurityConfig extends WebSecurityConfigurerAdapter {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Bean(name="custom")
|
@Bean(name="custom")
|
||||||
public AuthenticationManager authenticationManagerBean()
|
public AuthenticationManager authenticationManagerBean()
|
||||||
throws Exception {
|
throws Exception {
|
||||||
return super.authenticationManagerBean();
|
return super.authenticationManagerBean();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
def "SEC-2549: Can load with child classloader"() {
|
def "SEC-2549: Can load with child classloader"() {
|
||||||
setup:
|
setup:
|
||||||
CanLoadWithChildConfig.AM = Mock(AuthenticationManager)
|
CanLoadWithChildConfig.AM = Mock(AuthenticationManager)
|
||||||
context = new AnnotationConfigApplicationContext()
|
context = new AnnotationConfigApplicationContext()
|
||||||
context.classLoader = new URLClassLoader(new URL[0], context.classLoader)
|
context.classLoader = new URLClassLoader(new URL[0], context.classLoader)
|
||||||
context.register(CanLoadWithChildConfig)
|
context.register(CanLoadWithChildConfig)
|
||||||
context.refresh()
|
context.refresh()
|
||||||
when:
|
when:
|
||||||
authenticationManager.authenticate(new UsernamePasswordAuthenticationToken("user", "password"))
|
authenticationManager.authenticate(new UsernamePasswordAuthenticationToken("user", "password"))
|
||||||
then:
|
then:
|
||||||
noExceptionThrown()
|
noExceptionThrown()
|
||||||
1 * CanLoadWithChildConfig.AM.authenticate(_) >> new TestingAuthenticationToken("user","password","ROLE_USER")
|
1 * CanLoadWithChildConfig.AM.authenticate(_) >> new TestingAuthenticationToken("user","password","ROLE_USER")
|
||||||
}
|
}
|
||||||
|
|
||||||
@EnableWebSecurity
|
@EnableWebSecurity
|
||||||
static class CanLoadWithChildConfig extends WebSecurityConfigurerAdapter {
|
static class CanLoadWithChildConfig extends WebSecurityConfigurerAdapter {
|
||||||
static AuthenticationManager AM
|
static AuthenticationManager AM
|
||||||
@Bean
|
@Bean
|
||||||
public AuthenticationManager am() {
|
public AuthenticationManager am() {
|
||||||
AM
|
AM
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
def "SEC-2515: @Bean still works when configure(AuthenticationManagerBuilder) used"() {
|
def "SEC-2515: @Bean still works when configure(AuthenticationManagerBuilder) used"() {
|
||||||
when:
|
when:
|
||||||
loadConfig(SecurityConfig)
|
loadConfig(SecurityConfig)
|
||||||
then:
|
then:
|
||||||
noExceptionThrown();
|
noExceptionThrown();
|
||||||
}
|
}
|
||||||
|
|
||||||
@EnableWebSecurity
|
@EnableWebSecurity
|
||||||
static class SecurityConfig extends WebSecurityConfigurerAdapter {
|
static class SecurityConfig extends WebSecurityConfigurerAdapter {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Bean
|
@Bean
|
||||||
public AuthenticationManager authenticationManagerBean()
|
public AuthenticationManager authenticationManagerBean()
|
||||||
throws Exception {
|
throws Exception {
|
||||||
return super.authenticationManagerBean();
|
return super.authenticationManagerBean();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void configure(AuthenticationManagerBuilder auth)
|
protected void configure(AuthenticationManagerBuilder auth)
|
||||||
throws Exception {
|
throws Exception {
|
||||||
auth.inMemoryAuthentication()
|
auth.inMemoryAuthentication()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
@ -36,83 +36,83 @@ import org.springframework.stereotype.Component
|
||||||
*/
|
*/
|
||||||
class Issue55Tests extends BaseSpringSpec {
|
class Issue55Tests extends BaseSpringSpec {
|
||||||
|
|
||||||
def "WebSecurityConfigurerAdapter defaults to @Autowired"() {
|
def "WebSecurityConfigurerAdapter defaults to @Autowired"() {
|
||||||
setup:
|
setup:
|
||||||
TestingAuthenticationToken token = new TestingAuthenticationToken("test", "this")
|
TestingAuthenticationToken token = new TestingAuthenticationToken("test", "this")
|
||||||
when:
|
when:
|
||||||
loadConfig(WebSecurityConfigurerAdapterDefaultsAuthManagerConfig)
|
loadConfig(WebSecurityConfigurerAdapterDefaultsAuthManagerConfig)
|
||||||
then:
|
then:
|
||||||
context.getBean(FilterChainProxy)
|
context.getBean(FilterChainProxy)
|
||||||
findFilter(FilterSecurityInterceptor).authenticationManager.authenticate(token) == CustomAuthenticationManager.RESULT
|
findFilter(FilterSecurityInterceptor).authenticationManager.authenticate(token) == CustomAuthenticationManager.RESULT
|
||||||
}
|
}
|
||||||
|
|
||||||
@EnableWebSecurity
|
@EnableWebSecurity
|
||||||
static class WebSecurityConfigurerAdapterDefaultsAuthManagerConfig {
|
static class WebSecurityConfigurerAdapterDefaultsAuthManagerConfig {
|
||||||
@Component
|
@Component
|
||||||
public static class WebSecurityAdapter extends WebSecurityConfigurerAdapter {
|
public static class WebSecurityAdapter extends WebSecurityConfigurerAdapter {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void configure(HttpSecurity http) throws Exception {
|
protected void configure(HttpSecurity http) throws Exception {
|
||||||
http
|
http
|
||||||
.authorizeRequests()
|
.authorizeRequests()
|
||||||
.anyRequest().hasRole("USER");
|
.anyRequest().hasRole("USER");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@Configuration
|
@Configuration
|
||||||
public static class AuthenticationManagerConfiguration {
|
public static class AuthenticationManagerConfiguration {
|
||||||
@Bean
|
@Bean
|
||||||
public AuthenticationManager authenticationManager() throws Exception {
|
public AuthenticationManager authenticationManager() throws Exception {
|
||||||
return new CustomAuthenticationManager();
|
return new CustomAuthenticationManager();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
def "multi http WebSecurityConfigurerAdapter defaults to @Autowired"() {
|
def "multi http WebSecurityConfigurerAdapter defaults to @Autowired"() {
|
||||||
setup:
|
setup:
|
||||||
TestingAuthenticationToken token = new TestingAuthenticationToken("test", "this")
|
TestingAuthenticationToken token = new TestingAuthenticationToken("test", "this")
|
||||||
when:
|
when:
|
||||||
loadConfig(MultiWebSecurityConfigurerAdapterDefaultsAuthManagerConfig)
|
loadConfig(MultiWebSecurityConfigurerAdapterDefaultsAuthManagerConfig)
|
||||||
then:
|
then:
|
||||||
context.getBean(FilterChainProxy)
|
context.getBean(FilterChainProxy)
|
||||||
findFilter(FilterSecurityInterceptor).authenticationManager.authenticate(token) == CustomAuthenticationManager.RESULT
|
findFilter(FilterSecurityInterceptor).authenticationManager.authenticate(token) == CustomAuthenticationManager.RESULT
|
||||||
findFilter(FilterSecurityInterceptor,1).authenticationManager.authenticate(token) == CustomAuthenticationManager.RESULT
|
findFilter(FilterSecurityInterceptor,1).authenticationManager.authenticate(token) == CustomAuthenticationManager.RESULT
|
||||||
}
|
}
|
||||||
|
|
||||||
@EnableWebSecurity
|
@EnableWebSecurity
|
||||||
static class MultiWebSecurityConfigurerAdapterDefaultsAuthManagerConfig {
|
static class MultiWebSecurityConfigurerAdapterDefaultsAuthManagerConfig {
|
||||||
@Component
|
@Component
|
||||||
@Order(1)
|
@Order(1)
|
||||||
public static class ApiWebSecurityAdapter extends WebSecurityConfigurerAdapter {
|
public static class ApiWebSecurityAdapter extends WebSecurityConfigurerAdapter {
|
||||||
@Override
|
@Override
|
||||||
protected void configure(HttpSecurity http) throws Exception {
|
protected void configure(HttpSecurity http) throws Exception {
|
||||||
http
|
http
|
||||||
.antMatcher("/api/**")
|
.antMatcher("/api/**")
|
||||||
.authorizeRequests()
|
.authorizeRequests()
|
||||||
.anyRequest().hasRole("USER");
|
.anyRequest().hasRole("USER");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@Component
|
@Component
|
||||||
public static class WebSecurityAdapter extends WebSecurityConfigurerAdapter {
|
public static class WebSecurityAdapter extends WebSecurityConfigurerAdapter {
|
||||||
@Override
|
@Override
|
||||||
protected void configure(HttpSecurity http) throws Exception {
|
protected void configure(HttpSecurity http) throws Exception {
|
||||||
http
|
http
|
||||||
.authorizeRequests()
|
.authorizeRequests()
|
||||||
.anyRequest().hasRole("USER");
|
.anyRequest().hasRole("USER");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@Configuration
|
@Configuration
|
||||||
public static class AuthenticationManagerConfiguration {
|
public static class AuthenticationManagerConfiguration {
|
||||||
@Bean
|
@Bean
|
||||||
public AuthenticationManager authenticationManager() throws Exception {
|
public AuthenticationManager authenticationManager() throws Exception {
|
||||||
return new CustomAuthenticationManager();
|
return new CustomAuthenticationManager();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static class CustomAuthenticationManager implements AuthenticationManager {
|
static class CustomAuthenticationManager implements AuthenticationManager {
|
||||||
static Authentication RESULT = new TestingAuthenticationToken("test", "this","ROLE_USER")
|
static Authentication RESULT = new TestingAuthenticationToken("test", "this","ROLE_USER")
|
||||||
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
|
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
|
||||||
return RESULT;
|
return RESULT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
@ -29,15 +29,15 @@ import org.springframework.stereotype.Service
|
||||||
@Service("authProvider")
|
@Service("authProvider")
|
||||||
public class TestAuthenticationProvider implements AuthenticationProvider {
|
public class TestAuthenticationProvider implements AuthenticationProvider {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public TestAuthenticationProvider(AuthProviderDependency authProviderDependency) {
|
public TestAuthenticationProvider(AuthProviderDependency authProviderDependency) {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
|
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean supports(Class<?> authentication) {
|
public boolean supports(Class<?> authentication) {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,11 +23,11 @@ package org.springframework.security.config.doc
|
||||||
* @see XsdDocumentedSpec
|
* @see XsdDocumentedSpec
|
||||||
*/
|
*/
|
||||||
class Attribute {
|
class Attribute {
|
||||||
def name
|
def name
|
||||||
def desc
|
def desc
|
||||||
def elmt
|
def elmt
|
||||||
|
|
||||||
def getId() {
|
def getId() {
|
||||||
return "${elmt.id}-${name}".toString()
|
return "${elmt.id}-${name}".toString()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,68 +23,68 @@ package org.springframework.security.config.doc
|
||||||
* @see XsdDocumentedSpec
|
* @see XsdDocumentedSpec
|
||||||
*/
|
*/
|
||||||
class Element {
|
class Element {
|
||||||
def name
|
def name
|
||||||
def desc
|
def desc
|
||||||
def attrs
|
def attrs
|
||||||
/**
|
/**
|
||||||
* Contains the elements that extend this element (i.e. any-user-service contains ldap-user-service)
|
* Contains the elements that extend this element (i.e. any-user-service contains ldap-user-service)
|
||||||
*/
|
*/
|
||||||
def subGrps = []
|
def subGrps = []
|
||||||
def childElmts = [:]
|
def childElmts = [:]
|
||||||
def parentElmts = [:]
|
def parentElmts = [:]
|
||||||
|
|
||||||
def getId() {
|
def getId() {
|
||||||
return "nsa-${name}".toString()
|
return "nsa-${name}".toString()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets all the ids related to this Element including attributes, parent elements, and child elements.
|
* Gets all the ids related to this Element including attributes, parent elements, and child elements.
|
||||||
*
|
*
|
||||||
* <p>
|
* <p>
|
||||||
* The expected ids to be found are documented below.
|
* The expected ids to be found are documented below.
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li>Elements - any xml element will have the nsa-<element>. For example the http element will have the id
|
* <li>Elements - any xml element will have the nsa-<element>. For example the http element will have the id
|
||||||
* nsa-http</li>
|
* nsa-http</li>
|
||||||
* <li>Parent Section - Any element with a parent other than beans will have a section named
|
* <li>Parent Section - Any element with a parent other than beans will have a section named
|
||||||
* nsa-<element>-parents. For example, authentication-provider would have a section id of
|
* nsa-<element>-parents. For example, authentication-provider would have a section id of
|
||||||
* nsa-authentication-provider-parents. The section would then contain a list of links pointing to the
|
* nsa-authentication-provider-parents. The section would then contain a list of links pointing to the
|
||||||
* documentation for each parent element.</li>
|
* documentation for each parent element.</li>
|
||||||
* <li>Attributes Section - Any element with attributes will have a section with the id
|
* <li>Attributes Section - Any element with attributes will have a section with the id
|
||||||
* nsa-<element>-attributes. For example the http element would require a section with the id
|
* nsa-<element>-attributes. For example the http element would require a section with the id
|
||||||
* http-attributes.</li>
|
* http-attributes.</li>
|
||||||
* <li>Attribute - Each attribute of an element would have an id of nsa-<element>-<attributeName>. For
|
* <li>Attribute - Each attribute of an element would have an id of nsa-<element>-<attributeName>. For
|
||||||
* example the attribute create-session for the http attribute would have the id http-create-session.</li>
|
* example the attribute create-session for the http attribute would have the id http-create-session.</li>
|
||||||
* <li>Child Section - Any element with a child element will have a section named nsa-<element>-children.
|
* <li>Child Section - Any element with a child element will have a section named nsa-<element>-children.
|
||||||
* For example, authentication-provider would have a section id of nsa-authentication-provider-children. The
|
* For example, authentication-provider would have a section id of nsa-authentication-provider-children. The
|
||||||
* section would then contain a list of links pointing to the documentation for each child element.</li>
|
* section would then contain a list of links pointing to the documentation for each child element.</li>
|
||||||
* </ul>
|
* </ul>
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
def getIds() {
|
def getIds() {
|
||||||
def ids = [id]
|
def ids = [id]
|
||||||
childElmts.values()*.ids.each { ids.addAll it }
|
childElmts.values()*.ids.each { ids.addAll it }
|
||||||
attrs*.id.each { ids.add it }
|
attrs*.id.each { ids.add it }
|
||||||
if(childElmts) {
|
if(childElmts) {
|
||||||
ids.add id+'-children'
|
ids.add id+'-children'
|
||||||
}
|
}
|
||||||
if(attrs) {
|
if(attrs) {
|
||||||
ids.add id+'-attributes'
|
ids.add id+'-attributes'
|
||||||
}
|
}
|
||||||
if(parentElmts) {
|
if(parentElmts) {
|
||||||
ids.add id+'-parents'
|
ids.add id+'-parents'
|
||||||
}
|
}
|
||||||
ids
|
ids
|
||||||
}
|
}
|
||||||
|
|
||||||
def getAllChildElmts() {
|
def getAllChildElmts() {
|
||||||
def result = [:]
|
def result = [:]
|
||||||
childElmts.values()*.subGrps*.each { elmt -> result.put(elmt.name,elmt) }
|
childElmts.values()*.subGrps*.each { elmt -> result.put(elmt.name,elmt) }
|
||||||
result + childElmts
|
result + childElmts
|
||||||
}
|
}
|
||||||
|
|
||||||
def getAllParentElmts() {
|
def getAllParentElmts() {
|
||||||
def result = [:]
|
def result = [:]
|
||||||
parentElmts.values()*.subGrps*.each { elmt -> result.put(elmt.name,elmt) }
|
parentElmts.values()*.subGrps*.each { elmt -> result.put(elmt.name,elmt) }
|
||||||
result + parentElmts
|
result + parentElmts
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,155 +23,155 @@ import groovy.xml.Namespace
|
||||||
* @author Rob Winch
|
* @author Rob Winch
|
||||||
*/
|
*/
|
||||||
class SpringSecurityXsdParser {
|
class SpringSecurityXsdParser {
|
||||||
private def rootElement
|
private def rootElement
|
||||||
|
|
||||||
private def xs = new Namespace("http://www.w3.org/2001/XMLSchema", 'xs')
|
private def xs = new Namespace("http://www.w3.org/2001/XMLSchema", 'xs')
|
||||||
private def attrElmts = [] as Set
|
private def attrElmts = [] as Set
|
||||||
private def elementNameToElement = [:] as Map
|
private def elementNameToElement = [:] as Map
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a map of the element name to the {@link Element}.
|
* Returns a map of the element name to the {@link Element}.
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
Map<String,Element> parse() {
|
Map<String,Element> parse() {
|
||||||
elements(rootElement)
|
elements(rootElement)
|
||||||
elementNameToElement
|
elementNameToElement
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a Map of the name to an Element object of all the children of element.
|
* Creates a Map of the name to an Element object of all the children of element.
|
||||||
*
|
*
|
||||||
* @param element
|
* @param element
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
private def elements(element) {
|
private def elements(element) {
|
||||||
def elementNameToElement = [:] as Map
|
def elementNameToElement = [:] as Map
|
||||||
element.children().each { c->
|
element.children().each { c->
|
||||||
if(c.name() == 'element') {
|
if(c.name() == 'element') {
|
||||||
def e = elmt(c)
|
def e = elmt(c)
|
||||||
elementNameToElement.put(e.name,e)
|
elementNameToElement.put(e.name,e)
|
||||||
} else {
|
} else {
|
||||||
elementNameToElement.putAll(elements(c))
|
elementNameToElement.putAll(elements(c))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
elementNameToElement
|
elementNameToElement
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Any children that are attribute will be returned as an Attribute object.
|
* Any children that are attribute will be returned as an Attribute object.
|
||||||
* @param element
|
* @param element
|
||||||
* @return a collection of Attribute objects that are children of element.
|
* @return a collection of Attribute objects that are children of element.
|
||||||
*/
|
*/
|
||||||
private def attrs(element) {
|
private def attrs(element) {
|
||||||
def r = []
|
def r = []
|
||||||
element.children().each { c->
|
element.children().each { c->
|
||||||
if(c.name() == 'attribute') {
|
if(c.name() == 'attribute') {
|
||||||
r.add(attr(c))
|
r.add(attr(c))
|
||||||
}else if(c.name() == 'element') {
|
}else if(c.name() == 'element') {
|
||||||
}else {
|
}else {
|
||||||
r.addAll(attrs(c))
|
r.addAll(attrs(c))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
r
|
r
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Any children will be searched for an attributeGroup, each of it's children will be returned as an Attribute
|
* Any children will be searched for an attributeGroup, each of it's children will be returned as an Attribute
|
||||||
* @param element
|
* @param element
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
private def attrgrps(element) {
|
private def attrgrps(element) {
|
||||||
def r = []
|
def r = []
|
||||||
element.children().each { c->
|
element.children().each { c->
|
||||||
if(c.name() == 'element') {
|
if(c.name() == 'element') {
|
||||||
}else if (c.name() == 'attributeGroup') {
|
}else if (c.name() == 'attributeGroup') {
|
||||||
if(c.attributes().get('name')) {
|
if(c.attributes().get('name')) {
|
||||||
r.addAll(attrgrp(c))
|
r.addAll(attrgrp(c))
|
||||||
} else {
|
} else {
|
||||||
def n = c.attributes().get('ref').split(':')[1]
|
def n = c.attributes().get('ref').split(':')[1]
|
||||||
def attrGrp = findNode(element,n)
|
def attrGrp = findNode(element,n)
|
||||||
r.addAll(attrgrp(attrGrp))
|
r.addAll(attrgrp(attrGrp))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
r.addAll(attrgrps(c))
|
r.addAll(attrgrps(c))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
r
|
r
|
||||||
}
|
}
|
||||||
|
|
||||||
private def findNode(c,name) {
|
private def findNode(c,name) {
|
||||||
def root = c
|
def root = c
|
||||||
while(root.name() != 'schema') {
|
while(root.name() != 'schema') {
|
||||||
root = root.parent()
|
root = root.parent()
|
||||||
}
|
}
|
||||||
def result = root.breadthFirst().find { child-> name == child.@name?.text() }
|
def result = root.breadthFirst().find { child-> name == child.@name?.text() }
|
||||||
assert result?.@name?.text() == name
|
assert result?.@name?.text() == name
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Processes an individual attributeGroup by obtaining all the attributes and then looking for more attributeGroup elements and prcessing them.
|
* Processes an individual attributeGroup by obtaining all the attributes and then looking for more attributeGroup elements and prcessing them.
|
||||||
* @param e
|
* @param e
|
||||||
* @return all the attributes for a specific attributeGroup and any child attributeGroups
|
* @return all the attributes for a specific attributeGroup and any child attributeGroups
|
||||||
*/
|
*/
|
||||||
private def attrgrp(e) {
|
private def attrgrp(e) {
|
||||||
def attrs = attrs(e)
|
def attrs = attrs(e)
|
||||||
attrs.addAll(attrgrps(e))
|
attrs.addAll(attrgrps(e))
|
||||||
attrs
|
attrs
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Obtains the description for a specific element
|
* Obtains the description for a specific element
|
||||||
* @param element
|
* @param element
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
private def desc(element) {
|
private def desc(element) {
|
||||||
return element['annotation']['documentation']
|
return element['annotation']['documentation']
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Given an element creates an attribute from it.
|
* Given an element creates an attribute from it.
|
||||||
* @param n
|
* @param n
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
private def attr(n) {
|
private def attr(n) {
|
||||||
new Attribute(desc: desc(n), name: n.@name.text())
|
new Attribute(desc: desc(n), name: n.@name.text())
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Given an element creates an Element out of it by collecting all its attributes and child elements.
|
* Given an element creates an Element out of it by collecting all its attributes and child elements.
|
||||||
*
|
*
|
||||||
* @param n
|
* @param n
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
private def elmt(n) {
|
private def elmt(n) {
|
||||||
def name = n.@ref.text()
|
def name = n.@ref.text()
|
||||||
if(name) {
|
if(name) {
|
||||||
name = name.split(':')[1]
|
name = name.split(':')[1]
|
||||||
n = findNode(n,name)
|
n = findNode(n,name)
|
||||||
} else {
|
} else {
|
||||||
name = n.@name.text()
|
name = n.@name.text()
|
||||||
}
|
}
|
||||||
if(elementNameToElement.containsKey(name)) {
|
if(elementNameToElement.containsKey(name)) {
|
||||||
return elementNameToElement.get(name)
|
return elementNameToElement.get(name)
|
||||||
}
|
}
|
||||||
attrElmts.add(name)
|
attrElmts.add(name)
|
||||||
def e = new Element()
|
def e = new Element()
|
||||||
e.name = n.@name.text()
|
e.name = n.@name.text()
|
||||||
e.desc = desc(n)
|
e.desc = desc(n)
|
||||||
e.childElmts = elements(n)
|
e.childElmts = elements(n)
|
||||||
e.attrs = attrs(n)
|
e.attrs = attrs(n)
|
||||||
e.attrs.addAll(attrgrps(n))
|
e.attrs.addAll(attrgrps(n))
|
||||||
e.attrs*.elmt = e
|
e.attrs*.elmt = e
|
||||||
e.childElmts.values()*.each { it.parentElmts.put(e.name,e) }
|
e.childElmts.values()*.each { it.parentElmts.put(e.name,e) }
|
||||||
|
|
||||||
def subGrpName = n.@substitutionGroup.text()
|
def subGrpName = n.@substitutionGroup.text()
|
||||||
if(subGrpName) {
|
if(subGrpName) {
|
||||||
def subGrp = elmt(findNode(n,subGrpName.split(":")[1]))
|
def subGrp = elmt(findNode(n,subGrpName.split(":")[1]))
|
||||||
subGrp.subGrps.add(e)
|
subGrp.subGrps.add(e)
|
||||||
}
|
}
|
||||||
|
|
||||||
elementNameToElement.put(name,e)
|
elementNameToElement.put(name,e)
|
||||||
e
|
e
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,167 +29,167 @@ import spock.lang.*
|
||||||
*/
|
*/
|
||||||
class XsdDocumentedTests extends Specification {
|
class XsdDocumentedTests extends Specification {
|
||||||
|
|
||||||
def ignoredIds = ['nsa-any-user-service','nsa-any-user-service-parents','nsa-authentication','nsa-websocket-security','nsa-ldap','nsa-method-security','nsa-web']
|
def ignoredIds = ['nsa-any-user-service','nsa-any-user-service-parents','nsa-authentication','nsa-websocket-security','nsa-ldap','nsa-method-security','nsa-web']
|
||||||
@Shared def reference = new File('../docs/manual/src/docs/asciidoc/index.adoc')
|
@Shared def reference = new File('../docs/manual/src/docs/asciidoc/index.adoc')
|
||||||
|
|
||||||
@Shared File schema31xDocument = new File('src/main/resources/org/springframework/security/config/spring-security-3.1.xsd')
|
@Shared File schema31xDocument = new File('src/main/resources/org/springframework/security/config/spring-security-3.1.xsd')
|
||||||
@Shared File schemaDocument = new File('src/main/resources/org/springframework/security/config/spring-security-4.0.xsd')
|
@Shared File schemaDocument = new File('src/main/resources/org/springframework/security/config/spring-security-4.0.xsd')
|
||||||
@Shared Map<String,Element> elementNameToElement
|
@Shared Map<String,Element> elementNameToElement
|
||||||
@Shared GPathResult schemaRootElement
|
@Shared GPathResult schemaRootElement
|
||||||
|
|
||||||
def setupSpec() {
|
def setupSpec() {
|
||||||
schemaRootElement = new XmlSlurper().parse(schemaDocument)
|
schemaRootElement = new XmlSlurper().parse(schemaDocument)
|
||||||
elementNameToElement = new SpringSecurityXsdParser(rootElement: schemaRootElement).parse()
|
elementNameToElement = new SpringSecurityXsdParser(rootElement: schemaRootElement).parse()
|
||||||
}
|
}
|
||||||
|
|
||||||
def cleanupSpec() {
|
def cleanupSpec() {
|
||||||
reference = null
|
reference = null
|
||||||
schema31xDocument = null
|
schema31xDocument = null
|
||||||
schemaDocument = null
|
schemaDocument = null
|
||||||
elementNameToElement = null
|
elementNameToElement = null
|
||||||
schemaRootElement = null
|
schemaRootElement = null
|
||||||
}
|
}
|
||||||
|
|
||||||
def 'SEC-2139: named-security-filter are all defined and ordered properly'() {
|
def 'SEC-2139: named-security-filter are all defined and ordered properly'() {
|
||||||
setup:
|
setup:
|
||||||
def expectedFilters = (EnumSet.allOf(SecurityFilters) as List).sort { it.order }
|
def expectedFilters = (EnumSet.allOf(SecurityFilters) as List).sort { it.order }
|
||||||
when:
|
when:
|
||||||
def nsf = schemaRootElement.simpleType.find { it.@name == 'named-security-filter' }
|
def nsf = schemaRootElement.simpleType.find { it.@name == 'named-security-filter' }
|
||||||
def nsfValues = nsf.children().children().collect { c ->
|
def nsfValues = nsf.children().children().collect { c ->
|
||||||
Enum.valueOf(SecurityFilters, c.@value.toString())
|
Enum.valueOf(SecurityFilters, c.@value.toString())
|
||||||
}
|
}
|
||||||
then:
|
then:
|
||||||
expectedFilters == nsfValues
|
expectedFilters == nsfValues
|
||||||
}
|
}
|
||||||
|
|
||||||
def 'SEC-2139: 3.1.x named-security-filter are all defined and ordered properly'() {
|
def 'SEC-2139: 3.1.x named-security-filter are all defined and ordered properly'() {
|
||||||
setup:
|
setup:
|
||||||
def expectedFilters = ["FIRST", "CHANNEL_FILTER", "SECURITY_CONTEXT_FILTER", "CONCURRENT_SESSION_FILTER", "LOGOUT_FILTER", "X509_FILTER",
|
def expectedFilters = ["FIRST", "CHANNEL_FILTER", "SECURITY_CONTEXT_FILTER", "CONCURRENT_SESSION_FILTER", "LOGOUT_FILTER", "X509_FILTER",
|
||||||
"PRE_AUTH_FILTER", "CAS_FILTER", "FORM_LOGIN_FILTER", "OPENID_FILTER", "LOGIN_PAGE_FILTER", "DIGEST_AUTH_FILTER","BASIC_AUTH_FILTER",
|
"PRE_AUTH_FILTER", "CAS_FILTER", "FORM_LOGIN_FILTER", "OPENID_FILTER", "LOGIN_PAGE_FILTER", "DIGEST_AUTH_FILTER","BASIC_AUTH_FILTER",
|
||||||
"REQUEST_CACHE_FILTER", "SERVLET_API_SUPPORT_FILTER", "JAAS_API_SUPPORT_FILTER", "REMEMBER_ME_FILTER", "ANONYMOUS_FILTER",
|
"REQUEST_CACHE_FILTER", "SERVLET_API_SUPPORT_FILTER", "JAAS_API_SUPPORT_FILTER", "REMEMBER_ME_FILTER", "ANONYMOUS_FILTER",
|
||||||
"SESSION_MANAGEMENT_FILTER", "EXCEPTION_TRANSLATION_FILTER", "FILTER_SECURITY_INTERCEPTOR", "SWITCH_USER_FILTER", "LAST"].collect {
|
"SESSION_MANAGEMENT_FILTER", "EXCEPTION_TRANSLATION_FILTER", "FILTER_SECURITY_INTERCEPTOR", "SWITCH_USER_FILTER", "LAST"].collect {
|
||||||
Enum.valueOf(SecurityFilters, it)
|
Enum.valueOf(SecurityFilters, it)
|
||||||
}
|
}
|
||||||
def schema31xRootElement = new XmlSlurper().parse(schema31xDocument)
|
def schema31xRootElement = new XmlSlurper().parse(schema31xDocument)
|
||||||
when:
|
when:
|
||||||
def nsf = schema31xRootElement.simpleType.find { it.@name == 'named-security-filter' }
|
def nsf = schema31xRootElement.simpleType.find { it.@name == 'named-security-filter' }
|
||||||
def nsfValues = nsf.children().children().collect { c ->
|
def nsfValues = nsf.children().children().collect { c ->
|
||||||
Enum.valueOf(SecurityFilters, c.@value.toString())
|
Enum.valueOf(SecurityFilters, c.@value.toString())
|
||||||
}
|
}
|
||||||
then:
|
then:
|
||||||
expectedFilters == nsfValues
|
expectedFilters == nsfValues
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This will check to ensure that the expected number of xsd documents are found to ensure that we are validating
|
* This will check to ensure that the expected number of xsd documents are found to ensure that we are validating
|
||||||
* against the current xsd document. If this test fails, all that is needed is to update the schemaDocument
|
* against the current xsd document. If this test fails, all that is needed is to update the schemaDocument
|
||||||
* and the expected size for this test.
|
* and the expected size for this test.
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
def 'the latest schema is being validated'() {
|
def 'the latest schema is being validated'() {
|
||||||
when: 'all the schemas are found'
|
when: 'all the schemas are found'
|
||||||
def schemas = schemaDocument.getParentFile().list().findAll { it.endsWith('.xsd') }
|
def schemas = schemaDocument.getParentFile().list().findAll { it.endsWith('.xsd') }
|
||||||
then: 'the count is equal to 8, if not then schemaDocument needs updated'
|
then: 'the count is equal to 8, if not then schemaDocument needs updated'
|
||||||
schemas.size() == 9
|
schemas.size() == 9
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This uses a naming convention for the ids of the appendix to ensure that the entire appendix is documented.
|
* This uses a naming convention for the ids of the appendix to ensure that the entire appendix is documented.
|
||||||
* The naming convention for the ids is documented in {@link Element#getIds()}.
|
* The naming convention for the ids is documented in {@link Element#getIds()}.
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
def 'the entire schema is included in the appendix documentation'() {
|
def 'the entire schema is included in the appendix documentation'() {
|
||||||
setup: 'get all the documented ids and the expected ids'
|
setup: 'get all the documented ids and the expected ids'
|
||||||
def documentedIds = []
|
def documentedIds = []
|
||||||
reference.eachLine { line ->
|
reference.eachLine { line ->
|
||||||
if(line.matches("\\[\\[(nsa-.*)\\]\\]")) {
|
if(line.matches("\\[\\[(nsa-.*)\\]\\]")) {
|
||||||
documentedIds.add(line.substring(2,line.length() - 2))
|
documentedIds.add(line.substring(2,line.length() - 2))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
when: 'the schema is compared to the appendix documentation'
|
when: 'the schema is compared to the appendix documentation'
|
||||||
def expectedIds = [] as Set
|
def expectedIds = [] as Set
|
||||||
elementNameToElement*.value*.ids*.each { expectedIds.addAll it }
|
elementNameToElement*.value*.ids*.each { expectedIds.addAll it }
|
||||||
documentedIds.removeAll ignoredIds
|
documentedIds.removeAll ignoredIds
|
||||||
expectedIds.removeAll ignoredIds
|
expectedIds.removeAll ignoredIds
|
||||||
def undocumentedIds = (expectedIds - documentedIds)
|
def undocumentedIds = (expectedIds - documentedIds)
|
||||||
def shouldNotBeDocumented = (documentedIds - expectedIds)
|
def shouldNotBeDocumented = (documentedIds - expectedIds)
|
||||||
then: 'all the elements and attributes are documented'
|
then: 'all the elements and attributes are documented'
|
||||||
shouldNotBeDocumented.empty
|
shouldNotBeDocumented.empty
|
||||||
undocumentedIds.empty
|
undocumentedIds.empty
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This test ensures that any element that has children or parents contains a section that has links pointing to that
|
* This test ensures that any element that has children or parents contains a section that has links pointing to that
|
||||||
* documentation.
|
* documentation.
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
def 'validate parents and children are linked in the appendix documentation'() {
|
def 'validate parents and children are linked in the appendix documentation'() {
|
||||||
when: "get all the links for each element's children and parents"
|
when: "get all the links for each element's children and parents"
|
||||||
def docAttrNameToChildren = [:]
|
def docAttrNameToChildren = [:]
|
||||||
def docAttrNameToParents = [:]
|
def docAttrNameToParents = [:]
|
||||||
|
|
||||||
def currentDocAttrNameToElmt
|
def currentDocAttrNameToElmt
|
||||||
def docAttrName
|
def docAttrName
|
||||||
|
|
||||||
reference.eachLine { line ->
|
reference.eachLine { line ->
|
||||||
if(line.matches('^\\[\\[.*\\]\\]$')) {
|
if(line.matches('^\\[\\[.*\\]\\]$')) {
|
||||||
def id = line.substring(2,line.length() - 2)
|
def id = line.substring(2,line.length() - 2)
|
||||||
if(id.endsWith("-children")) {
|
if(id.endsWith("-children")) {
|
||||||
docAttrName = id.substring(0,id.length() - 9)
|
docAttrName = id.substring(0,id.length() - 9)
|
||||||
currentDocAttrNameToElmt = docAttrNameToChildren
|
currentDocAttrNameToElmt = docAttrNameToChildren
|
||||||
} else if(id.endsWith("-parents")) {
|
} else if(id.endsWith("-parents")) {
|
||||||
docAttrName = id.substring(0,id.length() - 8)
|
docAttrName = id.substring(0,id.length() - 8)
|
||||||
currentDocAttrNameToElmt = docAttrNameToParents
|
currentDocAttrNameToElmt = docAttrNameToParents
|
||||||
} else if(docAttrName && !id.startsWith(docAttrName)) {
|
} else if(docAttrName && !id.startsWith(docAttrName)) {
|
||||||
currentDocAttrNameToElmt = null
|
currentDocAttrNameToElmt = null
|
||||||
docAttrName = null
|
docAttrName = null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(docAttrName) {
|
if(docAttrName) {
|
||||||
def expression = '^\\* <<(nsa-.*),.*>>$'
|
def expression = '^\\* <<(nsa-.*),.*>>$'
|
||||||
if(line.matches(expression)) {
|
if(line.matches(expression)) {
|
||||||
String elmtId = line.replaceAll(expression, '$1')
|
String elmtId = line.replaceAll(expression, '$1')
|
||||||
currentDocAttrNameToElmt.get(docAttrName, []).add(elmtId)
|
currentDocAttrNameToElmt.get(docAttrName, []).add(elmtId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
def schemaAttrNameToParents = [:]
|
def schemaAttrNameToParents = [:]
|
||||||
def schemaAttrNameToChildren = [:]
|
def schemaAttrNameToChildren = [:]
|
||||||
elementNameToElement.each { entry ->
|
elementNameToElement.each { entry ->
|
||||||
def key = 'nsa-'+entry.key
|
def key = 'nsa-'+entry.key
|
||||||
if(ignoredIds.contains(key)) {
|
if(ignoredIds.contains(key)) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
def parentIds = entry.value.allParentElmts.values()*.id.findAll { !ignoredIds.contains(it) }.sort()
|
def parentIds = entry.value.allParentElmts.values()*.id.findAll { !ignoredIds.contains(it) }.sort()
|
||||||
if(parentIds) {
|
if(parentIds) {
|
||||||
schemaAttrNameToParents.put(key,parentIds)
|
schemaAttrNameToParents.put(key,parentIds)
|
||||||
}
|
}
|
||||||
def childIds = entry.value.allChildElmts.values()*.id.findAll { !ignoredIds.contains(it) }.sort()
|
def childIds = entry.value.allChildElmts.values()*.id.findAll { !ignoredIds.contains(it) }.sort()
|
||||||
if(childIds) {
|
if(childIds) {
|
||||||
schemaAttrNameToChildren.put(key,childIds)
|
schemaAttrNameToChildren.put(key,childIds)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
then: "the expected parents and children are all documented"
|
then: "the expected parents and children are all documented"
|
||||||
schemaAttrNameToChildren.sort() == docAttrNameToChildren.sort()
|
schemaAttrNameToChildren.sort() == docAttrNameToChildren.sort()
|
||||||
schemaAttrNameToParents.sort() == docAttrNameToParents.sort()
|
schemaAttrNameToParents.sort() == docAttrNameToParents.sort()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This test checks each xsd element and ensures there is documentation for it.
|
* This test checks each xsd element and ensures there is documentation for it.
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
def 'entire xsd is documented'() {
|
def 'entire xsd is documented'() {
|
||||||
when: "validate that the entire xsd contains documentation"
|
when: "validate that the entire xsd contains documentation"
|
||||||
def notDocElmtIds = elementNameToElement.values().findAll {
|
def notDocElmtIds = elementNameToElement.values().findAll {
|
||||||
!it.desc.text() && !ignoredIds.contains(it.id)
|
!it.desc.text() && !ignoredIds.contains(it.id)
|
||||||
}*.id.sort().join("\n")
|
}*.id.sort().join("\n")
|
||||||
def notDocAttrIds = elementNameToElement.values()*.attrs.flatten().findAll {
|
def notDocAttrIds = elementNameToElement.values()*.attrs.flatten().findAll {
|
||||||
!it.desc.text() && !ignoredIds.contains(it.id)
|
!it.desc.text() && !ignoredIds.contains(it.id)
|
||||||
}*.id.sort().join("\n")
|
}*.id.sort().join("\n")
|
||||||
then: "all the elements and attributes have some documentation"
|
then: "all the elements and attributes have some documentation"
|
||||||
!notDocElmtIds
|
!notDocElmtIds
|
||||||
!notDocAttrIds
|
!notDocAttrIds
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,55 +28,55 @@ import javax.servlet.http.HttpServletRequest
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
abstract class AbstractHttpConfigTests extends AbstractXmlConfigTests {
|
abstract class AbstractHttpConfigTests extends AbstractXmlConfigTests {
|
||||||
final int AUTO_CONFIG_FILTERS = 14;
|
final int AUTO_CONFIG_FILTERS = 14;
|
||||||
|
|
||||||
def httpAutoConfig(Closure c) {
|
def httpAutoConfig(Closure c) {
|
||||||
xml.http(['auto-config': 'true', 'use-expressions':false], c)
|
xml.http(['auto-config': 'true', 'use-expressions':false], c)
|
||||||
}
|
}
|
||||||
|
|
||||||
def httpAutoConfig(String matcher, Closure c) {
|
def httpAutoConfig(String matcher, Closure c) {
|
||||||
xml.http(['auto-config': 'true', 'use-expressions':false, 'request-matcher': matcher], c)
|
xml.http(['auto-config': 'true', 'use-expressions':false, 'request-matcher': matcher], c)
|
||||||
}
|
}
|
||||||
|
|
||||||
def interceptUrl(String path, String authz) {
|
def interceptUrl(String path, String authz) {
|
||||||
xml.'intercept-url'(pattern: path, access: authz)
|
xml.'intercept-url'(pattern: path, access: authz)
|
||||||
}
|
}
|
||||||
|
|
||||||
def interceptUrl(String path, String httpMethod, String authz) {
|
def interceptUrl(String path, String httpMethod, String authz) {
|
||||||
xml.'intercept-url'(pattern: path, method: httpMethod, access: authz)
|
xml.'intercept-url'(pattern: path, method: httpMethod, access: authz)
|
||||||
}
|
}
|
||||||
|
|
||||||
Filter getFilter(Class type) {
|
Filter getFilter(Class type) {
|
||||||
List filters = getFilters("/any");
|
List filters = getFilters("/any");
|
||||||
|
|
||||||
for (f in filters) {
|
for (f in filters) {
|
||||||
if (f.class.isAssignableFrom(type)) {
|
if (f.class.isAssignableFrom(type)) {
|
||||||
return f;
|
return f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
List getFilters(String url) {
|
List getFilters(String url) {
|
||||||
springSecurityFilterChain.getFilters(url)
|
springSecurityFilterChain.getFilters(url)
|
||||||
}
|
}
|
||||||
|
|
||||||
Filter getSpringSecurityFilterChain() {
|
Filter getSpringSecurityFilterChain() {
|
||||||
appContext.getBean(BeanIds.FILTER_CHAIN_PROXY)
|
appContext.getBean(BeanIds.FILTER_CHAIN_PROXY)
|
||||||
}
|
}
|
||||||
|
|
||||||
FilterInvocation createFilterinvocation(String path, String method) {
|
FilterInvocation createFilterinvocation(String path, String method) {
|
||||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||||
request.setMethod(method);
|
request.setMethod(method);
|
||||||
request.setRequestURI(null);
|
request.setRequestURI(null);
|
||||||
request.setServletPath(path);
|
request.setServletPath(path);
|
||||||
|
|
||||||
return new FilterInvocation(request, new MockHttpServletResponse(), new MockFilterChain());
|
return new FilterInvocation(request, new MockHttpServletResponse(), new MockFilterChain());
|
||||||
}
|
}
|
||||||
|
|
||||||
def basicLogin(HttpServletRequest request, String username="user",String password="password") {
|
def basicLogin(HttpServletRequest request, String username="user",String password="password") {
|
||||||
def credentials = username + ":" + password
|
def credentials = username + ":" + password
|
||||||
request.addHeader("Authorization", "Basic " + credentials.bytes.encodeBase64())
|
request.addHeader("Authorization", "Basic " + credentials.bytes.encodeBase64())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,38 +10,38 @@ import org.springframework.security.web.access.ExceptionTranslationFilter
|
||||||
* @author Luke Taylor
|
* @author Luke Taylor
|
||||||
*/
|
*/
|
||||||
class AccessDeniedConfigTests extends AbstractHttpConfigTests {
|
class AccessDeniedConfigTests extends AbstractHttpConfigTests {
|
||||||
def invalidAccessDeniedUrlIsDetected() {
|
def invalidAccessDeniedUrlIsDetected() {
|
||||||
when:
|
when:
|
||||||
httpAutoConfig() {
|
httpAutoConfig() {
|
||||||
'access-denied-handler'('error-page':'noLeadingSlash')
|
'access-denied-handler'('error-page':'noLeadingSlash')
|
||||||
}
|
}
|
||||||
createAppContext();
|
createAppContext();
|
||||||
then:
|
then:
|
||||||
thrown(BeanCreationException)
|
thrown(BeanCreationException)
|
||||||
}
|
}
|
||||||
|
|
||||||
def accessDeniedHandlerIsSetCorectly() {
|
def accessDeniedHandlerIsSetCorectly() {
|
||||||
httpAutoConfig() {
|
httpAutoConfig() {
|
||||||
'access-denied-handler'(ref: 'adh')
|
'access-denied-handler'(ref: 'adh')
|
||||||
}
|
}
|
||||||
bean('adh', AccessDeniedHandlerImpl)
|
bean('adh', AccessDeniedHandlerImpl)
|
||||||
createAppContext();
|
createAppContext();
|
||||||
|
|
||||||
def filter = getFilter(ExceptionTranslationFilter.class);
|
def filter = getFilter(ExceptionTranslationFilter.class);
|
||||||
def adh = appContext.getBean("adh");
|
def adh = appContext.getBean("adh");
|
||||||
|
|
||||||
expect:
|
expect:
|
||||||
filter.accessDeniedHandler == adh
|
filter.accessDeniedHandler == adh
|
||||||
}
|
}
|
||||||
|
|
||||||
def void accessDeniedHandlerPageAndRefAreMutuallyExclusive() {
|
def void accessDeniedHandlerPageAndRefAreMutuallyExclusive() {
|
||||||
when:
|
when:
|
||||||
httpAutoConfig {
|
httpAutoConfig {
|
||||||
'access-denied-handler'('error-page': '/go-away', ref: 'adh')
|
'access-denied-handler'('error-page': '/go-away', ref: 'adh')
|
||||||
}
|
}
|
||||||
createAppContext();
|
createAppContext();
|
||||||
bean('adh', AccessDeniedHandlerImpl)
|
bean('adh', AccessDeniedHandlerImpl)
|
||||||
then:
|
then:
|
||||||
thrown(BeanDefinitionParsingException)
|
thrown(BeanDefinitionParsingException)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,303 +43,303 @@ import spock.lang.Unroll
|
||||||
* @author Rob Winch
|
* @author Rob Winch
|
||||||
*/
|
*/
|
||||||
class CsrfConfigTests extends AbstractHttpConfigTests {
|
class CsrfConfigTests extends AbstractHttpConfigTests {
|
||||||
MockHttpServletRequest request = new MockHttpServletRequest()
|
MockHttpServletRequest request = new MockHttpServletRequest()
|
||||||
MockHttpServletResponse response = new MockHttpServletResponse()
|
MockHttpServletResponse response = new MockHttpServletResponse()
|
||||||
MockFilterChain chain = new MockFilterChain()
|
MockFilterChain chain = new MockFilterChain()
|
||||||
|
|
||||||
@Unroll
|
@Unroll
|
||||||
def 'csrf is enabled by default'() {
|
def 'csrf is enabled by default'() {
|
||||||
setup:
|
setup:
|
||||||
httpAutoConfig {
|
httpAutoConfig {
|
||||||
}
|
}
|
||||||
createAppContext()
|
createAppContext()
|
||||||
when:
|
when:
|
||||||
request.method = httpMethod
|
request.method = httpMethod
|
||||||
springSecurityFilterChain.doFilter(request,response,chain)
|
springSecurityFilterChain.doFilter(request,response,chain)
|
||||||
then:
|
then:
|
||||||
response.status == httpStatus
|
response.status == httpStatus
|
||||||
where:
|
where:
|
||||||
httpMethod | httpStatus
|
httpMethod | httpStatus
|
||||||
'POST' | HttpServletResponse.SC_FORBIDDEN
|
'POST' | HttpServletResponse.SC_FORBIDDEN
|
||||||
'PUT' | HttpServletResponse.SC_FORBIDDEN
|
'PUT' | HttpServletResponse.SC_FORBIDDEN
|
||||||
'PATCH' | HttpServletResponse.SC_FORBIDDEN
|
'PATCH' | HttpServletResponse.SC_FORBIDDEN
|
||||||
'DELETE' | HttpServletResponse.SC_FORBIDDEN
|
'DELETE' | HttpServletResponse.SC_FORBIDDEN
|
||||||
'INVALID' | HttpServletResponse.SC_FORBIDDEN
|
'INVALID' | HttpServletResponse.SC_FORBIDDEN
|
||||||
'GET' | HttpServletResponse.SC_OK
|
'GET' | HttpServletResponse.SC_OK
|
||||||
'HEAD' | HttpServletResponse.SC_OK
|
'HEAD' | HttpServletResponse.SC_OK
|
||||||
'TRACE' | HttpServletResponse.SC_OK
|
'TRACE' | HttpServletResponse.SC_OK
|
||||||
'OPTIONS' | HttpServletResponse.SC_OK
|
'OPTIONS' | HttpServletResponse.SC_OK
|
||||||
}
|
}
|
||||||
|
|
||||||
def 'csrf disabled'() {
|
def 'csrf disabled'() {
|
||||||
when:
|
when:
|
||||||
httpAutoConfig {
|
httpAutoConfig {
|
||||||
csrf(disabled:true)
|
csrf(disabled:true)
|
||||||
}
|
}
|
||||||
createAppContext()
|
createAppContext()
|
||||||
then:
|
then:
|
||||||
!getFilter(CsrfFilter)
|
!getFilter(CsrfFilter)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Unroll
|
@Unroll
|
||||||
def 'csrf defaults'() {
|
def 'csrf defaults'() {
|
||||||
setup:
|
setup:
|
||||||
httpAutoConfig {
|
httpAutoConfig {
|
||||||
'csrf'()
|
'csrf'()
|
||||||
}
|
}
|
||||||
createAppContext()
|
createAppContext()
|
||||||
when:
|
when:
|
||||||
request.method = httpMethod
|
request.method = httpMethod
|
||||||
springSecurityFilterChain.doFilter(request,response,chain)
|
springSecurityFilterChain.doFilter(request,response,chain)
|
||||||
then:
|
then:
|
||||||
response.status == httpStatus
|
response.status == httpStatus
|
||||||
where:
|
where:
|
||||||
httpMethod | httpStatus
|
httpMethod | httpStatus
|
||||||
'POST' | HttpServletResponse.SC_FORBIDDEN
|
'POST' | HttpServletResponse.SC_FORBIDDEN
|
||||||
'PUT' | HttpServletResponse.SC_FORBIDDEN
|
'PUT' | HttpServletResponse.SC_FORBIDDEN
|
||||||
'PATCH' | HttpServletResponse.SC_FORBIDDEN
|
'PATCH' | HttpServletResponse.SC_FORBIDDEN
|
||||||
'DELETE' | HttpServletResponse.SC_FORBIDDEN
|
'DELETE' | HttpServletResponse.SC_FORBIDDEN
|
||||||
'INVALID' | HttpServletResponse.SC_FORBIDDEN
|
'INVALID' | HttpServletResponse.SC_FORBIDDEN
|
||||||
'GET' | HttpServletResponse.SC_OK
|
'GET' | HttpServletResponse.SC_OK
|
||||||
'HEAD' | HttpServletResponse.SC_OK
|
'HEAD' | HttpServletResponse.SC_OK
|
||||||
'TRACE' | HttpServletResponse.SC_OK
|
'TRACE' | HttpServletResponse.SC_OK
|
||||||
'OPTIONS' | HttpServletResponse.SC_OK
|
'OPTIONS' | HttpServletResponse.SC_OK
|
||||||
}
|
}
|
||||||
|
|
||||||
def 'csrf default creates CsrfRequestDataValueProcessor'() {
|
def 'csrf default creates CsrfRequestDataValueProcessor'() {
|
||||||
when:
|
when:
|
||||||
httpAutoConfig {
|
httpAutoConfig {
|
||||||
'csrf'()
|
'csrf'()
|
||||||
}
|
}
|
||||||
createAppContext()
|
createAppContext()
|
||||||
then:
|
then:
|
||||||
appContext.getBean("requestDataValueProcessor",RequestDataValueProcessor)
|
appContext.getBean("requestDataValueProcessor",RequestDataValueProcessor)
|
||||||
}
|
}
|
||||||
|
|
||||||
def 'csrf custom AccessDeniedHandler'() {
|
def 'csrf custom AccessDeniedHandler'() {
|
||||||
setup:
|
setup:
|
||||||
httpAutoConfig {
|
httpAutoConfig {
|
||||||
'access-denied-handler'(ref:'adh')
|
'access-denied-handler'(ref:'adh')
|
||||||
'csrf'()
|
'csrf'()
|
||||||
}
|
}
|
||||||
mockBean(AccessDeniedHandler,'adh')
|
mockBean(AccessDeniedHandler,'adh')
|
||||||
createAppContext()
|
createAppContext()
|
||||||
AccessDeniedHandler adh = appContext.getBean(AccessDeniedHandler)
|
AccessDeniedHandler adh = appContext.getBean(AccessDeniedHandler)
|
||||||
request.method = "POST"
|
request.method = "POST"
|
||||||
when:
|
when:
|
||||||
springSecurityFilterChain.doFilter(request,response,chain)
|
springSecurityFilterChain.doFilter(request,response,chain)
|
||||||
then:
|
then:
|
||||||
verify(adh).handle(any(HttpServletRequest),any(HttpServletResponse),any(AccessDeniedException))
|
verify(adh).handle(any(HttpServletRequest),any(HttpServletResponse),any(AccessDeniedException))
|
||||||
response.status == HttpServletResponse.SC_OK // our mock doesn't do anything
|
response.status == HttpServletResponse.SC_OK // our mock doesn't do anything
|
||||||
}
|
}
|
||||||
|
|
||||||
def "csrf disables posts for RequestCache"() {
|
def "csrf disables posts for RequestCache"() {
|
||||||
setup:
|
setup:
|
||||||
httpAutoConfig {
|
httpAutoConfig {
|
||||||
'csrf'('token-repository-ref':'repo')
|
'csrf'('token-repository-ref':'repo')
|
||||||
'intercept-url'(pattern:"/**",access:'ROLE_USER')
|
'intercept-url'(pattern:"/**",access:'ROLE_USER')
|
||||||
}
|
}
|
||||||
mockBean(CsrfTokenRepository,'repo')
|
mockBean(CsrfTokenRepository,'repo')
|
||||||
createAppContext()
|
createAppContext()
|
||||||
CsrfTokenRepository repo = appContext.getBean("repo",CsrfTokenRepository)
|
CsrfTokenRepository repo = appContext.getBean("repo",CsrfTokenRepository)
|
||||||
CsrfToken token = new DefaultCsrfToken("X-CSRF-TOKEN","_csrf", "abc")
|
CsrfToken token = new DefaultCsrfToken("X-CSRF-TOKEN","_csrf", "abc")
|
||||||
when(repo.loadToken(any(HttpServletRequest))).thenReturn(token)
|
when(repo.loadToken(any(HttpServletRequest))).thenReturn(token)
|
||||||
when(repo.generateToken(any(HttpServletRequest))).thenReturn(token)
|
when(repo.generateToken(any(HttpServletRequest))).thenReturn(token)
|
||||||
request.setParameter(token.parameterName,token.token)
|
request.setParameter(token.parameterName,token.token)
|
||||||
request.servletPath = "/some-url"
|
request.servletPath = "/some-url"
|
||||||
request.requestURI = "/some-url"
|
request.requestURI = "/some-url"
|
||||||
request.method = "POST"
|
request.method = "POST"
|
||||||
when: "CSRF passes and our session times out"
|
when: "CSRF passes and our session times out"
|
||||||
springSecurityFilterChain.doFilter(request,response,chain)
|
springSecurityFilterChain.doFilter(request,response,chain)
|
||||||
then: "sent to the login page"
|
then: "sent to the login page"
|
||||||
response.status == HttpServletResponse.SC_MOVED_TEMPORARILY
|
response.status == HttpServletResponse.SC_MOVED_TEMPORARILY
|
||||||
response.redirectedUrl == "http://localhost/login"
|
response.redirectedUrl == "http://localhost/login"
|
||||||
when: "authenticate successfully"
|
when: "authenticate successfully"
|
||||||
response = new MockHttpServletResponse()
|
response = new MockHttpServletResponse()
|
||||||
request = new MockHttpServletRequest(session: request.session)
|
request = new MockHttpServletRequest(session: request.session)
|
||||||
request.servletPath = "/login"
|
request.servletPath = "/login"
|
||||||
request.setParameter(token.parameterName,token.token)
|
request.setParameter(token.parameterName,token.token)
|
||||||
request.setParameter("username","user")
|
request.setParameter("username","user")
|
||||||
request.setParameter("password","password")
|
request.setParameter("password","password")
|
||||||
request.method = "POST"
|
request.method = "POST"
|
||||||
springSecurityFilterChain.doFilter(request,response,chain)
|
springSecurityFilterChain.doFilter(request,response,chain)
|
||||||
then: "sent to default success because we don't want csrf attempts made prior to authentication to pass"
|
then: "sent to default success because we don't want csrf attempts made prior to authentication to pass"
|
||||||
response.status == HttpServletResponse.SC_MOVED_TEMPORARILY
|
response.status == HttpServletResponse.SC_MOVED_TEMPORARILY
|
||||||
response.redirectedUrl == "/"
|
response.redirectedUrl == "/"
|
||||||
}
|
}
|
||||||
|
|
||||||
def "csrf enables gets for RequestCache"() {
|
def "csrf enables gets for RequestCache"() {
|
||||||
setup:
|
setup:
|
||||||
httpAutoConfig {
|
httpAutoConfig {
|
||||||
'csrf'('token-repository-ref':'repo')
|
'csrf'('token-repository-ref':'repo')
|
||||||
'intercept-url'(pattern:"/**",access:'ROLE_USER')
|
'intercept-url'(pattern:"/**",access:'ROLE_USER')
|
||||||
}
|
}
|
||||||
mockBean(CsrfTokenRepository,'repo')
|
mockBean(CsrfTokenRepository,'repo')
|
||||||
createAppContext()
|
createAppContext()
|
||||||
CsrfTokenRepository repo = appContext.getBean("repo",CsrfTokenRepository)
|
CsrfTokenRepository repo = appContext.getBean("repo",CsrfTokenRepository)
|
||||||
CsrfToken token = new DefaultCsrfToken("X-CSRF-TOKEN","_csrf", "abc")
|
CsrfToken token = new DefaultCsrfToken("X-CSRF-TOKEN","_csrf", "abc")
|
||||||
when(repo.loadToken(any(HttpServletRequest))).thenReturn(token)
|
when(repo.loadToken(any(HttpServletRequest))).thenReturn(token)
|
||||||
when(repo.generateToken(any(HttpServletRequest))).thenReturn(token)
|
when(repo.generateToken(any(HttpServletRequest))).thenReturn(token)
|
||||||
request.setParameter(token.parameterName,token.token)
|
request.setParameter(token.parameterName,token.token)
|
||||||
request.servletPath = "/some-url"
|
request.servletPath = "/some-url"
|
||||||
request.requestURI = "/some-url"
|
request.requestURI = "/some-url"
|
||||||
request.method = "GET"
|
request.method = "GET"
|
||||||
when: "CSRF passes and our session times out"
|
when: "CSRF passes and our session times out"
|
||||||
springSecurityFilterChain.doFilter(request,response,chain)
|
springSecurityFilterChain.doFilter(request,response,chain)
|
||||||
then: "sent to the login page"
|
then: "sent to the login page"
|
||||||
response.status == HttpServletResponse.SC_MOVED_TEMPORARILY
|
response.status == HttpServletResponse.SC_MOVED_TEMPORARILY
|
||||||
response.redirectedUrl == "http://localhost/login"
|
response.redirectedUrl == "http://localhost/login"
|
||||||
when: "authenticate successfully"
|
when: "authenticate successfully"
|
||||||
response = new MockHttpServletResponse()
|
response = new MockHttpServletResponse()
|
||||||
request = new MockHttpServletRequest(session: request.session)
|
request = new MockHttpServletRequest(session: request.session)
|
||||||
request.servletPath = "/login"
|
request.servletPath = "/login"
|
||||||
request.setParameter(token.parameterName,token.token)
|
request.setParameter(token.parameterName,token.token)
|
||||||
request.setParameter("username","user")
|
request.setParameter("username","user")
|
||||||
request.setParameter("password","password")
|
request.setParameter("password","password")
|
||||||
request.method = "POST"
|
request.method = "POST"
|
||||||
springSecurityFilterChain.doFilter(request,response,chain)
|
springSecurityFilterChain.doFilter(request,response,chain)
|
||||||
then: "sent to original URL since it was a GET"
|
then: "sent to original URL since it was a GET"
|
||||||
response.status == HttpServletResponse.SC_MOVED_TEMPORARILY
|
response.status == HttpServletResponse.SC_MOVED_TEMPORARILY
|
||||||
response.redirectedUrl == "http://localhost/some-url"
|
response.redirectedUrl == "http://localhost/some-url"
|
||||||
}
|
}
|
||||||
|
|
||||||
def "SEC-2422: csrf expire CSRF token and session-management invalid-session-url"() {
|
def "SEC-2422: csrf expire CSRF token and session-management invalid-session-url"() {
|
||||||
setup:
|
setup:
|
||||||
httpAutoConfig {
|
httpAutoConfig {
|
||||||
'csrf'()
|
'csrf'()
|
||||||
'session-management'('invalid-session-url': '/error/sessionError')
|
'session-management'('invalid-session-url': '/error/sessionError')
|
||||||
}
|
}
|
||||||
createAppContext()
|
createAppContext()
|
||||||
request.setParameter("_csrf","abc")
|
request.setParameter("_csrf","abc")
|
||||||
request.method = "POST"
|
request.method = "POST"
|
||||||
when: "No existing expected CsrfToken (session times out) and a POST"
|
when: "No existing expected CsrfToken (session times out) and a POST"
|
||||||
springSecurityFilterChain.doFilter(request,response,chain)
|
springSecurityFilterChain.doFilter(request,response,chain)
|
||||||
then: "sent to the session timeout page page"
|
then: "sent to the session timeout page page"
|
||||||
response.status == HttpServletResponse.SC_MOVED_TEMPORARILY
|
response.status == HttpServletResponse.SC_MOVED_TEMPORARILY
|
||||||
response.redirectedUrl == "/error/sessionError"
|
response.redirectedUrl == "/error/sessionError"
|
||||||
when: "Existing expected CsrfToken and a POST (invalid token provided)"
|
when: "Existing expected CsrfToken and a POST (invalid token provided)"
|
||||||
response = new MockHttpServletResponse()
|
response = new MockHttpServletResponse()
|
||||||
request = new MockHttpServletRequest(session: request.session, method:'POST')
|
request = new MockHttpServletRequest(session: request.session, method:'POST')
|
||||||
springSecurityFilterChain.doFilter(request,response,chain)
|
springSecurityFilterChain.doFilter(request,response,chain)
|
||||||
then: "Access Denied occurs"
|
then: "Access Denied occurs"
|
||||||
response.status == HttpServletResponse.SC_FORBIDDEN
|
response.status == HttpServletResponse.SC_FORBIDDEN
|
||||||
}
|
}
|
||||||
|
|
||||||
def "csrf requireCsrfProtectionMatcher"() {
|
def "csrf requireCsrfProtectionMatcher"() {
|
||||||
setup:
|
setup:
|
||||||
httpAutoConfig {
|
httpAutoConfig {
|
||||||
'csrf'('request-matcher-ref':'matcher')
|
'csrf'('request-matcher-ref':'matcher')
|
||||||
}
|
}
|
||||||
mockBean(RequestMatcher,'matcher')
|
mockBean(RequestMatcher,'matcher')
|
||||||
createAppContext()
|
createAppContext()
|
||||||
request.method = 'POST'
|
request.method = 'POST'
|
||||||
RequestMatcher matcher = appContext.getBean("matcher",RequestMatcher)
|
RequestMatcher matcher = appContext.getBean("matcher",RequestMatcher)
|
||||||
when:
|
when:
|
||||||
when(matcher.matches(any(HttpServletRequest))).thenReturn(false)
|
when(matcher.matches(any(HttpServletRequest))).thenReturn(false)
|
||||||
springSecurityFilterChain.doFilter(request,response,chain)
|
springSecurityFilterChain.doFilter(request,response,chain)
|
||||||
then:
|
then:
|
||||||
response.status == HttpServletResponse.SC_OK
|
response.status == HttpServletResponse.SC_OK
|
||||||
when:
|
when:
|
||||||
when(matcher.matches(any(HttpServletRequest))).thenReturn(true)
|
when(matcher.matches(any(HttpServletRequest))).thenReturn(true)
|
||||||
springSecurityFilterChain.doFilter(request,response,chain)
|
springSecurityFilterChain.doFilter(request,response,chain)
|
||||||
then:
|
then:
|
||||||
response.status == HttpServletResponse.SC_FORBIDDEN
|
response.status == HttpServletResponse.SC_FORBIDDEN
|
||||||
}
|
}
|
||||||
|
|
||||||
def "csrf csrfTokenRepository"() {
|
def "csrf csrfTokenRepository"() {
|
||||||
setup:
|
setup:
|
||||||
httpAutoConfig {
|
httpAutoConfig {
|
||||||
'csrf'('token-repository-ref':'repo')
|
'csrf'('token-repository-ref':'repo')
|
||||||
}
|
}
|
||||||
mockBean(CsrfTokenRepository,'repo')
|
mockBean(CsrfTokenRepository,'repo')
|
||||||
createAppContext()
|
createAppContext()
|
||||||
CsrfTokenRepository repo = appContext.getBean("repo",CsrfTokenRepository)
|
CsrfTokenRepository repo = appContext.getBean("repo",CsrfTokenRepository)
|
||||||
CsrfToken token = new DefaultCsrfToken("X-CSRF-TOKEN","_csrf", "abc")
|
CsrfToken token = new DefaultCsrfToken("X-CSRF-TOKEN","_csrf", "abc")
|
||||||
when(repo.loadToken(any(HttpServletRequest))).thenReturn(token)
|
when(repo.loadToken(any(HttpServletRequest))).thenReturn(token)
|
||||||
request.setParameter(token.parameterName,token.token)
|
request.setParameter(token.parameterName,token.token)
|
||||||
request.method = "POST"
|
request.method = "POST"
|
||||||
when:
|
when:
|
||||||
springSecurityFilterChain.doFilter(request,response,chain)
|
springSecurityFilterChain.doFilter(request,response,chain)
|
||||||
then:
|
then:
|
||||||
response.status == HttpServletResponse.SC_OK
|
response.status == HttpServletResponse.SC_OK
|
||||||
when:
|
when:
|
||||||
request.setParameter(token.parameterName,token.token+"INVALID")
|
request.setParameter(token.parameterName,token.token+"INVALID")
|
||||||
springSecurityFilterChain.doFilter(request,response,chain)
|
springSecurityFilterChain.doFilter(request,response,chain)
|
||||||
then:
|
then:
|
||||||
response.status == HttpServletResponse.SC_FORBIDDEN
|
response.status == HttpServletResponse.SC_FORBIDDEN
|
||||||
}
|
}
|
||||||
|
|
||||||
def "csrf clears on login"() {
|
def "csrf clears on login"() {
|
||||||
setup:
|
setup:
|
||||||
httpAutoConfig {
|
httpAutoConfig {
|
||||||
'csrf'('token-repository-ref':'repo')
|
'csrf'('token-repository-ref':'repo')
|
||||||
}
|
}
|
||||||
mockBean(CsrfTokenRepository,'repo')
|
mockBean(CsrfTokenRepository,'repo')
|
||||||
createAppContext()
|
createAppContext()
|
||||||
CsrfTokenRepository repo = appContext.getBean("repo",CsrfTokenRepository)
|
CsrfTokenRepository repo = appContext.getBean("repo",CsrfTokenRepository)
|
||||||
CsrfToken token = new DefaultCsrfToken("X-CSRF-TOKEN","_csrf", "abc")
|
CsrfToken token = new DefaultCsrfToken("X-CSRF-TOKEN","_csrf", "abc")
|
||||||
when(repo.loadToken(any(HttpServletRequest))).thenReturn(token)
|
when(repo.loadToken(any(HttpServletRequest))).thenReturn(token)
|
||||||
when(repo.generateToken(any(HttpServletRequest))).thenReturn(token)
|
when(repo.generateToken(any(HttpServletRequest))).thenReturn(token)
|
||||||
request.setParameter(token.parameterName,token.token)
|
request.setParameter(token.parameterName,token.token)
|
||||||
request.method = "POST"
|
request.method = "POST"
|
||||||
request.setParameter("username","user")
|
request.setParameter("username","user")
|
||||||
request.setParameter("password","password")
|
request.setParameter("password","password")
|
||||||
request.servletPath = "/login"
|
request.servletPath = "/login"
|
||||||
when:
|
when:
|
||||||
springSecurityFilterChain.doFilter(request,response,chain)
|
springSecurityFilterChain.doFilter(request,response,chain)
|
||||||
then:
|
then:
|
||||||
verify(repo, atLeastOnce()).saveToken(eq(null),any(HttpServletRequest), any(HttpServletResponse))
|
verify(repo, atLeastOnce()).saveToken(eq(null),any(HttpServletRequest), any(HttpServletResponse))
|
||||||
}
|
}
|
||||||
|
|
||||||
def "csrf clears on logout"() {
|
def "csrf clears on logout"() {
|
||||||
setup:
|
setup:
|
||||||
httpAutoConfig {
|
httpAutoConfig {
|
||||||
'csrf'('token-repository-ref':'repo')
|
'csrf'('token-repository-ref':'repo')
|
||||||
}
|
}
|
||||||
mockBean(CsrfTokenRepository,'repo')
|
mockBean(CsrfTokenRepository,'repo')
|
||||||
createAppContext()
|
createAppContext()
|
||||||
CsrfTokenRepository repo = appContext.getBean("repo",CsrfTokenRepository)
|
CsrfTokenRepository repo = appContext.getBean("repo",CsrfTokenRepository)
|
||||||
CsrfToken token = new DefaultCsrfToken("X-CSRF-TOKEN","_csrf", "abc")
|
CsrfToken token = new DefaultCsrfToken("X-CSRF-TOKEN","_csrf", "abc")
|
||||||
when(repo.loadToken(any(HttpServletRequest))).thenReturn(token)
|
when(repo.loadToken(any(HttpServletRequest))).thenReturn(token)
|
||||||
request.setParameter(token.parameterName,token.token)
|
request.setParameter(token.parameterName,token.token)
|
||||||
request.method = "POST"
|
request.method = "POST"
|
||||||
request.servletPath = "/logout"
|
request.servletPath = "/logout"
|
||||||
when:
|
when:
|
||||||
springSecurityFilterChain.doFilter(request,response,chain)
|
springSecurityFilterChain.doFilter(request,response,chain)
|
||||||
then:
|
then:
|
||||||
verify(repo).saveToken(eq(null),any(HttpServletRequest), any(HttpServletResponse))
|
verify(repo).saveToken(eq(null),any(HttpServletRequest), any(HttpServletResponse))
|
||||||
}
|
}
|
||||||
|
|
||||||
def "SEC-2495: csrf disables logout on GET"() {
|
def "SEC-2495: csrf disables logout on GET"() {
|
||||||
setup:
|
setup:
|
||||||
httpAutoConfig {
|
httpAutoConfig {
|
||||||
'csrf'()
|
'csrf'()
|
||||||
}
|
}
|
||||||
createAppContext()
|
createAppContext()
|
||||||
login()
|
login()
|
||||||
request.method = "GET"
|
request.method = "GET"
|
||||||
request.requestURI = "/logout"
|
request.requestURI = "/logout"
|
||||||
when:
|
when:
|
||||||
springSecurityFilterChain.doFilter(request,response,chain)
|
springSecurityFilterChain.doFilter(request,response,chain)
|
||||||
then:
|
then:
|
||||||
getAuthentication(request) != null
|
getAuthentication(request) != null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def login(String username="user", String role="ROLE_USER") {
|
def login(String username="user", String role="ROLE_USER") {
|
||||||
login(new UsernamePasswordAuthenticationToken(username, null, AuthorityUtils.createAuthorityList(role)))
|
login(new UsernamePasswordAuthenticationToken(username, null, AuthorityUtils.createAuthorityList(role)))
|
||||||
}
|
}
|
||||||
|
|
||||||
def login(Authentication auth) {
|
def login(Authentication auth) {
|
||||||
HttpSessionSecurityContextRepository repo = new HttpSessionSecurityContextRepository()
|
HttpSessionSecurityContextRepository repo = new HttpSessionSecurityContextRepository()
|
||||||
HttpRequestResponseHolder requestResponseHolder = new HttpRequestResponseHolder(request, response)
|
HttpRequestResponseHolder requestResponseHolder = new HttpRequestResponseHolder(request, response)
|
||||||
repo.loadContext(requestResponseHolder)
|
repo.loadContext(requestResponseHolder)
|
||||||
repo.saveContext(new SecurityContextImpl(authentication:auth), requestResponseHolder.request, requestResponseHolder.response)
|
repo.saveContext(new SecurityContextImpl(authentication:auth), requestResponseHolder.request, requestResponseHolder.response)
|
||||||
}
|
}
|
||||||
|
|
||||||
def getAuthentication(HttpServletRequest request) {
|
def getAuthentication(HttpServletRequest request) {
|
||||||
HttpSessionSecurityContextRepository repo = new HttpSessionSecurityContextRepository()
|
HttpSessionSecurityContextRepository repo = new HttpSessionSecurityContextRepository()
|
||||||
HttpRequestResponseHolder requestResponseHolder = new HttpRequestResponseHolder(request, response)
|
HttpRequestResponseHolder requestResponseHolder = new HttpRequestResponseHolder(request, response)
|
||||||
repo.loadContext(requestResponseHolder)?.authentication
|
repo.loadContext(requestResponseHolder)?.authentication
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,104 +10,104 @@ import org.springframework.mock.web.MockHttpServletResponse
|
||||||
*/
|
*/
|
||||||
class FormLoginBeanDefinitionParserTests extends AbstractHttpConfigTests {
|
class FormLoginBeanDefinitionParserTests extends AbstractHttpConfigTests {
|
||||||
|
|
||||||
def 'form-login default login page'() {
|
def 'form-login default login page'() {
|
||||||
setup:
|
setup:
|
||||||
MockHttpServletRequest request = new MockHttpServletRequest(method:'GET',requestURI:'/login')
|
MockHttpServletRequest request = new MockHttpServletRequest(method:'GET',requestURI:'/login')
|
||||||
MockHttpServletResponse response = new MockHttpServletResponse()
|
MockHttpServletResponse response = new MockHttpServletResponse()
|
||||||
MockFilterChain chain = new MockFilterChain()
|
MockFilterChain chain = new MockFilterChain()
|
||||||
httpAutoConfig {
|
httpAutoConfig {
|
||||||
csrf(disabled:true)
|
csrf(disabled:true)
|
||||||
}
|
}
|
||||||
createAppContext()
|
createAppContext()
|
||||||
when:
|
when:
|
||||||
springSecurityFilterChain.doFilter(request,response,chain)
|
springSecurityFilterChain.doFilter(request,response,chain)
|
||||||
then:
|
then:
|
||||||
response.getContentAsString() == """<html><head><title>Login Page</title></head><body onload='document.f.username.focus();'>
|
response.getContentAsString() == """<html><head><title>Login Page</title></head><body onload='document.f.username.focus();'>
|
||||||
<h3>Login with Username and Password</h3><form name='f' action='/login' method='POST'>
|
<h3>Login with Username and Password</h3><form name='f' action='/login' method='POST'>
|
||||||
<table>
|
<table>
|
||||||
<tr><td>User:</td><td><input type='text' name='username' value=''></td></tr>
|
<tr><td>User:</td><td><input type='text' name='username' value=''></td></tr>
|
||||||
<tr><td>Password:</td><td><input type='password' name='password'/></td></tr>
|
<tr><td>Password:</td><td><input type='password' name='password'/></td></tr>
|
||||||
<tr><td colspan='2'><input name="submit" type="submit" value="Login"/></td></tr>
|
<tr><td colspan='2'><input name="submit" type="submit" value="Login"/></td></tr>
|
||||||
</table>
|
</table>
|
||||||
</form></body></html>"""
|
</form></body></html>"""
|
||||||
}
|
}
|
||||||
|
|
||||||
def 'form-login default login page custom attributes'() {
|
def 'form-login default login page custom attributes'() {
|
||||||
setup:
|
setup:
|
||||||
MockHttpServletRequest request = new MockHttpServletRequest(method:'GET',requestURI:'/login')
|
MockHttpServletRequest request = new MockHttpServletRequest(method:'GET',requestURI:'/login')
|
||||||
MockHttpServletResponse response = new MockHttpServletResponse()
|
MockHttpServletResponse response = new MockHttpServletResponse()
|
||||||
MockFilterChain chain = new MockFilterChain()
|
MockFilterChain chain = new MockFilterChain()
|
||||||
httpAutoConfig {
|
httpAutoConfig {
|
||||||
'form-login'('login-processing-url':'/login_custom','username-parameter':'custom_user','password-parameter':'custom_password')
|
'form-login'('login-processing-url':'/login_custom','username-parameter':'custom_user','password-parameter':'custom_password')
|
||||||
csrf(disabled:true)
|
csrf(disabled:true)
|
||||||
}
|
}
|
||||||
createAppContext()
|
createAppContext()
|
||||||
when:
|
when:
|
||||||
springSecurityFilterChain.doFilter(request,response,chain)
|
springSecurityFilterChain.doFilter(request,response,chain)
|
||||||
then:
|
then:
|
||||||
response.getContentAsString() == """<html><head><title>Login Page</title></head><body onload='document.f.custom_user.focus();'>
|
response.getContentAsString() == """<html><head><title>Login Page</title></head><body onload='document.f.custom_user.focus();'>
|
||||||
<h3>Login with Username and Password</h3><form name='f' action='/login_custom' method='POST'>
|
<h3>Login with Username and Password</h3><form name='f' action='/login_custom' method='POST'>
|
||||||
<table>
|
<table>
|
||||||
<tr><td>User:</td><td><input type='text' name='custom_user' value=''></td></tr>
|
<tr><td>User:</td><td><input type='text' name='custom_user' value=''></td></tr>
|
||||||
<tr><td>Password:</td><td><input type='password' name='custom_password'/></td></tr>
|
<tr><td>Password:</td><td><input type='password' name='custom_password'/></td></tr>
|
||||||
<tr><td colspan='2'><input name="submit" type="submit" value="Login"/></td></tr>
|
<tr><td colspan='2'><input name="submit" type="submit" value="Login"/></td></tr>
|
||||||
</table>
|
</table>
|
||||||
</form></body></html>"""
|
</form></body></html>"""
|
||||||
}
|
}
|
||||||
|
|
||||||
def 'openid-login default login page'() {
|
def 'openid-login default login page'() {
|
||||||
setup:
|
setup:
|
||||||
MockHttpServletRequest request = new MockHttpServletRequest(method:'GET',requestURI:'/login')
|
MockHttpServletRequest request = new MockHttpServletRequest(method:'GET',requestURI:'/login')
|
||||||
MockHttpServletResponse response = new MockHttpServletResponse()
|
MockHttpServletResponse response = new MockHttpServletResponse()
|
||||||
MockFilterChain chain = new MockFilterChain()
|
MockFilterChain chain = new MockFilterChain()
|
||||||
httpAutoConfig {
|
httpAutoConfig {
|
||||||
'openid-login'()
|
'openid-login'()
|
||||||
csrf(disabled:true)
|
csrf(disabled:true)
|
||||||
}
|
}
|
||||||
createAppContext()
|
createAppContext()
|
||||||
when:
|
when:
|
||||||
springSecurityFilterChain.doFilter(request,response,chain)
|
springSecurityFilterChain.doFilter(request,response,chain)
|
||||||
then:
|
then:
|
||||||
response.getContentAsString() == """<html><head><title>Login Page</title></head><body onload='document.f.username.focus();'>
|
response.getContentAsString() == """<html><head><title>Login Page</title></head><body onload='document.f.username.focus();'>
|
||||||
<h3>Login with Username and Password</h3><form name='f' action='/login' method='POST'>
|
<h3>Login with Username and Password</h3><form name='f' action='/login' method='POST'>
|
||||||
<table>
|
<table>
|
||||||
<tr><td>User:</td><td><input type='text' name='username' value=''></td></tr>
|
<tr><td>User:</td><td><input type='text' name='username' value=''></td></tr>
|
||||||
<tr><td>Password:</td><td><input type='password' name='password'/></td></tr>
|
<tr><td>Password:</td><td><input type='password' name='password'/></td></tr>
|
||||||
<tr><td colspan='2'><input name="submit" type="submit" value="Login"/></td></tr>
|
<tr><td colspan='2'><input name="submit" type="submit" value="Login"/></td></tr>
|
||||||
</table>
|
</table>
|
||||||
</form><h3>Login with OpenID Identity</h3><form name='oidf' action='/login/openid' method='POST'>
|
</form><h3>Login with OpenID Identity</h3><form name='oidf' action='/login/openid' method='POST'>
|
||||||
<table>
|
<table>
|
||||||
<tr><td>Identity:</td><td><input type='text' size='30' name='openid_identifier'/></td></tr>
|
<tr><td>Identity:</td><td><input type='text' size='30' name='openid_identifier'/></td></tr>
|
||||||
<tr><td colspan='2'><input name="submit" type="submit" value="Login"/></td></tr>
|
<tr><td colspan='2'><input name="submit" type="submit" value="Login"/></td></tr>
|
||||||
</table>
|
</table>
|
||||||
</form></body></html>"""
|
</form></body></html>"""
|
||||||
}
|
}
|
||||||
|
|
||||||
def 'openid-login default login page custom attributes'() {
|
def 'openid-login default login page custom attributes'() {
|
||||||
setup:
|
setup:
|
||||||
MockHttpServletRequest request = new MockHttpServletRequest(method:'GET',requestURI:'/login')
|
MockHttpServletRequest request = new MockHttpServletRequest(method:'GET',requestURI:'/login')
|
||||||
MockHttpServletResponse response = new MockHttpServletResponse()
|
MockHttpServletResponse response = new MockHttpServletResponse()
|
||||||
MockFilterChain chain = new MockFilterChain()
|
MockFilterChain chain = new MockFilterChain()
|
||||||
httpAutoConfig {
|
httpAutoConfig {
|
||||||
'openid-login'('login-processing-url':'/login_custom')
|
'openid-login'('login-processing-url':'/login_custom')
|
||||||
csrf(disabled:true)
|
csrf(disabled:true)
|
||||||
}
|
}
|
||||||
createAppContext()
|
createAppContext()
|
||||||
when:
|
when:
|
||||||
springSecurityFilterChain.doFilter(request,response,chain)
|
springSecurityFilterChain.doFilter(request,response,chain)
|
||||||
then:
|
then:
|
||||||
response.getContentAsString() == """<html><head><title>Login Page</title></head><body onload='document.f.username.focus();'>
|
response.getContentAsString() == """<html><head><title>Login Page</title></head><body onload='document.f.username.focus();'>
|
||||||
<h3>Login with Username and Password</h3><form name='f' action='/login' method='POST'>
|
<h3>Login with Username and Password</h3><form name='f' action='/login' method='POST'>
|
||||||
<table>
|
<table>
|
||||||
<tr><td>User:</td><td><input type='text' name='username' value=''></td></tr>
|
<tr><td>User:</td><td><input type='text' name='username' value=''></td></tr>
|
||||||
<tr><td>Password:</td><td><input type='password' name='password'/></td></tr>
|
<tr><td>Password:</td><td><input type='password' name='password'/></td></tr>
|
||||||
<tr><td colspan='2'><input name="submit" type="submit" value="Login"/></td></tr>
|
<tr><td colspan='2'><input name="submit" type="submit" value="Login"/></td></tr>
|
||||||
</table>
|
</table>
|
||||||
</form><h3>Login with OpenID Identity</h3><form name='oidf' action='/login_custom' method='POST'>
|
</form><h3>Login with OpenID Identity</h3><form name='oidf' action='/login_custom' method='POST'>
|
||||||
<table>
|
<table>
|
||||||
<tr><td>Identity:</td><td><input type='text' size='30' name='openid_identifier'/></td></tr>
|
<tr><td>Identity:</td><td><input type='text' size='30' name='openid_identifier'/></td></tr>
|
||||||
<tr><td colspan='2'><input name="submit" type="submit" value="Login"/></td></tr>
|
<tr><td colspan='2'><input name="submit" type="submit" value="Login"/></td></tr>
|
||||||
</table>
|
</table>
|
||||||
</form></body></html>"""
|
</form></body></html>"""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,93 +15,93 @@ import org.springframework.util.ReflectionUtils;
|
||||||
*/
|
*/
|
||||||
class FormLoginConfigTests extends AbstractHttpConfigTests {
|
class FormLoginConfigTests extends AbstractHttpConfigTests {
|
||||||
|
|
||||||
def formLoginWithNoLoginPageAddsDefaultLoginPageFilter() {
|
def formLoginWithNoLoginPageAddsDefaultLoginPageFilter() {
|
||||||
httpAutoConfig('ant') {
|
httpAutoConfig('ant') {
|
||||||
form-login()
|
form-login()
|
||||||
}
|
}
|
||||||
createAppContext()
|
createAppContext()
|
||||||
filtersMatchExpectedAutoConfigList();
|
filtersMatchExpectedAutoConfigList();
|
||||||
}
|
}
|
||||||
|
|
||||||
def 'Form login alwaysUseDefaultTarget sets correct property'() {
|
def 'Form login alwaysUseDefaultTarget sets correct property'() {
|
||||||
xml.http {
|
xml.http {
|
||||||
'form-login'('default-target-url':'/default', 'always-use-default-target': 'true')
|
'form-login'('default-target-url':'/default', 'always-use-default-target': 'true')
|
||||||
}
|
}
|
||||||
createAppContext()
|
createAppContext()
|
||||||
def filter = getFilter(UsernamePasswordAuthenticationFilter.class);
|
def filter = getFilter(UsernamePasswordAuthenticationFilter.class);
|
||||||
|
|
||||||
expect:
|
expect:
|
||||||
FieldUtils.getFieldValue(filter, 'successHandler.defaultTargetUrl') == '/default';
|
FieldUtils.getFieldValue(filter, 'successHandler.defaultTargetUrl') == '/default';
|
||||||
FieldUtils.getFieldValue(filter, 'successHandler.alwaysUseDefaultTargetUrl');
|
FieldUtils.getFieldValue(filter, 'successHandler.alwaysUseDefaultTargetUrl');
|
||||||
}
|
}
|
||||||
|
|
||||||
def 'form-login attributes support SpEL'() {
|
def 'form-login attributes support SpEL'() {
|
||||||
setup:
|
setup:
|
||||||
def spelUrl = '#{T(org.springframework.security.config.http.WebConfigUtilsTest).URL}'
|
def spelUrl = '#{T(org.springframework.security.config.http.WebConfigUtilsTest).URL}'
|
||||||
def expectedUrl = WebConfigUtilsTest.URL
|
def expectedUrl = WebConfigUtilsTest.URL
|
||||||
when:
|
when:
|
||||||
xml.http {
|
xml.http {
|
||||||
'form-login'('default-target-url': spelUrl , 'authentication-failure-url': spelUrl, 'login-page': spelUrl)
|
'form-login'('default-target-url': spelUrl , 'authentication-failure-url': spelUrl, 'login-page': spelUrl)
|
||||||
}
|
}
|
||||||
createAppContext()
|
createAppContext()
|
||||||
def unPwdFilter = getFilter(UsernamePasswordAuthenticationFilter)
|
def unPwdFilter = getFilter(UsernamePasswordAuthenticationFilter)
|
||||||
def exTransFilter = getFilter(ExceptionTranslationFilter)
|
def exTransFilter = getFilter(ExceptionTranslationFilter)
|
||||||
|
|
||||||
then:
|
then:
|
||||||
unPwdFilter.successHandler.defaultTargetUrl == expectedUrl
|
unPwdFilter.successHandler.defaultTargetUrl == expectedUrl
|
||||||
unPwdFilter
|
unPwdFilter
|
||||||
FieldUtils.getFieldValue(unPwdFilter, 'successHandler.defaultTargetUrl') == expectedUrl
|
FieldUtils.getFieldValue(unPwdFilter, 'successHandler.defaultTargetUrl') == expectedUrl
|
||||||
FieldUtils.getFieldValue(unPwdFilter, 'failureHandler.defaultFailureUrl') == expectedUrl
|
FieldUtils.getFieldValue(unPwdFilter, 'failureHandler.defaultFailureUrl') == expectedUrl
|
||||||
FieldUtils.getFieldValue(exTransFilter, 'authenticationEntryPoint.loginFormUrl') == expectedUrl
|
FieldUtils.getFieldValue(exTransFilter, 'authenticationEntryPoint.loginFormUrl') == expectedUrl
|
||||||
}
|
}
|
||||||
|
|
||||||
def invalidLoginPageIsDetected() {
|
def invalidLoginPageIsDetected() {
|
||||||
when:
|
when:
|
||||||
xml.http {
|
xml.http {
|
||||||
'form-login'('login-page': 'noLeadingSlash')
|
'form-login'('login-page': 'noLeadingSlash')
|
||||||
}
|
}
|
||||||
createAppContext()
|
createAppContext()
|
||||||
|
|
||||||
then:
|
then:
|
||||||
BeanCreationException e = thrown();
|
BeanCreationException e = thrown();
|
||||||
}
|
}
|
||||||
|
|
||||||
def invalidDefaultTargetUrlIsDetected() {
|
def invalidDefaultTargetUrlIsDetected() {
|
||||||
when:
|
when:
|
||||||
xml.http {
|
xml.http {
|
||||||
'form-login'('default-target-url': 'noLeadingSlash')
|
'form-login'('default-target-url': 'noLeadingSlash')
|
||||||
}
|
}
|
||||||
createAppContext()
|
createAppContext()
|
||||||
|
|
||||||
then:
|
then:
|
||||||
BeanCreationException e = thrown();
|
BeanCreationException e = thrown();
|
||||||
}
|
}
|
||||||
|
|
||||||
def customSuccessAndFailureHandlersCanBeSetThroughTheNamespace() {
|
def customSuccessAndFailureHandlersCanBeSetThroughTheNamespace() {
|
||||||
xml.http {
|
xml.http {
|
||||||
'form-login'('authentication-success-handler-ref': 'sh', 'authentication-failure-handler-ref':'fh')
|
'form-login'('authentication-success-handler-ref': 'sh', 'authentication-failure-handler-ref':'fh')
|
||||||
}
|
}
|
||||||
bean('sh', SavedRequestAwareAuthenticationSuccessHandler.class.name)
|
bean('sh', SavedRequestAwareAuthenticationSuccessHandler.class.name)
|
||||||
bean('fh', SimpleUrlAuthenticationFailureHandler.class.name)
|
bean('fh', SimpleUrlAuthenticationFailureHandler.class.name)
|
||||||
createAppContext()
|
createAppContext()
|
||||||
|
|
||||||
def apf = getFilter(UsernamePasswordAuthenticationFilter.class);
|
def apf = getFilter(UsernamePasswordAuthenticationFilter.class);
|
||||||
|
|
||||||
expect:
|
expect:
|
||||||
FieldUtils.getFieldValue(apf, "successHandler") == appContext.getBean("sh");
|
FieldUtils.getFieldValue(apf, "successHandler") == appContext.getBean("sh");
|
||||||
FieldUtils.getFieldValue(apf, "failureHandler") == appContext.getBean("fh")
|
FieldUtils.getFieldValue(apf, "failureHandler") == appContext.getBean("fh")
|
||||||
}
|
}
|
||||||
|
|
||||||
def usernameAndPasswordParametersCanBeSetThroughNamespace() {
|
def usernameAndPasswordParametersCanBeSetThroughNamespace() {
|
||||||
xml.http {
|
xml.http {
|
||||||
'form-login'('username-parameter': 'xname', 'password-parameter':'xpass')
|
'form-login'('username-parameter': 'xname', 'password-parameter':'xpass')
|
||||||
}
|
}
|
||||||
createAppContext()
|
createAppContext()
|
||||||
|
|
||||||
def apf = getFilter(UsernamePasswordAuthenticationFilter.class);
|
def apf = getFilter(UsernamePasswordAuthenticationFilter.class);
|
||||||
|
|
||||||
expect:
|
expect:
|
||||||
apf.usernameParameter == 'xname';
|
apf.usernameParameter == 'xname';
|
||||||
apf.passwordParameter == 'xpass'
|
apf.passwordParameter == 'xpass'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,20 +43,20 @@ import static org.mockito.Mockito.*
|
||||||
* @author Rob Winch
|
* @author Rob Winch
|
||||||
*/
|
*/
|
||||||
class HttpConfigTests extends AbstractHttpConfigTests {
|
class HttpConfigTests extends AbstractHttpConfigTests {
|
||||||
MockHttpServletRequest request = new MockHttpServletRequest('GET','/secure')
|
MockHttpServletRequest request = new MockHttpServletRequest('GET','/secure')
|
||||||
MockHttpServletResponse response = new MockHttpServletResponse()
|
MockHttpServletResponse response = new MockHttpServletResponse()
|
||||||
MockFilterChain chain = new MockFilterChain()
|
MockFilterChain chain = new MockFilterChain()
|
||||||
|
|
||||||
def 'http minimal configuration works'() {
|
def 'http minimal configuration works'() {
|
||||||
setup:
|
setup:
|
||||||
xml.http() {}
|
xml.http() {}
|
||||||
createAppContext("""<user-service>
|
createAppContext("""<user-service>
|
||||||
<user name="user" password="password" authorities="ROLE_USER" />
|
<user name="user" password="password" authorities="ROLE_USER" />
|
||||||
</user-service>""")
|
</user-service>""")
|
||||||
when: 'request protected URL'
|
when: 'request protected URL'
|
||||||
springSecurityFilterChain.doFilter(request,response,chain)
|
springSecurityFilterChain.doFilter(request,response,chain)
|
||||||
then: 'sent to login page'
|
then: 'sent to login page'
|
||||||
response.status == HttpServletResponse.SC_MOVED_TEMPORARILY
|
response.status == HttpServletResponse.SC_MOVED_TEMPORARILY
|
||||||
response.redirectedUrl == 'http://localhost/login'
|
response.redirectedUrl == 'http://localhost/login'
|
||||||
}
|
}
|
||||||
}
|
}
|
File diff suppressed because it is too large
Load Diff
|
@ -23,132 +23,132 @@ import javax.servlet.Filter
|
||||||
*/
|
*/
|
||||||
class OpenIDConfigTests extends AbstractHttpConfigTests {
|
class OpenIDConfigTests extends AbstractHttpConfigTests {
|
||||||
|
|
||||||
def openIDAndFormLoginWorkTogether() {
|
def openIDAndFormLoginWorkTogether() {
|
||||||
xml.http() {
|
xml.http() {
|
||||||
'openid-login'()
|
'openid-login'()
|
||||||
'form-login'()
|
'form-login'()
|
||||||
}
|
}
|
||||||
createAppContext()
|
createAppContext()
|
||||||
|
|
||||||
def etf = getFilter(ExceptionTranslationFilter)
|
def etf = getFilter(ExceptionTranslationFilter)
|
||||||
def ap = etf.getAuthenticationEntryPoint();
|
def ap = etf.getAuthenticationEntryPoint();
|
||||||
|
|
||||||
expect:
|
expect:
|
||||||
ap.loginFormUrl == "/login"
|
ap.loginFormUrl == "/login"
|
||||||
// Default login filter should be present since we haven't specified any login URLs
|
// Default login filter should be present since we haven't specified any login URLs
|
||||||
getFilter(DefaultLoginPageGeneratingFilter) != null
|
getFilter(DefaultLoginPageGeneratingFilter) != null
|
||||||
}
|
}
|
||||||
|
|
||||||
def formLoginEntryPointTakesPrecedenceIfLoginUrlIsSet() {
|
def formLoginEntryPointTakesPrecedenceIfLoginUrlIsSet() {
|
||||||
xml.http() {
|
xml.http() {
|
||||||
'openid-login'()
|
'openid-login'()
|
||||||
'form-login'('login-page': '/form-page')
|
'form-login'('login-page': '/form-page')
|
||||||
}
|
}
|
||||||
createAppContext()
|
createAppContext()
|
||||||
|
|
||||||
expect:
|
expect:
|
||||||
getFilter(ExceptionTranslationFilter).authenticationEntryPoint.loginFormUrl == '/form-page'
|
getFilter(ExceptionTranslationFilter).authenticationEntryPoint.loginFormUrl == '/form-page'
|
||||||
}
|
}
|
||||||
|
|
||||||
def openIDEntryPointTakesPrecedenceIfLoginUrlIsSet() {
|
def openIDEntryPointTakesPrecedenceIfLoginUrlIsSet() {
|
||||||
xml.http() {
|
xml.http() {
|
||||||
'openid-login'('login-page': '/openid-page')
|
'openid-login'('login-page': '/openid-page')
|
||||||
'form-login'()
|
'form-login'()
|
||||||
}
|
}
|
||||||
createAppContext()
|
createAppContext()
|
||||||
|
|
||||||
expect:
|
expect:
|
||||||
getFilter(ExceptionTranslationFilter).authenticationEntryPoint.loginFormUrl == '/openid-page'
|
getFilter(ExceptionTranslationFilter).authenticationEntryPoint.loginFormUrl == '/openid-page'
|
||||||
}
|
}
|
||||||
|
|
||||||
def multipleLoginPagesCausesError() {
|
def multipleLoginPagesCausesError() {
|
||||||
when:
|
when:
|
||||||
xml.http() {
|
xml.http() {
|
||||||
'openid-login'('login-page': '/openid-page')
|
'openid-login'('login-page': '/openid-page')
|
||||||
'form-login'('login-page': '/form-page')
|
'form-login'('login-page': '/form-page')
|
||||||
}
|
}
|
||||||
createAppContext()
|
createAppContext()
|
||||||
then:
|
then:
|
||||||
thrown(BeanDefinitionParsingException)
|
thrown(BeanDefinitionParsingException)
|
||||||
}
|
}
|
||||||
|
|
||||||
def openIDAndRememberMeWorkTogether() {
|
def openIDAndRememberMeWorkTogether() {
|
||||||
xml.debug()
|
xml.debug()
|
||||||
xml.http() {
|
xml.http() {
|
||||||
interceptUrl('/**', 'denyAll')
|
interceptUrl('/**', 'denyAll')
|
||||||
'openid-login'()
|
'openid-login'()
|
||||||
'remember-me'()
|
'remember-me'()
|
||||||
'csrf'(disabled:true)
|
'csrf'(disabled:true)
|
||||||
}
|
}
|
||||||
createAppContext()
|
createAppContext()
|
||||||
|
|
||||||
// Default login filter should be present since we haven't specified any login URLs
|
// Default login filter should be present since we haven't specified any login URLs
|
||||||
def loginFilter = getFilter(DefaultLoginPageGeneratingFilter)
|
def loginFilter = getFilter(DefaultLoginPageGeneratingFilter)
|
||||||
def openIDFilter = getFilter(OpenIDAuthenticationFilter)
|
def openIDFilter = getFilter(OpenIDAuthenticationFilter)
|
||||||
openIDFilter.setConsumer(new OpenIDConsumer() {
|
openIDFilter.setConsumer(new OpenIDConsumer() {
|
||||||
public String beginConsumption(HttpServletRequest req, String claimedIdentity, String returnToUrl, String realm)
|
public String beginConsumption(HttpServletRequest req, String claimedIdentity, String returnToUrl, String realm)
|
||||||
throws OpenIDConsumerException {
|
throws OpenIDConsumerException {
|
||||||
return "http://testopenid.com?openid.return_to=" + returnToUrl;
|
return "http://testopenid.com?openid.return_to=" + returnToUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
public OpenIDAuthenticationToken endConsumption(HttpServletRequest req) throws OpenIDConsumerException {
|
public OpenIDAuthenticationToken endConsumption(HttpServletRequest req) throws OpenIDConsumerException {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
Set<String> returnToUrlParameters = new HashSet<String>()
|
Set<String> returnToUrlParameters = new HashSet<String>()
|
||||||
returnToUrlParameters.add(AbstractRememberMeServices.DEFAULT_PARAMETER)
|
returnToUrlParameters.add(AbstractRememberMeServices.DEFAULT_PARAMETER)
|
||||||
openIDFilter.setReturnToUrlParameters(returnToUrlParameters)
|
openIDFilter.setReturnToUrlParameters(returnToUrlParameters)
|
||||||
assert loginFilter.openIDrememberMeParameter != null
|
assert loginFilter.openIDrememberMeParameter != null
|
||||||
|
|
||||||
MockHttpServletRequest request = new MockHttpServletRequest(method:'GET');
|
MockHttpServletRequest request = new MockHttpServletRequest(method:'GET');
|
||||||
MockHttpServletResponse response = new MockHttpServletResponse();
|
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||||
|
|
||||||
when: "Initial request is made"
|
when: "Initial request is made"
|
||||||
Filter fc = appContext.getBean(BeanIds.SPRING_SECURITY_FILTER_CHAIN)
|
Filter fc = appContext.getBean(BeanIds.SPRING_SECURITY_FILTER_CHAIN)
|
||||||
request.setServletPath("/something.html")
|
request.setServletPath("/something.html")
|
||||||
fc.doFilter(request, response, new MockFilterChain())
|
fc.doFilter(request, response, new MockFilterChain())
|
||||||
then: "Redirected to login"
|
then: "Redirected to login"
|
||||||
response.getRedirectedUrl().endsWith("/login")
|
response.getRedirectedUrl().endsWith("/login")
|
||||||
when: "Login page is requested"
|
when: "Login page is requested"
|
||||||
request.setServletPath("/login")
|
request.setServletPath("/login")
|
||||||
request.setRequestURI("/login")
|
request.setRequestURI("/login")
|
||||||
response = new MockHttpServletResponse()
|
response = new MockHttpServletResponse()
|
||||||
fc.doFilter(request, response, new MockFilterChain())
|
fc.doFilter(request, response, new MockFilterChain())
|
||||||
then: "Remember-me choice is added to page"
|
then: "Remember-me choice is added to page"
|
||||||
response.getContentAsString().contains(AbstractRememberMeServices.DEFAULT_PARAMETER)
|
response.getContentAsString().contains(AbstractRememberMeServices.DEFAULT_PARAMETER)
|
||||||
when: "Login is submitted with remember-me selected"
|
when: "Login is submitted with remember-me selected"
|
||||||
request.servletPath = "/login/openid"
|
request.servletPath = "/login/openid"
|
||||||
request.setParameter(OpenIDAuthenticationFilter.DEFAULT_CLAIMED_IDENTITY_FIELD, "http://hey.openid.com/")
|
request.setParameter(OpenIDAuthenticationFilter.DEFAULT_CLAIMED_IDENTITY_FIELD, "http://hey.openid.com/")
|
||||||
request.setParameter(AbstractRememberMeServices.DEFAULT_PARAMETER, "on")
|
request.setParameter(AbstractRememberMeServices.DEFAULT_PARAMETER, "on")
|
||||||
response = new MockHttpServletResponse();
|
response = new MockHttpServletResponse();
|
||||||
fc.doFilter(request, response, new MockFilterChain());
|
fc.doFilter(request, response, new MockFilterChain());
|
||||||
String expectedReturnTo = request.getRequestURL().append("?")
|
String expectedReturnTo = request.getRequestURL().append("?")
|
||||||
.append(AbstractRememberMeServices.DEFAULT_PARAMETER)
|
.append(AbstractRememberMeServices.DEFAULT_PARAMETER)
|
||||||
.append("=").append("on").toString();
|
.append("=").append("on").toString();
|
||||||
then: "return_to URL contains remember-me choice"
|
then: "return_to URL contains remember-me choice"
|
||||||
response.getRedirectedUrl() == "http://testopenid.com?openid.return_to=" + expectedReturnTo
|
response.getRedirectedUrl() == "http://testopenid.com?openid.return_to=" + expectedReturnTo
|
||||||
}
|
}
|
||||||
|
|
||||||
def openIDWithAttributeExchangeConfigurationIsParsedCorrectly() {
|
def openIDWithAttributeExchangeConfigurationIsParsedCorrectly() {
|
||||||
xml.http() {
|
xml.http() {
|
||||||
'openid-login'() {
|
'openid-login'() {
|
||||||
'attribute-exchange'() {
|
'attribute-exchange'() {
|
||||||
'openid-attribute'(name: 'nickname', type: 'http://schema.openid.net/namePerson/friendly')
|
'openid-attribute'(name: 'nickname', type: 'http://schema.openid.net/namePerson/friendly')
|
||||||
'openid-attribute'(name: 'email', type: 'http://schema.openid.net/contact/email', required: 'true',
|
'openid-attribute'(name: 'email', type: 'http://schema.openid.net/contact/email', required: 'true',
|
||||||
'count': '2')
|
'count': '2')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
createAppContext()
|
createAppContext()
|
||||||
|
|
||||||
List attributes = getFilter(OpenIDAuthenticationFilter).consumer.attributesToFetchFactory.createAttributeList('http://someid')
|
List attributes = getFilter(OpenIDAuthenticationFilter).consumer.attributesToFetchFactory.createAttributeList('http://someid')
|
||||||
|
|
||||||
expect:
|
expect:
|
||||||
attributes.size() == 2
|
attributes.size() == 2
|
||||||
attributes[0].name == 'nickname'
|
attributes[0].name == 'nickname'
|
||||||
attributes[0].type == 'http://schema.openid.net/namePerson/friendly'
|
attributes[0].type == 'http://schema.openid.net/namePerson/friendly'
|
||||||
!attributes[0].required
|
!attributes[0].required
|
||||||
attributes[1].required
|
attributes[1].required
|
||||||
attributes[1].getCount() == 2
|
attributes[1].getCount() == 2
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
@ -85,80 +85,80 @@ import org.springframework.security.authentication.AuthenticationManager
|
||||||
class InterceptUrlConfigTests extends AbstractHttpConfigTests {
|
class InterceptUrlConfigTests extends AbstractHttpConfigTests {
|
||||||
|
|
||||||
def "SEC-2256: intercept-url method is not given priority"() {
|
def "SEC-2256: intercept-url method is not given priority"() {
|
||||||
when:
|
when:
|
||||||
httpAutoConfig {
|
httpAutoConfig {
|
||||||
'intercept-url'(pattern: '/anyurl', access: "ROLE_USER")
|
'intercept-url'(pattern: '/anyurl', access: "ROLE_USER")
|
||||||
'intercept-url'(pattern: '/anyurl', 'method':'GET',access: 'ROLE_ADMIN')
|
'intercept-url'(pattern: '/anyurl', 'method':'GET',access: 'ROLE_ADMIN')
|
||||||
}
|
}
|
||||||
createAppContext()
|
createAppContext()
|
||||||
|
|
||||||
def fids = getFilter(FilterSecurityInterceptor).securityMetadataSource
|
def fids = getFilter(FilterSecurityInterceptor).securityMetadataSource
|
||||||
def attrs = fids.getAttributes(createFilterinvocation("/anyurl", "GET"))
|
def attrs = fids.getAttributes(createFilterinvocation("/anyurl", "GET"))
|
||||||
def attrsPost = fids.getAttributes(createFilterinvocation("/anyurl", "POST"))
|
def attrsPost = fids.getAttributes(createFilterinvocation("/anyurl", "POST"))
|
||||||
|
|
||||||
then:
|
then:
|
||||||
attrs.size() == 1
|
attrs.size() == 1
|
||||||
attrs.contains(new SecurityConfig("ROLE_USER"))
|
attrs.contains(new SecurityConfig("ROLE_USER"))
|
||||||
attrsPost.size() == 1
|
attrsPost.size() == 1
|
||||||
attrsPost.contains(new SecurityConfig("ROLE_USER"))
|
attrsPost.contains(new SecurityConfig("ROLE_USER"))
|
||||||
}
|
}
|
||||||
|
|
||||||
def "SEC-2355: intercept-url support patch"() {
|
def "SEC-2355: intercept-url support patch"() {
|
||||||
setup:
|
setup:
|
||||||
MockHttpServletRequest request = new MockHttpServletRequest(method:'GET')
|
MockHttpServletRequest request = new MockHttpServletRequest(method:'GET')
|
||||||
MockHttpServletResponse response = new MockHttpServletResponse()
|
MockHttpServletResponse response = new MockHttpServletResponse()
|
||||||
MockFilterChain chain = new MockFilterChain()
|
MockFilterChain chain = new MockFilterChain()
|
||||||
xml.http('use-expressions':false) {
|
xml.http('use-expressions':false) {
|
||||||
'http-basic'()
|
'http-basic'()
|
||||||
'intercept-url'(pattern: '/**', 'method':'PATCH',access: 'ROLE_ADMIN')
|
'intercept-url'(pattern: '/**', 'method':'PATCH',access: 'ROLE_ADMIN')
|
||||||
csrf(disabled:true)
|
csrf(disabled:true)
|
||||||
}
|
}
|
||||||
createAppContext()
|
createAppContext()
|
||||||
when: 'Method other than PATCH is used'
|
when: 'Method other than PATCH is used'
|
||||||
springSecurityFilterChain.doFilter(request,response,chain)
|
springSecurityFilterChain.doFilter(request,response,chain)
|
||||||
then: 'The response is OK'
|
then: 'The response is OK'
|
||||||
response.status == HttpServletResponse.SC_OK
|
response.status == HttpServletResponse.SC_OK
|
||||||
when: 'Method of PATCH is used'
|
when: 'Method of PATCH is used'
|
||||||
request = new MockHttpServletRequest(method:'PATCH')
|
request = new MockHttpServletRequest(method:'PATCH')
|
||||||
response = new MockHttpServletResponse()
|
response = new MockHttpServletResponse()
|
||||||
chain = new MockFilterChain()
|
chain = new MockFilterChain()
|
||||||
springSecurityFilterChain.doFilter(request, response, chain)
|
springSecurityFilterChain.doFilter(request, response, chain)
|
||||||
then: 'The response is unauthorized'
|
then: 'The response is unauthorized'
|
||||||
response.status == HttpServletResponse.SC_UNAUTHORIZED
|
response.status == HttpServletResponse.SC_UNAUTHORIZED
|
||||||
}
|
}
|
||||||
|
|
||||||
def "intercept-url supports hasAnyRoles"() {
|
def "intercept-url supports hasAnyRoles"() {
|
||||||
setup:
|
setup:
|
||||||
MockHttpServletRequest request = new MockHttpServletRequest(method:'GET')
|
MockHttpServletRequest request = new MockHttpServletRequest(method:'GET')
|
||||||
MockHttpServletResponse response = new MockHttpServletResponse()
|
MockHttpServletResponse response = new MockHttpServletResponse()
|
||||||
MockFilterChain chain = new MockFilterChain()
|
MockFilterChain chain = new MockFilterChain()
|
||||||
xml.http('use-expressions':true) {
|
xml.http('use-expressions':true) {
|
||||||
'http-basic'()
|
'http-basic'()
|
||||||
'intercept-url'(pattern: '/**', access: "hasAnyRole('ROLE_DEVELOPER','ROLE_USER')")
|
'intercept-url'(pattern: '/**', access: "hasAnyRole('ROLE_DEVELOPER','ROLE_USER')")
|
||||||
csrf(disabled:true)
|
csrf(disabled:true)
|
||||||
}
|
}
|
||||||
when:
|
when:
|
||||||
createAppContext()
|
createAppContext()
|
||||||
then: 'no error'
|
then: 'no error'
|
||||||
noExceptionThrown()
|
noExceptionThrown()
|
||||||
when: 'ROLE_USER can access'
|
when: 'ROLE_USER can access'
|
||||||
login(request, 'user', 'password')
|
login(request, 'user', 'password')
|
||||||
springSecurityFilterChain.doFilter(request,response,chain)
|
springSecurityFilterChain.doFilter(request,response,chain)
|
||||||
then: 'The response is OK'
|
then: 'The response is OK'
|
||||||
response.status == HttpServletResponse.SC_OK
|
response.status == HttpServletResponse.SC_OK
|
||||||
when: 'ROLE_A cannot access'
|
when: 'ROLE_A cannot access'
|
||||||
request = new MockHttpServletRequest(method:'GET')
|
request = new MockHttpServletRequest(method:'GET')
|
||||||
response = new MockHttpServletResponse()
|
response = new MockHttpServletResponse()
|
||||||
chain = new MockFilterChain()
|
chain = new MockFilterChain()
|
||||||
login(request, 'bob', 'bobspassword')
|
login(request, 'bob', 'bobspassword')
|
||||||
springSecurityFilterChain.doFilter(request,response,chain)
|
springSecurityFilterChain.doFilter(request,response,chain)
|
||||||
then: 'The response is Forbidden'
|
then: 'The response is Forbidden'
|
||||||
response.status == HttpServletResponse.SC_FORBIDDEN
|
response.status == HttpServletResponse.SC_FORBIDDEN
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def login(MockHttpServletRequest request, String username, String password) {
|
def login(MockHttpServletRequest request, String username, String password) {
|
||||||
String toEncode = username + ':' + password
|
String toEncode = username + ':' + password
|
||||||
request.addHeader('Authorization','Basic ' + new String(Base64.encode(toEncode.getBytes('UTF-8'))))
|
request.addHeader('Authorization','Basic ' + new String(Base64.encode(toEncode.getBytes('UTF-8'))))
|
||||||
}
|
}
|
||||||
}
|
}
|
File diff suppressed because it is too large
Load Diff
|
@ -24,110 +24,110 @@ import org.springframework.security.web.SecurityFilterChain
|
||||||
*/
|
*/
|
||||||
class MultiHttpBlockConfigTests extends AbstractHttpConfigTests {
|
class MultiHttpBlockConfigTests extends AbstractHttpConfigTests {
|
||||||
|
|
||||||
def multipleHttpElementsAreSupported () {
|
def multipleHttpElementsAreSupported () {
|
||||||
when: "Two <http> elements are used"
|
when: "Two <http> elements are used"
|
||||||
xml.http(pattern: '/stateless/**', 'create-session': 'stateless') {
|
xml.http(pattern: '/stateless/**', 'create-session': 'stateless') {
|
||||||
'http-basic'()
|
'http-basic'()
|
||||||
}
|
}
|
||||||
xml.http(pattern: '/stateful/**') {
|
xml.http(pattern: '/stateful/**') {
|
||||||
'form-login'()
|
'form-login'()
|
||||||
}
|
}
|
||||||
createAppContext()
|
createAppContext()
|
||||||
FilterChainProxy fcp = appContext.getBean(BeanIds.FILTER_CHAIN_PROXY)
|
FilterChainProxy fcp = appContext.getBean(BeanIds.FILTER_CHAIN_PROXY)
|
||||||
def filterChains = fcp.getFilterChains();
|
def filterChains = fcp.getFilterChains();
|
||||||
|
|
||||||
then:
|
then:
|
||||||
filterChains.size() == 2
|
filterChains.size() == 2
|
||||||
filterChains[0].requestMatcher.pattern == '/stateless/**'
|
filterChains[0].requestMatcher.pattern == '/stateless/**'
|
||||||
}
|
}
|
||||||
|
|
||||||
def duplicateHttpElementsAreRejected () {
|
def duplicateHttpElementsAreRejected () {
|
||||||
when: "Two <http> elements are used"
|
when: "Two <http> elements are used"
|
||||||
xml.http('create-session': 'stateless') {
|
xml.http('create-session': 'stateless') {
|
||||||
'http-basic'()
|
'http-basic'()
|
||||||
}
|
}
|
||||||
xml.http() {
|
xml.http() {
|
||||||
'form-login'()
|
'form-login'()
|
||||||
}
|
}
|
||||||
createAppContext()
|
createAppContext()
|
||||||
then:
|
then:
|
||||||
BeanCreationException e = thrown()
|
BeanCreationException e = thrown()
|
||||||
e.cause instanceof IllegalArgumentException
|
e.cause instanceof IllegalArgumentException
|
||||||
}
|
}
|
||||||
|
|
||||||
def duplicatePatternsAreRejected () {
|
def duplicatePatternsAreRejected () {
|
||||||
when: "Two <http> elements with the same pattern are used"
|
when: "Two <http> elements with the same pattern are used"
|
||||||
xml.http(pattern: '/stateless/**', 'create-session': 'stateless') {
|
xml.http(pattern: '/stateless/**', 'create-session': 'stateless') {
|
||||||
'http-basic'()
|
'http-basic'()
|
||||||
}
|
}
|
||||||
xml.http(pattern: '/stateless/**') {
|
xml.http(pattern: '/stateless/**') {
|
||||||
'form-login'()
|
'form-login'()
|
||||||
}
|
}
|
||||||
createAppContext()
|
createAppContext()
|
||||||
then:
|
then:
|
||||||
BeanCreationException e = thrown()
|
BeanCreationException e = thrown()
|
||||||
e.cause instanceof IllegalArgumentException
|
e.cause instanceof IllegalArgumentException
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def 'SEC-1937: http@authentication-manager-ref and multi authentication-mananager'() {
|
def 'SEC-1937: http@authentication-manager-ref and multi authentication-mananager'() {
|
||||||
setup:
|
setup:
|
||||||
xml.http('authentication-manager-ref' : 'authManager', 'pattern' : '/first/**') {
|
xml.http('authentication-manager-ref' : 'authManager', 'pattern' : '/first/**') {
|
||||||
'form-login'('login-processing-url': '/first/login')
|
'form-login'('login-processing-url': '/first/login')
|
||||||
csrf(disabled:true)
|
csrf(disabled:true)
|
||||||
}
|
}
|
||||||
xml.http('authentication-manager-ref' : 'authManager2') {
|
xml.http('authentication-manager-ref' : 'authManager2') {
|
||||||
'form-login'()
|
'form-login'()
|
||||||
csrf(disabled:true)
|
csrf(disabled:true)
|
||||||
}
|
}
|
||||||
mockBean(UserDetailsService,'uds')
|
mockBean(UserDetailsService,'uds')
|
||||||
mockBean(UserDetailsService,'uds2')
|
mockBean(UserDetailsService,'uds2')
|
||||||
createAppContext("""
|
createAppContext("""
|
||||||
<authentication-manager id="authManager">
|
<authentication-manager id="authManager">
|
||||||
<authentication-provider user-service-ref="uds" />
|
<authentication-provider user-service-ref="uds" />
|
||||||
</authentication-manager>
|
</authentication-manager>
|
||||||
<authentication-manager id="authManager2">
|
<authentication-manager id="authManager2">
|
||||||
<authentication-provider user-service-ref="uds2" />
|
<authentication-provider user-service-ref="uds2" />
|
||||||
</authentication-manager>
|
</authentication-manager>
|
||||||
""")
|
""")
|
||||||
UserDetailsService uds = appContext.getBean('uds')
|
UserDetailsService uds = appContext.getBean('uds')
|
||||||
UserDetailsService uds2 = appContext.getBean('uds2')
|
UserDetailsService uds2 = appContext.getBean('uds2')
|
||||||
when:
|
when:
|
||||||
MockHttpServletRequest request = new MockHttpServletRequest()
|
MockHttpServletRequest request = new MockHttpServletRequest()
|
||||||
MockHttpServletResponse response = new MockHttpServletResponse()
|
MockHttpServletResponse response = new MockHttpServletResponse()
|
||||||
MockFilterChain chain = new MockFilterChain()
|
MockFilterChain chain = new MockFilterChain()
|
||||||
request.servletPath = "/first/login"
|
request.servletPath = "/first/login"
|
||||||
request.requestURI = "/first/login"
|
request.requestURI = "/first/login"
|
||||||
request.method = 'POST'
|
request.method = 'POST'
|
||||||
springSecurityFilterChain.doFilter(request,response,chain)
|
springSecurityFilterChain.doFilter(request,response,chain)
|
||||||
then:
|
then:
|
||||||
verify(uds).loadUserByUsername(anyString()) || true
|
verify(uds).loadUserByUsername(anyString()) || true
|
||||||
verifyZeroInteractions(uds2) || true
|
verifyZeroInteractions(uds2) || true
|
||||||
when:
|
when:
|
||||||
MockHttpServletRequest request2 = new MockHttpServletRequest()
|
MockHttpServletRequest request2 = new MockHttpServletRequest()
|
||||||
MockHttpServletResponse response2 = new MockHttpServletResponse()
|
MockHttpServletResponse response2 = new MockHttpServletResponse()
|
||||||
MockFilterChain chain2 = new MockFilterChain()
|
MockFilterChain chain2 = new MockFilterChain()
|
||||||
request2.servletPath = "/login"
|
request2.servletPath = "/login"
|
||||||
request2.requestURI = "/login"
|
request2.requestURI = "/login"
|
||||||
request2.method = 'POST'
|
request2.method = 'POST'
|
||||||
springSecurityFilterChain.doFilter(request2,response2,chain2)
|
springSecurityFilterChain.doFilter(request2,response2,chain2)
|
||||||
then:
|
then:
|
||||||
verify(uds2).loadUserByUsername(anyString()) || true
|
verify(uds2).loadUserByUsername(anyString()) || true
|
||||||
verifyNoMoreInteractions(uds) || true
|
verifyNoMoreInteractions(uds) || true
|
||||||
}
|
}
|
||||||
|
|
||||||
def multipleAuthenticationManagersWorks () {
|
def multipleAuthenticationManagersWorks () {
|
||||||
xml.http(name: 'basic', pattern: '/basic/**', ) {
|
xml.http(name: 'basic', pattern: '/basic/**', ) {
|
||||||
'http-basic'()
|
'http-basic'()
|
||||||
}
|
}
|
||||||
xml.http(pattern: '/form/**') {
|
xml.http(pattern: '/form/**') {
|
||||||
'form-login'()
|
'form-login'()
|
||||||
}
|
}
|
||||||
createAppContext()
|
createAppContext()
|
||||||
FilterChainProxy fcp = appContext.getBean(BeanIds.FILTER_CHAIN_PROXY)
|
FilterChainProxy fcp = appContext.getBean(BeanIds.FILTER_CHAIN_PROXY)
|
||||||
SecurityFilterChain basicChain = fcp.filterChains[0];
|
SecurityFilterChain basicChain = fcp.filterChains[0];
|
||||||
|
|
||||||
expect:
|
expect:
|
||||||
Assert.assertSame (basicChain, appContext.getBean('basic'))
|
Assert.assertSame (basicChain, appContext.getBean('basic'))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,140 +17,140 @@ import org.springframework.security.web.authentication.UsernamePasswordAuthentic
|
||||||
|
|
||||||
class PlaceHolderAndELConfigTests extends AbstractHttpConfigTests {
|
class PlaceHolderAndELConfigTests extends AbstractHttpConfigTests {
|
||||||
|
|
||||||
def setup() {
|
def setup() {
|
||||||
// Add a PropertyPlaceholderConfigurer to the context for all the tests
|
// Add a PropertyPlaceholderConfigurer to the context for all the tests
|
||||||
bean(PropertyPlaceholderConfigurer.class.name, PropertyPlaceholderConfigurer.class)
|
bean(PropertyPlaceholderConfigurer.class.name, PropertyPlaceholderConfigurer.class)
|
||||||
}
|
}
|
||||||
|
|
||||||
def unsecuredPatternSupportsPlaceholderForPattern() {
|
def unsecuredPatternSupportsPlaceholderForPattern() {
|
||||||
System.setProperty("pattern.nofilters", "/unprotected");
|
System.setProperty("pattern.nofilters", "/unprotected");
|
||||||
|
|
||||||
xml.http(pattern: '${pattern.nofilters}', security: 'none')
|
xml.http(pattern: '${pattern.nofilters}', security: 'none')
|
||||||
httpAutoConfig() {
|
httpAutoConfig() {
|
||||||
interceptUrl('/**', 'ROLE_A')
|
interceptUrl('/**', 'ROLE_A')
|
||||||
}
|
}
|
||||||
createAppContext()
|
createAppContext()
|
||||||
|
|
||||||
List filters = getFilters("/unprotected");
|
List filters = getFilters("/unprotected");
|
||||||
|
|
||||||
expect:
|
expect:
|
||||||
filters.size() == 0
|
filters.size() == 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// SEC-1201
|
// SEC-1201
|
||||||
def interceptUrlsAndFormLoginSupportPropertyPlaceholders() {
|
def interceptUrlsAndFormLoginSupportPropertyPlaceholders() {
|
||||||
System.setProperty("secure.Url", "/Secure");
|
System.setProperty("secure.Url", "/Secure");
|
||||||
System.setProperty("secure.role", "ROLE_A");
|
System.setProperty("secure.role", "ROLE_A");
|
||||||
System.setProperty("login.page", "/loginPage");
|
System.setProperty("login.page", "/loginPage");
|
||||||
System.setProperty("default.target", "/defaultTarget");
|
System.setProperty("default.target", "/defaultTarget");
|
||||||
System.setProperty("auth.failure", "/authFailure");
|
System.setProperty("auth.failure", "/authFailure");
|
||||||
|
|
||||||
xml.http(pattern: '${login.page}', security: 'none')
|
xml.http(pattern: '${login.page}', security: 'none')
|
||||||
xml.http('use-expressions':false) {
|
xml.http('use-expressions':false) {
|
||||||
interceptUrl('${secure.Url}', '${secure.role}')
|
interceptUrl('${secure.Url}', '${secure.role}')
|
||||||
'form-login'('login-page':'${login.page}', 'default-target-url': '${default.target}',
|
'form-login'('login-page':'${login.page}', 'default-target-url': '${default.target}',
|
||||||
'authentication-failure-url':'${auth.failure}');
|
'authentication-failure-url':'${auth.failure}');
|
||||||
}
|
}
|
||||||
createAppContext();
|
createAppContext();
|
||||||
|
|
||||||
expect:
|
expect:
|
||||||
propertyValuesMatchPlaceholders()
|
propertyValuesMatchPlaceholders()
|
||||||
getFilters("/loginPage").size() == 0
|
getFilters("/loginPage").size() == 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// SEC-1309
|
// SEC-1309
|
||||||
def interceptUrlsAndFormLoginSupportEL() {
|
def interceptUrlsAndFormLoginSupportEL() {
|
||||||
System.setProperty("secure.url", "/Secure");
|
System.setProperty("secure.url", "/Secure");
|
||||||
System.setProperty("secure.role", "ROLE_A");
|
System.setProperty("secure.role", "ROLE_A");
|
||||||
System.setProperty("login.page", "/loginPage");
|
System.setProperty("login.page", "/loginPage");
|
||||||
System.setProperty("default.target", "/defaultTarget");
|
System.setProperty("default.target", "/defaultTarget");
|
||||||
System.setProperty("auth.failure", "/authFailure");
|
System.setProperty("auth.failure", "/authFailure");
|
||||||
|
|
||||||
xml.http('use-expressions':false) {
|
xml.http('use-expressions':false) {
|
||||||
interceptUrl("#{systemProperties['secure.url']}", "#{systemProperties['secure.role']}")
|
interceptUrl("#{systemProperties['secure.url']}", "#{systemProperties['secure.role']}")
|
||||||
'form-login'('login-page':"#{systemProperties['login.page']}", 'default-target-url': "#{systemProperties['default.target']}",
|
'form-login'('login-page':"#{systemProperties['login.page']}", 'default-target-url': "#{systemProperties['default.target']}",
|
||||||
'authentication-failure-url':"#{systemProperties['auth.failure']}");
|
'authentication-failure-url':"#{systemProperties['auth.failure']}");
|
||||||
}
|
}
|
||||||
createAppContext()
|
createAppContext()
|
||||||
|
|
||||||
expect:
|
expect:
|
||||||
propertyValuesMatchPlaceholders()
|
propertyValuesMatchPlaceholders()
|
||||||
}
|
}
|
||||||
|
|
||||||
private void propertyValuesMatchPlaceholders() {
|
private void propertyValuesMatchPlaceholders() {
|
||||||
// Check the security attribute
|
// Check the security attribute
|
||||||
def fis = getFilter(FilterSecurityInterceptor);
|
def fis = getFilter(FilterSecurityInterceptor);
|
||||||
def fids = fis.getSecurityMetadataSource();
|
def fids = fis.getSecurityMetadataSource();
|
||||||
Collection attrs = fids.getAttributes(createFilterinvocation("/secure", null));
|
Collection attrs = fids.getAttributes(createFilterinvocation("/secure", null));
|
||||||
assert attrs.size() == 1
|
assert attrs.size() == 1
|
||||||
assert attrs.contains(new SecurityConfig("ROLE_A"))
|
assert attrs.contains(new SecurityConfig("ROLE_A"))
|
||||||
|
|
||||||
// Check the form login properties are set
|
// Check the form login properties are set
|
||||||
def apf = getFilter(UsernamePasswordAuthenticationFilter)
|
def apf = getFilter(UsernamePasswordAuthenticationFilter)
|
||||||
assert FieldUtils.getFieldValue(apf, "successHandler.defaultTargetUrl") == '/defaultTarget'
|
assert FieldUtils.getFieldValue(apf, "successHandler.defaultTargetUrl") == '/defaultTarget'
|
||||||
assert "/authFailure" == FieldUtils.getFieldValue(apf, "failureHandler.defaultFailureUrl")
|
assert "/authFailure" == FieldUtils.getFieldValue(apf, "failureHandler.defaultFailureUrl")
|
||||||
|
|
||||||
def etf = getFilter(ExceptionTranslationFilter)
|
def etf = getFilter(ExceptionTranslationFilter)
|
||||||
assert "/loginPage"== etf.authenticationEntryPoint.loginFormUrl
|
assert "/loginPage"== etf.authenticationEntryPoint.loginFormUrl
|
||||||
}
|
}
|
||||||
|
|
||||||
def portMappingsWorkWithPlaceholdersAndEL() {
|
def portMappingsWorkWithPlaceholdersAndEL() {
|
||||||
System.setProperty("http", "9080");
|
System.setProperty("http", "9080");
|
||||||
System.setProperty("https", "9443");
|
System.setProperty("https", "9443");
|
||||||
|
|
||||||
httpAutoConfig {
|
httpAutoConfig {
|
||||||
'port-mappings'() {
|
'port-mappings'() {
|
||||||
'port-mapping'(http: '#{systemProperties.http}', https: '${https}')
|
'port-mapping'(http: '#{systemProperties.http}', https: '${https}')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
createAppContext();
|
createAppContext();
|
||||||
|
|
||||||
def pm = (appContext.getBeansOfType(PortMapperImpl).values() as List)[0];
|
def pm = (appContext.getBeansOfType(PortMapperImpl).values() as List)[0];
|
||||||
|
|
||||||
expect:
|
expect:
|
||||||
pm.getTranslatedPortMappings().size() == 1
|
pm.getTranslatedPortMappings().size() == 1
|
||||||
pm.lookupHttpPort(9443) == 9080
|
pm.lookupHttpPort(9443) == 9080
|
||||||
pm.lookupHttpsPort(9080) == 9443
|
pm.lookupHttpsPort(9080) == 9443
|
||||||
}
|
}
|
||||||
|
|
||||||
def requiresChannelSupportsPlaceholder() {
|
def requiresChannelSupportsPlaceholder() {
|
||||||
System.setProperty("secure.url", "/secure");
|
System.setProperty("secure.url", "/secure");
|
||||||
System.setProperty("required.channel", "https");
|
System.setProperty("required.channel", "https");
|
||||||
|
|
||||||
httpAutoConfig {
|
httpAutoConfig {
|
||||||
'intercept-url'(pattern: '${secure.url}', 'requires-channel': '${required.channel}')
|
'intercept-url'(pattern: '${secure.url}', 'requires-channel': '${required.channel}')
|
||||||
}
|
}
|
||||||
createAppContext();
|
createAppContext();
|
||||||
List filters = getFilters("/secure");
|
List filters = getFilters("/secure");
|
||||||
|
|
||||||
expect:
|
expect:
|
||||||
filters.size() == AUTO_CONFIG_FILTERS + 1
|
filters.size() == AUTO_CONFIG_FILTERS + 1
|
||||||
filters[0] instanceof ChannelProcessingFilter
|
filters[0] instanceof ChannelProcessingFilter
|
||||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||||
request.setServletPath("/secure");
|
request.setServletPath("/secure");
|
||||||
MockHttpServletResponse response = new MockHttpServletResponse();
|
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||||
filters[0].doFilter(request, response, new MockFilterChain());
|
filters[0].doFilter(request, response, new MockFilterChain());
|
||||||
response.getRedirectedUrl().startsWith("https")
|
response.getRedirectedUrl().startsWith("https")
|
||||||
}
|
}
|
||||||
|
|
||||||
def accessDeniedPageWorksWithPlaceholders() {
|
def accessDeniedPageWorksWithPlaceholders() {
|
||||||
System.setProperty("accessDenied", "/go-away");
|
System.setProperty("accessDenied", "/go-away");
|
||||||
xml.http('auto-config': 'true') {
|
xml.http('auto-config': 'true') {
|
||||||
'access-denied-handler'('error-page' : '${accessDenied}') {}
|
'access-denied-handler'('error-page' : '${accessDenied}') {}
|
||||||
}
|
}
|
||||||
createAppContext();
|
createAppContext();
|
||||||
|
|
||||||
expect:
|
expect:
|
||||||
FieldUtils.getFieldValue(getFilter(ExceptionTranslationFilter.class), "accessDeniedHandler.errorPage") == '/go-away'
|
FieldUtils.getFieldValue(getFilter(ExceptionTranslationFilter.class), "accessDeniedHandler.errorPage") == '/go-away'
|
||||||
}
|
}
|
||||||
|
|
||||||
def accessDeniedHandlerPageWorksWithEL() {
|
def accessDeniedHandlerPageWorksWithEL() {
|
||||||
httpAutoConfig {
|
httpAutoConfig {
|
||||||
'access-denied-handler'('error-page': "#{'/go' + '-away'}")
|
'access-denied-handler'('error-page': "#{'/go' + '-away'}")
|
||||||
}
|
}
|
||||||
createAppContext()
|
createAppContext()
|
||||||
|
|
||||||
expect:
|
expect:
|
||||||
getFilter(ExceptionTranslationFilter).accessDeniedHandler.errorPage == '/go-away'
|
getFilter(ExceptionTranslationFilter).accessDeniedHandler.errorPage == '/go-away'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
@ -45,268 +45,268 @@ import org.springframework.security.web.authentication.rememberme.TokenBasedReme
|
||||||
*/
|
*/
|
||||||
class RememberMeConfigTests extends AbstractHttpConfigTests {
|
class RememberMeConfigTests extends AbstractHttpConfigTests {
|
||||||
|
|
||||||
def rememberMeServiceWorksWithTokenRepoRef() {
|
def rememberMeServiceWorksWithTokenRepoRef() {
|
||||||
httpAutoConfig () {
|
httpAutoConfig () {
|
||||||
'remember-me'('token-repository-ref': 'tokenRepo')
|
'remember-me'('token-repository-ref': 'tokenRepo')
|
||||||
}
|
}
|
||||||
bean('tokenRepo', CustomTokenRepository.class.name)
|
bean('tokenRepo', CustomTokenRepository.class.name)
|
||||||
|
|
||||||
createAppContext(AUTH_PROVIDER_XML)
|
createAppContext(AUTH_PROVIDER_XML)
|
||||||
|
|
||||||
def rememberMeServices = rememberMeServices()
|
def rememberMeServices = rememberMeServices()
|
||||||
|
|
||||||
expect:
|
expect:
|
||||||
rememberMeServices instanceof PersistentTokenBasedRememberMeServices
|
rememberMeServices instanceof PersistentTokenBasedRememberMeServices
|
||||||
rememberMeServices.tokenRepository instanceof CustomTokenRepository
|
rememberMeServices.tokenRepository instanceof CustomTokenRepository
|
||||||
FieldUtils.getFieldValue(rememberMeServices, "useSecureCookie") == null
|
FieldUtils.getFieldValue(rememberMeServices, "useSecureCookie") == null
|
||||||
}
|
}
|
||||||
|
|
||||||
def rememberMeServiceWorksWithDataSourceRef() {
|
def rememberMeServiceWorksWithDataSourceRef() {
|
||||||
httpAutoConfig () {
|
httpAutoConfig () {
|
||||||
'remember-me'('data-source-ref': 'ds')
|
'remember-me'('data-source-ref': 'ds')
|
||||||
}
|
}
|
||||||
bean('ds', TestDataSource.class.name, ['tokendb'])
|
bean('ds', TestDataSource.class.name, ['tokendb'])
|
||||||
|
|
||||||
createAppContext(AUTH_PROVIDER_XML)
|
createAppContext(AUTH_PROVIDER_XML)
|
||||||
|
|
||||||
def rememberMeServices = rememberMeServices()
|
def rememberMeServices = rememberMeServices()
|
||||||
|
|
||||||
expect:
|
expect:
|
||||||
rememberMeServices instanceof PersistentTokenBasedRememberMeServices
|
rememberMeServices instanceof PersistentTokenBasedRememberMeServices
|
||||||
rememberMeServices.tokenRepository instanceof JdbcTokenRepositoryImpl
|
rememberMeServices.tokenRepository instanceof JdbcTokenRepositoryImpl
|
||||||
}
|
}
|
||||||
|
|
||||||
def rememberMeServiceWorksWithAuthenticationSuccessHandlerRef() {
|
def rememberMeServiceWorksWithAuthenticationSuccessHandlerRef() {
|
||||||
httpAutoConfig () {
|
httpAutoConfig () {
|
||||||
'remember-me'('authentication-success-handler-ref': 'sh')
|
'remember-me'('authentication-success-handler-ref': 'sh')
|
||||||
}
|
}
|
||||||
bean('sh', SimpleUrlAuthenticationSuccessHandler.class.name, ['/target'])
|
bean('sh', SimpleUrlAuthenticationSuccessHandler.class.name, ['/target'])
|
||||||
|
|
||||||
createAppContext(AUTH_PROVIDER_XML)
|
createAppContext(AUTH_PROVIDER_XML)
|
||||||
|
|
||||||
expect:
|
expect:
|
||||||
getFilter(RememberMeAuthenticationFilter.class).successHandler instanceof SimpleUrlAuthenticationSuccessHandler
|
getFilter(RememberMeAuthenticationFilter.class).successHandler instanceof SimpleUrlAuthenticationSuccessHandler
|
||||||
}
|
}
|
||||||
|
|
||||||
def rememberMeServiceWorksWithExternalServicesImpl() {
|
def rememberMeServiceWorksWithExternalServicesImpl() {
|
||||||
httpAutoConfig () {
|
httpAutoConfig () {
|
||||||
'remember-me'('key': "#{'our' + 'key'}", 'services-ref': 'rms')
|
'remember-me'('key': "#{'our' + 'key'}", 'services-ref': 'rms')
|
||||||
csrf(disabled:true)
|
csrf(disabled:true)
|
||||||
}
|
}
|
||||||
xml.'b:bean'(id: 'rms', 'class': TokenBasedRememberMeServices.class.name) {
|
xml.'b:bean'(id: 'rms', 'class': TokenBasedRememberMeServices.class.name) {
|
||||||
'b:constructor-arg'(value: 'ourKey')
|
'b:constructor-arg'(value: 'ourKey')
|
||||||
'b:constructor-arg'(ref: 'us')
|
'b:constructor-arg'(ref: 'us')
|
||||||
'b:property'(name: 'tokenValiditySeconds', value: '5000')
|
'b:property'(name: 'tokenValiditySeconds', value: '5000')
|
||||||
}
|
}
|
||||||
|
|
||||||
createAppContext(AUTH_PROVIDER_XML)
|
createAppContext(AUTH_PROVIDER_XML)
|
||||||
|
|
||||||
List logoutHandlers = FieldUtils.getFieldValue(getFilter(LogoutFilter.class), "handlers");
|
List logoutHandlers = FieldUtils.getFieldValue(getFilter(LogoutFilter.class), "handlers");
|
||||||
Map ams = appContext.getBeansOfType(ProviderManager.class);
|
Map ams = appContext.getBeansOfType(ProviderManager.class);
|
||||||
ProviderManager am = (ams.values() as List).find { it instanceof ProviderManager && it.providers.size() == 2}
|
ProviderManager am = (ams.values() as List).find { it instanceof ProviderManager && it.providers.size() == 2}
|
||||||
RememberMeAuthenticationProvider rmp = am.providers.find { it instanceof RememberMeAuthenticationProvider}
|
RememberMeAuthenticationProvider rmp = am.providers.find { it instanceof RememberMeAuthenticationProvider}
|
||||||
|
|
||||||
expect:
|
expect:
|
||||||
rmp != null
|
rmp != null
|
||||||
5000 == FieldUtils.getFieldValue(rememberMeServices(), "tokenValiditySeconds")
|
5000 == FieldUtils.getFieldValue(rememberMeServices(), "tokenValiditySeconds")
|
||||||
// SEC-909
|
// SEC-909
|
||||||
logoutHandlers.size() == 2
|
logoutHandlers.size() == 2
|
||||||
logoutHandlers.get(1) == rememberMeServices()
|
logoutHandlers.get(1) == rememberMeServices()
|
||||||
// SEC-1281
|
// SEC-1281
|
||||||
rmp.key == "ourkey"
|
rmp.key == "ourkey"
|
||||||
}
|
}
|
||||||
|
|
||||||
def rememberMeAddsLogoutHandlerToLogoutFilter() {
|
def rememberMeAddsLogoutHandlerToLogoutFilter() {
|
||||||
httpAutoConfig () {
|
httpAutoConfig () {
|
||||||
'remember-me'()
|
'remember-me'()
|
||||||
csrf(disabled:true)
|
csrf(disabled:true)
|
||||||
}
|
}
|
||||||
createAppContext(AUTH_PROVIDER_XML)
|
createAppContext(AUTH_PROVIDER_XML)
|
||||||
|
|
||||||
def rememberMeServices = rememberMeServices()
|
def rememberMeServices = rememberMeServices()
|
||||||
List logoutHandlers = getFilter(LogoutFilter.class).handlers
|
List logoutHandlers = getFilter(LogoutFilter.class).handlers
|
||||||
|
|
||||||
expect:
|
expect:
|
||||||
rememberMeServices
|
rememberMeServices
|
||||||
logoutHandlers.size() == 2
|
logoutHandlers.size() == 2
|
||||||
logoutHandlers.get(0) instanceof SecurityContextLogoutHandler
|
logoutHandlers.get(0) instanceof SecurityContextLogoutHandler
|
||||||
logoutHandlers.get(1) == rememberMeServices
|
logoutHandlers.get(1) == rememberMeServices
|
||||||
}
|
}
|
||||||
|
|
||||||
def rememberMeTokenValidityIsParsedCorrectly() {
|
def rememberMeTokenValidityIsParsedCorrectly() {
|
||||||
httpAutoConfig () {
|
httpAutoConfig () {
|
||||||
'remember-me'('key': 'ourkey', 'token-validity-seconds':'10000')
|
'remember-me'('key': 'ourkey', 'token-validity-seconds':'10000')
|
||||||
}
|
}
|
||||||
|
|
||||||
createAppContext(AUTH_PROVIDER_XML)
|
createAppContext(AUTH_PROVIDER_XML)
|
||||||
|
|
||||||
def rememberMeServices = rememberMeServices()
|
def rememberMeServices = rememberMeServices()
|
||||||
def rememberMeFilter = getFilter(RememberMeAuthenticationFilter.class)
|
def rememberMeFilter = getFilter(RememberMeAuthenticationFilter.class)
|
||||||
|
|
||||||
expect:
|
expect:
|
||||||
rememberMeFilter.authenticationManager
|
rememberMeFilter.authenticationManager
|
||||||
rememberMeServices.key == 'ourkey'
|
rememberMeServices.key == 'ourkey'
|
||||||
rememberMeServices.tokenValiditySeconds == 10000
|
rememberMeServices.tokenValiditySeconds == 10000
|
||||||
rememberMeServices.userDetailsService
|
rememberMeServices.userDetailsService
|
||||||
}
|
}
|
||||||
|
|
||||||
def 'Remember-me token validity allows negative value for non-persistent implementation'() {
|
def 'Remember-me token validity allows negative value for non-persistent implementation'() {
|
||||||
httpAutoConfig () {
|
httpAutoConfig () {
|
||||||
'remember-me'('key': 'ourkey', 'token-validity-seconds':'-1')
|
'remember-me'('key': 'ourkey', 'token-validity-seconds':'-1')
|
||||||
}
|
}
|
||||||
|
|
||||||
createAppContext(AUTH_PROVIDER_XML)
|
createAppContext(AUTH_PROVIDER_XML)
|
||||||
expect:
|
expect:
|
||||||
rememberMeServices().tokenValiditySeconds == -1
|
rememberMeServices().tokenValiditySeconds == -1
|
||||||
}
|
}
|
||||||
|
|
||||||
def 'remember-me@token-validity-seconds denies for persistent implementation'() {
|
def 'remember-me@token-validity-seconds denies for persistent implementation'() {
|
||||||
setup:
|
setup:
|
||||||
httpAutoConfig () {
|
httpAutoConfig () {
|
||||||
'remember-me'('key': 'ourkey', 'token-validity-seconds':'-1', 'dataSource' : 'dataSource')
|
'remember-me'('key': 'ourkey', 'token-validity-seconds':'-1', 'dataSource' : 'dataSource')
|
||||||
}
|
}
|
||||||
mockBean(DataSource)
|
mockBean(DataSource)
|
||||||
when:
|
when:
|
||||||
createAppContext(AUTH_PROVIDER_XML)
|
createAppContext(AUTH_PROVIDER_XML)
|
||||||
then:
|
then:
|
||||||
thrown(FatalBeanException)
|
thrown(FatalBeanException)
|
||||||
}
|
}
|
||||||
|
|
||||||
def 'SEC-2165: remember-me@token-validity-seconds allows property placeholders'() {
|
def 'SEC-2165: remember-me@token-validity-seconds allows property placeholders'() {
|
||||||
when:
|
when:
|
||||||
httpAutoConfig () {
|
httpAutoConfig () {
|
||||||
'remember-me'('key': 'ourkey', 'token-validity-seconds':'${security.rememberme.ttl}')
|
'remember-me'('key': 'ourkey', 'token-validity-seconds':'${security.rememberme.ttl}')
|
||||||
}
|
}
|
||||||
xml.'b:bean'(class: PropertyPlaceholderConfigurer.name) {
|
xml.'b:bean'(class: PropertyPlaceholderConfigurer.name) {
|
||||||
'b:property'(name:'properties', value:'security.rememberme.ttl=30')
|
'b:property'(name:'properties', value:'security.rememberme.ttl=30')
|
||||||
}
|
}
|
||||||
|
|
||||||
createAppContext(AUTH_PROVIDER_XML)
|
createAppContext(AUTH_PROVIDER_XML)
|
||||||
then:
|
then:
|
||||||
rememberMeServices().tokenValiditySeconds == 30
|
rememberMeServices().tokenValiditySeconds == 30
|
||||||
}
|
}
|
||||||
|
|
||||||
def rememberMeSecureCookieAttributeIsSetCorrectly() {
|
def rememberMeSecureCookieAttributeIsSetCorrectly() {
|
||||||
httpAutoConfig () {
|
httpAutoConfig () {
|
||||||
'remember-me'('key': 'ourkey', 'use-secure-cookie':'true')
|
'remember-me'('key': 'ourkey', 'use-secure-cookie':'true')
|
||||||
}
|
}
|
||||||
|
|
||||||
createAppContext(AUTH_PROVIDER_XML)
|
createAppContext(AUTH_PROVIDER_XML)
|
||||||
expect:
|
expect:
|
||||||
FieldUtils.getFieldValue(rememberMeServices(), "useSecureCookie")
|
FieldUtils.getFieldValue(rememberMeServices(), "useSecureCookie")
|
||||||
}
|
}
|
||||||
|
|
||||||
// SEC-1827
|
// SEC-1827
|
||||||
def rememberMeSecureCookieAttributeFalse() {
|
def rememberMeSecureCookieAttributeFalse() {
|
||||||
httpAutoConfig () {
|
httpAutoConfig () {
|
||||||
'remember-me'('key': 'ourkey', 'use-secure-cookie':'false')
|
'remember-me'('key': 'ourkey', 'use-secure-cookie':'false')
|
||||||
}
|
}
|
||||||
|
|
||||||
createAppContext(AUTH_PROVIDER_XML)
|
createAppContext(AUTH_PROVIDER_XML)
|
||||||
expect: 'useSecureCookie is false'
|
expect: 'useSecureCookie is false'
|
||||||
FieldUtils.getFieldValue(rememberMeServices(), "useSecureCookie") == Boolean.FALSE
|
FieldUtils.getFieldValue(rememberMeServices(), "useSecureCookie") == Boolean.FALSE
|
||||||
}
|
}
|
||||||
|
|
||||||
def 'Negative token-validity is rejected with persistent implementation'() {
|
def 'Negative token-validity is rejected with persistent implementation'() {
|
||||||
when:
|
when:
|
||||||
httpAutoConfig () {
|
httpAutoConfig () {
|
||||||
'remember-me'('key': 'ourkey', 'token-validity-seconds':'-1', 'token-repository-ref': 'tokenRepo')
|
'remember-me'('key': 'ourkey', 'token-validity-seconds':'-1', 'token-repository-ref': 'tokenRepo')
|
||||||
}
|
}
|
||||||
bean('tokenRepo', InMemoryTokenRepositoryImpl.class.name)
|
bean('tokenRepo', InMemoryTokenRepositoryImpl.class.name)
|
||||||
createAppContext(AUTH_PROVIDER_XML)
|
createAppContext(AUTH_PROVIDER_XML)
|
||||||
|
|
||||||
then:
|
then:
|
||||||
BeanDefinitionParsingException e = thrown()
|
BeanDefinitionParsingException e = thrown()
|
||||||
}
|
}
|
||||||
|
|
||||||
def 'Custom user service is supported'() {
|
def 'Custom user service is supported'() {
|
||||||
when:
|
when:
|
||||||
httpAutoConfig () {
|
httpAutoConfig () {
|
||||||
'remember-me'('key': 'ourkey', 'token-validity-seconds':'-1', 'user-service-ref': 'userService')
|
'remember-me'('key': 'ourkey', 'token-validity-seconds':'-1', 'user-service-ref': 'userService')
|
||||||
}
|
}
|
||||||
bean('userService', MockUserDetailsService.class.name)
|
bean('userService', MockUserDetailsService.class.name)
|
||||||
createAppContext(AUTH_PROVIDER_XML)
|
createAppContext(AUTH_PROVIDER_XML)
|
||||||
|
|
||||||
then: "Parses OK"
|
then: "Parses OK"
|
||||||
notThrown BeanDefinitionParsingException
|
notThrown BeanDefinitionParsingException
|
||||||
}
|
}
|
||||||
|
|
||||||
// SEC-742
|
// SEC-742
|
||||||
def rememberMeWorksWithoutBasicProcessingFilter() {
|
def rememberMeWorksWithoutBasicProcessingFilter() {
|
||||||
when:
|
when:
|
||||||
xml.http () {
|
xml.http () {
|
||||||
'form-login'('login-page': '/login.jsp', 'default-target-url': '/messageList.html' )
|
'form-login'('login-page': '/login.jsp', 'default-target-url': '/messageList.html' )
|
||||||
logout('logout-success-url': '/login.jsp')
|
logout('logout-success-url': '/login.jsp')
|
||||||
anonymous(username: 'guest', 'granted-authority': 'guest')
|
anonymous(username: 'guest', 'granted-authority': 'guest')
|
||||||
'remember-me'()
|
'remember-me'()
|
||||||
}
|
}
|
||||||
createAppContext(AUTH_PROVIDER_XML)
|
createAppContext(AUTH_PROVIDER_XML)
|
||||||
|
|
||||||
then: "Parses OK"
|
then: "Parses OK"
|
||||||
notThrown BeanDefinitionParsingException
|
notThrown BeanDefinitionParsingException
|
||||||
}
|
}
|
||||||
|
|
||||||
def 'Default remember-me-parameter is correct'() {
|
def 'Default remember-me-parameter is correct'() {
|
||||||
httpAutoConfig () {
|
httpAutoConfig () {
|
||||||
'remember-me'()
|
'remember-me'()
|
||||||
}
|
}
|
||||||
|
|
||||||
createAppContext(AUTH_PROVIDER_XML)
|
createAppContext(AUTH_PROVIDER_XML)
|
||||||
expect:
|
expect:
|
||||||
rememberMeServices().parameter == AbstractRememberMeServices.DEFAULT_PARAMETER
|
rememberMeServices().parameter == AbstractRememberMeServices.DEFAULT_PARAMETER
|
||||||
}
|
}
|
||||||
|
|
||||||
// SEC-2119
|
// SEC-2119
|
||||||
def 'Custom remember-me-parameter is supported'() {
|
def 'Custom remember-me-parameter is supported'() {
|
||||||
httpAutoConfig () {
|
httpAutoConfig () {
|
||||||
'remember-me'('remember-me-parameter': 'ourParam')
|
'remember-me'('remember-me-parameter': 'ourParam')
|
||||||
}
|
}
|
||||||
|
|
||||||
createAppContext(AUTH_PROVIDER_XML)
|
createAppContext(AUTH_PROVIDER_XML)
|
||||||
expect:
|
expect:
|
||||||
rememberMeServices().parameter == 'ourParam'
|
rememberMeServices().parameter == 'ourParam'
|
||||||
}
|
}
|
||||||
|
|
||||||
def 'remember-me-parameter cannot be used together with services-ref'() {
|
def 'remember-me-parameter cannot be used together with services-ref'() {
|
||||||
when:
|
when:
|
||||||
httpAutoConfig () {
|
httpAutoConfig () {
|
||||||
'remember-me'('remember-me-parameter': 'ourParam', 'services-ref': 'ourService')
|
'remember-me'('remember-me-parameter': 'ourParam', 'services-ref': 'ourService')
|
||||||
}
|
}
|
||||||
createAppContext(AUTH_PROVIDER_XML)
|
createAppContext(AUTH_PROVIDER_XML)
|
||||||
then:
|
then:
|
||||||
BeanDefinitionParsingException e = thrown()
|
BeanDefinitionParsingException e = thrown()
|
||||||
}
|
}
|
||||||
|
|
||||||
// SEC-2826
|
// SEC-2826
|
||||||
def 'Custom remember-me-cookie is supported'() {
|
def 'Custom remember-me-cookie is supported'() {
|
||||||
httpAutoConfig () {
|
httpAutoConfig () {
|
||||||
'remember-me'('remember-me-cookie': 'ourCookie')
|
'remember-me'('remember-me-cookie': 'ourCookie')
|
||||||
}
|
}
|
||||||
|
|
||||||
createAppContext(AUTH_PROVIDER_XML)
|
createAppContext(AUTH_PROVIDER_XML)
|
||||||
expect:
|
expect:
|
||||||
rememberMeServices().cookieName == 'ourCookie'
|
rememberMeServices().cookieName == 'ourCookie'
|
||||||
}
|
}
|
||||||
|
|
||||||
// SEC-2826
|
// SEC-2826
|
||||||
def 'remember-me-cookie cannot be used together with services-ref'() {
|
def 'remember-me-cookie cannot be used together with services-ref'() {
|
||||||
when:
|
when:
|
||||||
httpAutoConfig () {
|
httpAutoConfig () {
|
||||||
'remember-me'('remember-me-cookie': 'ourCookie', 'services-ref': 'ourService')
|
'remember-me'('remember-me-cookie': 'ourCookie', 'services-ref': 'ourService')
|
||||||
}
|
}
|
||||||
|
|
||||||
createAppContext(AUTH_PROVIDER_XML)
|
createAppContext(AUTH_PROVIDER_XML)
|
||||||
then:
|
then:
|
||||||
BeanDefinitionParsingException e = thrown()
|
BeanDefinitionParsingException e = thrown()
|
||||||
expect:
|
expect:
|
||||||
e.message == 'Configuration problem: services-ref can\'t be used in combination with attributes token-repository-ref,data-source-ref, user-service-ref, token-validity-seconds, use-secure-cookie, remember-me-parameter or remember-me-cookie\nOffending resource: null'
|
e.message == 'Configuration problem: services-ref can\'t be used in combination with attributes token-repository-ref,data-source-ref, user-service-ref, token-validity-seconds, use-secure-cookie, remember-me-parameter or remember-me-cookie\nOffending resource: null'
|
||||||
}
|
}
|
||||||
|
|
||||||
def rememberMeServices() {
|
def rememberMeServices() {
|
||||||
getFilter(RememberMeAuthenticationFilter.class).getRememberMeServices()
|
getFilter(RememberMeAuthenticationFilter.class).getRememberMeServices()
|
||||||
}
|
}
|
||||||
|
|
||||||
static class CustomTokenRepository extends InMemoryTokenRepositoryImpl {
|
static class CustomTokenRepository extends InMemoryTokenRepositoryImpl {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
@ -58,375 +58,375 @@ import org.springframework.security.web.session.SessionManagementFilter
|
||||||
*/
|
*/
|
||||||
class SessionManagementConfigTests extends AbstractHttpConfigTests {
|
class SessionManagementConfigTests extends AbstractHttpConfigTests {
|
||||||
|
|
||||||
def settingCreateSessionToAlwaysSetsFilterPropertiesCorrectly() {
|
def settingCreateSessionToAlwaysSetsFilterPropertiesCorrectly() {
|
||||||
httpCreateSession('always') { }
|
httpCreateSession('always') { }
|
||||||
createAppContext();
|
createAppContext();
|
||||||
|
|
||||||
def filter = getFilter(SecurityContextPersistenceFilter.class);
|
def filter = getFilter(SecurityContextPersistenceFilter.class);
|
||||||
|
|
||||||
expect:
|
expect:
|
||||||
filter.forceEagerSessionCreation
|
filter.forceEagerSessionCreation
|
||||||
filter.repo.allowSessionCreation
|
filter.repo.allowSessionCreation
|
||||||
!filter.repo.disableUrlRewriting
|
!filter.repo.disableUrlRewriting
|
||||||
}
|
}
|
||||||
|
|
||||||
def settingCreateSessionToNeverSetsFilterPropertiesCorrectly() {
|
def settingCreateSessionToNeverSetsFilterPropertiesCorrectly() {
|
||||||
httpCreateSession('never') { }
|
httpCreateSession('never') { }
|
||||||
createAppContext();
|
createAppContext();
|
||||||
|
|
||||||
def filter = getFilter(SecurityContextPersistenceFilter.class);
|
def filter = getFilter(SecurityContextPersistenceFilter.class);
|
||||||
|
|
||||||
expect:
|
expect:
|
||||||
!filter.forceEagerSessionCreation
|
!filter.forceEagerSessionCreation
|
||||||
!filter.repo.allowSessionCreation
|
!filter.repo.allowSessionCreation
|
||||||
}
|
}
|
||||||
|
|
||||||
def settingCreateSessionToStatelessSetsFilterPropertiesCorrectly() {
|
def settingCreateSessionToStatelessSetsFilterPropertiesCorrectly() {
|
||||||
httpCreateSession('stateless') { }
|
httpCreateSession('stateless') { }
|
||||||
createAppContext();
|
createAppContext();
|
||||||
|
|
||||||
def filter = getFilter(SecurityContextPersistenceFilter.class);
|
def filter = getFilter(SecurityContextPersistenceFilter.class);
|
||||||
|
|
||||||
expect:
|
expect:
|
||||||
!filter.forceEagerSessionCreation
|
!filter.forceEagerSessionCreation
|
||||||
filter.repo instanceof NullSecurityContextRepository
|
filter.repo instanceof NullSecurityContextRepository
|
||||||
getFilter(SessionManagementFilter.class) == null
|
getFilter(SessionManagementFilter.class) == null
|
||||||
getFilter(RequestCacheAwareFilter.class) == null
|
getFilter(RequestCacheAwareFilter.class) == null
|
||||||
}
|
}
|
||||||
|
|
||||||
def settingCreateSessionToIfRequiredDoesntCreateASessionForPublicInvocation() {
|
def settingCreateSessionToIfRequiredDoesntCreateASessionForPublicInvocation() {
|
||||||
httpCreateSession('ifRequired') { }
|
httpCreateSession('ifRequired') { }
|
||||||
createAppContext();
|
createAppContext();
|
||||||
|
|
||||||
def filter = getFilter(SecurityContextPersistenceFilter.class);
|
def filter = getFilter(SecurityContextPersistenceFilter.class);
|
||||||
|
|
||||||
expect:
|
expect:
|
||||||
!filter.forceEagerSessionCreation
|
!filter.forceEagerSessionCreation
|
||||||
filter.repo.allowSessionCreation
|
filter.repo.allowSessionCreation
|
||||||
}
|
}
|
||||||
|
|
||||||
def 'SEC-1208: Session is not created when rejecting user due to max sessions exceeded'() {
|
def 'SEC-1208: Session is not created when rejecting user due to max sessions exceeded'() {
|
||||||
setup:
|
setup:
|
||||||
httpCreateSession('never') {
|
httpCreateSession('never') {
|
||||||
'session-management'() {
|
'session-management'() {
|
||||||
'concurrency-control'('max-sessions':1,'error-if-maximum-exceeded':'true')
|
'concurrency-control'('max-sessions':1,'error-if-maximum-exceeded':'true')
|
||||||
}
|
}
|
||||||
csrf(disabled:true)
|
csrf(disabled:true)
|
||||||
}
|
}
|
||||||
createAppContext()
|
createAppContext()
|
||||||
SessionRegistry registry = appContext.getBean(SessionRegistry)
|
SessionRegistry registry = appContext.getBean(SessionRegistry)
|
||||||
registry.registerNewSession("1", new User("user","password",AuthorityUtils.createAuthorityList("ROLE_USER")))
|
registry.registerNewSession("1", new User("user","password",AuthorityUtils.createAuthorityList("ROLE_USER")))
|
||||||
MockHttpServletRequest request = new MockHttpServletRequest()
|
MockHttpServletRequest request = new MockHttpServletRequest()
|
||||||
MockHttpServletResponse response = new MockHttpServletResponse()
|
MockHttpServletResponse response = new MockHttpServletResponse()
|
||||||
String credentials = "user:password"
|
String credentials = "user:password"
|
||||||
request.addHeader("Authorization", "Basic " + credentials.bytes.encodeBase64())
|
request.addHeader("Authorization", "Basic " + credentials.bytes.encodeBase64())
|
||||||
when: "exceed max authentication attempts"
|
when: "exceed max authentication attempts"
|
||||||
appContext.getBean(FilterChainProxy).doFilter(request, response, new MockFilterChain())
|
appContext.getBean(FilterChainProxy).doFilter(request, response, new MockFilterChain())
|
||||||
then: "no new session is created"
|
then: "no new session is created"
|
||||||
request.getSession(false) == null
|
request.getSession(false) == null
|
||||||
response.status == HttpServletResponse.SC_UNAUTHORIZED
|
response.status == HttpServletResponse.SC_UNAUTHORIZED
|
||||||
}
|
}
|
||||||
|
|
||||||
def 'SEC-2137: disable session fixation and enable concurrency control'() {
|
def 'SEC-2137: disable session fixation and enable concurrency control'() {
|
||||||
setup: "context where session fixation is disabled and concurrency control is enabled"
|
setup: "context where session fixation is disabled and concurrency control is enabled"
|
||||||
httpAutoConfig {
|
httpAutoConfig {
|
||||||
'session-management'('session-fixation-protection':'none') {
|
'session-management'('session-fixation-protection':'none') {
|
||||||
'concurrency-control'('max-sessions':'1','error-if-maximum-exceeded':'true')
|
'concurrency-control'('max-sessions':'1','error-if-maximum-exceeded':'true')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
createAppContext()
|
createAppContext()
|
||||||
MockHttpServletRequest request = new MockHttpServletRequest()
|
MockHttpServletRequest request = new MockHttpServletRequest()
|
||||||
MockHttpServletResponse response = new MockHttpServletResponse()
|
MockHttpServletResponse response = new MockHttpServletResponse()
|
||||||
String originalSessionId = request.session.id
|
String originalSessionId = request.session.id
|
||||||
String credentials = "user:password"
|
String credentials = "user:password"
|
||||||
request.addHeader("Authorization", "Basic " + credentials.bytes.encodeBase64())
|
request.addHeader("Authorization", "Basic " + credentials.bytes.encodeBase64())
|
||||||
when: "authenticate"
|
when: "authenticate"
|
||||||
appContext.getBean(FilterChainProxy).doFilter(request, response, new MockFilterChain())
|
appContext.getBean(FilterChainProxy).doFilter(request, response, new MockFilterChain())
|
||||||
then: "session invalidate is not called"
|
then: "session invalidate is not called"
|
||||||
request.session.id == originalSessionId
|
request.session.id == originalSessionId
|
||||||
}
|
}
|
||||||
|
|
||||||
def httpCreateSession(String create, Closure c) {
|
def httpCreateSession(String create, Closure c) {
|
||||||
xml.http(['auto-config': 'true', 'create-session': create], c)
|
xml.http(['auto-config': 'true', 'create-session': create], c)
|
||||||
}
|
}
|
||||||
|
|
||||||
def concurrentSessionSupportAddsFilterAndExpectedBeans() {
|
def concurrentSessionSupportAddsFilterAndExpectedBeans() {
|
||||||
when:
|
when:
|
||||||
httpAutoConfig {
|
httpAutoConfig {
|
||||||
'session-management'() {
|
'session-management'() {
|
||||||
'concurrency-control'('session-registry-alias':'sr', 'expired-url': '/expired')
|
'concurrency-control'('session-registry-alias':'sr', 'expired-url': '/expired')
|
||||||
}
|
}
|
||||||
csrf(disabled:true)
|
csrf(disabled:true)
|
||||||
}
|
}
|
||||||
createAppContext();
|
createAppContext();
|
||||||
List filters = getFilters("/someurl");
|
List filters = getFilters("/someurl");
|
||||||
def concurrentSessionFilter = filters.get(1)
|
def concurrentSessionFilter = filters.get(1)
|
||||||
|
|
||||||
then:
|
then:
|
||||||
concurrentSessionFilter instanceof ConcurrentSessionFilter
|
concurrentSessionFilter instanceof ConcurrentSessionFilter
|
||||||
concurrentSessionFilter.expiredUrl == '/expired'
|
concurrentSessionFilter.expiredUrl == '/expired'
|
||||||
appContext.getBean("sr") != null
|
appContext.getBean("sr") != null
|
||||||
getFilter(SessionManagementFilter.class) != null
|
getFilter(SessionManagementFilter.class) != null
|
||||||
sessionRegistryIsValid();
|
sessionRegistryIsValid();
|
||||||
|
|
||||||
concurrentSessionFilter.handlers.size() == 1
|
concurrentSessionFilter.handlers.size() == 1
|
||||||
def logoutHandler = concurrentSessionFilter.handlers[0]
|
def logoutHandler = concurrentSessionFilter.handlers[0]
|
||||||
logoutHandler instanceof SecurityContextLogoutHandler
|
logoutHandler instanceof SecurityContextLogoutHandler
|
||||||
logoutHandler.invalidateHttpSession
|
logoutHandler.invalidateHttpSession
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def 'concurrency-control adds custom logout handlers'() {
|
def 'concurrency-control adds custom logout handlers'() {
|
||||||
when: 'Custom logout and remember-me'
|
when: 'Custom logout and remember-me'
|
||||||
httpAutoConfig {
|
httpAutoConfig {
|
||||||
'session-management'() {
|
'session-management'() {
|
||||||
'concurrency-control'()
|
'concurrency-control'()
|
||||||
}
|
}
|
||||||
'logout'('invalidate-session': false, 'delete-cookies': 'testCookie')
|
'logout'('invalidate-session': false, 'delete-cookies': 'testCookie')
|
||||||
'remember-me'()
|
'remember-me'()
|
||||||
csrf(disabled:true)
|
csrf(disabled:true)
|
||||||
}
|
}
|
||||||
createAppContext()
|
createAppContext()
|
||||||
|
|
||||||
List filters = getFilters("/someurl")
|
List filters = getFilters("/someurl")
|
||||||
ConcurrentSessionFilter concurrentSessionFilter = filters.get(1)
|
ConcurrentSessionFilter concurrentSessionFilter = filters.get(1)
|
||||||
def logoutHandlers = concurrentSessionFilter.handlers
|
def logoutHandlers = concurrentSessionFilter.handlers
|
||||||
|
|
||||||
then: 'ConcurrentSessionFilter contains the customized LogoutHandlers'
|
then: 'ConcurrentSessionFilter contains the customized LogoutHandlers'
|
||||||
logoutHandlers.size() == 3
|
logoutHandlers.size() == 3
|
||||||
def securityCtxlogoutHandler = logoutHandlers.find { it instanceof SecurityContextLogoutHandler }
|
def securityCtxlogoutHandler = logoutHandlers.find { it instanceof SecurityContextLogoutHandler }
|
||||||
securityCtxlogoutHandler.invalidateHttpSession == false
|
securityCtxlogoutHandler.invalidateHttpSession == false
|
||||||
def cookieClearingLogoutHandler = logoutHandlers.find { it instanceof CookieClearingLogoutHandler }
|
def cookieClearingLogoutHandler = logoutHandlers.find { it instanceof CookieClearingLogoutHandler }
|
||||||
cookieClearingLogoutHandler.cookiesToClear == ['testCookie']
|
cookieClearingLogoutHandler.cookiesToClear == ['testCookie']
|
||||||
def remembermeLogoutHandler = logoutHandlers.find { it instanceof RememberMeServices }
|
def remembermeLogoutHandler = logoutHandlers.find { it instanceof RememberMeServices }
|
||||||
remembermeLogoutHandler == getFilter(RememberMeAuthenticationFilter.class).rememberMeServices
|
remembermeLogoutHandler == getFilter(RememberMeAuthenticationFilter.class).rememberMeServices
|
||||||
}
|
}
|
||||||
|
|
||||||
def 'concurrency-control with remember-me and no LogoutFilter contains SecurityContextLogoutHandler and RememberMeServices as LogoutHandlers'() {
|
def 'concurrency-control with remember-me and no LogoutFilter contains SecurityContextLogoutHandler and RememberMeServices as LogoutHandlers'() {
|
||||||
when: 'RememberMe and No LogoutFilter'
|
when: 'RememberMe and No LogoutFilter'
|
||||||
xml.http(['entry-point-ref': 'entryPoint'], {
|
xml.http(['entry-point-ref': 'entryPoint'], {
|
||||||
'session-management'() {
|
'session-management'() {
|
||||||
'concurrency-control'()
|
'concurrency-control'()
|
||||||
}
|
}
|
||||||
'remember-me'()
|
'remember-me'()
|
||||||
csrf(disabled:true)
|
csrf(disabled:true)
|
||||||
})
|
})
|
||||||
bean('entryPoint', 'org.springframework.security.web.authentication.Http403ForbiddenEntryPoint')
|
bean('entryPoint', 'org.springframework.security.web.authentication.Http403ForbiddenEntryPoint')
|
||||||
createAppContext()
|
createAppContext()
|
||||||
|
|
||||||
List filters = getFilters("/someurl")
|
List filters = getFilters("/someurl")
|
||||||
ConcurrentSessionFilter concurrentSessionFilter = filters.get(1)
|
ConcurrentSessionFilter concurrentSessionFilter = filters.get(1)
|
||||||
def logoutHandlers = concurrentSessionFilter.handlers
|
def logoutHandlers = concurrentSessionFilter.handlers
|
||||||
|
|
||||||
then: 'SecurityContextLogoutHandler and RememberMeServices are in ConcurrentSessionFilter logoutHandlers'
|
then: 'SecurityContextLogoutHandler and RememberMeServices are in ConcurrentSessionFilter logoutHandlers'
|
||||||
!filters.find { it instanceof LogoutFilter }
|
!filters.find { it instanceof LogoutFilter }
|
||||||
logoutHandlers.size() == 2
|
logoutHandlers.size() == 2
|
||||||
def securityCtxlogoutHandler = logoutHandlers.find { it instanceof SecurityContextLogoutHandler }
|
def securityCtxlogoutHandler = logoutHandlers.find { it instanceof SecurityContextLogoutHandler }
|
||||||
securityCtxlogoutHandler.invalidateHttpSession == true
|
securityCtxlogoutHandler.invalidateHttpSession == true
|
||||||
logoutHandlers.find { it instanceof RememberMeServices } == getFilter(RememberMeAuthenticationFilter).rememberMeServices
|
logoutHandlers.find { it instanceof RememberMeServices } == getFilter(RememberMeAuthenticationFilter).rememberMeServices
|
||||||
}
|
}
|
||||||
|
|
||||||
def 'concurrency-control with no remember-me or LogoutFilter contains SecurityContextLogoutHandler as LogoutHandlers'() {
|
def 'concurrency-control with no remember-me or LogoutFilter contains SecurityContextLogoutHandler as LogoutHandlers'() {
|
||||||
when: 'No Logout Filter or RememberMe'
|
when: 'No Logout Filter or RememberMe'
|
||||||
xml.http(['entry-point-ref': 'entryPoint'], {
|
xml.http(['entry-point-ref': 'entryPoint'], {
|
||||||
'session-management'() {
|
'session-management'() {
|
||||||
'concurrency-control'()
|
'concurrency-control'()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
bean('entryPoint', 'org.springframework.security.web.authentication.Http403ForbiddenEntryPoint')
|
bean('entryPoint', 'org.springframework.security.web.authentication.Http403ForbiddenEntryPoint')
|
||||||
createAppContext()
|
createAppContext()
|
||||||
|
|
||||||
List filters = getFilters("/someurl")
|
List filters = getFilters("/someurl")
|
||||||
ConcurrentSessionFilter concurrentSessionFilter = filters.get(1)
|
ConcurrentSessionFilter concurrentSessionFilter = filters.get(1)
|
||||||
def logoutHandlers = concurrentSessionFilter.handlers
|
def logoutHandlers = concurrentSessionFilter.handlers
|
||||||
|
|
||||||
then: 'Only SecurityContextLogoutHandler is found in ConcurrentSessionFilter logoutHandlers'
|
then: 'Only SecurityContextLogoutHandler is found in ConcurrentSessionFilter logoutHandlers'
|
||||||
!filters.find { it instanceof LogoutFilter }
|
!filters.find { it instanceof LogoutFilter }
|
||||||
logoutHandlers.size() == 1
|
logoutHandlers.size() == 1
|
||||||
def securityCtxlogoutHandler = logoutHandlers.find { it instanceof SecurityContextLogoutHandler }
|
def securityCtxlogoutHandler = logoutHandlers.find { it instanceof SecurityContextLogoutHandler }
|
||||||
securityCtxlogoutHandler.invalidateHttpSession == true
|
securityCtxlogoutHandler.invalidateHttpSession == true
|
||||||
}
|
}
|
||||||
|
|
||||||
def 'SEC-2057: ConcurrentSessionFilter is after SecurityContextPersistenceFilter'() {
|
def 'SEC-2057: ConcurrentSessionFilter is after SecurityContextPersistenceFilter'() {
|
||||||
httpAutoConfig {
|
httpAutoConfig {
|
||||||
'session-management'() {
|
'session-management'() {
|
||||||
'concurrency-control'()
|
'concurrency-control'()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
createAppContext()
|
createAppContext()
|
||||||
List filters = getFilters("/someurl")
|
List filters = getFilters("/someurl")
|
||||||
|
|
||||||
expect:
|
expect:
|
||||||
filters.get(0) instanceof SecurityContextPersistenceFilter
|
filters.get(0) instanceof SecurityContextPersistenceFilter
|
||||||
filters.get(1) instanceof ConcurrentSessionFilter
|
filters.get(1) instanceof ConcurrentSessionFilter
|
||||||
}
|
}
|
||||||
|
|
||||||
def 'concurrency-control handles default expired-url as null'() {
|
def 'concurrency-control handles default expired-url as null'() {
|
||||||
httpAutoConfig {
|
httpAutoConfig {
|
||||||
'session-management'() {
|
'session-management'() {
|
||||||
'concurrency-control'('session-registry-alias':'sr')
|
'concurrency-control'('session-registry-alias':'sr')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
createAppContext();
|
createAppContext();
|
||||||
List filters = getFilters("/someurl");
|
List filters = getFilters("/someurl");
|
||||||
|
|
||||||
expect:
|
expect:
|
||||||
filters.get(1).expiredUrl == null
|
filters.get(1).expiredUrl == null
|
||||||
}
|
}
|
||||||
|
|
||||||
def externalSessionStrategyIsSupported() {
|
def externalSessionStrategyIsSupported() {
|
||||||
setup:
|
setup:
|
||||||
httpAutoConfig {
|
httpAutoConfig {
|
||||||
'session-management'('session-authentication-strategy-ref':'ss')
|
'session-management'('session-authentication-strategy-ref':'ss')
|
||||||
csrf(disabled:true)
|
csrf(disabled:true)
|
||||||
}
|
}
|
||||||
mockBean(SessionAuthenticationStrategy,'ss')
|
mockBean(SessionAuthenticationStrategy,'ss')
|
||||||
createAppContext()
|
createAppContext()
|
||||||
|
|
||||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||||
request.getSession();
|
request.getSession();
|
||||||
request.servletPath = "/login"
|
request.servletPath = "/login"
|
||||||
request.setMethod("POST");
|
request.setMethod("POST");
|
||||||
request.setParameter("username", "user");
|
request.setParameter("username", "user");
|
||||||
request.setParameter("password", "password");
|
request.setParameter("password", "password");
|
||||||
|
|
||||||
SessionAuthenticationStrategy sessionAuthStrategy = appContext.getBean('ss',SessionAuthenticationStrategy)
|
SessionAuthenticationStrategy sessionAuthStrategy = appContext.getBean('ss',SessionAuthenticationStrategy)
|
||||||
FilterChainProxy springSecurityFilterChain = appContext.getBean(FilterChainProxy)
|
FilterChainProxy springSecurityFilterChain = appContext.getBean(FilterChainProxy)
|
||||||
when:
|
when:
|
||||||
springSecurityFilterChain.doFilter(request,new MockHttpServletResponse(), new MockFilterChain())
|
springSecurityFilterChain.doFilter(request,new MockHttpServletResponse(), new MockFilterChain())
|
||||||
then: "CustomSessionAuthenticationStrategy has seen the request (although REQUEST is a wrapped request)"
|
then: "CustomSessionAuthenticationStrategy has seen the request (although REQUEST is a wrapped request)"
|
||||||
verify(sessionAuthStrategy).onAuthentication(any(Authentication), any(HttpServletRequest), any(HttpServletResponse))
|
verify(sessionAuthStrategy).onAuthentication(any(Authentication), any(HttpServletRequest), any(HttpServletResponse))
|
||||||
}
|
}
|
||||||
|
|
||||||
def externalSessionRegistryBeanIsConfiguredCorrectly() {
|
def externalSessionRegistryBeanIsConfiguredCorrectly() {
|
||||||
httpAutoConfig {
|
httpAutoConfig {
|
||||||
'session-management'() {
|
'session-management'() {
|
||||||
'concurrency-control'('session-registry-ref':'sr')
|
'concurrency-control'('session-registry-ref':'sr')
|
||||||
}
|
}
|
||||||
csrf(disabled:true)
|
csrf(disabled:true)
|
||||||
}
|
}
|
||||||
bean('sr', SessionRegistryImpl.class.name)
|
bean('sr', SessionRegistryImpl.class.name)
|
||||||
createAppContext();
|
createAppContext();
|
||||||
|
|
||||||
expect:
|
expect:
|
||||||
sessionRegistryIsValid();
|
sessionRegistryIsValid();
|
||||||
}
|
}
|
||||||
|
|
||||||
def sessionRegistryIsValid() {
|
def sessionRegistryIsValid() {
|
||||||
Object sessionRegistry = appContext.getBean("sr");
|
Object sessionRegistry = appContext.getBean("sr");
|
||||||
Object sessionRegistryFromConcurrencyFilter = FieldUtils.getFieldValue(
|
Object sessionRegistryFromConcurrencyFilter = FieldUtils.getFieldValue(
|
||||||
getFilter(ConcurrentSessionFilter.class), "sessionRegistry");
|
getFilter(ConcurrentSessionFilter.class), "sessionRegistry");
|
||||||
Object sessionRegistryFromFormLoginFilter = FieldUtils.getFieldValue(getFilter(UsernamePasswordAuthenticationFilter),"sessionStrategy").delegateStrategies[0].sessionRegistry
|
Object sessionRegistryFromFormLoginFilter = FieldUtils.getFieldValue(getFilter(UsernamePasswordAuthenticationFilter),"sessionStrategy").delegateStrategies[0].sessionRegistry
|
||||||
Object sessionRegistryFromMgmtFilter = FieldUtils.getFieldValue(getFilter(SessionManagementFilter),"sessionAuthenticationStrategy").delegateStrategies[0].sessionRegistry
|
Object sessionRegistryFromMgmtFilter = FieldUtils.getFieldValue(getFilter(SessionManagementFilter),"sessionAuthenticationStrategy").delegateStrategies[0].sessionRegistry
|
||||||
|
|
||||||
assertSame(sessionRegistry, sessionRegistryFromConcurrencyFilter);
|
assertSame(sessionRegistry, sessionRegistryFromConcurrencyFilter);
|
||||||
assertSame(sessionRegistry, sessionRegistryFromMgmtFilter);
|
assertSame(sessionRegistry, sessionRegistryFromMgmtFilter);
|
||||||
// SEC-1143
|
// SEC-1143
|
||||||
assertSame(sessionRegistry, sessionRegistryFromFormLoginFilter);
|
assertSame(sessionRegistry, sessionRegistryFromFormLoginFilter);
|
||||||
true;
|
true;
|
||||||
}
|
}
|
||||||
|
|
||||||
def concurrentSessionMaxSessionsIsCorrectlyConfigured() {
|
def concurrentSessionMaxSessionsIsCorrectlyConfigured() {
|
||||||
setup:
|
setup:
|
||||||
httpAutoConfig {
|
httpAutoConfig {
|
||||||
'session-management'('session-authentication-error-url':'/max-exceeded') {
|
'session-management'('session-authentication-error-url':'/max-exceeded') {
|
||||||
'concurrency-control'('max-sessions': '2', 'error-if-maximum-exceeded':'true')
|
'concurrency-control'('max-sessions': '2', 'error-if-maximum-exceeded':'true')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
createAppContext();
|
createAppContext();
|
||||||
|
|
||||||
def seshFilter = getFilter(SessionManagementFilter.class);
|
def seshFilter = getFilter(SessionManagementFilter.class);
|
||||||
def auth = new UsernamePasswordAuthenticationToken("bob", "pass");
|
def auth = new UsernamePasswordAuthenticationToken("bob", "pass");
|
||||||
SecurityContextHolder.getContext().setAuthentication(auth);
|
SecurityContextHolder.getContext().setAuthentication(auth);
|
||||||
MockHttpServletResponse mockResponse = new MockHttpServletResponse();
|
MockHttpServletResponse mockResponse = new MockHttpServletResponse();
|
||||||
def response = new SaveContextOnUpdateOrErrorResponseWrapper(mockResponse, false) {
|
def response = new SaveContextOnUpdateOrErrorResponseWrapper(mockResponse, false) {
|
||||||
protected void saveContext(SecurityContext context) {
|
protected void saveContext(SecurityContext context) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
when: "First session is established"
|
when: "First session is established"
|
||||||
seshFilter.doFilter(new MockHttpServletRequest(), response, new MockFilterChain());
|
seshFilter.doFilter(new MockHttpServletRequest(), response, new MockFilterChain());
|
||||||
then: "ok"
|
then: "ok"
|
||||||
mockResponse.redirectedUrl == null
|
mockResponse.redirectedUrl == null
|
||||||
when: "Second session is established"
|
when: "Second session is established"
|
||||||
seshFilter.doFilter(new MockHttpServletRequest(), response, new MockFilterChain());
|
seshFilter.doFilter(new MockHttpServletRequest(), response, new MockFilterChain());
|
||||||
then: "ok"
|
then: "ok"
|
||||||
mockResponse.redirectedUrl == null
|
mockResponse.redirectedUrl == null
|
||||||
when: "Third session is established"
|
when: "Third session is established"
|
||||||
seshFilter.doFilter(new MockHttpServletRequest(), response, new MockFilterChain());
|
seshFilter.doFilter(new MockHttpServletRequest(), response, new MockFilterChain());
|
||||||
then: "Rejected"
|
then: "Rejected"
|
||||||
mockResponse.redirectedUrl == "/max-exceeded";
|
mockResponse.redirectedUrl == "/max-exceeded";
|
||||||
}
|
}
|
||||||
|
|
||||||
def disablingSessionProtectionRemovesSessionManagementFilterIfNoInvalidSessionUrlSet() {
|
def disablingSessionProtectionRemovesSessionManagementFilterIfNoInvalidSessionUrlSet() {
|
||||||
httpAutoConfig {
|
httpAutoConfig {
|
||||||
'session-management'('session-fixation-protection': 'none')
|
'session-management'('session-fixation-protection': 'none')
|
||||||
csrf(disabled:true)
|
csrf(disabled:true)
|
||||||
}
|
}
|
||||||
createAppContext()
|
createAppContext()
|
||||||
|
|
||||||
expect:
|
expect:
|
||||||
!(getFilters("/someurl").find { it instanceof SessionManagementFilter})
|
!(getFilters("/someurl").find { it instanceof SessionManagementFilter})
|
||||||
}
|
}
|
||||||
|
|
||||||
def 'session-fixation-protection=none'() {
|
def 'session-fixation-protection=none'() {
|
||||||
setup:
|
setup:
|
||||||
MockHttpServletRequest request = new MockHttpServletRequest(method:'POST')
|
MockHttpServletRequest request = new MockHttpServletRequest(method:'POST')
|
||||||
request.session.id = '123'
|
request.session.id = '123'
|
||||||
request.setParameter('username', 'user')
|
request.setParameter('username', 'user')
|
||||||
request.setParameter('password', 'password')
|
request.setParameter('password', 'password')
|
||||||
request.servletPath = '/login'
|
request.servletPath = '/login'
|
||||||
|
|
||||||
MockHttpServletResponse response = new MockHttpServletResponse()
|
MockHttpServletResponse response = new MockHttpServletResponse()
|
||||||
MockFilterChain chain = new MockFilterChain()
|
MockFilterChain chain = new MockFilterChain()
|
||||||
httpAutoConfig {
|
httpAutoConfig {
|
||||||
'session-management'('session-fixation-protection': 'none')
|
'session-management'('session-fixation-protection': 'none')
|
||||||
csrf(disabled:true)
|
csrf(disabled:true)
|
||||||
}
|
}
|
||||||
createAppContext()
|
createAppContext()
|
||||||
request.session.id = '123'
|
request.session.id = '123'
|
||||||
|
|
||||||
when:
|
when:
|
||||||
springSecurityFilterChain.doFilter(request,response, chain)
|
springSecurityFilterChain.doFilter(request,response, chain)
|
||||||
|
|
||||||
then:
|
then:
|
||||||
request.session.id == '123'
|
request.session.id == '123'
|
||||||
}
|
}
|
||||||
|
|
||||||
def 'session-fixation-protection=migrateSession'() {
|
def 'session-fixation-protection=migrateSession'() {
|
||||||
setup:
|
setup:
|
||||||
MockHttpServletRequest request = new MockHttpServletRequest(method:'POST')
|
MockHttpServletRequest request = new MockHttpServletRequest(method:'POST')
|
||||||
request.session.id = '123'
|
request.session.id = '123'
|
||||||
request.setParameter('username', 'user')
|
request.setParameter('username', 'user')
|
||||||
request.setParameter('password', 'password')
|
request.setParameter('password', 'password')
|
||||||
request.servletPath = '/login'
|
request.servletPath = '/login'
|
||||||
|
|
||||||
MockHttpServletResponse response = new MockHttpServletResponse()
|
MockHttpServletResponse response = new MockHttpServletResponse()
|
||||||
MockFilterChain chain = new MockFilterChain()
|
MockFilterChain chain = new MockFilterChain()
|
||||||
httpAutoConfig {
|
httpAutoConfig {
|
||||||
'session-management'('session-fixation-protection': 'migrateSession')
|
'session-management'('session-fixation-protection': 'migrateSession')
|
||||||
csrf(disabled:true)
|
csrf(disabled:true)
|
||||||
}
|
}
|
||||||
createAppContext()
|
createAppContext()
|
||||||
request.session.id = '123'
|
request.session.id = '123'
|
||||||
|
|
||||||
when:
|
when:
|
||||||
springSecurityFilterChain.doFilter(request,response, chain)
|
springSecurityFilterChain.doFilter(request,response, chain)
|
||||||
|
|
||||||
then:
|
then:
|
||||||
request.session.id != '123'
|
request.session.id != '123'
|
||||||
}
|
}
|
||||||
|
|
||||||
def disablingSessionProtectionRetainsSessionManagementFilterInvalidSessionUrlSet() {
|
def disablingSessionProtectionRetainsSessionManagementFilterInvalidSessionUrlSet() {
|
||||||
httpAutoConfig {
|
httpAutoConfig {
|
||||||
'session-management'('session-fixation-protection': 'none', 'invalid-session-url': '/timeoutUrl')
|
'session-management'('session-fixation-protection': 'none', 'invalid-session-url': '/timeoutUrl')
|
||||||
csrf(disabled:true)
|
csrf(disabled:true)
|
||||||
}
|
}
|
||||||
createAppContext()
|
createAppContext()
|
||||||
def filter = getFilters("/someurl")[10]
|
def filter = getFilters("/someurl")[10]
|
||||||
|
|
||||||
expect:
|
expect:
|
||||||
filter instanceof SessionManagementFilter
|
filter instanceof SessionManagementFilter
|
||||||
filter.invalidSessionStrategy.destinationUrl == '/timeoutUrl'
|
filter.invalidSessionStrategy.destinationUrl == '/timeoutUrl'
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,47 +5,47 @@ def cryptoProject = project(':spring-security-crypto')
|
||||||
def cryptoClasses = cryptoProject.sourceSets.main.output
|
def cryptoClasses = cryptoProject.sourceSets.main.output
|
||||||
|
|
||||||
configurations {
|
configurations {
|
||||||
included
|
included
|
||||||
|
|
||||||
compile.extendsFrom included
|
compile.extendsFrom included
|
||||||
|
|
||||||
testCompile.exclude group: 'org.mockito', module: 'mockito-all'
|
testCompile.exclude group: 'org.mockito', module: 'mockito-all'
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
compile springCoreDependency,
|
compile springCoreDependency,
|
||||||
'aopalliance:aopalliance:1.0',
|
'aopalliance:aopalliance:1.0',
|
||||||
"org.springframework:spring-aop:$springVersion",
|
"org.springframework:spring-aop:$springVersion",
|
||||||
"org.springframework:spring-beans:$springVersion",
|
"org.springframework:spring-beans:$springVersion",
|
||||||
"org.springframework:spring-context:$springVersion",
|
"org.springframework:spring-context:$springVersion",
|
||||||
"org.springframework:spring-expression:$springVersion"
|
"org.springframework:spring-expression:$springVersion"
|
||||||
|
|
||||||
optional "net.sf.ehcache:ehcache:$ehcacheVersion",
|
optional "net.sf.ehcache:ehcache:$ehcacheVersion",
|
||||||
'javax.annotation:jsr250-api:1.0',
|
'javax.annotation:jsr250-api:1.0',
|
||||||
"org.aspectj:aspectjrt:$aspectjVersion",
|
"org.aspectj:aspectjrt:$aspectjVersion",
|
||||||
"org.springframework:spring-jdbc:$springVersion",
|
"org.springframework:spring-jdbc:$springVersion",
|
||||||
"org.springframework:spring-tx:$springVersion"
|
"org.springframework:spring-tx:$springVersion"
|
||||||
|
|
||||||
included cryptoProject
|
included cryptoProject
|
||||||
|
|
||||||
testCompile "commons-collections:commons-collections:$commonsCollectionsVersion",
|
testCompile "commons-collections:commons-collections:$commonsCollectionsVersion",
|
||||||
"org.springframework:spring-test:$springVersion",
|
"org.springframework:spring-test:$springVersion",
|
||||||
"org.slf4j:jcl-over-slf4j:$slf4jVersion",
|
"org.slf4j:jcl-over-slf4j:$slf4jVersion",
|
||||||
powerMockDependencies
|
powerMockDependencies
|
||||||
|
|
||||||
testRuntime "org.hsqldb:hsqldb:$hsqlVersion"
|
testRuntime "org.hsqldb:hsqldb:$hsqlVersion"
|
||||||
}
|
}
|
||||||
|
|
||||||
classes.doLast {
|
classes.doLast {
|
||||||
copy {
|
copy {
|
||||||
from cryptoClasses
|
from cryptoClasses
|
||||||
into sourceSets.main.output.classesDir
|
into sourceSets.main.output.classesDir
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sourceJar.from cryptoProject.sourceSets.main.java
|
sourceJar.from cryptoProject.sourceSets.main.java
|
||||||
|
|
||||||
configure(project.tasks.withType(Test)) {
|
configure(project.tasks.withType(Test)) {
|
||||||
systemProperties['springSecurityVersion'] = version
|
systemProperties['springSecurityVersion'] = version
|
||||||
systemProperties['springVersion'] = springVersion
|
systemProperties['springVersion'] = springVersion
|
||||||
}
|
}
|
|
@ -5,8 +5,8 @@
|
||||||
int maxAESKeySize = javax.crypto.Cipher.getMaxAllowedKeyLength('AES')
|
int maxAESKeySize = javax.crypto.Cipher.getMaxAllowedKeyLength('AES')
|
||||||
|
|
||||||
configure(project.tasks.withType(Test)) {
|
configure(project.tasks.withType(Test)) {
|
||||||
if (maxAESKeySize < 256) {
|
if (maxAESKeySize < 256) {
|
||||||
println "AES keysize limited to $maxAESKeySize, skipping EncryptorsTests"
|
println "AES keysize limited to $maxAESKeySize, skipping EncryptorsTests"
|
||||||
exclude '**/EncryptorsTests.class'
|
exclude '**/EncryptorsTests.class'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
dependencies {
|
dependencies {
|
||||||
compile project(':spring-security-core'),
|
compile project(':spring-security-core'),
|
||||||
springCoreDependency,
|
springCoreDependency,
|
||||||
"org.springframework.data:spring-data-commons:$springDataCommonsVersion"
|
"org.springframework.data:spring-data-commons:$springDataCommonsVersion"
|
||||||
|
|
||||||
}
|
}
|
208
docs/docs.gradle
208
docs/docs.gradle
|
@ -1,147 +1,147 @@
|
||||||
// Docbook and Javadoc building and uploading tasks
|
// Docbook and Javadoc building and uploading tasks
|
||||||
apply plugin: 'base'
|
apply plugin: 'base'
|
||||||
|
|
||||||
task docs {
|
task docs {
|
||||||
dependsOn 'manual:reference', 'apidocs', 'guides:asciidoctor'
|
dependsOn 'manual:reference', 'apidocs', 'guides:asciidoctor'
|
||||||
}
|
}
|
||||||
|
|
||||||
project('manual') {
|
project('manual') {
|
||||||
apply plugin: 'base'
|
apply plugin: 'base'
|
||||||
apply plugin: 'org.asciidoctor.gradle.asciidoctor'
|
apply plugin: 'org.asciidoctor.gradle.asciidoctor'
|
||||||
apply plugin: 'docbook-reference'
|
apply plugin: 'docbook-reference'
|
||||||
|
|
||||||
ext.expandPlaceholders = ""
|
ext.expandPlaceholders = ""
|
||||||
|
|
||||||
asciidoctorj {
|
asciidoctorj {
|
||||||
version = '1.5.2'
|
version = '1.5.2'
|
||||||
}
|
}
|
||||||
|
|
||||||
asciidoctor {
|
asciidoctor {
|
||||||
backends = ['docbook5']
|
backends = ['docbook5']
|
||||||
options = [
|
options = [
|
||||||
eruby: 'erubis',
|
eruby: 'erubis',
|
||||||
attributes: [
|
attributes: [
|
||||||
copycss : '',
|
copycss : '',
|
||||||
icons : 'font',
|
icons : 'font',
|
||||||
'source-highlighter': 'prettify',
|
'source-highlighter': 'prettify',
|
||||||
sectanchors : '',
|
sectanchors : '',
|
||||||
toc2: '',
|
toc2: '',
|
||||||
idprefix: '',
|
idprefix: '',
|
||||||
idseparator: '-',
|
idseparator: '-',
|
||||||
doctype: 'book',
|
doctype: 'book',
|
||||||
numbered: '',
|
numbered: '',
|
||||||
'spring-security-version' : project.version,
|
'spring-security-version' : project.version,
|
||||||
'spring-version' : springVersion,
|
'spring-version' : springVersion,
|
||||||
revnumber : project.version
|
revnumber : project.version
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
reference {
|
reference {
|
||||||
sourceDir = new File(asciidoctor.outputDir , 'docbook5')
|
sourceDir = new File(asciidoctor.outputDir , 'docbook5')
|
||||||
pdfFilename = "spring-security-reference.pdf"
|
pdfFilename = "spring-security-reference.pdf"
|
||||||
epubFilename = "spring-security-reference.epub"
|
epubFilename = "spring-security-reference.epub"
|
||||||
expandPlaceholders = ""
|
expandPlaceholders = ""
|
||||||
}
|
}
|
||||||
|
|
||||||
afterEvaluate {
|
afterEvaluate {
|
||||||
tasks.findAll { it.name.startsWith("reference") }.each{ it.dependsOn.add("asciidoctor") }
|
tasks.findAll { it.name.startsWith("reference") }.each{ it.dependsOn.add("asciidoctor") }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ext.spec = copySpec {
|
ext.spec = copySpec {
|
||||||
from (reference) {
|
from (reference) {
|
||||||
into 'reference'
|
into 'reference'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
task apidocs(type: Javadoc) {
|
task apidocs(type: Javadoc) {
|
||||||
destinationDir = new File(buildDir, 'apidocs')
|
destinationDir = new File(buildDir, 'apidocs')
|
||||||
title = "Spring Security $version API"
|
title = "Spring Security $version API"
|
||||||
|
|
||||||
source coreModuleProjects.collect { project ->
|
source coreModuleProjects.collect { project ->
|
||||||
project.sourceSets.main.allJava
|
project.sourceSets.main.allJava
|
||||||
}
|
}
|
||||||
|
|
||||||
classpath = files(coreModuleProjects.collect { project ->
|
classpath = files(coreModuleProjects.collect { project ->
|
||||||
project.sourceSets.main.compileClasspath
|
project.sourceSets.main.compileClasspath
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
apidocs.options.outputLevel = org.gradle.external.javadoc.JavadocOutputLevel.QUIET
|
apidocs.options.outputLevel = org.gradle.external.javadoc.JavadocOutputLevel.QUIET
|
||||||
|
|
||||||
apidocs.options.links = [
|
apidocs.options.links = [
|
||||||
"http://static.springframework.org/spring/docs/3.2.x/javadoc-api",
|
"http://static.springframework.org/spring/docs/3.2.x/javadoc-api",
|
||||||
"http://static.springsource.org/spring-ldap/docs/1.3.x/apidocs/",
|
"http://static.springsource.org/spring-ldap/docs/1.3.x/apidocs/",
|
||||||
"http://download.oracle.com/javase/6/docs/api/"
|
"http://download.oracle.com/javase/6/docs/api/"
|
||||||
]
|
]
|
||||||
|
|
||||||
apidocs.options.groups = [
|
apidocs.options.groups = [
|
||||||
'Spring Security Core':[
|
'Spring Security Core':[
|
||||||
'org.springframework.security.core*',
|
'org.springframework.security.core*',
|
||||||
'org.springframework.security.authentication*',
|
'org.springframework.security.authentication*',
|
||||||
'org.springframework.security.access*',
|
'org.springframework.security.access*',
|
||||||
'org.springframework.security.remoting*',
|
'org.springframework.security.remoting*',
|
||||||
'org.springframework.security.provisioning*',
|
'org.springframework.security.provisioning*',
|
||||||
'org.springframework.security.util*'],
|
'org.springframework.security.util*'],
|
||||||
'Spring Security Web':['org.springframework.security.web*'],
|
'Spring Security Web':['org.springframework.security.web*'],
|
||||||
'Spring Security LDAP':['org.springframework.security.ldap*'],
|
'Spring Security LDAP':['org.springframework.security.ldap*'],
|
||||||
'Spring Security Crypto':['org.springframework.security.crypto*'],
|
'Spring Security Crypto':['org.springframework.security.crypto*'],
|
||||||
'Spring Security OpenID':['org.springframework.security.openid*'],
|
'Spring Security OpenID':['org.springframework.security.openid*'],
|
||||||
'Spring Security CAS':['org.springframework.security.cas*'],
|
'Spring Security CAS':['org.springframework.security.cas*'],
|
||||||
'Spring Security ACL':['org.springframework.security.acls*'],
|
'Spring Security ACL':['org.springframework.security.acls*'],
|
||||||
'Spring Security Config':['org.springframework.security.config*'],
|
'Spring Security Config':['org.springframework.security.config*'],
|
||||||
'Spring Security Taglibs':['org.springframework.security.taglibs*'],
|
'Spring Security Taglibs':['org.springframework.security.taglibs*'],
|
||||||
|
|
||||||
]
|
]
|
||||||
|
|
||||||
ext.apiSpec = copySpec {
|
ext.apiSpec = copySpec {
|
||||||
into('apidocs') {
|
into('apidocs') {
|
||||||
from(apidocs.destinationDir)
|
from(apidocs.destinationDir)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
assemble.dependsOn = [apidocs, 'manual:asciidoctor']
|
assemble.dependsOn = [apidocs, 'manual:asciidoctor']
|
||||||
|
|
||||||
task docsZip(type: Zip) {
|
task docsZip(type: Zip) {
|
||||||
dependsOn docs
|
dependsOn docs
|
||||||
evaluationDependsOn('guides')
|
evaluationDependsOn('guides')
|
||||||
group = 'Distribution'
|
group = 'Distribution'
|
||||||
baseName = rootProject.name
|
baseName = rootProject.name
|
||||||
classifier = 'docs'
|
classifier = 'docs'
|
||||||
description = "Builds -${classifier} archive containing api and reference " +
|
description = "Builds -${classifier} archive containing api and reference " +
|
||||||
"for deployment at static.springframework.org/spring-security/site/docs."
|
"for deployment at static.springframework.org/spring-security/site/docs."
|
||||||
|
|
||||||
with(project(':docs').apiSpec)
|
with(project(':docs').apiSpec)
|
||||||
with(project(':docs:manual').spec)
|
with(project(':docs:manual').spec)
|
||||||
with(project(':docs:guides').spec)
|
with(project(':docs:guides').spec)
|
||||||
}
|
}
|
||||||
|
|
||||||
task schemaZip(type: Zip) {
|
task schemaZip(type: Zip) {
|
||||||
group = 'Distribution'
|
group = 'Distribution'
|
||||||
baseName = rootProject.name
|
baseName = rootProject.name
|
||||||
classifier = 'schema'
|
classifier = 'schema'
|
||||||
description = "Builds -${classifier} archive containing all " +
|
description = "Builds -${classifier} archive containing all " +
|
||||||
"XSDs for deployment at static.springframework.org/schema."
|
"XSDs for deployment at static.springframework.org/schema."
|
||||||
|
|
||||||
coreModuleProjects.each { module ->
|
coreModuleProjects.each { module ->
|
||||||
def Properties schemas = new Properties();
|
def Properties schemas = new Properties();
|
||||||
|
|
||||||
module.sourceSets.main.resources.find {
|
module.sourceSets.main.resources.find {
|
||||||
it.path.endsWith('META-INF/spring.schemas')
|
it.path.endsWith('META-INF/spring.schemas')
|
||||||
}?.withInputStream { schemas.load(it) }
|
}?.withInputStream { schemas.load(it) }
|
||||||
|
|
||||||
for (def key : schemas.keySet()) {
|
for (def key : schemas.keySet()) {
|
||||||
def shortName = key.replaceAll(/http.*schema.(.*).spring-.*/, '$1')
|
def shortName = key.replaceAll(/http.*schema.(.*).spring-.*/, '$1')
|
||||||
assert shortName != key
|
assert shortName != key
|
||||||
File xsdFile = module.sourceSets.main.resources.find {
|
File xsdFile = module.sourceSets.main.resources.find {
|
||||||
it.path.endsWith(schemas.get(key))
|
it.path.endsWith(schemas.get(key))
|
||||||
}
|
}
|
||||||
assert xsdFile != null
|
assert xsdFile != null
|
||||||
into (shortName) {
|
into (shortName) {
|
||||||
from xsdFile.path
|
from xsdFile.path
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,46 +1,46 @@
|
||||||
apply plugin: 'org.asciidoctor.gradle.asciidoctor'
|
apply plugin: 'org.asciidoctor.gradle.asciidoctor'
|
||||||
|
|
||||||
asciidoctor {
|
asciidoctor {
|
||||||
baseDir = file('src/docs/asciidoc')
|
baseDir = file('src/docs/asciidoc')
|
||||||
options = [
|
options = [
|
||||||
eruby: 'erubis',
|
eruby: 'erubis',
|
||||||
eruby: 'erubis',
|
eruby: 'erubis',
|
||||||
attributes: [
|
attributes: [
|
||||||
copycss : '',
|
copycss : '',
|
||||||
icons : 'font',
|
icons : 'font',
|
||||||
'source-highlighter': 'prettify',
|
'source-highlighter': 'prettify',
|
||||||
sectanchors : '',
|
sectanchors : '',
|
||||||
toc: '',
|
toc: '',
|
||||||
'toc-placement' : 'preamble',
|
'toc-placement' : 'preamble',
|
||||||
idprefix: '',
|
idprefix: '',
|
||||||
idseparator: '-',
|
idseparator: '-',
|
||||||
doctype: 'book',
|
doctype: 'book',
|
||||||
'spring-security-version' : project.version,
|
'spring-security-version' : project.version,
|
||||||
'download-url' : getDownloadUrl(),
|
'download-url' : getDownloadUrl(),
|
||||||
'include-maven-repository' : getMavenRepositoryInclude(),
|
'include-maven-repository' : getMavenRepositoryInclude(),
|
||||||
revnumber : project.version
|
revnumber : project.version
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
ext.spec = copySpec {
|
ext.spec = copySpec {
|
||||||
into ('guides') {
|
into ('guides') {
|
||||||
from(asciidoctor.outputDir)
|
from(asciidoctor.outputDir)
|
||||||
exclude 'build', 'Guardfile'
|
exclude 'build', 'Guardfile'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
def getDownloadUrl() {
|
def getDownloadUrl() {
|
||||||
snapshotBuild ? "https://github.com/SpringSource/spring-security/archive/master.zip" : "https://github.com/spring-projects/spring-security/archive/${project.version}.zip"
|
snapshotBuild ? "https://github.com/SpringSource/spring-security/archive/master.zip" : "https://github.com/spring-projects/spring-security/archive/${project.version}.zip"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def getMavenRepositoryInclude() {
|
def getMavenRepositoryInclude() {
|
||||||
if(snapshotBuild) {
|
if(snapshotBuild) {
|
||||||
return "_includes/maven-repository-snapshot.asc"
|
return "_includes/maven-repository-snapshot.asc"
|
||||||
} else if(releaseBuild) {
|
} else if(releaseBuild) {
|
||||||
return "_includes/maven-repository-release.asc"
|
return "_includes/maven-repository-release.asc"
|
||||||
} else {
|
} else {
|
||||||
return "_includes/maven-repository-milestone.asc"
|
return "_includes/maven-repository-milestone.asc"
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -41,206 +41,206 @@ ext.thymeleafVersion = '2.1.3.RELEASE'
|
||||||
ext.thymeleafVersion = '1.2.7.RELEASE'
|
ext.thymeleafVersion = '1.2.7.RELEASE'
|
||||||
|
|
||||||
ext.spockDependencies = [
|
ext.spockDependencies = [
|
||||||
dependencies.create("org.spockframework:spock-spring:$spockVersion") {
|
dependencies.create("org.spockframework:spock-spring:$spockVersion") {
|
||||||
exclude group: 'junit', module: 'junit-dep'
|
exclude group: 'junit', module: 'junit-dep'
|
||||||
},
|
},
|
||||||
dependencies.create("org.spockframework:spock-core:$spockVersion") {
|
dependencies.create("org.spockframework:spock-core:$spockVersion") {
|
||||||
exclude group: 'junit', module: 'junit-dep'
|
exclude group: 'junit', module: 'junit-dep'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
ext.gebDependencies = spockDependencies + [
|
ext.gebDependencies = spockDependencies + [
|
||||||
"org.seleniumhq.selenium:selenium-htmlunit-driver:$seleniumVersion",
|
"org.seleniumhq.selenium:selenium-htmlunit-driver:$seleniumVersion",
|
||||||
"org.gebish:geb-spock:$gebVersion",
|
"org.gebish:geb-spock:$gebVersion",
|
||||||
'commons-httpclient:commons-httpclient:3.1',
|
'commons-httpclient:commons-httpclient:3.1',
|
||||||
"org.codehaus.groovy:groovy:$groovyVersion"
|
"org.codehaus.groovy:groovy:$groovyVersion"
|
||||||
]
|
]
|
||||||
|
|
||||||
ext.powerMockDependencies = [
|
ext.powerMockDependencies = [
|
||||||
"org.powermock:powermock-core:$powerMockVersion",
|
"org.powermock:powermock-core:$powerMockVersion",
|
||||||
"org.powermock:powermock-api-support:$powerMockVersion",
|
"org.powermock:powermock-api-support:$powerMockVersion",
|
||||||
"org.powermock:powermock-module-junit4-common:$powerMockVersion",
|
"org.powermock:powermock-module-junit4-common:$powerMockVersion",
|
||||||
"org.powermock:powermock-module-junit4:$powerMockVersion",
|
"org.powermock:powermock-module-junit4:$powerMockVersion",
|
||||||
dependencies.create("org.powermock:powermock-api-mockito:$powerMockVersion") {
|
dependencies.create("org.powermock:powermock-api-mockito:$powerMockVersion") {
|
||||||
exclude group: 'org.mockito', module: 'mockito-all'
|
exclude group: 'org.mockito', module: 'mockito-all'
|
||||||
},
|
},
|
||||||
"org.powermock:powermock-reflect:$powerMockVersion"
|
"org.powermock:powermock-reflect:$powerMockVersion"
|
||||||
]
|
]
|
||||||
|
|
||||||
ext.springCoreDependency = [
|
ext.springCoreDependency = [
|
||||||
dependencies.create("org.springframework:spring-core:$springVersion") {
|
dependencies.create("org.springframework:spring-core:$springVersion") {
|
||||||
exclude(group: 'commons-logging', module: 'commons-logging')
|
exclude(group: 'commons-logging', module: 'commons-logging')
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
ext.jstlDependencies = [
|
ext.jstlDependencies = [
|
||||||
"javax.servlet.jsp.jstl:javax.servlet.jsp.jstl-api:$jstlVersion",
|
"javax.servlet.jsp.jstl:javax.servlet.jsp.jstl-api:$jstlVersion",
|
||||||
"org.apache.taglibs:taglibs-standard-jstlel:1.2.1"
|
"org.apache.taglibs:taglibs-standard-jstlel:1.2.1"
|
||||||
]
|
]
|
||||||
|
|
||||||
ext.apachedsDependencies = [
|
ext.apachedsDependencies = [
|
||||||
"org.apache.directory.server:apacheds-core:$apacheDsVersion",
|
"org.apache.directory.server:apacheds-core:$apacheDsVersion",
|
||||||
"org.apache.directory.server:apacheds-core-entry:$apacheDsVersion",
|
"org.apache.directory.server:apacheds-core-entry:$apacheDsVersion",
|
||||||
"org.apache.directory.server:apacheds-protocol-shared:$apacheDsVersion",
|
"org.apache.directory.server:apacheds-protocol-shared:$apacheDsVersion",
|
||||||
"org.apache.directory.server:apacheds-protocol-ldap:$apacheDsVersion",
|
"org.apache.directory.server:apacheds-protocol-ldap:$apacheDsVersion",
|
||||||
"org.apache.directory.server:apacheds-server-jndi:$apacheDsVersion",
|
"org.apache.directory.server:apacheds-server-jndi:$apacheDsVersion",
|
||||||
'org.apache.directory.shared:shared-ldap:0.9.15'
|
'org.apache.directory.shared:shared-ldap:0.9.15'
|
||||||
]
|
]
|
||||||
|
|
||||||
// Integration test setup
|
// Integration test setup
|
||||||
configurations {
|
configurations {
|
||||||
integrationTestCompile {
|
integrationTestCompile {
|
||||||
extendsFrom testCompile, optional, provided
|
extendsFrom testCompile, optional, provided
|
||||||
}
|
}
|
||||||
integrationTestRuntime {
|
integrationTestRuntime {
|
||||||
extendsFrom integrationTestCompile, testRuntime
|
extendsFrom integrationTestCompile, testRuntime
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sourceSets {
|
sourceSets {
|
||||||
integrationTest {
|
integrationTest {
|
||||||
java.srcDir file('src/integration-test/java')
|
java.srcDir file('src/integration-test/java')
|
||||||
groovy.srcDirs file('src/integration-test/groovy')
|
groovy.srcDirs file('src/integration-test/groovy')
|
||||||
resources.srcDir file('src/integration-test/resources')
|
resources.srcDir file('src/integration-test/resources')
|
||||||
compileClasspath = sourceSets.main.output + sourceSets.test.output + configurations.integrationTestCompile
|
compileClasspath = sourceSets.main.output + sourceSets.test.output + configurations.integrationTestCompile
|
||||||
runtimeClasspath = output + compileClasspath + configurations.integrationTestRuntime
|
runtimeClasspath = output + compileClasspath + configurations.integrationTestRuntime
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
task integrationTest(type: Test, dependsOn: jar) {
|
task integrationTest(type: Test, dependsOn: jar) {
|
||||||
testClassesDir = sourceSets.integrationTest.output.classesDir
|
testClassesDir = sourceSets.integrationTest.output.classesDir
|
||||||
logging.captureStandardOutput(LogLevel.INFO)
|
logging.captureStandardOutput(LogLevel.INFO)
|
||||||
classpath = sourceSets.integrationTest.runtimeClasspath
|
classpath = sourceSets.integrationTest.runtimeClasspath
|
||||||
maxParallelForks = 1
|
maxParallelForks = 1
|
||||||
reports {
|
reports {
|
||||||
html.destination = project.file("$project.buildDir/reports/integration-tests/")
|
html.destination = project.file("$project.buildDir/reports/integration-tests/")
|
||||||
junitXml.destination = project.file("$project.buildDir/integration-test-results/")
|
junitXml.destination = project.file("$project.buildDir/integration-test-results/")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
eclipse {
|
eclipse {
|
||||||
classpath {
|
classpath {
|
||||||
plusConfigurations += [ configurations.integrationTestCompile ]
|
plusConfigurations += [ configurations.integrationTestCompile ]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
project.conf2ScopeMappings.addMapping(MavenPlugin.TEST_COMPILE_PRIORITY + 1, project.configurations.getByName("integrationTestCompile"), Conf2ScopeMappingContainer.TEST)
|
project.conf2ScopeMappings.addMapping(MavenPlugin.TEST_COMPILE_PRIORITY + 1, project.configurations.getByName("integrationTestCompile"), Conf2ScopeMappingContainer.TEST)
|
||||||
project.conf2ScopeMappings.addMapping(MavenPlugin.TEST_COMPILE_PRIORITY + 2, project.configurations.getByName("integrationTestRuntime"), Conf2ScopeMappingContainer.TEST)
|
project.conf2ScopeMappings.addMapping(MavenPlugin.TEST_COMPILE_PRIORITY + 2, project.configurations.getByName("integrationTestRuntime"), Conf2ScopeMappingContainer.TEST)
|
||||||
check.dependsOn integrationTest
|
check.dependsOn integrationTest
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
optional "commons-logging:commons-logging:$commonsLoggingVersion"
|
optional "commons-logging:commons-logging:$commonsLoggingVersion"
|
||||||
|
|
||||||
testCompile "junit:junit:$junitVersion",
|
testCompile "junit:junit:$junitVersion",
|
||||||
'org.mockito:mockito-core:1.9.5',
|
'org.mockito:mockito-core:1.9.5',
|
||||||
"org.springframework:spring-test:$springVersion",
|
"org.springframework:spring-test:$springVersion",
|
||||||
'org.easytesting:fest-assert:1.4'
|
'org.easytesting:fest-assert:1.4'
|
||||||
|
|
||||||
// Use slf4j/logback for logging
|
// Use slf4j/logback for logging
|
||||||
testRuntime "org.slf4j:jcl-over-slf4j:$slf4jVersion",
|
testRuntime "org.slf4j:jcl-over-slf4j:$slf4jVersion",
|
||||||
"ch.qos.logback:logback-classic:$logbackVersion"
|
"ch.qos.logback:logback-classic:$logbackVersion"
|
||||||
}
|
}
|
||||||
|
|
||||||
[configurations.runtime, configurations.default, configurations.testCompile]*.exclude(module: 'commons-logging')
|
[configurations.runtime, configurations.default, configurations.testCompile]*.exclude(module: 'commons-logging')
|
||||||
|
|
||||||
configurations.all {
|
configurations.all {
|
||||||
resolutionStrategy.eachDependency { DependencyResolveDetails details ->
|
resolutionStrategy.eachDependency { DependencyResolveDetails details ->
|
||||||
if (details.requested.group == 'org.slf4j') {
|
if (details.requested.group == 'org.slf4j') {
|
||||||
details.useVersion slf4jVersion
|
details.useVersion slf4jVersion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[compileJava, compileTestJava]*.options*.encoding = 'UTF-8'
|
[compileJava, compileTestJava]*.options*.encoding = 'UTF-8'
|
||||||
|
|
||||||
project.tasks.matching { it instanceof Test && it.name != 'integrationTest' }.all {
|
project.tasks.matching { it instanceof Test && it.name != 'integrationTest' }.all {
|
||||||
jvmArgs = ['-ea', '-Xmx500m', '-XX:MaxPermSize=256M']
|
jvmArgs = ['-ea', '-Xmx500m', '-XX:MaxPermSize=256M']
|
||||||
maxParallelForks = guessMaxForks()
|
maxParallelForks = guessMaxForks()
|
||||||
logging.captureStandardOutput(LogLevel.INFO)
|
logging.captureStandardOutput(LogLevel.INFO)
|
||||||
}
|
}
|
||||||
|
|
||||||
def guessMaxForks() {
|
def guessMaxForks() {
|
||||||
int processors = Runtime.runtime.availableProcessors()
|
int processors = Runtime.runtime.availableProcessors()
|
||||||
return Math.max(2, (int) (processors / 2))
|
return Math.max(2, (int) (processors / 2))
|
||||||
}
|
}
|
||||||
|
|
||||||
javadoc {
|
javadoc {
|
||||||
title = "Spring Security $version API"
|
title = "Spring Security $version API"
|
||||||
source = sourceSets.main.allJava
|
source = sourceSets.main.allJava
|
||||||
options {
|
options {
|
||||||
memberLevel = org.gradle.external.javadoc.JavadocMemberLevel.PROTECTED
|
memberLevel = org.gradle.external.javadoc.JavadocMemberLevel.PROTECTED
|
||||||
author = true
|
author = true
|
||||||
header = project.name
|
header = project.name
|
||||||
outputLevel = org.gradle.external.javadoc.JavadocOutputLevel.QUIET
|
outputLevel = org.gradle.external.javadoc.JavadocOutputLevel.QUIET
|
||||||
links = [
|
links = [
|
||||||
"http://static.springsource.org/spring/docs/3.2.x/javadoc-api/",
|
"http://static.springsource.org/spring/docs/3.2.x/javadoc-api/",
|
||||||
"http://static.springsource.org/spring-ldap/docs/1.3.x/apidocs/",
|
"http://static.springsource.org/spring-ldap/docs/1.3.x/apidocs/",
|
||||||
"http://download.oracle.com/javase/6/docs/api/"
|
"http://download.oracle.com/javase/6/docs/api/"
|
||||||
]
|
]
|
||||||
groups = [
|
groups = [
|
||||||
'Spring Security Core':[
|
'Spring Security Core':[
|
||||||
'org.springframework.security.core*',
|
'org.springframework.security.core*',
|
||||||
'org.springframework.security.authentication*',
|
'org.springframework.security.authentication*',
|
||||||
'org.springframework.security.access*',
|
'org.springframework.security.access*',
|
||||||
'org.springframework.security.remoting*',
|
'org.springframework.security.remoting*',
|
||||||
'org.springframework.security.provisioning*',
|
'org.springframework.security.provisioning*',
|
||||||
'org.springframework.security.util*'],
|
'org.springframework.security.util*'],
|
||||||
'Spring Security Web':['org.springframework.security.web*'],
|
'Spring Security Web':['org.springframework.security.web*'],
|
||||||
'Spring Security LDAP':['org.springframework.security.ldap*'],
|
'Spring Security LDAP':['org.springframework.security.ldap*'],
|
||||||
'Spring Security Crypto':['org.springframework.security.crypto*'],
|
'Spring Security Crypto':['org.springframework.security.crypto*'],
|
||||||
'Spring Security OpenID':['org.springframework.security.openid*'],
|
'Spring Security OpenID':['org.springframework.security.openid*'],
|
||||||
'Spring Security CAS':['org.springframework.security.cas*'],
|
'Spring Security CAS':['org.springframework.security.cas*'],
|
||||||
'Spring Security ACL':['org.springframework.security.acls*'],
|
'Spring Security ACL':['org.springframework.security.acls*'],
|
||||||
'Spring Security Config':['org.springframework.security.config*'],
|
'Spring Security Config':['org.springframework.security.config*'],
|
||||||
'Spring Security Taglibs':['org.springframework.security.taglibs*'],
|
'Spring Security Taglibs':['org.springframework.security.taglibs*'],
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
eclipse.classpath.downloadSources = true
|
eclipse.classpath.downloadSources = true
|
||||||
|
|
||||||
// http://forums.gradle.org/gradle/topics/eclipse_wtp_deploys_testcode_to_server_example_provided
|
// http://forums.gradle.org/gradle/topics/eclipse_wtp_deploys_testcode_to_server_example_provided
|
||||||
eclipse.classpath {
|
eclipse.classpath {
|
||||||
defaultOutputDir = file('bin/main')
|
defaultOutputDir = file('bin/main')
|
||||||
file.whenMerged { cp ->
|
file.whenMerged { cp ->
|
||||||
cp.entries.findAll { it instanceof SourceFolder && (it.path.contains("test") || it.path.contains("Test")) }*.output = "bin/test"
|
cp.entries.findAll { it instanceof SourceFolder && (it.path.contains("test") || it.path.contains("Test")) }*.output = "bin/test"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// GRADLE-1116
|
// GRADLE-1116
|
||||||
project.eclipse.classpath.file.whenMerged { classpath ->
|
project.eclipse.classpath.file.whenMerged { classpath ->
|
||||||
classpath.entries.removeAll { entry -> entry.path.endsWith('/build/resources/test') }
|
classpath.entries.removeAll { entry -> entry.path.endsWith('/build/resources/test') }
|
||||||
classpath.entries.removeAll { entry -> entry.path.endsWith('/build/classes/test') }
|
classpath.entries.removeAll { entry -> entry.path.endsWith('/build/classes/test') }
|
||||||
classpath.entries.removeAll { entry -> entry.path.endsWith('/build/resources/main') }
|
classpath.entries.removeAll { entry -> entry.path.endsWith('/build/resources/main') }
|
||||||
classpath.entries.removeAll { entry -> entry.path.endsWith('/build/classes/main') }
|
classpath.entries.removeAll { entry -> entry.path.endsWith('/build/classes/main') }
|
||||||
}
|
}
|
||||||
|
|
||||||
// GRADLE-1422
|
// GRADLE-1422
|
||||||
project.eclipseClasspath.doFirst {
|
project.eclipseClasspath.doFirst {
|
||||||
// delay adding whenMerged till the entryAttributes are added (must be the last whenMerged)
|
// delay adding whenMerged till the entryAttributes are added (must be the last whenMerged)
|
||||||
project.eclipse.classpath.file.whenMerged { classpath ->
|
project.eclipse.classpath.file.whenMerged { classpath ->
|
||||||
def includeDeps = project.configurations.getByName('runtime').collect {f -> f.absolutePath } as Set
|
def includeDeps = project.configurations.getByName('runtime').collect {f -> f.absolutePath } as Set
|
||||||
classpath.entries.each { cp ->
|
classpath.entries.each { cp ->
|
||||||
if(cp instanceof org.gradle.plugins.ide.eclipse.model.Library) {
|
if(cp instanceof org.gradle.plugins.ide.eclipse.model.Library) {
|
||||||
def include = includeDeps.contains(cp.path)
|
def include = includeDeps.contains(cp.path)
|
||||||
def attr = 'org.eclipse.jst.component.dependency'
|
def attr = 'org.eclipse.jst.component.dependency'
|
||||||
if(!include) {
|
if(!include) {
|
||||||
cp.entryAttributes.remove(attr)
|
cp.entryAttributes.remove(attr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
project.idea.module {
|
project.idea.module {
|
||||||
scopes.TEST.plus += [project.configurations.integrationTestRuntime]
|
scopes.TEST.plus += [project.configurations.integrationTestRuntime]
|
||||||
testSourceDirs += sourceSets.integrationTest.resources.srcDirs
|
testSourceDirs += sourceSets.integrationTest.resources.srcDirs
|
||||||
}
|
}
|
||||||
|
|
||||||
task javadocJar(type: Jar) {
|
task javadocJar(type: Jar) {
|
||||||
classifier = 'javadoc'
|
classifier = 'javadoc'
|
||||||
from javadoc
|
from javadoc
|
||||||
}
|
}
|
||||||
|
|
||||||
artifacts {
|
artifacts {
|
||||||
archives javadocJar
|
archives javadocJar
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,129 +2,129 @@ apply plugin: 'maven'
|
||||||
|
|
||||||
// Create a source jar for uploading
|
// Create a source jar for uploading
|
||||||
task sourceJar(type: Jar) {
|
task sourceJar(type: Jar) {
|
||||||
classifier = 'sources'
|
classifier = 'sources'
|
||||||
from sourceSets.main.java.srcDirs
|
from sourceSets.main.java.srcDirs
|
||||||
include '**/*.java', '**/*.aj'
|
include '**/*.java', '**/*.aj'
|
||||||
}
|
}
|
||||||
|
|
||||||
artifacts {
|
artifacts {
|
||||||
archives sourceJar
|
archives sourceJar
|
||||||
}
|
}
|
||||||
|
|
||||||
// Configuration for SpringSource s3 maven deployer
|
// Configuration for SpringSource s3 maven deployer
|
||||||
configurations {
|
configurations {
|
||||||
deployerJars
|
deployerJars
|
||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
deployerJars "org.springframework.build.aws:org.springframework.build.aws.maven:3.0.0.RELEASE"
|
deployerJars "org.springframework.build.aws:org.springframework.build.aws.maven:3.0.0.RELEASE"
|
||||||
}
|
}
|
||||||
|
|
||||||
install {
|
install {
|
||||||
repositories.mavenInstaller {
|
repositories.mavenInstaller {
|
||||||
customizePom(pom, project)
|
customizePom(pom, project)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
def customizePom(pom, gradleProject) {
|
def customizePom(pom, gradleProject) {
|
||||||
pom.whenConfigured { p ->
|
pom.whenConfigured { p ->
|
||||||
p.dependencies.findAll{ it.scope == "optional" }.each {
|
p.dependencies.findAll{ it.scope == "optional" }.each {
|
||||||
it.scope = "compile"
|
it.scope = "compile"
|
||||||
it.optional = true
|
it.optional = true
|
||||||
}
|
}
|
||||||
// sort to make pom dependencies order consistent to ease comparison of older poms
|
// sort to make pom dependencies order consistent to ease comparison of older poms
|
||||||
p.dependencies = p.dependencies.sort { dep ->
|
p.dependencies = p.dependencies.sort { dep ->
|
||||||
"$dep.scope:$dep.optional:$dep.groupId:$dep.artifactId"
|
"$dep.scope:$dep.optional:$dep.groupId:$dep.artifactId"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
def isWar = project.hasProperty('war')
|
def isWar = project.hasProperty('war')
|
||||||
pom.project {
|
pom.project {
|
||||||
name = gradleProject.name
|
name = gradleProject.name
|
||||||
if(isWar) {
|
if(isWar) {
|
||||||
packaging = "war"
|
packaging = "war"
|
||||||
}
|
}
|
||||||
description = gradleProject.name
|
description = gradleProject.name
|
||||||
url = 'http://spring.io/spring-security'
|
url = 'http://spring.io/spring-security'
|
||||||
organization {
|
organization {
|
||||||
name = 'spring.io'
|
name = 'spring.io'
|
||||||
url = 'http://spring.io/'
|
url = 'http://spring.io/'
|
||||||
}
|
}
|
||||||
licenses {
|
licenses {
|
||||||
license {
|
license {
|
||||||
name 'The Apache Software License, Version 2.0'
|
name 'The Apache Software License, Version 2.0'
|
||||||
url 'http://www.apache.org/licenses/LICENSE-2.0.txt'
|
url 'http://www.apache.org/licenses/LICENSE-2.0.txt'
|
||||||
distribution 'repo'
|
distribution 'repo'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
scm {
|
scm {
|
||||||
url = 'https://github.com/spring-projects/spring-security'
|
url = 'https://github.com/spring-projects/spring-security'
|
||||||
connection = 'scm:git:git://github.com/spring-projects/spring-security'
|
connection = 'scm:git:git://github.com/spring-projects/spring-security'
|
||||||
developerConnection = 'scm:git:git://github.com/spring-projects/spring-security'
|
developerConnection = 'scm:git:git://github.com/spring-projects/spring-security'
|
||||||
}
|
}
|
||||||
developers {
|
developers {
|
||||||
developer {
|
developer {
|
||||||
id = 'rwinch'
|
id = 'rwinch'
|
||||||
name = 'Rob Winch'
|
name = 'Rob Winch'
|
||||||
email = 'rwinch@gopivotal.com'
|
email = 'rwinch@gopivotal.com'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(isWar) {
|
if(isWar) {
|
||||||
properties {
|
properties {
|
||||||
'm2eclipse.wtp.contextRoot' '/' + project.war.baseName
|
'm2eclipse.wtp.contextRoot' '/' + project.war.baseName
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(project.snapshotBuild) {
|
if(project.snapshotBuild) {
|
||||||
repositories {
|
repositories {
|
||||||
repository {
|
repository {
|
||||||
id 'spring-snasphot'
|
id 'spring-snasphot'
|
||||||
url 'https://repo.spring.io/snapshot'
|
url 'https://repo.spring.io/snapshot'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if(!project.releaseBuild) {
|
} else if(!project.releaseBuild) {
|
||||||
repositories {
|
repositories {
|
||||||
repository {
|
repository {
|
||||||
id 'spring-milestone'
|
id 'spring-milestone'
|
||||||
url 'https://repo.spring.io/milestone'
|
url 'https://repo.spring.io/milestone'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// http://forums.gradle.org/gradle/topics/after_upgrade_gradle_to_2_0_version_the_maven_pom_not_support_build_property
|
// http://forums.gradle.org/gradle/topics/after_upgrade_gradle_to_2_0_version_the_maven_pom_not_support_build_property
|
||||||
pom.withXml {
|
pom.withXml {
|
||||||
def plugins = asNode().appendNode('build').appendNode('plugins')
|
def plugins = asNode().appendNode('build').appendNode('plugins')
|
||||||
plugins
|
plugins
|
||||||
.appendNode('plugin')
|
.appendNode('plugin')
|
||||||
.appendNode('artifactId','maven-compiler-plugin').parent()
|
.appendNode('artifactId','maven-compiler-plugin').parent()
|
||||||
.appendNode('configuration')
|
.appendNode('configuration')
|
||||||
.appendNode('source','1.7').parent()
|
.appendNode('source','1.7').parent()
|
||||||
.appendNode('target','1.7')
|
.appendNode('target','1.7')
|
||||||
if(isWar) {
|
if(isWar) {
|
||||||
plugins
|
plugins
|
||||||
.appendNode('plugin')
|
.appendNode('plugin')
|
||||||
.appendNode('artifactId','maven-war-plugin').parent()
|
.appendNode('artifactId','maven-war-plugin').parent()
|
||||||
.appendNode('version','2.3').parent()
|
.appendNode('version','2.3').parent()
|
||||||
.appendNode('configuration')
|
.appendNode('configuration')
|
||||||
.appendNode('failOnMissingWebXml','false')
|
.appendNode('failOnMissingWebXml','false')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
task generatePom {
|
task generatePom {
|
||||||
group = 'Build'
|
group = 'Build'
|
||||||
description = 'Generates a Maven pom.xml'
|
description = 'Generates a Maven pom.xml'
|
||||||
|
|
||||||
ext.generatedPomFileName = "pom.xml"
|
ext.generatedPomFileName = "pom.xml"
|
||||||
onlyIf { install.enabled }
|
onlyIf { install.enabled }
|
||||||
|
|
||||||
inputs.files(fileTree(project.rootProject.rootDir).include("**/*.gradle").files)
|
inputs.files(fileTree(project.rootProject.rootDir).include("**/*.gradle").files)
|
||||||
inputs.files(new File(project.rootProject.rootDir, Project.GRADLE_PROPERTIES))
|
inputs.files(new File(project.rootProject.rootDir, Project.GRADLE_PROPERTIES))
|
||||||
outputs.files(generatedPomFileName)
|
outputs.files(generatedPomFileName)
|
||||||
|
|
||||||
doLast() {
|
doLast() {
|
||||||
def p = pom {}
|
def p = pom {}
|
||||||
customizePom(p, project)
|
customizePom(p, project)
|
||||||
p.writeTo(generatedPomFileName)
|
p.writeTo(generatedPomFileName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
build.dependsOn generatePom
|
build.dependsOn generatePom
|
||||||
|
|
|
@ -1,22 +1,22 @@
|
||||||
task checkDependencies << {
|
task checkDependencies << {
|
||||||
verifyNoDependenciesMatchingVersion(".*-SNAPSHOT")
|
verifyNoDependenciesMatchingVersion(".*-SNAPSHOT")
|
||||||
if(releaseBuild) {
|
if(releaseBuild) {
|
||||||
verifyNoDependenciesMatchingVersion(".*M.*")
|
verifyNoDependenciesMatchingVersion(".*M.*")
|
||||||
verifyNoDependenciesMatchingVersion(".*RC.*")
|
verifyNoDependenciesMatchingVersion(".*RC.*")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!snapshotBuild) {
|
if(!snapshotBuild) {
|
||||||
tasks.findByPath('check')?.dependsOn checkDependencies
|
tasks.findByPath('check')?.dependsOn checkDependencies
|
||||||
}
|
}
|
||||||
|
|
||||||
def verifyNoDependenciesMatchingVersion(def pattern) {
|
def verifyNoDependenciesMatchingVersion(def pattern) {
|
||||||
def dependencies = configurations.all*.allDependencies*.findAll { d ->
|
def dependencies = configurations.all*.allDependencies*.findAll { d ->
|
||||||
def ignored = 'io.spring.platform:platform-versions'
|
def ignored = 'io.spring.platform:platform-versions'
|
||||||
def groupAndName = "$d.group:$d.name".toString()
|
def groupAndName = "$d.group:$d.name".toString()
|
||||||
ignored != groupAndName && d.version?.matches(pattern)
|
ignored != groupAndName && d.version?.matches(pattern)
|
||||||
}.flatten().toSet().join("\n ")
|
}.flatten().toSet().join("\n ")
|
||||||
if(dependencies) {
|
if(dependencies) {
|
||||||
throw new GradleException("${project.name} cannot have dependencies with a version that matches $pattern when its version is ${project.version}. Got\n $dependencies")
|
throw new GradleException("${project.name} cannot have dependencies with a version that matches $pattern when its version is ${project.version}. Got\n $dependencies")
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,68 +1,68 @@
|
||||||
buildscript {
|
buildscript {
|
||||||
repositories {
|
repositories {
|
||||||
maven { url "https://repo.spring.io/plugins-release" }
|
maven { url "https://repo.spring.io/plugins-release" }
|
||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath("org.gradle.api.plugins:gradle-tomcat-plugin:1.2.5")
|
classpath("org.gradle.api.plugins:gradle-tomcat-plugin:1.2.5")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
apply plugin: 'tomcat'
|
apply plugin: 'tomcat'
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
def tomcatVersion = '7.0.54'
|
def tomcatVersion = '7.0.54'
|
||||||
tomcat "org.apache.tomcat.embed:tomcat-embed-core:${tomcatVersion}",
|
tomcat "org.apache.tomcat.embed:tomcat-embed-core:${tomcatVersion}",
|
||||||
"org.apache.tomcat.embed:tomcat-embed-logging-juli:${tomcatVersion}",
|
"org.apache.tomcat.embed:tomcat-embed-logging-juli:${tomcatVersion}",
|
||||||
"org.apache.tomcat.embed:tomcat-embed-websocket:${tomcatVersion}"
|
"org.apache.tomcat.embed:tomcat-embed-websocket:${tomcatVersion}"
|
||||||
tomcat("org.apache.tomcat.embed:tomcat-embed-jasper:${tomcatVersion}") {
|
tomcat("org.apache.tomcat.embed:tomcat-embed-jasper:${tomcatVersion}") {
|
||||||
exclude group: 'org.eclipse.jdt.core.compiler', module: 'ecj'
|
exclude group: 'org.eclipse.jdt.core.compiler', module: 'ecj'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
task integrationTomcatRun(type: org.gradle.api.plugins.tomcat.tasks.TomcatRun) {
|
task integrationTomcatRun(type: org.gradle.api.plugins.tomcat.tasks.TomcatRun) {
|
||||||
onlyIf { !sourceSets.integrationTest.allSource.empty }
|
onlyIf { !sourceSets.integrationTest.allSource.empty }
|
||||||
buildscriptClasspath = tomcatRun.buildscriptClasspath
|
buildscriptClasspath = tomcatRun.buildscriptClasspath
|
||||||
contextPath = tomcatRun.contextPath
|
contextPath = tomcatRun.contextPath
|
||||||
daemon = true
|
daemon = true
|
||||||
tomcatClasspath = tomcatRun.tomcatClasspath
|
tomcatClasspath = tomcatRun.tomcatClasspath
|
||||||
webAppClasspath = tomcatRun.webAppClasspath
|
webAppClasspath = tomcatRun.webAppClasspath
|
||||||
webAppSourceDirectory = tomcatRun.webAppSourceDirectory
|
webAppSourceDirectory = tomcatRun.webAppSourceDirectory
|
||||||
doFirst {
|
doFirst {
|
||||||
def mainOutputDir = project.sourceSets.main.output.classesDir
|
def mainOutputDir = project.sourceSets.main.output.classesDir
|
||||||
if(mainOutputDir) {
|
if(mainOutputDir) {
|
||||||
classesDirectory = mainOutputDir
|
classesDirectory = mainOutputDir
|
||||||
}
|
}
|
||||||
// delay reserving ports to ensure they are still available
|
// delay reserving ports to ensure they are still available
|
||||||
def ports = reservePorts(3)
|
def ports = reservePorts(3)
|
||||||
httpPort = ports[0]
|
httpPort = ports[0]
|
||||||
ajpPort = ports[1]
|
ajpPort = ports[1]
|
||||||
stopPort = ports[2]
|
stopPort = ports[2]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
task integrationTomcatStop(type: org.gradle.api.plugins.tomcat.tasks.TomcatStop) {
|
task integrationTomcatStop(type: org.gradle.api.plugins.tomcat.tasks.TomcatStop) {
|
||||||
onlyIf { !sourceSets.integrationTest.allSource.empty }
|
onlyIf { !sourceSets.integrationTest.allSource.empty }
|
||||||
doFirst {
|
doFirst {
|
||||||
stopPort = integrationTomcatRun.stopPort
|
stopPort = integrationTomcatRun.stopPort
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
integrationTest {
|
integrationTest {
|
||||||
dependsOn integrationTomcatRun
|
dependsOn integrationTomcatRun
|
||||||
doFirst {
|
doFirst {
|
||||||
def host = 'localhost:' + integrationTomcatRun.httpPort
|
def host = 'localhost:' + integrationTomcatRun.httpPort
|
||||||
systemProperties['geb.build.baseUrl'] = 'http://'+host+'/' + integrationTomcatRun.contextPath + '/'
|
systemProperties['geb.build.baseUrl'] = 'http://'+host+'/' + integrationTomcatRun.contextPath + '/'
|
||||||
systemProperties['geb.build.reportsDir'] = 'build/geb-reports'
|
systemProperties['geb.build.reportsDir'] = 'build/geb-reports'
|
||||||
}
|
}
|
||||||
finalizedBy integrationTomcatStop
|
finalizedBy integrationTomcatStop
|
||||||
}
|
}
|
||||||
|
|
||||||
def reservePorts(int count) {
|
def reservePorts(int count) {
|
||||||
def sockets = []
|
def sockets = []
|
||||||
for(int i in 1..count) {
|
for(int i in 1..count) {
|
||||||
sockets << new ServerSocket(0)
|
sockets << new ServerSocket(0)
|
||||||
}
|
}
|
||||||
def result = sockets*.localPort
|
def result = sockets*.localPort
|
||||||
sockets*.close()
|
sockets*.close()
|
||||||
result
|
result
|
||||||
}
|
}
|
|
@ -2,9 +2,9 @@ apply plugin: 'war'
|
||||||
apply from: TOMCAT_GRADLE
|
apply from: TOMCAT_GRADLE
|
||||||
|
|
||||||
war {
|
war {
|
||||||
baseName = "sample"
|
baseName = "sample"
|
||||||
}
|
}
|
||||||
|
|
||||||
sonarRunner {
|
sonarRunner {
|
||||||
skipProject = true
|
skipProject = true
|
||||||
}
|
}
|
|
@ -1,17 +1,17 @@
|
||||||
System.setProperty('python.cachedir.skip', 'true')
|
System.setProperty('python.cachedir.skip', 'true')
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
compile project(':spring-security-core'),
|
compile project(':spring-security-core'),
|
||||||
'aopalliance:aopalliance:1.0',
|
'aopalliance:aopalliance:1.0',
|
||||||
'org.python:jython:2.5.0',
|
'org.python:jython:2.5.0',
|
||||||
"org.springframework:spring-context:$springVersion",
|
"org.springframework:spring-context:$springVersion",
|
||||||
"org.springframework:spring-aop:$springVersion",
|
"org.springframework:spring-aop:$springVersion",
|
||||||
"org.springframework:spring-tx:$springVersion",
|
"org.springframework:spring-tx:$springVersion",
|
||||||
"org.springframework:spring-beans:$springVersion"
|
"org.springframework:spring-beans:$springVersion"
|
||||||
|
|
||||||
testCompile project(':spring-security-web'),
|
testCompile project(':spring-security-web'),
|
||||||
"javax.servlet:javax.servlet-api:$servletApiVersion",
|
"javax.servlet:javax.servlet-api:$servletApiVersion",
|
||||||
"org.springframework:spring-web:$springVersion"
|
"org.springframework:spring-web:$springVersion"
|
||||||
testRuntime project(':spring-security-config'),
|
testRuntime project(':spring-security-config'),
|
||||||
"org.aspectj:aspectjweaver:$aspectjVersion"
|
"org.aspectj:aspectjweaver:$aspectjVersion"
|
||||||
}
|
}
|
|
@ -1,38 +1,38 @@
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
compile "org.springframework:spring-context:$springVersion",
|
compile "org.springframework:spring-context:$springVersion",
|
||||||
"org.springframework:spring-web:$springVersion"
|
"org.springframework:spring-web:$springVersion"
|
||||||
|
|
||||||
provided "javax.servlet:javax.servlet-api:$servletApiVersion"
|
provided "javax.servlet:javax.servlet-api:$servletApiVersion"
|
||||||
|
|
||||||
testCompile project(':spring-security-core'),
|
testCompile project(':spring-security-core'),
|
||||||
project(':spring-security-web'),
|
project(':spring-security-web'),
|
||||||
project(':spring-security-taglibs'),
|
project(':spring-security-taglibs'),
|
||||||
"org.springframework:spring-beans:$springVersion",
|
"org.springframework:spring-beans:$springVersion",
|
||||||
"org.springframework:spring-webmvc:$springVersion",
|
"org.springframework:spring-webmvc:$springVersion",
|
||||||
"org.mortbay.jetty:jetty-util:$jettyVersion",
|
"org.mortbay.jetty:jetty-util:$jettyVersion",
|
||||||
"org.testng:testng:5.11:jdk15"
|
"org.testng:testng:5.11:jdk15"
|
||||||
testCompile ("org.mortbay.jetty:jetty:$jettyVersion") {
|
testCompile ("org.mortbay.jetty:jetty:$jettyVersion") {
|
||||||
exclude group: 'org.mortbay.jetty', module: 'servlet-api'
|
exclude group: 'org.mortbay.jetty', module: 'servlet-api'
|
||||||
}
|
}
|
||||||
testCompile ('net.sourceforge.jwebunit:jwebunit-core:2.2') {
|
testCompile ('net.sourceforge.jwebunit:jwebunit-core:2.2') {
|
||||||
exclude group: 'javax.servlet', module: 'servlet-api'
|
exclude group: 'javax.servlet', module: 'servlet-api'
|
||||||
exclude group: 'regexp', module: 'regexp'
|
exclude group: 'regexp', module: 'regexp'
|
||||||
}
|
}
|
||||||
|
|
||||||
testRuntime project(':spring-security-config'),
|
testRuntime project(':spring-security-config'),
|
||||||
project(':spring-security-ldap'),
|
project(':spring-security-ldap'),
|
||||||
"org.mortbay.jetty:jsp-2.1-jetty:$jettyVersion",
|
"org.mortbay.jetty:jsp-2.1-jetty:$jettyVersion",
|
||||||
testRuntime ('net.sourceforge.jwebunit:jwebunit-htmlunit-plugin:2.2') {
|
testRuntime ('net.sourceforge.jwebunit:jwebunit-htmlunit-plugin:2.2') {
|
||||||
exclude group: 'javax.servlet', module: 'servlet-api'
|
exclude group: 'javax.servlet', module: 'servlet-api'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
integrationTest {
|
integrationTest {
|
||||||
useTestNG();
|
useTestNG();
|
||||||
options {
|
options {
|
||||||
jvmArgs = ["-ea", '-Xms128m', '-Xmx500m']
|
jvmArgs = ["-ea", '-Xms128m', '-Xmx500m']
|
||||||
systemProperties = ['webapp.dir': "$projectDir/src/main/webapp"]
|
systemProperties = ['webapp.dir': "$projectDir/src/main/webapp"]
|
||||||
}
|
}
|
||||||
maxParallelForks = 1
|
maxParallelForks = 1
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,41 +1,41 @@
|
||||||
// Ldap build file
|
// Ldap build file
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
compile project(':spring-security-core'),
|
compile project(':spring-security-core'),
|
||||||
springCoreDependency,
|
springCoreDependency,
|
||||||
"org.springframework:spring-beans:$springVersion",
|
"org.springframework:spring-beans:$springVersion",
|
||||||
"org.springframework:spring-context:$springVersion",
|
"org.springframework:spring-context:$springVersion",
|
||||||
"org.springframework:spring-tx:$springVersion"
|
"org.springframework:spring-tx:$springVersion"
|
||||||
|
|
||||||
optional "org.apache.directory.server:apacheds-core:$apacheDsVersion",
|
optional "org.apache.directory.server:apacheds-core:$apacheDsVersion",
|
||||||
"org.apache.directory.server:apacheds-core-entry:$apacheDsVersion",
|
"org.apache.directory.server:apacheds-core-entry:$apacheDsVersion",
|
||||||
"org.apache.directory.server:apacheds-protocol-shared:$apacheDsVersion",
|
"org.apache.directory.server:apacheds-protocol-shared:$apacheDsVersion",
|
||||||
"org.apache.directory.server:apacheds-protocol-ldap:$apacheDsVersion",
|
"org.apache.directory.server:apacheds-protocol-ldap:$apacheDsVersion",
|
||||||
"org.apache.directory.server:apacheds-server-jndi:$apacheDsVersion",
|
"org.apache.directory.server:apacheds-server-jndi:$apacheDsVersion",
|
||||||
'org.apache.directory.shared:shared-ldap:0.9.15',
|
'org.apache.directory.shared:shared-ldap:0.9.15',
|
||||||
'ldapsdk:ldapsdk:4.1'
|
'ldapsdk:ldapsdk:4.1'
|
||||||
|
|
||||||
compile ("org.springframework.ldap:spring-ldap-core:$springLdapVersion") {
|
compile ("org.springframework.ldap:spring-ldap-core:$springLdapVersion") {
|
||||||
exclude(group: 'commons-logging', module: 'commons-logging')
|
exclude(group: 'commons-logging', module: 'commons-logging')
|
||||||
exclude(group: 'org.springframework', module: 'spring-core')
|
exclude(group: 'org.springframework', module: 'spring-core')
|
||||||
exclude(group: 'org.springframework', module: 'spring-tx')
|
exclude(group: 'org.springframework', module: 'spring-tx')
|
||||||
exclude(group: 'org.springframework', module: 'spring-beans')
|
exclude(group: 'org.springframework', module: 'spring-beans')
|
||||||
exclude(group: 'org.springframework.data', module: 'spring-data-commons')
|
exclude(group: 'org.springframework.data', module: 'spring-data-commons')
|
||||||
}
|
}
|
||||||
|
|
||||||
testCompile "org.slf4j:slf4j-api:$slf4jVersion",
|
testCompile "org.slf4j:slf4j-api:$slf4jVersion",
|
||||||
"org.slf4j:jcl-over-slf4j:$slf4jVersion"
|
"org.slf4j:jcl-over-slf4j:$slf4jVersion"
|
||||||
}
|
}
|
||||||
|
|
||||||
integrationTest {
|
integrationTest {
|
||||||
include('**/ApacheDSServerIntegrationTests.class')
|
include('**/ApacheDSServerIntegrationTests.class')
|
||||||
// exclude('**/OpenLDAPIntegrationTestSuite.class')
|
// exclude('**/OpenLDAPIntegrationTestSuite.class')
|
||||||
maxParallelForks = 1
|
maxParallelForks = 1
|
||||||
}
|
}
|
||||||
|
|
||||||
// Runs a server for running the integration tests against (from an IDE, for example)
|
// Runs a server for running the integration tests against (from an IDE, for example)
|
||||||
task(ldapServer, dependsOn: 'integrationTestClasses', type: JavaExec) {
|
task(ldapServer, dependsOn: 'integrationTestClasses', type: JavaExec) {
|
||||||
classpath = sourceSets.integrationTest.runtimeClasspath
|
classpath = sourceSets.integrationTest.runtimeClasspath
|
||||||
main = 'org.springframework.security.ldap.ApacheDSServerIntegrationTests'
|
main = 'org.springframework.security.ldap.ApacheDSServerIntegrationTests'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,24 +1,24 @@
|
||||||
apply plugin: 'groovy'
|
apply plugin: 'groovy'
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
compile project(':spring-security-core'),
|
compile project(':spring-security-core'),
|
||||||
springCoreDependency,
|
springCoreDependency,
|
||||||
'aopalliance:aopalliance:1.0',
|
'aopalliance:aopalliance:1.0',
|
||||||
"org.springframework:spring-beans:$springVersion",
|
"org.springframework:spring-beans:$springVersion",
|
||||||
"org.springframework:spring-context:$springVersion",
|
"org.springframework:spring-context:$springVersion",
|
||||||
"org.springframework:spring-expression:$springVersion",
|
"org.springframework:spring-expression:$springVersion",
|
||||||
"org.springframework:spring-messaging:$springVersion"
|
"org.springframework:spring-messaging:$springVersion"
|
||||||
|
|
||||||
optional project(':spring-security-web'),
|
optional project(':spring-security-web'),
|
||||||
"org.springframework:spring-websocket:$springVersion",
|
"org.springframework:spring-websocket:$springVersion",
|
||||||
"javax.servlet:javax.servlet-api:$servletApiVersion"
|
"javax.servlet:javax.servlet-api:$servletApiVersion"
|
||||||
|
|
||||||
testCompile project(':spring-security-core').sourceSets.test.output,
|
testCompile project(':spring-security-core').sourceSets.test.output,
|
||||||
"commons-codec:commons-codec:$commonsCodecVersion",
|
"commons-codec:commons-codec:$commonsCodecVersion",
|
||||||
"org.slf4j:jcl-over-slf4j:$slf4jVersion",
|
"org.slf4j:jcl-over-slf4j:$slf4jVersion",
|
||||||
"org.codehaus.groovy:groovy-all:$groovyVersion",
|
"org.codehaus.groovy:groovy-all:$groovyVersion",
|
||||||
powerMockDependencies,
|
powerMockDependencies,
|
||||||
spockDependencies
|
spockDependencies
|
||||||
|
|
||||||
testRuntime "org.hsqldb:hsqldb:$hsqlVersion"
|
testRuntime "org.hsqldb:hsqldb:$hsqlVersion"
|
||||||
}
|
}
|
|
@ -1,24 +1,24 @@
|
||||||
// OpenID Module build file
|
// OpenID Module build file
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
compile project(':spring-security-core'),
|
compile project(':spring-security-core'),
|
||||||
project(':spring-security-web'),
|
project(':spring-security-web'),
|
||||||
springCoreDependency,
|
springCoreDependency,
|
||||||
"org.springframework:spring-aop:$springVersion",
|
"org.springframework:spring-aop:$springVersion",
|
||||||
"org.springframework:spring-context:$springVersion",
|
"org.springframework:spring-context:$springVersion",
|
||||||
"org.springframework:spring-beans:$springVersion",
|
"org.springframework:spring-beans:$springVersion",
|
||||||
"org.springframework:spring-web:$springVersion"
|
"org.springframework:spring-web:$springVersion"
|
||||||
|
|
||||||
// openid4java has a compile time dep on guice with a group
|
// openid4java has a compile time dep on guice with a group
|
||||||
// name which is different from the maven central one.
|
// name which is different from the maven central one.
|
||||||
// We use the maven central version here instead.
|
// We use the maven central version here instead.
|
||||||
compile('org.openid4java:openid4java-nodeps:0.9.6') {
|
compile('org.openid4java:openid4java-nodeps:0.9.6') {
|
||||||
exclude group: 'com.google.code.guice', module: 'guice'
|
exclude group: 'com.google.code.guice', module: 'guice'
|
||||||
}
|
}
|
||||||
compile 'com.google.inject:guice:2.0'
|
compile 'com.google.inject:guice:2.0'
|
||||||
|
|
||||||
provided "javax.servlet:javax.servlet-api:$servletApiVersion"
|
provided "javax.servlet:javax.servlet-api:$servletApiVersion"
|
||||||
|
|
||||||
runtime 'org.apache.httpcomponents:httpclient:4.2.3',
|
runtime 'org.apache.httpcomponents:httpclient:4.2.3',
|
||||||
'net.sourceforge.nekohtml:nekohtml:1.9.20'
|
'net.sourceforge.nekohtml:nekohtml:1.9.20'
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
// Remoting module build file
|
// Remoting module build file
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
compile project(':spring-security-core'),
|
compile project(':spring-security-core'),
|
||||||
'aopalliance:aopalliance:1.0',
|
'aopalliance:aopalliance:1.0',
|
||||||
springCoreDependency,
|
springCoreDependency,
|
||||||
"org.springframework:spring-beans:$springVersion",
|
"org.springframework:spring-beans:$springVersion",
|
||||||
"org.springframework:spring-context:$springVersion",
|
"org.springframework:spring-context:$springVersion",
|
||||||
"org.springframework:spring-web:$springVersion"
|
"org.springframework:spring-web:$springVersion"
|
||||||
|
|
||||||
testCompile project(':spring-security-core').sourceSets.test.output
|
testCompile project(':spring-security-core').sourceSets.test.output
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
compile project(':spring-security-core'),
|
compile project(':spring-security-core'),
|
||||||
project(':spring-security-config')
|
project(':spring-security-config')
|
||||||
|
|
||||||
aspectpath project(':spring-security-aspects')
|
aspectpath project(':spring-security-aspects')
|
||||||
|
|
||||||
runtime project(':spring-security-aspects')
|
runtime project(':spring-security-aspects')
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
compile project(':spring-security-core')
|
compile project(':spring-security-core')
|
||||||
|
|
||||||
aspectpath project(':spring-security-aspects')
|
aspectpath project(':spring-security-aspects')
|
||||||
|
|
||||||
runtime project(':spring-security-config'),
|
runtime project(':spring-security-config'),
|
||||||
project(':spring-security-aspects')
|
project(':spring-security-aspects')
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,65 +10,65 @@ def keystore = "$rootDir/samples/certificates/server.jks"
|
||||||
def password = 'password'
|
def password = 'password'
|
||||||
|
|
||||||
configurations {
|
configurations {
|
||||||
casServer
|
casServer
|
||||||
excludeModules.each {name ->
|
excludeModules.each {name ->
|
||||||
runtime.exclude module: name
|
runtime.exclude module: name
|
||||||
}
|
}
|
||||||
|
|
||||||
runtime.exclude group: 'org.aspectj'
|
runtime.exclude group: 'org.aspectj'
|
||||||
}
|
}
|
||||||
|
|
||||||
sourceSets {
|
sourceSets {
|
||||||
test.resources.exclude 'GebConfig.groovy'
|
test.resources.exclude 'GebConfig.groovy'
|
||||||
integrationTest.groovy.srcDir file('src/integration-test/groovy')
|
integrationTest.groovy.srcDir file('src/integration-test/groovy')
|
||||||
}
|
}
|
||||||
|
|
||||||
eclipse.classpath.plusConfigurations += [configurations.integrationTestRuntime]
|
eclipse.classpath.plusConfigurations += [configurations.integrationTestRuntime]
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
providedCompile "javax.servlet:javax.servlet-api:$servletApiVersion"
|
providedCompile "javax.servlet:javax.servlet-api:$servletApiVersion"
|
||||||
|
|
||||||
compile project(':spring-security-core'),
|
compile project(':spring-security-core'),
|
||||||
project(':spring-security-cas'),
|
project(':spring-security-cas'),
|
||||||
"org.jasig.cas.client:cas-client-core:$casClientVersion"
|
"org.jasig.cas.client:cas-client-core:$casClientVersion"
|
||||||
|
|
||||||
runtime project(':spring-security-web'),
|
runtime project(':spring-security-web'),
|
||||||
project(':spring-security-config'),
|
project(':spring-security-config'),
|
||||||
"org.springframework:spring-context-support:$springVersion",
|
"org.springframework:spring-context-support:$springVersion",
|
||||||
"org.slf4j:jcl-over-slf4j:$slf4jVersion",
|
"org.slf4j:jcl-over-slf4j:$slf4jVersion",
|
||||||
"ch.qos.logback:logback-classic:$logbackVersion",
|
"ch.qos.logback:logback-classic:$logbackVersion",
|
||||||
"net.sf.ehcache:ehcache:$ehcacheVersion"
|
"net.sf.ehcache:ehcache:$ehcacheVersion"
|
||||||
|
|
||||||
integrationTestCompile project(':spring-security-cas'),
|
integrationTestCompile project(':spring-security-cas'),
|
||||||
"org.seleniumhq.selenium:selenium-htmlunit-driver:$seleniumVersion",
|
"org.seleniumhq.selenium:selenium-htmlunit-driver:$seleniumVersion",
|
||||||
"org.gebish:geb-spock:$gebVersion",
|
"org.gebish:geb-spock:$gebVersion",
|
||||||
'commons-httpclient:commons-httpclient:3.1',
|
'commons-httpclient:commons-httpclient:3.1',
|
||||||
"org.eclipse.jetty:jetty-server:$jettyVersion",
|
"org.eclipse.jetty:jetty-server:$jettyVersion",
|
||||||
"org.eclipse.jetty:jetty-servlet:$jettyVersion",
|
"org.eclipse.jetty:jetty-servlet:$jettyVersion",
|
||||||
"org.codehaus.groovy:groovy:$groovyVersion",
|
"org.codehaus.groovy:groovy:$groovyVersion",
|
||||||
"org.slf4j:jcl-over-slf4j:$slf4jVersion",
|
"org.slf4j:jcl-over-slf4j:$slf4jVersion",
|
||||||
spockDependencies
|
spockDependencies
|
||||||
}
|
}
|
||||||
|
|
||||||
[jettyRun, jettyRunWar]*.configure {
|
[jettyRun, jettyRunWar]*.configure {
|
||||||
contextPath = "/cas-sample"
|
contextPath = "/cas-sample"
|
||||||
def httpConnector = jettyRunWar.class.classLoader.loadClass('org.mortbay.jetty.nio.SelectChannelConnector').newInstance()
|
def httpConnector = jettyRunWar.class.classLoader.loadClass('org.mortbay.jetty.nio.SelectChannelConnector').newInstance()
|
||||||
httpConnector.port = 8080
|
httpConnector.port = 8080
|
||||||
httpConnector.confidentialPort = 8443
|
httpConnector.confidentialPort = 8443
|
||||||
def httpsConnector = jettyRunWar.class.classLoader.loadClass('org.mortbay.jetty.security.SslSocketConnector').newInstance()
|
def httpsConnector = jettyRunWar.class.classLoader.loadClass('org.mortbay.jetty.security.SslSocketConnector').newInstance()
|
||||||
httpsConnector.port = 8443
|
httpsConnector.port = 8443
|
||||||
httpsConnector.keystore = httpsConnector.truststore = keystore
|
httpsConnector.keystore = httpsConnector.truststore = keystore
|
||||||
httpsConnector.keyPassword = httpsConnector.trustPassword = password
|
httpsConnector.keyPassword = httpsConnector.trustPassword = password
|
||||||
|
|
||||||
connectors = [httpConnector, httpsConnector]
|
connectors = [httpConnector, httpsConnector]
|
||||||
doFirst() {
|
doFirst() {
|
||||||
System.setProperty('cas.server.host', casServer().httpsHost)
|
System.setProperty('cas.server.host', casServer().httpsHost)
|
||||||
System.setProperty('cas.service.host', jettyRunWar.httpsHost)
|
System.setProperty('cas.service.host', jettyRunWar.httpsHost)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
task cas (dependsOn: [jettyRunWar]) {
|
task cas (dependsOn: [jettyRunWar]) {
|
||||||
jettyRunWar.dependsOn(':spring-security-samples-casserver:casServer')
|
jettyRunWar.dependsOn(':spring-security-samples-casserver:casServer')
|
||||||
}
|
}
|
||||||
|
|
||||||
task casServer(dependsOn: ':spring-security-samples-casserver:casServer') {
|
task casServer(dependsOn: ':spring-security-samples-casserver:casServer') {
|
||||||
|
@ -76,54 +76,54 @@ task casServer(dependsOn: ':spring-security-samples-casserver:casServer') {
|
||||||
|
|
||||||
integrationTest.dependsOn cas
|
integrationTest.dependsOn cas
|
||||||
integrationTest.doFirst {
|
integrationTest.doFirst {
|
||||||
def casServiceHost = jettyRunWar.httpsHost
|
def casServiceHost = jettyRunWar.httpsHost
|
||||||
systemProperties['cas.server.host'] = casServer().httpsHost
|
systemProperties['cas.server.host'] = casServer().httpsHost
|
||||||
systemProperties['cas.service.host'] = casServiceHost
|
systemProperties['cas.service.host'] = casServiceHost
|
||||||
systemProperties['geb.build.baseUrl'] = 'https://'+casServiceHost+'/cas-sample/'
|
systemProperties['geb.build.baseUrl'] = 'https://'+casServiceHost+'/cas-sample/'
|
||||||
systemProperties['geb.build.reportsDir'] = 'build/geb-reports'
|
systemProperties['geb.build.reportsDir'] = 'build/geb-reports'
|
||||||
systemProperties['jar.path'] = jar.archivePath
|
systemProperties['jar.path'] = jar.archivePath
|
||||||
systemProperties['javax.net.ssl.trustStore'] = keystore
|
systemProperties['javax.net.ssl.trustStore'] = keystore
|
||||||
systemProperties['javax.net.ssl.trustStorePassword'] = password
|
systemProperties['javax.net.ssl.trustStorePassword'] = password
|
||||||
}
|
}
|
||||||
|
|
||||||
gradle.taskGraph.whenReady {graph ->
|
gradle.taskGraph.whenReady {graph ->
|
||||||
def casServer = casServer()
|
def casServer = casServer()
|
||||||
[casServer,jettyRunWar]*.metaClass*.getHttpsConnector {->
|
[casServer,jettyRunWar]*.metaClass*.getHttpsConnector {->
|
||||||
def sslSocketConnClass = jettyRunWar.class.classLoader.loadClass('org.mortbay.jetty.security.SslSocketConnector')
|
def sslSocketConnClass = jettyRunWar.class.classLoader.loadClass('org.mortbay.jetty.security.SslSocketConnector')
|
||||||
delegate.connectors.find { it in sslSocketConnClass }
|
delegate.connectors.find { it in sslSocketConnClass }
|
||||||
}
|
}
|
||||||
[casServer,jettyRunWar]*.metaClass*.getHttpsHost {->
|
[casServer,jettyRunWar]*.metaClass*.getHttpsHost {->
|
||||||
"localhost:"+delegate.httpsConnector.port
|
"localhost:"+delegate.httpsConnector.port
|
||||||
}
|
}
|
||||||
jettyRunWar.metaClass.getHttpConnector {->
|
jettyRunWar.metaClass.getHttpConnector {->
|
||||||
def channelConnClass = jettyRunWar.class.classLoader.loadClass('org.mortbay.jetty.nio.SelectChannelConnector')
|
def channelConnClass = jettyRunWar.class.classLoader.loadClass('org.mortbay.jetty.nio.SelectChannelConnector')
|
||||||
delegate.connectors.find { it in channelConnClass }
|
delegate.connectors.find { it in channelConnClass }
|
||||||
}
|
}
|
||||||
if (graph.hasTask(cas)) {
|
if (graph.hasTask(cas)) {
|
||||||
casServer.daemon = true
|
casServer.daemon = true
|
||||||
}
|
}
|
||||||
if(graph.hasTask(integrationTest)) {
|
if(graph.hasTask(integrationTest)) {
|
||||||
tasks.getByPath(':spring-security-samples-casserver:casServerOverlay').logLevel = 'ERROR'
|
tasks.getByPath(':spring-security-samples-casserver:casServerOverlay').logLevel = 'ERROR'
|
||||||
jettyRunWar {
|
jettyRunWar {
|
||||||
additionalRuntimeJars += file("src/integration-test/resources")
|
additionalRuntimeJars += file("src/integration-test/resources")
|
||||||
daemon = true
|
daemon = true
|
||||||
}
|
}
|
||||||
|
|
||||||
[jettyRunWar.httpConnector,jettyRunWar.httpsConnector,casServer.httpsConnector]*.metaClass*.reservePort { taskToCloseSocket ->
|
[jettyRunWar.httpConnector,jettyRunWar.httpsConnector,casServer.httpsConnector]*.metaClass*.reservePort { taskToCloseSocket ->
|
||||||
def serverSocket = new ServerSocket(0)
|
def serverSocket = new ServerSocket(0)
|
||||||
delegate.metaClass.serverSocket = serverSocket
|
delegate.metaClass.serverSocket = serverSocket
|
||||||
delegate.port = serverSocket.localPort
|
delegate.port = serverSocket.localPort
|
||||||
taskToCloseSocket.doFirst {
|
taskToCloseSocket.doFirst {
|
||||||
serverSocket.close()
|
serverSocket.close()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[jettyRunWar.httpConnector,jettyRunWar.httpsConnector]*.reservePort(jettyRunWar)
|
[jettyRunWar.httpConnector,jettyRunWar.httpsConnector]*.reservePort(jettyRunWar)
|
||||||
jettyRunWar.httpConnector.confidentialPort = jettyRunWar.httpsConnector.port
|
jettyRunWar.httpConnector.confidentialPort = jettyRunWar.httpsConnector.port
|
||||||
casServer.httpsConnector.reservePort(casServer)
|
casServer.httpsConnector.reservePort(casServer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
def casServer() {
|
def casServer() {
|
||||||
tasks.getByPath(':spring-security-samples-casserver:casServer')
|
tasks.getByPath(':spring-security-samples-casserver:casServer')
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,58 +6,58 @@ def keystore = "$rootDir/samples/certificates/server.jks"
|
||||||
def password = 'password'
|
def password = 'password'
|
||||||
|
|
||||||
configurations {
|
configurations {
|
||||||
casServer
|
casServer
|
||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
casServer "org.jasig.cas:cas-server-webapp:4.0.0@war"
|
casServer "org.jasig.cas:cas-server-webapp:4.0.0@war"
|
||||||
}
|
}
|
||||||
|
|
||||||
task casServerOverlay(type: Sync) {
|
task casServerOverlay(type: Sync) {
|
||||||
def war = configurations.casServer.resolve().toArray()[0]
|
def war = configurations.casServer.resolve().toArray()[0]
|
||||||
def warName = war.name.replace('.war','-custom')
|
def warName = war.name.replace('.war','-custom')
|
||||||
def overlayDir = file('src/main/webapp')
|
def overlayDir = file('src/main/webapp')
|
||||||
def explodedWar = file("$buildDir/tmp/${warName}")
|
def explodedWar = file("$buildDir/tmp/${warName}")
|
||||||
ext.customWar = file("$buildDir/tmp/${warName}.war")
|
ext.customWar = file("$buildDir/tmp/${warName}.war")
|
||||||
ext.tokens = [logLevel: 'INFO']
|
ext.tokens = [logLevel: 'INFO']
|
||||||
|
|
||||||
inputs.files(war, overlayDir)
|
inputs.files(war, overlayDir)
|
||||||
inputs.property('tokens',{tokens})
|
inputs.property('tokens',{tokens})
|
||||||
outputs.files (customWar,explodedWar,file("$buildDir/tmp/expandedArchives"))
|
outputs.files (customWar,explodedWar,file("$buildDir/tmp/expandedArchives"))
|
||||||
|
|
||||||
from zipTree(war)
|
from zipTree(war)
|
||||||
from (overlayDir) {
|
from (overlayDir) {
|
||||||
filter(ReplaceTokens,tokens: tokens)
|
filter(ReplaceTokens,tokens: tokens)
|
||||||
}
|
}
|
||||||
into explodedWar
|
into explodedWar
|
||||||
|
|
||||||
doLast {
|
doLast {
|
||||||
if(customWar.exists()) {
|
if(customWar.exists()) {
|
||||||
customWar.delete()
|
customWar.delete()
|
||||||
}
|
}
|
||||||
ant.zip(destfile: customWar, baseDir: explodedWar)
|
ant.zip(destfile: customWar, baseDir: explodedWar)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
casServerOverlay.metaClass.setLogLevel { level ->
|
casServerOverlay.metaClass.setLogLevel { level ->
|
||||||
tokens['logLevel'] = level
|
tokens['logLevel'] = level
|
||||||
}
|
}
|
||||||
|
|
||||||
task casServer (type: org.gradle.api.plugins.jetty.JettyRunWar, dependsOn: 'casServerOverlay') {
|
task casServer (type: org.gradle.api.plugins.jetty.JettyRunWar, dependsOn: 'casServerOverlay') {
|
||||||
contextPath = "/cas"
|
contextPath = "/cas"
|
||||||
connectors = [casServer.class.classLoader.loadClass('org.mortbay.jetty.security.SslSocketConnector').newInstance()]
|
connectors = [casServer.class.classLoader.loadClass('org.mortbay.jetty.security.SslSocketConnector').newInstance()]
|
||||||
connectors[0].port = 9443
|
connectors[0].port = 9443
|
||||||
connectors[0].keystore = connectors[0].truststore = keystore
|
connectors[0].keystore = connectors[0].truststore = keystore
|
||||||
connectors[0].keyPassword = connectors[0].trustPassword = password
|
connectors[0].keyPassword = connectors[0].trustPassword = password
|
||||||
connectors[0].wantClientAuth = true
|
connectors[0].wantClientAuth = true
|
||||||
connectors[0].needClientAuth = false
|
connectors[0].needClientAuth = false
|
||||||
webApp = casServerOverlay.customWar
|
webApp = casServerOverlay.customWar
|
||||||
|
|
||||||
inputs.file casServerOverlay.customWar
|
inputs.file casServerOverlay.customWar
|
||||||
|
|
||||||
doFirst() {
|
doFirst() {
|
||||||
System.setProperty('javax.net.ssl.trustStore', keystore)
|
System.setProperty('javax.net.ssl.trustStore', keystore)
|
||||||
System.setProperty('javax.net.ssl.trustStorePassword', password)
|
System.setProperty('javax.net.ssl.trustStorePassword', password)
|
||||||
System.setProperty('java.naming.factory.url.pkgs','org.mortbay.naming')
|
System.setProperty('java.naming.factory.url.pkgs','org.mortbay.naming')
|
||||||
System.setProperty('java.naming.factory.initial','org.mortbay.naming.InitialContextFactory')
|
System.setProperty('java.naming.factory.initial','org.mortbay.naming.InitialContextFactory')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,40 +1,40 @@
|
||||||
apply from: WAR_SAMPLE_GRADLE
|
apply from: WAR_SAMPLE_GRADLE
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
maven { url 'http://clojars.org/repo' }
|
maven { url 'http://clojars.org/repo' }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
providedCompile "javax.servlet:javax.servlet-api:$servletApiVersion"
|
providedCompile "javax.servlet:javax.servlet-api:$servletApiVersion"
|
||||||
|
|
||||||
compile project(":spring-security-web"),
|
compile project(":spring-security-web"),
|
||||||
project(":spring-security-config"),
|
project(":spring-security-config"),
|
||||||
project(":spring-security-messaging"),
|
project(":spring-security-messaging"),
|
||||||
project(":spring-security-data"),
|
project(":spring-security-data"),
|
||||||
"org.springframework:spring-webmvc:${springVersion}",
|
"org.springframework:spring-webmvc:${springVersion}",
|
||||||
"org.springframework:spring-websocket:${springVersion}",
|
"org.springframework:spring-websocket:${springVersion}",
|
||||||
"org.springframework:spring-messaging:${springVersion}",
|
"org.springframework:spring-messaging:${springVersion}",
|
||||||
"org.springframework.session:spring-session:${springSessionVersion}",
|
"org.springframework.session:spring-session:${springSessionVersion}",
|
||||||
"org.springframework.data:spring-data-redis:${springDataRedisVersion}",
|
"org.springframework.data:spring-data-redis:${springDataRedisVersion}",
|
||||||
"org.hibernate.javax.persistence:hibernate-jpa-2.0-api:1.0.0.Final",
|
"org.hibernate.javax.persistence:hibernate-jpa-2.0-api:1.0.0.Final",
|
||||||
"org.hsqldb:hsqldb:$hsqlVersion",
|
"org.hsqldb:hsqldb:$hsqlVersion",
|
||||||
"javax.validation:validation-api:1.0.0.GA",
|
"javax.validation:validation-api:1.0.0.GA",
|
||||||
"org.hibernate:hibernate-validator:4.2.0.Final",
|
"org.hibernate:hibernate-validator:4.2.0.Final",
|
||||||
"redis.clients:jedis:2.4.2",
|
"redis.clients:jedis:2.4.2",
|
||||||
"redis.embedded:embedded-redis:0.2",
|
"redis.embedded:embedded-redis:0.2",
|
||||||
"org.apache.commons:commons-pool2:2.2",
|
"org.apache.commons:commons-pool2:2.2",
|
||||||
"org.thymeleaf:thymeleaf-spring4:$thymeleafVersion",
|
"org.thymeleaf:thymeleaf-spring4:$thymeleafVersion",
|
||||||
"org.thymeleaf.extras:thymeleaf-extras-tiles2-spring4:2.1.1.RELEASE",
|
"org.thymeleaf.extras:thymeleaf-extras-tiles2-spring4:2.1.1.RELEASE",
|
||||||
"org.slf4j:slf4j-api:$slf4jVersion",
|
"org.slf4j:slf4j-api:$slf4jVersion",
|
||||||
"javax.servlet.jsp.jstl:javax.servlet.jsp.jstl-api:$jstlVersion",
|
"javax.servlet.jsp.jstl:javax.servlet.jsp.jstl-api:$jstlVersion",
|
||||||
"com.fasterxml.jackson.core:jackson-databind:$jacksonDatavindVersion"
|
"com.fasterxml.jackson.core:jackson-databind:$jacksonDatavindVersion"
|
||||||
compile('org.hibernate:hibernate-entitymanager:3.6.10.Final') {
|
compile('org.hibernate:hibernate-entitymanager:3.6.10.Final') {
|
||||||
exclude group:'javassist', module: 'javassist'
|
exclude group:'javassist', module: 'javassist'
|
||||||
}
|
}
|
||||||
compile("org.springframework.data:spring-data-jpa:$springDataJpaVersion") {
|
compile("org.springframework.data:spring-data-jpa:$springDataJpaVersion") {
|
||||||
exclude group:'org.aspectj', module:'aspectjrt'
|
exclude group:'org.aspectj', module:'aspectjrt'
|
||||||
}
|
}
|
||||||
|
|
||||||
runtime "ch.qos.logback:logback-classic:$logbackVersion"
|
runtime "ch.qos.logback:logback-classic:$logbackVersion"
|
||||||
}
|
}
|
|
@ -2,24 +2,24 @@ apply from: WAR_SAMPLE_GRADLE
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
|
||||||
providedCompile "javax.servlet:javax.servlet-api:3.0.1",
|
providedCompile "javax.servlet:javax.servlet-api:3.0.1",
|
||||||
'javax.servlet.jsp:jsp-api:2.1'
|
'javax.servlet.jsp:jsp-api:2.1'
|
||||||
|
|
||||||
compile project(":spring-security-config"),
|
compile project(":spring-security-config"),
|
||||||
project(":spring-security-samples-messages-jc"),
|
project(":spring-security-samples-messages-jc"),
|
||||||
project(":spring-security-core"),
|
project(":spring-security-core"),
|
||||||
project(":spring-security-web"),
|
project(":spring-security-web"),
|
||||||
"org.springframework:spring-webmvc:$springVersion",
|
"org.springframework:spring-webmvc:$springVersion",
|
||||||
"org.springframework:spring-jdbc:$springVersion",
|
"org.springframework:spring-jdbc:$springVersion",
|
||||||
"org.slf4j:slf4j-api:$slf4jVersion",
|
"org.slf4j:slf4j-api:$slf4jVersion",
|
||||||
"org.slf4j:log4j-over-slf4j:$slf4jVersion",
|
"org.slf4j:log4j-over-slf4j:$slf4jVersion",
|
||||||
"org.slf4j:jul-to-slf4j:$slf4jVersion",
|
"org.slf4j:jul-to-slf4j:$slf4jVersion",
|
||||||
"org.slf4j:jcl-over-slf4j:$slf4jVersion",
|
"org.slf4j:jcl-over-slf4j:$slf4jVersion",
|
||||||
"javax.servlet.jsp.jstl:javax.servlet.jsp.jstl-api:$jstlVersion",
|
"javax.servlet.jsp.jstl:javax.servlet.jsp.jstl-api:$jstlVersion",
|
||||||
"javax.validation:validation-api:1.0.0.GA",
|
"javax.validation:validation-api:1.0.0.GA",
|
||||||
"org.hibernate:hibernate-validator:4.2.0.Final"
|
"org.hibernate:hibernate-validator:4.2.0.Final"
|
||||||
|
|
||||||
runtime "opensymphony:sitemesh:2.4.2",
|
runtime "opensymphony:sitemesh:2.4.2",
|
||||||
"cglib:cglib-nodep:$cglibVersion",
|
"cglib:cglib-nodep:$cglibVersion",
|
||||||
'ch.qos.logback:logback-classic:0.9.30'
|
'ch.qos.logback:logback-classic:0.9.30'
|
||||||
}
|
}
|
|
@ -3,27 +3,27 @@
|
||||||
apply from: WAR_SAMPLE_GRADLE
|
apply from: WAR_SAMPLE_GRADLE
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
providedCompile "javax.servlet:javax.servlet-api:$servletApiVersion"
|
providedCompile "javax.servlet:javax.servlet-api:$servletApiVersion"
|
||||||
|
|
||||||
compile project(':spring-security-core'),
|
compile project(':spring-security-core'),
|
||||||
project(':spring-security-acl'),
|
project(':spring-security-acl'),
|
||||||
"org.springframework:spring-aop:$springVersion",
|
"org.springframework:spring-aop:$springVersion",
|
||||||
"org.springframework:spring-beans:$springVersion",
|
"org.springframework:spring-beans:$springVersion",
|
||||||
"org.springframework:spring-context:$springVersion",
|
"org.springframework:spring-context:$springVersion",
|
||||||
"org.springframework:spring-jdbc:$springVersion",
|
"org.springframework:spring-jdbc:$springVersion",
|
||||||
"org.springframework:spring-tx:$springVersion",
|
"org.springframework:spring-tx:$springVersion",
|
||||||
"org.springframework:spring-web:$springVersion",
|
"org.springframework:spring-web:$springVersion",
|
||||||
"org.springframework:spring-webmvc:$springVersion"
|
"org.springframework:spring-webmvc:$springVersion"
|
||||||
|
|
||||||
runtime project(':spring-security-web'),
|
runtime project(':spring-security-web'),
|
||||||
project(':spring-security-config'),
|
project(':spring-security-config'),
|
||||||
project(':spring-security-taglibs'),
|
project(':spring-security-taglibs'),
|
||||||
"org.springframework:spring-context-support:$springVersion",
|
"org.springframework:spring-context-support:$springVersion",
|
||||||
jstlDependencies,
|
jstlDependencies,
|
||||||
"org.hsqldb:hsqldb:$hsqlVersion",
|
"org.hsqldb:hsqldb:$hsqlVersion",
|
||||||
"org.slf4j:jcl-over-slf4j:$slf4jVersion",
|
"org.slf4j:jcl-over-slf4j:$slf4jVersion",
|
||||||
"ch.qos.logback:logback-classic:$logbackVersion",
|
"ch.qos.logback:logback-classic:$logbackVersion",
|
||||||
"net.sf.ehcache:ehcache:$ehcacheVersion"
|
"net.sf.ehcache:ehcache:$ehcacheVersion"
|
||||||
|
|
||||||
integrationTestCompile gebDependencies
|
integrationTestCompile gebDependencies
|
||||||
}
|
}
|
|
@ -5,7 +5,7 @@
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
@ -26,62 +26,62 @@ import org.springframework.security.samples.pages.*
|
||||||
*/
|
*/
|
||||||
@Stepwise
|
@Stepwise
|
||||||
class ContactsTests extends GebReportingSpec {
|
class ContactsTests extends GebReportingSpec {
|
||||||
def 'access home page with unauthenticated user success'() {
|
def 'access home page with unauthenticated user success'() {
|
||||||
when: 'Unauthenticated user accesses the Home Page'
|
when: 'Unauthenticated user accesses the Home Page'
|
||||||
to HomePage
|
to HomePage
|
||||||
then: 'The page is displayed'
|
then: 'The page is displayed'
|
||||||
at HomePage
|
at HomePage
|
||||||
}
|
}
|
||||||
|
|
||||||
def 'access manage page with unauthenticated user sends to login page'() {
|
def 'access manage page with unauthenticated user sends to login page'() {
|
||||||
when: 'Unauthenticated user accesses the Manage Page'
|
when: 'Unauthenticated user accesses the Manage Page'
|
||||||
manage.click(LoginPage)
|
manage.click(LoginPage)
|
||||||
then: 'The login page is displayed'
|
then: 'The login page is displayed'
|
||||||
at LoginPage
|
at LoginPage
|
||||||
}
|
}
|
||||||
|
|
||||||
def 'authenticated user is sent to original page'() {
|
def 'authenticated user is sent to original page'() {
|
||||||
when: 'user authenticates'
|
when: 'user authenticates'
|
||||||
login()
|
login()
|
||||||
then: 'The manage page is displayed'
|
then: 'The manage page is displayed'
|
||||||
at ContactsPage
|
at ContactsPage
|
||||||
}
|
}
|
||||||
|
|
||||||
def 'add contact link works'() {
|
def 'add contact link works'() {
|
||||||
when: 'user clicks add link'
|
when: 'user clicks add link'
|
||||||
addContact.click(AddPage)
|
addContact.click(AddPage)
|
||||||
then: 'The add page is displayed'
|
then: 'The add page is displayed'
|
||||||
at AddPage
|
at AddPage
|
||||||
}
|
}
|
||||||
|
|
||||||
def 'add contact'() {
|
def 'add contact'() {
|
||||||
when: 'add a contact'
|
when: 'add a contact'
|
||||||
addContact
|
addContact
|
||||||
then: 'The add page is displayed'
|
then: 'The add page is displayed'
|
||||||
at ContactsPage
|
at ContactsPage
|
||||||
and: 'The new contact is displayed'
|
and: 'The new contact is displayed'
|
||||||
contacts.find { it.email == 'rob@example.com' }?.name == 'Rob Winch'
|
contacts.find { it.email == 'rob@example.com' }?.name == 'Rob Winch'
|
||||||
}
|
}
|
||||||
|
|
||||||
def 'delete contact'() {
|
def 'delete contact'() {
|
||||||
when: 'delete a contact'
|
when: 'delete a contact'
|
||||||
contacts.find { it.email == 'rob@example.com' }.delete()
|
contacts.find { it.email == 'rob@example.com' }.delete()
|
||||||
then: 'Delete confirmation displayed'
|
then: 'Delete confirmation displayed'
|
||||||
at DeleteConfirmPage
|
at DeleteConfirmPage
|
||||||
when: 'View Manage Page'
|
when: 'View Manage Page'
|
||||||
manage.click()
|
manage.click()
|
||||||
then: 'New contact has been removed'
|
then: 'New contact has been removed'
|
||||||
!contacts.find { it.email == 'rob@example.com' }
|
!contacts.find { it.email == 'rob@example.com' }
|
||||||
}
|
}
|
||||||
|
|
||||||
def 'authenticated user logs out'() {
|
def 'authenticated user logs out'() {
|
||||||
when: 'user logs out'
|
when: 'user logs out'
|
||||||
logout.click()
|
logout.click()
|
||||||
then: 'the default logout success page is displayed'
|
then: 'the default logout success page is displayed'
|
||||||
at HomePage
|
at HomePage
|
||||||
when: 'Unauthenticated user accesses the Manage Page'
|
when: 'Unauthenticated user accesses the Manage Page'
|
||||||
via ContactsPage
|
via ContactsPage
|
||||||
then: 'The login page is displayed'
|
then: 'The login page is displayed'
|
||||||
at LoginPage
|
at LoginPage
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -5,7 +5,7 @@
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
@ -23,15 +23,15 @@ import geb.Page
|
||||||
* @author Rob Winch
|
* @author Rob Winch
|
||||||
*/
|
*/
|
||||||
class AddPage extends Page {
|
class AddPage extends Page {
|
||||||
static url = 'add'
|
static url = 'add'
|
||||||
static at = { assert driver.title == 'Add New Contact'; true}
|
static at = { assert driver.title == 'Add New Contact'; true}
|
||||||
static content = {
|
static content = {
|
||||||
addContact(required:false) { name = 'Rob Winch', email = 'rob@example.com'->
|
addContact(required:false) { name = 'Rob Winch', email = 'rob@example.com'->
|
||||||
addForm.name = name
|
addForm.name = name
|
||||||
addForm.email = email
|
addForm.email = email
|
||||||
submit.click()
|
submit.click()
|
||||||
}
|
}
|
||||||
addForm { $('form') }
|
addForm { $('form') }
|
||||||
submit { $('input', type: 'submit') }
|
submit { $('input', type: 'submit') }
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -5,7 +5,7 @@
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
@ -23,11 +23,11 @@ import geb.*
|
||||||
* @author Rob Winch
|
* @author Rob Winch
|
||||||
*/
|
*/
|
||||||
class HomePage extends Page {
|
class HomePage extends Page {
|
||||||
static url = ''
|
static url = ''
|
||||||
static at = { assert driver.title == 'Contacts Security Demo'; true}
|
static at = { assert driver.title == 'Contacts Security Demo'; true}
|
||||||
static content = {
|
static content = {
|
||||||
manage(to: [ContactsPage,LoginPage]) { $('a', text: 'Manage') }
|
manage(to: [ContactsPage,LoginPage]) { $('a', text: 'Manage') }
|
||||||
debug { $('a', text: 'Debug').click() }
|
debug { $('a', text: 'Debug').click() }
|
||||||
frames { $('a', text: 'Frames').click() }
|
frames { $('a', text: 'Frames').click() }
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -5,7 +5,7 @@
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
@ -23,15 +23,15 @@ import geb.*
|
||||||
* @author Rob Winch
|
* @author Rob Winch
|
||||||
*/
|
*/
|
||||||
class LoginPage extends Page {
|
class LoginPage extends Page {
|
||||||
static url = 'login'
|
static url = 'login'
|
||||||
static at = { assert driver.title == 'Login'; true}
|
static at = { assert driver.title == 'Login'; true}
|
||||||
static content = {
|
static content = {
|
||||||
login(required:false) { user='rod', password='koala' ->
|
login(required:false) { user='rod', password='koala' ->
|
||||||
loginForm.username = user
|
loginForm.username = user
|
||||||
loginForm.password = password
|
loginForm.password = password
|
||||||
submit.click()
|
submit.click()
|
||||||
}
|
}
|
||||||
loginForm { $('form') }
|
loginForm { $('form') }
|
||||||
submit { $('input', type: 'submit') }
|
submit { $('input', type: 'submit') }
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,10 +1,10 @@
|
||||||
dependencies {
|
dependencies {
|
||||||
compile project(':spring-security-data'),
|
compile project(':spring-security-data'),
|
||||||
project(':spring-security-config'),
|
project(':spring-security-config'),
|
||||||
"org.springframework.data:spring-data-jpa:$springDataJpaVersion",
|
"org.springframework.data:spring-data-jpa:$springDataJpaVersion",
|
||||||
"org.hibernate.javax.persistence:hibernate-jpa-2.0-api:1.0.0.Final",
|
"org.hibernate.javax.persistence:hibernate-jpa-2.0-api:1.0.0.Final",
|
||||||
'org.hibernate:hibernate-entitymanager:3.6.10.Final',
|
'org.hibernate:hibernate-entitymanager:3.6.10.Final',
|
||||||
"org.hsqldb:hsqldb:$hsqlVersion",
|
"org.hsqldb:hsqldb:$hsqlVersion",
|
||||||
"javax.validation:validation-api:1.0.0.GA",
|
"javax.validation:validation-api:1.0.0.GA",
|
||||||
"org.hibernate:hibernate-validator:4.2.0.Final"
|
"org.hibernate:hibernate-validator:4.2.0.Final"
|
||||||
}
|
}
|
|
@ -1,16 +1,16 @@
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
compile project(':spring-security-core'),
|
compile project(':spring-security-core'),
|
||||||
project(':spring-security-acl'),
|
project(':spring-security-acl'),
|
||||||
"org.springframework:spring-beans:$springVersion",
|
"org.springframework:spring-beans:$springVersion",
|
||||||
"org.springframework:spring-tx:$springVersion",
|
"org.springframework:spring-tx:$springVersion",
|
||||||
"org.springframework:spring-jdbc:$springVersion"
|
"org.springframework:spring-jdbc:$springVersion"
|
||||||
|
|
||||||
testCompile "org.springframework:spring-context:$springVersion"
|
testCompile "org.springframework:spring-context:$springVersion"
|
||||||
|
|
||||||
runtime project(':spring-security-config'),
|
runtime project(':spring-security-config'),
|
||||||
"org.hsqldb:hsqldb:$hsqlVersion",
|
"org.hsqldb:hsqldb:$hsqlVersion",
|
||||||
"org.springframework:spring-context-support:$springVersion"
|
"org.springframework:spring-context-support:$springVersion"
|
||||||
|
|
||||||
optional "net.sf.ehcache:ehcache:$ehcacheVersion"
|
optional "net.sf.ehcache:ehcache:$ehcacheVersion"
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,26 +2,26 @@ apply from: WAR_SAMPLE_GRADLE
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
|
||||||
providedCompile "javax.servlet:javax.servlet-api:3.0.1",
|
providedCompile "javax.servlet:javax.servlet-api:3.0.1",
|
||||||
'javax.servlet.jsp:jsp-api:2.1'
|
'javax.servlet.jsp:jsp-api:2.1'
|
||||||
|
|
||||||
compile project(":spring-security-config"),
|
compile project(":spring-security-config"),
|
||||||
project(":spring-security-samples-messages-jc"),
|
project(":spring-security-samples-messages-jc"),
|
||||||
project(":spring-security-core"),
|
project(":spring-security-core"),
|
||||||
project(":spring-security-web"),
|
project(":spring-security-web"),
|
||||||
"org.springframework:spring-webmvc:$springVersion",
|
"org.springframework:spring-webmvc:$springVersion",
|
||||||
"org.springframework:spring-jdbc:$springVersion",
|
"org.springframework:spring-jdbc:$springVersion",
|
||||||
"org.slf4j:slf4j-api:$slf4jVersion",
|
"org.slf4j:slf4j-api:$slf4jVersion",
|
||||||
"org.slf4j:log4j-over-slf4j:$slf4jVersion",
|
"org.slf4j:log4j-over-slf4j:$slf4jVersion",
|
||||||
"org.slf4j:jul-to-slf4j:$slf4jVersion",
|
"org.slf4j:jul-to-slf4j:$slf4jVersion",
|
||||||
"org.slf4j:jcl-over-slf4j:$slf4jVersion",
|
"org.slf4j:jcl-over-slf4j:$slf4jVersion",
|
||||||
"javax.servlet.jsp.jstl:javax.servlet.jsp.jstl-api:$jstlVersion",
|
"javax.servlet.jsp.jstl:javax.servlet.jsp.jstl-api:$jstlVersion",
|
||||||
"javax.validation:validation-api:1.0.0.GA",
|
"javax.validation:validation-api:1.0.0.GA",
|
||||||
"org.hibernate:hibernate-validator:4.2.0.Final"
|
"org.hibernate:hibernate-validator:4.2.0.Final"
|
||||||
|
|
||||||
runtime "opensymphony:sitemesh:2.4.2",
|
runtime "opensymphony:sitemesh:2.4.2",
|
||||||
"cglib:cglib-nodep:$cglibVersion",
|
"cglib:cglib-nodep:$cglibVersion",
|
||||||
'ch.qos.logback:logback-classic:0.9.30'
|
'ch.qos.logback:logback-classic:0.9.30'
|
||||||
|
|
||||||
integrationTestCompile gebDependencies
|
integrationTestCompile gebDependencies
|
||||||
}
|
}
|
|
@ -5,7 +5,7 @@
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
@ -27,30 +27,30 @@ import org.springframework.security.samples.pages.*
|
||||||
*/
|
*/
|
||||||
@Stepwise
|
@Stepwise
|
||||||
class FormJcTests extends GebReportingSpec {
|
class FormJcTests extends GebReportingSpec {
|
||||||
def 'access home page with unauthenticated user sends to login page'() {
|
def 'access home page with unauthenticated user sends to login page'() {
|
||||||
when: 'Unauthenticated user accesses the Home Page'
|
when: 'Unauthenticated user accesses the Home Page'
|
||||||
via HomePage
|
via HomePage
|
||||||
then: 'The login page is displayed'
|
then: 'The login page is displayed'
|
||||||
at LoginPage
|
at LoginPage
|
||||||
}
|
}
|
||||||
|
|
||||||
def 'authenticated user is sent to original page'() {
|
def 'authenticated user is sent to original page'() {
|
||||||
when: 'user authenticates'
|
when: 'user authenticates'
|
||||||
login()
|
login()
|
||||||
then: 'The home page is displayed'
|
then: 'The home page is displayed'
|
||||||
at HomePage
|
at HomePage
|
||||||
and: 'The username is displayed'
|
and: 'The username is displayed'
|
||||||
user == 'user'
|
user == 'user'
|
||||||
}
|
}
|
||||||
|
|
||||||
def 'authenticated user logs out'() {
|
def 'authenticated user logs out'() {
|
||||||
when: 'user logs out'
|
when: 'user logs out'
|
||||||
logout()
|
logout()
|
||||||
then: 'the login page is displayed'
|
then: 'the login page is displayed'
|
||||||
at LoginPage
|
at LoginPage
|
||||||
when: 'Unauthenticated user accesses the Home Page'
|
when: 'Unauthenticated user accesses the Home Page'
|
||||||
via HomePage
|
via HomePage
|
||||||
then: 'The login page is displayed'
|
then: 'The login page is displayed'
|
||||||
at LoginPage
|
at LoginPage
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -5,7 +5,7 @@
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
@ -23,10 +23,10 @@ import geb.*
|
||||||
* @author Rob Winch
|
* @author Rob Winch
|
||||||
*/
|
*/
|
||||||
class HomePage extends Page {
|
class HomePage extends Page {
|
||||||
static url = ''
|
static url = ''
|
||||||
static at = { assert driver.title == 'Messages : View All'; true}
|
static at = { assert driver.title == 'Messages : View All'; true}
|
||||||
static content = {
|
static content = {
|
||||||
user { $('p.navbar-text').text() }
|
user { $('p.navbar-text').text() }
|
||||||
logout { $('input', type: 'submit').click() }
|
logout { $('input', type: 'submit').click() }
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -5,7 +5,7 @@
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
@ -23,15 +23,15 @@ import geb.*
|
||||||
* @author Rob Winch
|
* @author Rob Winch
|
||||||
*/
|
*/
|
||||||
class LoginPage extends Page {
|
class LoginPage extends Page {
|
||||||
static url = 'login'
|
static url = 'login'
|
||||||
static at = { assert driver.title == 'Please Login'; true}
|
static at = { assert driver.title == 'Please Login'; true}
|
||||||
static content = {
|
static content = {
|
||||||
login(required:false) { user='user', password='password' ->
|
login(required:false) { user='user', password='password' ->
|
||||||
loginForm.username = user
|
loginForm.username = user
|
||||||
loginForm.password = password
|
loginForm.password = password
|
||||||
submit.click()
|
submit.click()
|
||||||
}
|
}
|
||||||
loginForm { $('form') }
|
loginForm { $('form') }
|
||||||
submit { $('button', type: 'submit') }
|
submit { $('button', type: 'submit') }
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -5,43 +5,43 @@ apply plugin: 'gae'
|
||||||
def gaeVersion="1.4.2"
|
def gaeVersion="1.4.2"
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
maven {
|
maven {
|
||||||
// Hibernate Validator
|
// Hibernate Validator
|
||||||
name = 'JBoss'
|
name = 'JBoss'
|
||||||
url = 'https://repository.jboss.org/nexus/content/repositories/releases'
|
url = 'https://repository.jboss.org/nexus/content/repositories/releases'
|
||||||
}
|
}
|
||||||
maven {
|
maven {
|
||||||
// GAE Jars
|
// GAE Jars
|
||||||
name = 'GAE'
|
name = 'GAE'
|
||||||
url = 'http://maven-gae-plugin.googlecode.com/svn/repository'
|
url = 'http://maven-gae-plugin.googlecode.com/svn/repository'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove logback as it causes security issues with GAE.
|
// Remove logback as it causes security issues with GAE.
|
||||||
configurations.runtime.exclude(group: 'ch.qos.logback')
|
configurations.runtime.exclude(group: 'ch.qos.logback')
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
providedCompile "javax.servlet:javax.servlet-api:$servletApiVersion"
|
providedCompile "javax.servlet:javax.servlet-api:$servletApiVersion"
|
||||||
|
|
||||||
compile project(':spring-security-core'),
|
compile project(':spring-security-core'),
|
||||||
project(':spring-security-web'),
|
project(':spring-security-web'),
|
||||||
"org.springframework:spring-beans:$springVersion",
|
"org.springframework:spring-beans:$springVersion",
|
||||||
"org.springframework:spring-web:$springVersion",
|
"org.springframework:spring-web:$springVersion",
|
||||||
"org.springframework:spring-webmvc:$springVersion",
|
"org.springframework:spring-webmvc:$springVersion",
|
||||||
"org.springframework:spring-context:$springVersion",
|
"org.springframework:spring-context:$springVersion",
|
||||||
"org.springframework:spring-context-support:$springVersion",
|
"org.springframework:spring-context-support:$springVersion",
|
||||||
"com.google.appengine:appengine-api-1.0-sdk:$gaeVersion",
|
"com.google.appengine:appengine-api-1.0-sdk:$gaeVersion",
|
||||||
'javax.validation:validation-api:1.0.0.GA',
|
'javax.validation:validation-api:1.0.0.GA',
|
||||||
'org.hibernate:hibernate-validator:4.2.0.Final',
|
'org.hibernate:hibernate-validator:4.2.0.Final',
|
||||||
"org.slf4j:slf4j-api:$slf4jVersion"
|
"org.slf4j:slf4j-api:$slf4jVersion"
|
||||||
|
|
||||||
runtime project(':spring-security-config'),
|
runtime project(':spring-security-config'),
|
||||||
project(':spring-security-taglibs'),
|
project(':spring-security-taglibs'),
|
||||||
"org.slf4j:jcl-over-slf4j:$slf4jVersion",
|
"org.slf4j:jcl-over-slf4j:$slf4jVersion",
|
||||||
"org.slf4j:slf4j-jdk14:$slf4jVersion"
|
"org.slf4j:slf4j-jdk14:$slf4jVersion"
|
||||||
testCompile "com.google.appengine:appengine-testing:$gaeVersion"
|
testCompile "com.google.appengine:appengine-testing:$gaeVersion"
|
||||||
|
|
||||||
testRuntime "com.google.appengine:appengine-api-labs:$gaeVersion",
|
testRuntime "com.google.appengine:appengine-api-labs:$gaeVersion",
|
||||||
"com.google.appengine:appengine-api-stubs:$gaeVersion"
|
"com.google.appengine:appengine-api-stubs:$gaeVersion"
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,25 +2,25 @@ apply from: WAR_SAMPLE_GRADLE
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
|
||||||
providedCompile "javax.servlet:javax.servlet-api:3.0.1",
|
providedCompile "javax.servlet:javax.servlet-api:3.0.1",
|
||||||
'javax.servlet.jsp:jsp-api:2.1'
|
'javax.servlet.jsp:jsp-api:2.1'
|
||||||
|
|
||||||
compile project(":spring-security-config"),
|
compile project(":spring-security-config"),
|
||||||
project(":spring-security-samples-messages-jc"),
|
project(":spring-security-samples-messages-jc"),
|
||||||
project(":spring-security-core"),
|
project(":spring-security-core"),
|
||||||
project(":spring-security-web"),
|
project(":spring-security-web"),
|
||||||
"org.springframework:spring-webmvc:$springVersion",
|
"org.springframework:spring-webmvc:$springVersion",
|
||||||
"org.springframework:spring-jdbc:$springVersion",
|
"org.springframework:spring-jdbc:$springVersion",
|
||||||
"org.slf4j:slf4j-api:$slf4jVersion",
|
"org.slf4j:slf4j-api:$slf4jVersion",
|
||||||
"org.slf4j:log4j-over-slf4j:$slf4jVersion",
|
"org.slf4j:log4j-over-slf4j:$slf4jVersion",
|
||||||
"org.slf4j:jul-to-slf4j:$slf4jVersion",
|
"org.slf4j:jul-to-slf4j:$slf4jVersion",
|
||||||
"org.slf4j:jcl-over-slf4j:$slf4jVersion",
|
"org.slf4j:jcl-over-slf4j:$slf4jVersion",
|
||||||
"javax.servlet.jsp.jstl:javax.servlet.jsp.jstl-api:$jstlVersion",
|
"javax.servlet.jsp.jstl:javax.servlet.jsp.jstl-api:$jstlVersion",
|
||||||
"javax.validation:validation-api:1.0.0.GA",
|
"javax.validation:validation-api:1.0.0.GA",
|
||||||
"org.hibernate:hibernate-validator:4.2.0.Final",
|
"org.hibernate:hibernate-validator:4.2.0.Final",
|
||||||
"com.fasterxml.jackson.core:jackson-databind:2.2.1"
|
"com.fasterxml.jackson.core:jackson-databind:2.2.1"
|
||||||
|
|
||||||
runtime "opensymphony:sitemesh:2.4.2",
|
runtime "opensymphony:sitemesh:2.4.2",
|
||||||
"cglib:cglib-nodep:$cglibVersion",
|
"cglib:cglib-nodep:$cglibVersion",
|
||||||
'ch.qos.logback:logback-classic:0.9.30'
|
'ch.qos.logback:logback-classic:0.9.30'
|
||||||
}
|
}
|
|
@ -2,26 +2,26 @@ apply from: WAR_SAMPLE_GRADLE
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
|
||||||
providedCompile "javax.servlet:javax.servlet-api:3.0.1",
|
providedCompile "javax.servlet:javax.servlet-api:3.0.1",
|
||||||
'javax.servlet.jsp:jsp-api:2.1'
|
'javax.servlet.jsp:jsp-api:2.1'
|
||||||
|
|
||||||
compile project(":spring-security-config"),
|
compile project(":spring-security-config"),
|
||||||
project(":spring-security-samples-messages-jc"),
|
project(":spring-security-samples-messages-jc"),
|
||||||
project(":spring-security-core"),
|
project(":spring-security-core"),
|
||||||
project(":spring-security-web"),
|
project(":spring-security-web"),
|
||||||
"org.springframework:spring-webmvc:$springVersion",
|
"org.springframework:spring-webmvc:$springVersion",
|
||||||
"org.springframework:spring-jdbc:$springVersion",
|
"org.springframework:spring-jdbc:$springVersion",
|
||||||
"org.slf4j:slf4j-api:$slf4jVersion",
|
"org.slf4j:slf4j-api:$slf4jVersion",
|
||||||
"org.slf4j:log4j-over-slf4j:$slf4jVersion",
|
"org.slf4j:log4j-over-slf4j:$slf4jVersion",
|
||||||
"org.slf4j:jul-to-slf4j:$slf4jVersion",
|
"org.slf4j:jul-to-slf4j:$slf4jVersion",
|
||||||
"org.slf4j:jcl-over-slf4j:$slf4jVersion",
|
"org.slf4j:jcl-over-slf4j:$slf4jVersion",
|
||||||
"javax.servlet.jsp.jstl:javax.servlet.jsp.jstl-api:$jstlVersion",
|
"javax.servlet.jsp.jstl:javax.servlet.jsp.jstl-api:$jstlVersion",
|
||||||
"javax.validation:validation-api:1.0.0.GA",
|
"javax.validation:validation-api:1.0.0.GA",
|
||||||
"org.hibernate:hibernate-validator:4.2.0.Final"
|
"org.hibernate:hibernate-validator:4.2.0.Final"
|
||||||
|
|
||||||
runtime "opensymphony:sitemesh:2.4.2",
|
runtime "opensymphony:sitemesh:2.4.2",
|
||||||
"cglib:cglib-nodep:$cglibVersion",
|
"cglib:cglib-nodep:$cglibVersion",
|
||||||
'ch.qos.logback:logback-classic:0.9.30'
|
'ch.qos.logback:logback-classic:0.9.30'
|
||||||
|
|
||||||
testCompile project(":spring-security-test")
|
testCompile project(":spring-security-test")
|
||||||
}
|
}
|
|
@ -2,15 +2,15 @@ apply from: WAR_SAMPLE_GRADLE
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
|
||||||
providedCompile "javax.servlet:javax.servlet-api:3.0.1",
|
providedCompile "javax.servlet:javax.servlet-api:3.0.1",
|
||||||
'javax.servlet.jsp:jsp-api:2.1'
|
'javax.servlet.jsp:jsp-api:2.1'
|
||||||
|
|
||||||
compile project(":spring-security-config"),
|
compile project(":spring-security-config"),
|
||||||
project(":spring-security-web"),
|
project(":spring-security-web"),
|
||||||
jstlDependencies,
|
jstlDependencies,
|
||||||
"org.slf4j:jcl-over-slf4j:$slf4jVersion"
|
"org.slf4j:jcl-over-slf4j:$slf4jVersion"
|
||||||
|
|
||||||
runtime "ch.qos.logback:logback-classic:$logbackVersion"
|
runtime "ch.qos.logback:logback-classic:$logbackVersion"
|
||||||
|
|
||||||
integrationTestCompile gebDependencies
|
integrationTestCompile gebDependencies
|
||||||
}
|
}
|
|
@ -5,7 +5,7 @@
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
@ -23,10 +23,10 @@ import geb.*
|
||||||
* @author Rob Winch
|
* @author Rob Winch
|
||||||
*/
|
*/
|
||||||
class HomePage extends Page {
|
class HomePage extends Page {
|
||||||
static url = ''
|
static url = ''
|
||||||
static at = { assert driver.title == 'Hello Security'; true}
|
static at = { assert driver.title == 'Hello Security'; true}
|
||||||
static content = {
|
static content = {
|
||||||
message { $('p').text() }
|
message { $('p').text() }
|
||||||
logout { $('input', type: 'submit').click() }
|
logout { $('input', type: 'submit').click() }
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -2,15 +2,15 @@ apply from: WAR_SAMPLE_GRADLE
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
|
||||||
providedCompile "javax.servlet:javax.servlet-api:3.0.1",
|
providedCompile "javax.servlet:javax.servlet-api:3.0.1",
|
||||||
'javax.servlet.jsp:jsp-api:2.1'
|
'javax.servlet.jsp:jsp-api:2.1'
|
||||||
|
|
||||||
compile project(":spring-security-config"),
|
compile project(":spring-security-config"),
|
||||||
project(":spring-security-web"),
|
project(":spring-security-web"),
|
||||||
jstlDependencies,
|
jstlDependencies,
|
||||||
"org.slf4j:jcl-over-slf4j:$slf4jVersion"
|
"org.slf4j:jcl-over-slf4j:$slf4jVersion"
|
||||||
|
|
||||||
runtime "ch.qos.logback:logback-classic:$logbackVersion"
|
runtime "ch.qos.logback:logback-classic:$logbackVersion"
|
||||||
|
|
||||||
integrationTestCompile gebDependencies
|
integrationTestCompile gebDependencies
|
||||||
}
|
}
|
|
@ -2,26 +2,26 @@ apply from: WAR_SAMPLE_GRADLE
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
|
||||||
providedCompile "javax.servlet:javax.servlet-api:3.0.1",
|
providedCompile "javax.servlet:javax.servlet-api:3.0.1",
|
||||||
'javax.servlet.jsp:jsp-api:2.1'
|
'javax.servlet.jsp:jsp-api:2.1'
|
||||||
|
|
||||||
compile project(":spring-security-config"),
|
compile project(":spring-security-config"),
|
||||||
project(":spring-security-samples-messages-jc"),
|
project(":spring-security-samples-messages-jc"),
|
||||||
project(":spring-security-core"),
|
project(":spring-security-core"),
|
||||||
project(":spring-security-web"),
|
project(":spring-security-web"),
|
||||||
"org.springframework:spring-webmvc:$springVersion",
|
"org.springframework:spring-webmvc:$springVersion",
|
||||||
"org.springframework:spring-jdbc:$springVersion",
|
"org.springframework:spring-jdbc:$springVersion",
|
||||||
"org.slf4j:slf4j-api:$slf4jVersion",
|
"org.slf4j:slf4j-api:$slf4jVersion",
|
||||||
"org.slf4j:log4j-over-slf4j:$slf4jVersion",
|
"org.slf4j:log4j-over-slf4j:$slf4jVersion",
|
||||||
"org.slf4j:jul-to-slf4j:$slf4jVersion",
|
"org.slf4j:jul-to-slf4j:$slf4jVersion",
|
||||||
"org.slf4j:jcl-over-slf4j:$slf4jVersion",
|
"org.slf4j:jcl-over-slf4j:$slf4jVersion",
|
||||||
"javax.servlet.jsp.jstl:javax.servlet.jsp.jstl-api:$jstlVersion",
|
"javax.servlet.jsp.jstl:javax.servlet.jsp.jstl-api:$jstlVersion",
|
||||||
"javax.validation:validation-api:1.0.0.GA",
|
"javax.validation:validation-api:1.0.0.GA",
|
||||||
"org.hibernate:hibernate-validator:4.2.0.Final"
|
"org.hibernate:hibernate-validator:4.2.0.Final"
|
||||||
|
|
||||||
runtime "opensymphony:sitemesh:2.4.2",
|
runtime "opensymphony:sitemesh:2.4.2",
|
||||||
"cglib:cglib-nodep:$cglibVersion",
|
"cglib:cglib-nodep:$cglibVersion",
|
||||||
'ch.qos.logback:logback-classic:0.9.30'
|
'ch.qos.logback:logback-classic:0.9.30'
|
||||||
|
|
||||||
testCompile project(":spring-security-test")
|
testCompile project(":spring-security-test")
|
||||||
}
|
}
|
|
@ -2,13 +2,13 @@ apply from: WAR_SAMPLE_GRADLE
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
|
||||||
providedCompile "javax.servlet:javax.servlet-api:3.0.1",
|
providedCompile "javax.servlet:javax.servlet-api:3.0.1",
|
||||||
'javax.servlet.jsp:jsp-api:2.1'
|
'javax.servlet.jsp:jsp-api:2.1'
|
||||||
|
|
||||||
compile jstlDependencies,
|
compile jstlDependencies,
|
||||||
"org.slf4j:jcl-over-slf4j:$slf4jVersion"
|
"org.slf4j:jcl-over-slf4j:$slf4jVersion"
|
||||||
|
|
||||||
runtime "ch.qos.logback:logback-classic:$logbackVersion"
|
runtime "ch.qos.logback:logback-classic:$logbackVersion"
|
||||||
|
|
||||||
integrationTestCompile gebDependencies
|
integrationTestCompile gebDependencies
|
||||||
}
|
}
|
|
@ -5,7 +5,7 @@
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
@ -26,12 +26,12 @@ import org.springframework.security.samples.pages.*
|
||||||
*/
|
*/
|
||||||
@Stepwise
|
@Stepwise
|
||||||
class HelloInsecureTests extends GebReportingSpec {
|
class HelloInsecureTests extends GebReportingSpec {
|
||||||
def 'The HomePage is accessible'() {
|
def 'The HomePage is accessible'() {
|
||||||
when: 'Unauthenticated user accesses the Home Page'
|
when: 'Unauthenticated user accesses the Home Page'
|
||||||
to HomePage
|
to HomePage
|
||||||
then: 'The HomePage is displayed'
|
then: 'The HomePage is displayed'
|
||||||
at HomePage
|
at HomePage
|
||||||
and: 'We can see the message'
|
and: 'We can see the message'
|
||||||
message == 'We would like to secure this page'
|
message == 'We would like to secure this page'
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -5,7 +5,7 @@
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
@ -23,9 +23,9 @@ import geb.*
|
||||||
* @author Rob Winch
|
* @author Rob Winch
|
||||||
*/
|
*/
|
||||||
class HomePage extends Page {
|
class HomePage extends Page {
|
||||||
static url = ''
|
static url = ''
|
||||||
static at = { assert driver.title == 'Hello World'; true}
|
static at = { assert driver.title == 'Hello World'; true}
|
||||||
static content = {
|
static content = {
|
||||||
message { $('p').text() }
|
message { $('p').text() }
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -2,21 +2,21 @@ apply from: WAR_SAMPLE_GRADLE
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
|
||||||
providedCompile "javax.servlet:javax.servlet-api:3.0.1",
|
providedCompile "javax.servlet:javax.servlet-api:3.0.1",
|
||||||
'javax.servlet.jsp:jsp-api:2.1'
|
'javax.servlet.jsp:jsp-api:2.1'
|
||||||
|
|
||||||
compile project(":spring-security-samples-messages-jc"),
|
compile project(":spring-security-samples-messages-jc"),
|
||||||
"org.springframework:spring-webmvc:$springVersion",
|
"org.springframework:spring-webmvc:$springVersion",
|
||||||
"org.springframework:spring-jdbc:$springVersion",
|
"org.springframework:spring-jdbc:$springVersion",
|
||||||
"org.slf4j:slf4j-api:$slf4jVersion",
|
"org.slf4j:slf4j-api:$slf4jVersion",
|
||||||
"org.slf4j:log4j-over-slf4j:$slf4jVersion",
|
"org.slf4j:log4j-over-slf4j:$slf4jVersion",
|
||||||
"org.slf4j:jul-to-slf4j:$slf4jVersion",
|
"org.slf4j:jul-to-slf4j:$slf4jVersion",
|
||||||
"org.slf4j:jcl-over-slf4j:$slf4jVersion",
|
"org.slf4j:jcl-over-slf4j:$slf4jVersion",
|
||||||
"javax.servlet.jsp.jstl:javax.servlet.jsp.jstl-api:$jstlVersion",
|
"javax.servlet.jsp.jstl:javax.servlet.jsp.jstl-api:$jstlVersion",
|
||||||
"javax.validation:validation-api:1.0.0.GA",
|
"javax.validation:validation-api:1.0.0.GA",
|
||||||
"org.hibernate:hibernate-validator:4.2.0.Final"
|
"org.hibernate:hibernate-validator:4.2.0.Final"
|
||||||
|
|
||||||
runtime "opensymphony:sitemesh:2.4.2",
|
runtime "opensymphony:sitemesh:2.4.2",
|
||||||
"cglib:cglib-nodep:$cglibVersion",
|
"cglib:cglib-nodep:$cglibVersion",
|
||||||
'ch.qos.logback:logback-classic:0.9.30'
|
'ch.qos.logback:logback-classic:0.9.30'
|
||||||
}
|
}
|
|
@ -4,28 +4,28 @@ apply from: WAR_SAMPLE_GRADLE
|
||||||
def excludeModules = ['spring-security-acl', 'jsr250-api', 'ehcache', 'spring-jdbc', 'spring-tx']
|
def excludeModules = ['spring-security-acl', 'jsr250-api', 'ehcache', 'spring-jdbc', 'spring-tx']
|
||||||
|
|
||||||
configurations {
|
configurations {
|
||||||
excludeModules.each {name ->
|
excludeModules.each {name ->
|
||||||
runtime.exclude module: name
|
runtime.exclude module: name
|
||||||
}
|
}
|
||||||
|
|
||||||
runtime.exclude group: 'org.aspectj'
|
runtime.exclude group: 'org.aspectj'
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
providedCompile "javax.servlet:javax.servlet-api:$servletApiVersion"
|
providedCompile "javax.servlet:javax.servlet-api:$servletApiVersion"
|
||||||
|
|
||||||
compile project(':spring-security-core'),
|
compile project(':spring-security-core'),
|
||||||
"org.springframework:spring-beans:$springVersion",
|
"org.springframework:spring-beans:$springVersion",
|
||||||
"org.springframework:spring-context:$springVersion",
|
"org.springframework:spring-context:$springVersion",
|
||||||
"org.springframework:spring-web:$springVersion"
|
"org.springframework:spring-web:$springVersion"
|
||||||
|
|
||||||
runtime project(':spring-security-web'),
|
runtime project(':spring-security-web'),
|
||||||
project(':spring-security-config'),
|
project(':spring-security-config'),
|
||||||
project(':spring-security-taglibs'),
|
project(':spring-security-taglibs'),
|
||||||
"org.springframework:spring-context-support:$springVersion",
|
"org.springframework:spring-context-support:$springVersion",
|
||||||
jstlDependencies,
|
jstlDependencies,
|
||||||
"org.slf4j:jcl-over-slf4j:$slf4jVersion",
|
"org.slf4j:jcl-over-slf4j:$slf4jVersion",
|
||||||
"ch.qos.logback:logback-classic:$logbackVersion"
|
"ch.qos.logback:logback-classic:$logbackVersion"
|
||||||
|
|
||||||
integrationTestCompile gebDependencies
|
integrationTestCompile gebDependencies
|
||||||
}
|
}
|
|
@ -5,7 +5,7 @@
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
@ -27,35 +27,35 @@ import org.springframework.security.samples.pages.*
|
||||||
*/
|
*/
|
||||||
@Stepwise
|
@Stepwise
|
||||||
class JaasXmlTests extends GebReportingSpec {
|
class JaasXmlTests extends GebReportingSpec {
|
||||||
def 'access home page with unauthenticated works'() {
|
def 'access home page with unauthenticated works'() {
|
||||||
when: 'Unauthenticated user accesses the Home Page'
|
when: 'Unauthenticated user accesses the Home Page'
|
||||||
to HomePage
|
to HomePage
|
||||||
then: 'The home page is displayed'
|
then: 'The home page is displayed'
|
||||||
at HomePage
|
at HomePage
|
||||||
}
|
}
|
||||||
|
|
||||||
def 'access secure page with unauthenticated requires login'() {
|
def 'access secure page with unauthenticated requires login'() {
|
||||||
when: 'Unauthenticated user accesses the Secure Page'
|
when: 'Unauthenticated user accesses the Secure Page'
|
||||||
securePage LoginPage
|
securePage LoginPage
|
||||||
then: 'The login page is displayed'
|
then: 'The login page is displayed'
|
||||||
at LoginPage
|
at LoginPage
|
||||||
}
|
}
|
||||||
|
|
||||||
def 'authenticated user is sent to original page'() {
|
def 'authenticated user is sent to original page'() {
|
||||||
when: 'user authenticates'
|
when: 'user authenticates'
|
||||||
login()
|
login()
|
||||||
then: 'The secure page is displayed'
|
then: 'The secure page is displayed'
|
||||||
at SecurePage
|
at SecurePage
|
||||||
}
|
}
|
||||||
|
|
||||||
def 'authenticated user logs out'() {
|
def 'authenticated user logs out'() {
|
||||||
when: 'user logs out'
|
when: 'user logs out'
|
||||||
logout()
|
logout()
|
||||||
then: 'the default logout success page is displayed'
|
then: 'the default logout success page is displayed'
|
||||||
at LogoutPage
|
at LogoutPage
|
||||||
when: 'Unauthenticated user accesses the Secure Page'
|
when: 'Unauthenticated user accesses the Secure Page'
|
||||||
via SecurePage
|
via SecurePage
|
||||||
then: 'The login page is displayed'
|
then: 'The login page is displayed'
|
||||||
at LoginPage
|
at LoginPage
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -5,7 +5,7 @@
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
@ -23,9 +23,9 @@ import geb.*
|
||||||
* @author Rob Winch
|
* @author Rob Winch
|
||||||
*/
|
*/
|
||||||
class HomePage extends Page {
|
class HomePage extends Page {
|
||||||
static url = ''
|
static url = ''
|
||||||
static at = { assert driver.title == 'Home Page'; true}
|
static at = { assert driver.title == 'Home Page'; true}
|
||||||
static content = {
|
static content = {
|
||||||
securePage(to: [SecurePage,LoginPage]) { $('a').click() }
|
securePage(to: [SecurePage,LoginPage]) { $('a').click() }
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -5,7 +5,7 @@
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
@ -23,15 +23,15 @@ import geb.*
|
||||||
* @author Rob Winch
|
* @author Rob Winch
|
||||||
*/
|
*/
|
||||||
class LoginPage extends Page {
|
class LoginPage extends Page {
|
||||||
static url = 'login'
|
static url = 'login'
|
||||||
static at = { assert driver.title == 'Login Page'; true}
|
static at = { assert driver.title == 'Login Page'; true}
|
||||||
static content = {
|
static content = {
|
||||||
login(required:false) { user='user', password='user' ->
|
login(required:false) { user='user', password='user' ->
|
||||||
loginForm.username = user
|
loginForm.username = user
|
||||||
loginForm.password = password
|
loginForm.password = password
|
||||||
submit.click()
|
submit.click()
|
||||||
}
|
}
|
||||||
loginForm { $('form') }
|
loginForm { $('form') }
|
||||||
submit { $('input', type: 'submit') }
|
submit { $('input', type: 'submit') }
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -5,7 +5,7 @@
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
@ -23,6 +23,6 @@ import geb.Page
|
||||||
* @author Rob Winch
|
* @author Rob Winch
|
||||||
*/
|
*/
|
||||||
class LogoutPage extends LoginPage {
|
class LogoutPage extends LoginPage {
|
||||||
static url = 'login'
|
static url = 'login'
|
||||||
static at = { assert driver.title == 'Login Page' && $('p').text() == 'You have been logged out'; true}
|
static at = { assert driver.title == 'Login Page' && $('p').text() == 'You have been logged out'; true}
|
||||||
}
|
}
|
|
@ -5,7 +5,7 @@
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
@ -23,10 +23,10 @@ import geb.Page
|
||||||
* @author Rob Winch
|
* @author Rob Winch
|
||||||
*/
|
*/
|
||||||
class SecurePage extends Page {
|
class SecurePage extends Page {
|
||||||
static url = 'secure/'
|
static url = 'secure/'
|
||||||
static at = { assert driver.title == 'Security Debug Information'; true}
|
static at = { assert driver.title == 'Security Debug Information'; true}
|
||||||
static content = {
|
static content = {
|
||||||
message { $('p').text() }
|
message { $('p').text() }
|
||||||
logout { $('input', type: 'submit').click() }
|
logout { $('input', type: 'submit').click() }
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -2,26 +2,26 @@ apply from: WAR_SAMPLE_GRADLE
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
|
||||||
providedCompile "javax.servlet:javax.servlet-api:3.0.1",
|
providedCompile "javax.servlet:javax.servlet-api:3.0.1",
|
||||||
'javax.servlet.jsp:jsp-api:2.1'
|
'javax.servlet.jsp:jsp-api:2.1'
|
||||||
|
|
||||||
compile project(":spring-security-config"),
|
compile project(":spring-security-config"),
|
||||||
project(":spring-security-samples-messages-jc"),
|
project(":spring-security-samples-messages-jc"),
|
||||||
project(":spring-security-core"),
|
project(":spring-security-core"),
|
||||||
project(":spring-security-web"),
|
project(":spring-security-web"),
|
||||||
"org.springframework:spring-webmvc:$springVersion",
|
"org.springframework:spring-webmvc:$springVersion",
|
||||||
"org.springframework:spring-jdbc:$springVersion",
|
"org.springframework:spring-jdbc:$springVersion",
|
||||||
"org.slf4j:slf4j-api:$slf4jVersion",
|
"org.slf4j:slf4j-api:$slf4jVersion",
|
||||||
"org.slf4j:log4j-over-slf4j:$slf4jVersion",
|
"org.slf4j:log4j-over-slf4j:$slf4jVersion",
|
||||||
"org.slf4j:jul-to-slf4j:$slf4jVersion",
|
"org.slf4j:jul-to-slf4j:$slf4jVersion",
|
||||||
"org.slf4j:jcl-over-slf4j:$slf4jVersion",
|
"org.slf4j:jcl-over-slf4j:$slf4jVersion",
|
||||||
"javax.servlet.jsp.jstl:javax.servlet.jsp.jstl-api:$jstlVersion",
|
"javax.servlet.jsp.jstl:javax.servlet.jsp.jstl-api:$jstlVersion",
|
||||||
"javax.validation:validation-api:1.0.0.GA",
|
"javax.validation:validation-api:1.0.0.GA",
|
||||||
"org.hibernate:hibernate-validator:4.2.0.Final"
|
"org.hibernate:hibernate-validator:4.2.0.Final"
|
||||||
|
|
||||||
runtime "opensymphony:sitemesh:2.4.2",
|
runtime "opensymphony:sitemesh:2.4.2",
|
||||||
"cglib:cglib-nodep:$cglibVersion",
|
"cglib:cglib-nodep:$cglibVersion",
|
||||||
'ch.qos.logback:logback-classic:0.9.30'
|
'ch.qos.logback:logback-classic:0.9.30'
|
||||||
|
|
||||||
integrationTestCompile gebDependencies
|
integrationTestCompile gebDependencies
|
||||||
}
|
}
|
|
@ -5,7 +5,7 @@
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
@ -27,30 +27,30 @@ import org.springframework.security.samples.pages.*
|
||||||
*/
|
*/
|
||||||
@Stepwise
|
@Stepwise
|
||||||
class JdbcJcTests extends GebReportingSpec {
|
class JdbcJcTests extends GebReportingSpec {
|
||||||
def 'access home page with unauthenticated user sends to login page'() {
|
def 'access home page with unauthenticated user sends to login page'() {
|
||||||
when: 'Unauthenticated user accesses the Home Page'
|
when: 'Unauthenticated user accesses the Home Page'
|
||||||
via HomePage
|
via HomePage
|
||||||
then: 'The login page is displayed'
|
then: 'The login page is displayed'
|
||||||
at LoginPage
|
at LoginPage
|
||||||
}
|
}
|
||||||
|
|
||||||
def 'authenticated user is sent to original page'() {
|
def 'authenticated user is sent to original page'() {
|
||||||
when: 'user authenticates'
|
when: 'user authenticates'
|
||||||
login()
|
login()
|
||||||
then: 'The home page is displayed'
|
then: 'The home page is displayed'
|
||||||
at HomePage
|
at HomePage
|
||||||
and: 'The username is displayed'
|
and: 'The username is displayed'
|
||||||
user == 'user'
|
user == 'user'
|
||||||
}
|
}
|
||||||
|
|
||||||
def 'authenticated user logs out'() {
|
def 'authenticated user logs out'() {
|
||||||
when: 'user logs out'
|
when: 'user logs out'
|
||||||
logout()
|
logout()
|
||||||
then: 'the login page is displayed'
|
then: 'the login page is displayed'
|
||||||
at LoginPage
|
at LoginPage
|
||||||
when: 'Unauthenticated user accesses the Home Page'
|
when: 'Unauthenticated user accesses the Home Page'
|
||||||
via HomePage
|
via HomePage
|
||||||
then: 'The login page is displayed'
|
then: 'The login page is displayed'
|
||||||
at LoginPage
|
at LoginPage
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -5,7 +5,7 @@
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
@ -23,10 +23,10 @@ import geb.*
|
||||||
* @author Rob Winch
|
* @author Rob Winch
|
||||||
*/
|
*/
|
||||||
class HomePage extends Page {
|
class HomePage extends Page {
|
||||||
static url = ''
|
static url = ''
|
||||||
static at = { assert driver.title == 'Messages : View All'; true}
|
static at = { assert driver.title == 'Messages : View All'; true}
|
||||||
static content = {
|
static content = {
|
||||||
user { $('p.navbar-text').text() }
|
user { $('p.navbar-text').text() }
|
||||||
logout { $('input', type: 'submit').click() }
|
logout { $('input', type: 'submit').click() }
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -5,7 +5,7 @@
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
@ -23,15 +23,15 @@ import geb.*
|
||||||
* @author Rob Winch
|
* @author Rob Winch
|
||||||
*/
|
*/
|
||||||
class LoginPage extends Page {
|
class LoginPage extends Page {
|
||||||
static url = 'login'
|
static url = 'login'
|
||||||
static at = { assert driver.title == 'Login Page'; true}
|
static at = { assert driver.title == 'Login Page'; true}
|
||||||
static content = {
|
static content = {
|
||||||
login(required:false) { user='user', password='password' ->
|
login(required:false) { user='user', password='password' ->
|
||||||
loginForm.username = user
|
loginForm.username = user
|
||||||
loginForm.password = password
|
loginForm.password = password
|
||||||
submit.click()
|
submit.click()
|
||||||
}
|
}
|
||||||
loginForm { $('form') }
|
loginForm { $('form') }
|
||||||
submit { $('input', type: 'submit') }
|
submit { $('input', type: 'submit') }
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -2,28 +2,28 @@ apply from: WAR_SAMPLE_GRADLE
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
|
||||||
providedCompile "javax.servlet:javax.servlet-api:3.0.1",
|
providedCompile "javax.servlet:javax.servlet-api:3.0.1",
|
||||||
'javax.servlet.jsp:jsp-api:2.1'
|
'javax.servlet.jsp:jsp-api:2.1'
|
||||||
|
|
||||||
compile project(":spring-security-ldap"),
|
compile project(":spring-security-ldap"),
|
||||||
apachedsDependencies,
|
apachedsDependencies,
|
||||||
project(":spring-security-config"),
|
project(":spring-security-config"),
|
||||||
project(":spring-security-samples-messages-jc"),
|
project(":spring-security-samples-messages-jc"),
|
||||||
project(":spring-security-core"),
|
project(":spring-security-core"),
|
||||||
project(":spring-security-web"),
|
project(":spring-security-web"),
|
||||||
"org.springframework:spring-webmvc:$springVersion",
|
"org.springframework:spring-webmvc:$springVersion",
|
||||||
"org.springframework:spring-jdbc:$springVersion",
|
"org.springframework:spring-jdbc:$springVersion",
|
||||||
"org.slf4j:slf4j-api:$slf4jVersion",
|
"org.slf4j:slf4j-api:$slf4jVersion",
|
||||||
"org.slf4j:log4j-over-slf4j:$slf4jVersion",
|
"org.slf4j:log4j-over-slf4j:$slf4jVersion",
|
||||||
"org.slf4j:jul-to-slf4j:$slf4jVersion",
|
"org.slf4j:jul-to-slf4j:$slf4jVersion",
|
||||||
"org.slf4j:jcl-over-slf4j:$slf4jVersion",
|
"org.slf4j:jcl-over-slf4j:$slf4jVersion",
|
||||||
"javax.servlet.jsp.jstl:javax.servlet.jsp.jstl-api:$jstlVersion",
|
"javax.servlet.jsp.jstl:javax.servlet.jsp.jstl-api:$jstlVersion",
|
||||||
"javax.validation:validation-api:1.0.0.GA",
|
"javax.validation:validation-api:1.0.0.GA",
|
||||||
"org.hibernate:hibernate-validator:4.2.0.Final"
|
"org.hibernate:hibernate-validator:4.2.0.Final"
|
||||||
|
|
||||||
runtime "opensymphony:sitemesh:2.4.2",
|
runtime "opensymphony:sitemesh:2.4.2",
|
||||||
"cglib:cglib-nodep:$cglibVersion",
|
"cglib:cglib-nodep:$cglibVersion",
|
||||||
'ch.qos.logback:logback-classic:0.9.30'
|
'ch.qos.logback:logback-classic:0.9.30'
|
||||||
|
|
||||||
integrationTestCompile gebDependencies
|
integrationTestCompile gebDependencies
|
||||||
}
|
}
|
|
@ -5,7 +5,7 @@
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
@ -27,30 +27,30 @@ import org.springframework.security.samples.pages.*
|
||||||
*/
|
*/
|
||||||
@Stepwise
|
@Stepwise
|
||||||
class LdapJcTests extends GebReportingSpec {
|
class LdapJcTests extends GebReportingSpec {
|
||||||
def 'access home page with unauthenticated user sends to login page'() {
|
def 'access home page with unauthenticated user sends to login page'() {
|
||||||
when: 'Unauthenticated user accesses the Home Page'
|
when: 'Unauthenticated user accesses the Home Page'
|
||||||
via HomePage
|
via HomePage
|
||||||
then: 'The login page is displayed'
|
then: 'The login page is displayed'
|
||||||
at LoginPage
|
at LoginPage
|
||||||
}
|
}
|
||||||
|
|
||||||
def 'authenticated user is sent to original page'() {
|
def 'authenticated user is sent to original page'() {
|
||||||
when: 'user authenticates'
|
when: 'user authenticates'
|
||||||
login()
|
login()
|
||||||
then: 'The home page is displayed'
|
then: 'The home page is displayed'
|
||||||
at HomePage
|
at HomePage
|
||||||
and: 'The username is displayed'
|
and: 'The username is displayed'
|
||||||
user == 'user'
|
user == 'user'
|
||||||
}
|
}
|
||||||
|
|
||||||
def 'authenticated user logs out'() {
|
def 'authenticated user logs out'() {
|
||||||
when: 'user logs out'
|
when: 'user logs out'
|
||||||
logout()
|
logout()
|
||||||
then: 'the login page is displayed'
|
then: 'the login page is displayed'
|
||||||
at LoginPage
|
at LoginPage
|
||||||
when: 'Unauthenticated user accesses the Home Page'
|
when: 'Unauthenticated user accesses the Home Page'
|
||||||
via HomePage
|
via HomePage
|
||||||
then: 'The login page is displayed'
|
then: 'The login page is displayed'
|
||||||
at LoginPage
|
at LoginPage
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -5,7 +5,7 @@
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
@ -23,10 +23,10 @@ import geb.*
|
||||||
* @author Rob Winch
|
* @author Rob Winch
|
||||||
*/
|
*/
|
||||||
class HomePage extends Page {
|
class HomePage extends Page {
|
||||||
static url = ''
|
static url = ''
|
||||||
static at = { assert driver.title == 'Messages : View All'; true}
|
static at = { assert driver.title == 'Messages : View All'; true}
|
||||||
static content = {
|
static content = {
|
||||||
user { $('p.navbar-text').text() }
|
user { $('p.navbar-text').text() }
|
||||||
logout { $('input', type: 'submit').click() }
|
logout { $('input', type: 'submit').click() }
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -5,7 +5,7 @@
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
@ -23,15 +23,15 @@ import geb.*
|
||||||
* @author Rob Winch
|
* @author Rob Winch
|
||||||
*/
|
*/
|
||||||
class LoginPage extends Page {
|
class LoginPage extends Page {
|
||||||
static url = 'login'
|
static url = 'login'
|
||||||
static at = { assert driver.title == 'Login Page'; true}
|
static at = { assert driver.title == 'Login Page'; true}
|
||||||
static content = {
|
static content = {
|
||||||
login(required:false) { user='user', password='password' ->
|
login(required:false) { user='user', password='password' ->
|
||||||
loginForm.username = user
|
loginForm.username = user
|
||||||
loginForm.password = password
|
loginForm.password = password
|
||||||
submit.click()
|
submit.click()
|
||||||
}
|
}
|
||||||
loginForm { $('form') }
|
loginForm { $('form') }
|
||||||
submit { $('input', type: 'submit') }
|
submit { $('input', type: 'submit') }
|
||||||
}
|
}
|
||||||
}
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue