SEC-2915: groovy/gradle spaces->tabs

This commit is contained in:
Rob Winch 2015-03-23 11:14:26 -05:00
parent cf9f58a4ac
commit 0a2e496a84
121 changed files with 6033 additions and 6033 deletions

View File

@ -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"
} }

View File

@ -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"
} }

View File

@ -5,5 +5,5 @@ generatePom.enabled = false
sonarRunner.skipProject = true sonarRunner.skipProject = true
mavenBom { mavenBom {
projects = coreModuleProjects projects = coreModuleProjects
} }

View File

@ -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
} }

View File

@ -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'
} }

View File

@ -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)
} }
} }
} }
} }
} }
} }
} }
} }
} }
} }
} }

View File

@ -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)
} }
} }
} }
} }
} }

View File

@ -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()
} }
} }

View File

@ -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)
} }
} }
} }

View File

@ -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()
} }
} }
} }

View File

@ -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"
} }

View File

@ -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

View File

@ -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);
} }
} }

View File

@ -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)
} }
} }

View File

@ -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")
} }
} }

View File

@ -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)
} }
} }

View File

@ -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;
} }
} }
} }

View File

@ -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]
} }
} }

View File

@ -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]
} }
} }

View File

@ -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");
} }
} }

View File

@ -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()
} }
} }
} }

View File

@ -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;
} }
} }
} }

View File

@ -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,

View File

@ -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();
} }
} }

View File

@ -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()
} }
} }

View File

@ -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-&lt;element&gt;. For example the http element will have the id * <li>Elements - any xml element will have the nsa-&lt;element&gt;. 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-&lt;element&gt;-parents. For example, authentication-provider would have a section id of * nsa-&lt;element&gt;-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-&lt;element&gt;-attributes. For example the http element would require a section with the id * nsa-&lt;element&gt;-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-&lt;element&gt;-&lt;attributeName&gt;. For * <li>Attribute - Each attribute of an element would have an id of nsa-&lt;element&gt;-&lt;attributeName&gt;. 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-&lt;element&gt;-children. * <li>Child Section - Any element with a child element will have a section named nsa-&lt;element&gt;-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
} }
} }

View File

@ -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
} }
} }

View File

@ -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
} }
} }

View File

@ -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())
} }
} }

View File

@ -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)
} }
} }

View File

@ -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
} }
} }

View File

@ -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>"""
} }
} }

View File

@ -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'
} }
} }

View File

@ -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'
} }
} }

View File

@ -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
} }
} }

View File

@ -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'))))
} }
} }

View File

@ -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'))
} }
} }

View File

@ -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'
} }
} }

View File

@ -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 {
} }
} }

View File

@ -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'
} }
} }

View File

@ -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
} }

View File

@ -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'
} }
} }

View File

@ -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"
} }

View File

@ -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
} }
} }
} }
} }

View File

@ -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"
} }
} }

View File

@ -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
} }

View File

@ -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

View File

@ -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")
} }
} }

View File

@ -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
} }

View File

@ -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
} }

View File

@ -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"
} }

View File

@ -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
} }

View File

@ -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'
} }

View File

@ -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"
} }

View File

@ -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'
} }

View File

@ -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
} }

View File

@ -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')
} }

View File

@ -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')
} }

View File

@ -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')
} }

View File

@ -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')
} }
} }

View File

@ -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"
} }

View File

@ -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'
} }

View File

@ -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
} }

View File

@ -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
} }
} }

View File

@ -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') }
} }
} }

View File

@ -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() }
} }
} }

View File

@ -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') }
} }
} }

View File

@ -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"
} }

View File

@ -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"
} }

View File

@ -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
} }

View File

@ -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
} }
} }

View File

@ -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() }
} }
} }

View File

@ -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') }
} }
} }

View File

@ -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"
} }

View File

@ -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'
} }

View File

@ -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")
} }

View File

@ -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
} }

View File

@ -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() }
} }
} }

View File

@ -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
} }

View File

@ -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")
} }

View File

@ -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
} }

View File

@ -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'
} }
} }

View File

@ -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() }
} }
} }

View File

@ -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'
} }

View File

@ -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
} }

View File

@ -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
} }
} }

View File

@ -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() }
} }
} }

View File

@ -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') }
} }
} }

View File

@ -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}
} }

View File

@ -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() }
} }
} }

View File

@ -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
} }

View File

@ -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
} }
} }

View File

@ -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() }
} }
} }

View File

@ -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') }
} }
} }

View File

@ -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
} }

View File

@ -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
} }
} }

View File

@ -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() }
} }
} }

View File

@ -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