Compare commits

..

7 Commits
main ... 5.5.0

Author SHA1 Message Date
Josh Cummings
fa1f474f25
Use JDK 11
Closes gh-21
2021-05-27 10:41:22 -06:00
Josh Cummings
324cca474d
Update to Spring Security 5.5.0
Closes gh-15
2021-05-27 10:29:08 -06:00
Josh Cummings
1a0e1f626d
Use OpenSAML 4 in SAML 2.0 Login Sample
Closes gh-20
2021-05-27 10:29:08 -06:00
Josh Cummings
43dbe19507
Update Kotlin Samples
Closes gh-19
2021-05-27 10:29:03 -06:00
Josh Cummings
ddc4db8cf6
Update to Spring Security 5.5.0-SNAPSHOT 2021-05-27 09:40:38 -06:00
Josh Cummings
6d9a28c2f7
Mfa Sample Depends on spring-security-crypto
Closes gh-18
2021-05-27 09:34:59 -06:00
Josh Cummings
1c0ec2e20a
Sync Gradle Version
Issue gh-16
2021-05-27 09:15:35 -06:00
437 changed files with 1042 additions and 27762 deletions

View File

@ -16,7 +16,7 @@ jobs:
- name: Set up JDK - name: Set up JDK
uses: actions/setup-java@v1 uses: actions/setup-java@v1
with: with:
java-version: '17' java-version: '11'
- name: Cache Gradle packages - name: Cache Gradle packages
uses: actions/cache@v2 uses: actions/cache@v2
with: with:

1
.gitignore vendored
View File

@ -73,7 +73,6 @@ local.properties
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
# User-specific stuff # User-specific stuff
.idea/**/libraries-with-intellij-classes.xml
.idea/**/workspace.xml .idea/**/workspace.xml
.idea/**/tasks.xml .idea/**/tasks.xml
.idea/**/usage.statistics.xml .idea/**/usage.statistics.xml

2
.idea/misc.xml generated
View File

@ -4,5 +4,5 @@
<component name="FrameworkDetectionExcludesConfiguration"> <component name="FrameworkDetectionExcludesConfiguration">
<file type="web" url="file://$PROJECT_DIR$" /> <file type="web" url="file://$PROJECT_DIR$" />
</component> </component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="temurin-17" project-jdk-type="JavaSDK" /> <component name="ProjectRootManager" version="2" languageLevel="JDK_11" default="true" project-jdk-name="11" project-jdk-type="JavaSDK" />
</project> </project>

View File

@ -1,71 +1,3 @@
image::https://github.com/spring-projects/spring-security-samples/workflows/CI/badge.svg[link=https://github.com/spring-projects/spring-security-samples/actions?query=workflow%3ACI] image::https://github.com/spring-projects/spring-security-samples/workflows/CI/badge.svg[link=https://github.com/spring-projects/spring-security-samples/actions?query=workflow%3ACI]
Samples for https://github.com/spring-projects/spring-security Samples for https://github.com/spring-projects/spring-security
== Samples catalog
=== Getting Started
* Hello Security - https://github.com/spring-projects/spring-security-samples/tree/main/servlet/spring-boot/java/hello-security[Spring Boot] | https://github.com/spring-projects/spring-security-samples/tree/main/reactive/webflux/java/hello-security[WebFlux] | https://github.com/spring-projects/spring-security-samples/tree/main/reactive/webflux-fn/hello-security[WebFlux.fn] | https://github.com/spring-projects/spring-security-samples/tree/main/servlet/java-configuration/hello-security[Java Configuration] | https://github.com/spring-projects/spring-security-samples/tree/main/servlet/xml/java/helloworld[XML] | https://github.com/spring-projects/spring-security-samples/tree/main/servlet/spring-boot/kotlin/hello-security[Kotlin] | https://github.com/spring-projects/spring-security-samples/tree/main/reactive/webflux/kotlin/hello-security[WebFlux Kotlin] | https://github.com/spring-projects/spring-security-samples/tree/main/reactive/rsocket/hello-security[RSocket]
* Hello Security (without Spring MVC) - https://github.com/spring-projects/spring-security-samples/tree/main/servlet/java-configuration/hello-security-explicit[Java Configuration]
* Hello Security with Explicit Configuration - https://github.com/spring-projects/spring-security-samples/tree/main/servlet/spring-boot/java/hello-security-explicit[Spring Boot] | https://github.com/spring-projects/spring-security-samples/tree/main/reactive/webflux/java/hello-security-explicit[WebFlux] | https://github.com/spring-projects/spring-security-samples/tree/main/servlet/java-configuration/hello-mvc-security[Java Configuration]
* Method Security - https://github.com/spring-projects/spring-security-samples/tree/main/reactive/webflux/java/method[WebFlux]
* Spring Data Integration - https://github.com/spring-projects/spring-security-samples/tree/main/servlet/java-configuration/data[Java Configuration]
* Max Sessions - https://github.com/spring-projects/spring-security-samples/tree/main/servlet/java-configuration/max-sessions[Java Configuration]
* AspectJ Security Configuration - https://github.com/spring-projects/spring-security-samples/tree/main/servlet/java-configuration/aspectj[Java Configuration]
=== OAuth 2.0
* https://github.com/spring-projects/spring-security-samples/tree/main/servlet/spring-boot/java/oauth2/authorization-server[Authorization Server]
* Login - https://github.com/spring-projects/spring-security-samples/tree/main/servlet/spring-boot/java/oauth2/login[Spring Boot] | https://github.com/spring-projects/spring-security-samples/tree/main/reactive/webflux/java/oauth2/login[WebFlux]
* Resource Server
** Hello Security - https://github.com/spring-projects/spring-security-samples/tree/main/servlet/spring-boot/java/oauth2/resource-server/hello-security[Spring Boot] | https://github.com/spring-projects/spring-security-samples/tree/main/reactive/webflux/java/oauth2/resource-server[WebFlux]
** https://github.com/spring-projects/spring-security-samples/tree/main/servlet/spring-boot/java/oauth2/resource-server/jwe[JSON Web Encryption (JWE)]
** https://github.com/spring-projects/spring-security-samples/tree/main/servlet/spring-boot/java/oauth2/resource-server/multi-tenancy[Multi-tenancy]
** https://github.com/spring-projects/spring-security-samples/tree/main/servlet/spring-boot/java/oauth2/resource-server/opaque[Opaque Token]
** https://github.com/spring-projects/spring-security-samples/tree/main/servlet/spring-boot/java/oauth2/resource-server/static[Static]
* WebClient - https://github.com/spring-projects/spring-security-samples/tree/main/servlet/spring-boot/java/oauth2/webclient[Spring Boot] | https://github.com/spring-projects/spring-security-samples/tree/main/reactive/webflux/java/oauth2/webclient[WebFlux]
=== SAML 2.0
* Login & Logout - https://github.com/spring-projects/spring-security-samples/tree/main/servlet/spring-boot/java/saml2/login[Spring Boot] | https://github.com/spring-projects/spring-security-samples/tree/main/servlet/java-configuration/saml2/login[Java Configuration]
=== Authentication
* https://github.com/spring-projects/spring-security-samples/tree/main/servlet/java-configuration/authentication/preauth[Pre-authentication]
* https://github.com/spring-projects/spring-security-samples/tree/main/servlet/java-configuration/authentication/remember-me[Remember-me]
* Username and password
** Form Login - https://github.com/spring-projects/spring-security-samples/tree/main/servlet/java-configuration/authentication/username-password/form[Java Configuration] | https://github.com/spring-projects/spring-security-samples/tree/main/reactive/webflux/java/authentication/username-password/form[WebFlux]
** https://github.com/spring-projects/spring-security-samples/tree/main/servlet/java-configuration/authentication/username-password/in-memory[In-memory `UserDetailsService`]
** https://github.com/spring-projects/spring-security-samples/tree/main/servlet/java-configuration/authentication/username-password/jdbc[JDBC]
** https://github.com/spring-projects/spring-security-samples/tree/main/servlet/java-configuration/authentication/username-password/ldap[LDAP]
** https://github.com/spring-projects/spring-security-samples/tree/main/servlet/spring-boot/java/authentication/username-password/mfa[Multi-factor authentication]
** https://github.com/spring-projects/spring-security-samples/tree/main/servlet/spring-boot/java/authentication/username-password/user-details-service/custom-user[Custom `UserDetails`]
* X.509 - https://github.com/spring-projects/spring-security-samples/tree/main/servlet/java-configuration/authentication/x509[Java Configuration] | https://github.com/spring-projects/spring-security-samples/tree/main/reactive/webflux/java/authentication/x509[WebFlux]
=== JWT
* Login - https://github.com/spring-projects/spring-security-samples/tree/main/servlet/spring-boot/java/jwt/login[Spring Boot]

View File

@ -21,25 +21,3 @@ allprojects {
} }
} }
} }
if (hasProperty('buildScan')) {
buildScan {
termsOfServiceUrl = 'https://gradle.com/terms-of-service'
termsOfServiceAgree = 'yes'
}
}
repositories {
mavenCentral()
}
tasks.register('runAllTests') {
var allTasks = rootProject.getAllTasks(true)
var allTestsTasks = allTasks.values().collect { t ->
t.findAll { it.name == 'test' || it.name == 'integrationTest' }
}.flatten()
it.dependsOn {
allTestsTasks
}
}

View File

@ -1,5 +1,5 @@
version=6.0.0-SNAPSHOT version=5.5.0
spring-security.version=6.0.0-SNAPSHOT spring-security.version=5.5.0
org.gradle.jvmargs=-Xmx3g -XX:+HeapDumpOnOutOfMemoryError org.gradle.jvmargs=-Xmx3g -XX:MaxPermSize=2048m -XX:+HeapDumpOnOutOfMemoryError
org.gradle.parallel=true org.gradle.parallel=true
org.gradle.caching=true org.gradle.caching=true

Binary file not shown.

View File

@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-6.9-bin.zip
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists

257
gradlew vendored
View File

@ -1,7 +1,7 @@
#!/bin/sh #!/usr/bin/env sh
# #
# Copyright © 2015-2021 the original authors. # Copyright 2015 the original author or authors.
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -17,101 +17,67 @@
# #
############################################################################## ##############################################################################
# ##
# Gradle start up script for POSIX generated by Gradle. ## Gradle start up script for UN*X
# ##
# Important for running:
#
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
# noncompliant, but you have some other compliant shell such as ksh or
# bash, then to run this script, type that shell name before the whole
# command line, like:
#
# ksh Gradle
#
# Busybox and similar reduced shells will NOT work, because this script
# requires all of these POSIX shell features:
# * functions;
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
# * compound commands having a testable exit status, especially «case»;
# * various built-in commands including «command», «set», and «ulimit».
#
# Important for patching:
#
# (2) This script targets any POSIX shell, so it avoids extensions provided
# by Bash, Ksh, etc; in particular arrays are avoided.
#
# The "traditional" practice of packing multiple parameters into a
# space-separated string is a well documented source of bugs and security
# problems, so this is (mostly) avoided, by progressively accumulating
# options in "$@", and eventually passing that to Java.
#
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
# see the in-line comments for details.
#
# There are tweaks for specific operating systems such as AIX, CygWin,
# Darwin, MinGW, and NonStop.
#
# (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project.
#
# You can find Gradle at https://github.com/gradle/gradle/.
#
############################################################################## ##############################################################################
# Attempt to set APP_HOME # Attempt to set APP_HOME
# Resolve links: $0 may be a link # Resolve links: $0 may be a link
app_path=$0 PRG="$0"
# Need this for relative symlinks.
# Need this for daisy-chained symlinks. while [ -h "$PRG" ] ; do
while ls=`ls -ld "$PRG"`
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path link=`expr "$ls" : '.*-> \(.*\)$'`
[ -h "$app_path" ] if expr "$link" : '/.*' > /dev/null; then
do PRG="$link"
ls=$( ls -ld "$app_path" ) else
link=${ls#*' -> '} PRG=`dirname "$PRG"`"/$link"
case $link in #( fi
/*) app_path=$link ;; #(
*) app_path=$APP_HOME$link ;;
esac
done done
SAVED="`pwd`"
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
APP_NAME="Gradle" APP_NAME="Gradle"
APP_BASE_NAME=${0##*/} APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value. # Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum MAX_FD="maximum"
warn () { warn () {
echo "$*" echo "$*"
} >&2 }
die () { die () {
echo echo
echo "$*" echo "$*"
echo echo
exit 1 exit 1
} >&2 }
# OS specific support (must be 'true' or 'false'). # OS specific support (must be 'true' or 'false').
cygwin=false cygwin=false
msys=false msys=false
darwin=false darwin=false
nonstop=false nonstop=false
case "$( uname )" in #( case "`uname`" in
CYGWIN* ) cygwin=true ;; #( CYGWIN* )
Darwin* ) darwin=true ;; #( cygwin=true
MSYS* | MINGW* ) msys=true ;; #( ;;
NONSTOP* ) nonstop=true ;; Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
esac esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
@ -121,9 +87,9 @@ CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
if [ -n "$JAVA_HOME" ] ; then if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables # IBM's JDK on AIX uses strange locations for the executables
JAVACMD=$JAVA_HOME/jre/sh/java JAVACMD="$JAVA_HOME/jre/sh/java"
else else
JAVACMD=$JAVA_HOME/bin/java JAVACMD="$JAVA_HOME/bin/java"
fi fi
if [ ! -x "$JAVACMD" ] ; then if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
@ -132,7 +98,7 @@ Please set the JAVA_HOME variable in your environment to match the
location of your Java installation." location of your Java installation."
fi fi
else else
JAVACMD=java JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the Please set the JAVA_HOME variable in your environment to match the
@ -140,95 +106,80 @@ location of your Java installation."
fi fi
# Increase the maximum file descriptors if we can. # Increase the maximum file descriptors if we can.
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
case $MAX_FD in #( MAX_FD_LIMIT=`ulimit -H -n`
max*) if [ $? -eq 0 ] ; then
MAX_FD=$( ulimit -H -n ) || if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
warn "Could not query maximum file descriptor limit" MAX_FD="$MAX_FD_LIMIT"
esac fi
case $MAX_FD in #( ulimit -n $MAX_FD
'' | soft) :;; #( if [ $? -ne 0 ] ; then
*) warn "Could not set maximum file descriptor limit: $MAX_FD"
ulimit -n "$MAX_FD" || fi
warn "Could not set maximum file descriptor limit to $MAX_FD" else
esac warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi fi
# Collect all arguments for the java command, stacking in reverse order: # For Darwin, add options to specify how the application appears in the dock
# * args from the command line if $darwin; then
# * the main class name GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
# * -classpath fi
# * -D...appname settings
# * --module-path (only if needed)
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
# For Cygwin or MSYS, switch paths to Windows format before running java # For Cygwin or MSYS, switch paths to Windows format before running java
if "$cygwin" || "$msys" ; then if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=$( cygpath --unix "$JAVACMD" ) JAVACMD=`cygpath --unix "$JAVACMD"`
# Now convert the arguments - kludge to limit ourselves to /bin/sh # We build the pattern for arguments to be converted via cygpath
for arg do ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
if SEP=""
case $arg in #( for dir in $ROOTDIRSRAW ; do
-*) false ;; # don't mess with options #( ROOTDIRS="$ROOTDIRS$SEP$dir"
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath SEP="|"
[ -e "$t" ] ;; #(
*) false ;;
esac
then
arg=$( cygpath --path --ignore --mixed "$arg" )
fi
# Roll the args list around exactly as many times as the number of
# args, so each arg winds up back in the position where it started, but
# possibly modified.
#
# NB: a `for` loop captures its iteration list before it begins, so
# changing the positional parameters here affects neither the number of
# iterations, nor the values presented in `arg`.
shift # remove old arg
set -- "$@" "$arg" # push replacement arg
done done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=`expr $i + 1`
done
case $i in
0) set -- ;;
1) set -- "$args0" ;;
2) set -- "$args0" "$args1" ;;
3) set -- "$args0" "$args1" "$args2" ;;
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi fi
# Collect all arguments for the java command; # Escape application args
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of save () {
# shell script including quotes and variable substitutions, so put them in for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
# double quotes to make sure that they get re-expanded; and echo " "
# * put everything else in single quotes, so that it's not re-expanded. }
APP_ARGS=`save "$@"`
set -- \ # Collect all arguments for the java command, following the shell quoting and substitution rules
"-Dorg.gradle.appname=$APP_BASE_NAME" \ eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
-classpath "$CLASSPATH" \
org.gradle.wrapper.GradleWrapperMain \
"$@"
# Use "xargs" to parse quoted args.
#
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
#
# In Bash we could simply go:
#
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
# set -- "${ARGS[@]}" "$@"
#
# but POSIX shell has neither arrays nor command substitution, so instead we
# post-process each arg (as a line of input to sed) to backslash-escape any
# character that might be a shell metacharacter, then use eval to reverse
# that process (while maintaining the separation between arguments), and wrap
# the whole thing up as a single "set" statement.
#
# This will of course break if any of these variables contains a newline or
# an unmatched quote.
#
eval "set -- $(
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
xargs -n1 |
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
tr '\n' ' '
)" '"$@"'
exec "$JAVACMD" "$@" exec "$JAVACMD" "$@"

21
gradlew.bat vendored
View File

@ -40,7 +40,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1 %JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto execute if "%ERRORLEVEL%" == "0" goto init
echo. echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
@ -54,7 +54,7 @@ goto fail
set JAVA_HOME=%JAVA_HOME:"=% set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute if exist "%JAVA_EXE%" goto init
echo. echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
@ -64,6 +64,21 @@ echo location of your Java installation.
goto fail goto fail
:init
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
:execute :execute
@rem Setup the command line @rem Setup the command line
@ -71,7 +86,7 @@ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle @rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end :end
@rem End local scope for the variables with windows NT shell @rem End local scope for the variables with windows NT shell

View File

@ -1,13 +1,12 @@
plugins { plugins {
id 'org.springframework.boot' version '3.0.0-SNAPSHOT' id 'org.springframework.boot' version '2.5.0'
id 'io.spring.dependency-management' version '1.0.11.RELEASE' id 'io.spring.dependency-management' version '1.0.10.RELEASE'
id "nebula.integtest" version "8.2.0" id "nebula.integtest" version "7.0.9"
id 'java' id 'java'
} }
repositories { repositories {
mavenCentral() jcenter()
maven { url "https://repo.spring.io/milestone" }
maven { url "https://repo.spring.io/snapshot" } maven { url "https://repo.spring.io/snapshot" }
} }
@ -22,5 +21,4 @@ dependencies {
tasks.withType(Test).configureEach { tasks.withType(Test).configureEach {
useJUnitPlatform() useJUnitPlatform()
outputs.upToDateWhen { false }
} }

View File

@ -1,2 +1,2 @@
version=6.0.0-SNAPSHOT version=5.5.0
spring-security.version=6.0.0-SNAPSHOT spring-security.version=5.5.0

View File

@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-6.9-bin.zip
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists

View File

@ -20,8 +20,8 @@ import org.junit.jupiter.api.Test;
import reactor.core.publisher.Mono; import reactor.core.publisher.Mono;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.rsocket.context.LocalRSocketServerPort;
import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.rsocket.server.LocalRSocketServerPort;
import org.springframework.messaging.rsocket.RSocketRequester; import org.springframework.messaging.rsocket.RSocketRequester;
import org.springframework.security.rsocket.metadata.SimpleAuthenticationEncoder; import org.springframework.security.rsocket.metadata.SimpleAuthenticationEncoder;
import org.springframework.security.rsocket.metadata.UsernamePasswordMetadata; import org.springframework.security.rsocket.metadata.UsernamePasswordMetadata;

View File

@ -1,13 +1,12 @@
plugins { plugins {
id 'org.springframework.boot' version '3.0.0-SNAPSHOT' id 'org.springframework.boot' version '2.5.0'
id 'io.spring.dependency-management' version '1.0.11.RELEASE' id 'io.spring.dependency-management' version '1.0.10.RELEASE'
id "nebula.integtest" version "8.2.0" id "nebula.integtest" version "7.0.9"
id 'java' id 'java'
} }
repositories { repositories {
mavenCentral() jcenter()
maven { url "https://repo.spring.io/milestone" }
maven { url "https://repo.spring.io/snapshot" } maven { url "https://repo.spring.io/snapshot" }
} }
@ -22,5 +21,4 @@ dependencies {
tasks.withType(Test).configureEach { tasks.withType(Test).configureEach {
useJUnitPlatform() useJUnitPlatform()
outputs.upToDateWhen { false }
} }

View File

@ -1,2 +1,2 @@
version=6.0.0-SNAPSHOT version=5.5.0
spring-security.version=6.0.0-SNAPSHOT spring-security.version=5.5.0

View File

@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-6.9-bin.zip
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists

View File

@ -28,7 +28,7 @@ import org.springframework.test.web.reactive.server.WebTestClient;
* @since 5.0 * @since 5.0
*/ */
@SpringBootTest @SpringBootTest
@AutoConfigureWebTestClient(timeout = "36000") @AutoConfigureWebTestClient
public class HelloTests { public class HelloTests {
@Autowired @Autowired

View File

@ -1,13 +1,12 @@
plugins { plugins {
id 'org.springframework.boot' version '3.0.0-SNAPSHOT' id 'org.springframework.boot' version '2.5.0'
id 'io.spring.dependency-management' version '1.0.11.RELEASE' id 'io.spring.dependency-management' version '1.0.10.RELEASE'
id "nebula.integtest" version "8.2.0" id "nebula.integtest" version "7.0.9"
id 'java' id 'java'
} }
repositories { repositories {
mavenCentral() jcenter()
maven { url "https://repo.spring.io/milestone" }
maven { url "https://repo.spring.io/snapshot" } maven { url "https://repo.spring.io/snapshot" }
} }
@ -20,5 +19,4 @@ dependencies {
tasks.withType(Test).configureEach { tasks.withType(Test).configureEach {
useJUnitPlatform() useJUnitPlatform()
outputs.upToDateWhen { false }
} }

View File

@ -1,2 +1,2 @@
version=6.0.0-SNAPSHOT version=5.5.0
spring-security.version=6.0.0-SNAPSHOT spring-security.version=5.5.0

View File

@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-6.9-bin.zip
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists

View File

@ -27,7 +27,7 @@ import org.springframework.test.web.reactive.server.WebTestClient;
* @since 5.0 * @since 5.0
*/ */
@SpringBootTest @SpringBootTest
@AutoConfigureWebTestClient(timeout = "36000") @AutoConfigureWebTestClient
public class HelloTests { public class HelloTests {
@Autowired @Autowired

View File

@ -1,13 +1,12 @@
plugins { plugins {
id 'org.springframework.boot' version '2.6.4' id 'org.springframework.boot' version '2.5.0'
id 'io.spring.dependency-management' version '1.0.11.RELEASE' id 'io.spring.dependency-management' version '1.0.10.RELEASE'
id "nebula.integtest" version "8.2.0" id "nebula.integtest" version "7.0.9"
id 'java' id 'java'
} }
repositories { repositories {
mavenCentral() jcenter()
maven { url "https://repo.spring.io/milestone" }
maven { url "https://repo.spring.io/snapshot" } maven { url "https://repo.spring.io/snapshot" }
} }
@ -26,5 +25,4 @@ dependencies {
tasks.withType(Test).configureEach { tasks.withType(Test).configureEach {
useJUnitPlatform() useJUnitPlatform()
outputs.upToDateWhen { false }
} }

View File

@ -1,2 +1,2 @@
version=5.7.0-SNAPSHOT version=5.5.0
spring-security.version=5.7.0-SNAPSHOT spring-security.version=5.5.0

View File

@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-6.9-bin.zip
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists

View File

@ -70,10 +70,8 @@ public class LoginPage {
private WebDriver driver; private WebDriver driver;
@FindBy(id = "username")
private WebElement username; private WebElement username;
@FindBy(id = "password")
private WebElement password; private WebElement password;
@FindBy(css = "button[type=submit]") @FindBy(css = "button[type=submit]")

View File

@ -53,7 +53,7 @@ public class WebfluxFormSecurityConfiguration {
SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) { SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
// @formatter:off // @formatter:off
http http
.authorizeExchange((authorize) -> authorize .authorizeExchange((exchanges) -> exchanges
.pathMatchers("/login").permitAll() .pathMatchers("/login").permitAll()
.anyExchange().authenticated() .anyExchange().authenticated()
) )

View File

@ -1,13 +1,12 @@
plugins { plugins {
id 'org.springframework.boot' version '3.0.0-SNAPSHOT' id 'org.springframework.boot' version '2.5.0'
id 'io.spring.dependency-management' version '1.0.11.RELEASE' id 'io.spring.dependency-management' version '1.0.10.RELEASE'
id "nebula.integtest" version "8.2.0" id "nebula.integtest" version "7.0.9"
id 'java' id 'java'
} }
repositories { repositories {
mavenCentral() jcenter()
maven { url "https://repo.spring.io/milestone" }
maven { url "https://repo.spring.io/snapshot" } maven { url "https://repo.spring.io/snapshot" }
} }
@ -22,5 +21,4 @@ dependencies {
tasks.withType(Test).configureEach { tasks.withType(Test).configureEach {
useJUnitPlatform() useJUnitPlatform()
outputs.upToDateWhen { false }
} }

View File

@ -1,2 +1,2 @@
version=6.0.0-SNAPSHOT version=5.5.0
spring-security.version=6.0.0-SNAPSHOT spring-security.version=5.5.0

View File

@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-6.9-bin.zip
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists

View File

@ -31,7 +31,7 @@ import org.junit.jupiter.api.Test;
import reactor.netty.http.client.HttpClient; import reactor.netty.http.client.HttpClient;
import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.boot.web.server.LocalServerPort;
import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.ClassPathResource;
import org.springframework.http.client.reactive.ClientHttpConnector; import org.springframework.http.client.reactive.ClientHttpConnector;
import org.springframework.http.client.reactive.ReactorClientHttpConnector; import org.springframework.http.client.reactive.ReactorClientHttpConnector;

View File

@ -53,7 +53,7 @@ public class WebfluxX509Application {
// @formatter:off // @formatter:off
http http
.x509(withDefaults()) .x509(withDefaults())
.authorizeExchange((authorize) -> authorize .authorizeExchange((exchanges) -> exchanges
.anyExchange().authenticated() .anyExchange().authenticated()
); );
// @formatter:on // @formatter:on

View File

@ -1,13 +1,12 @@
plugins { plugins {
id 'org.springframework.boot' version '3.0.0-SNAPSHOT' id 'org.springframework.boot' version '2.5.0'
id 'io.spring.dependency-management' version '1.0.11.RELEASE' id 'io.spring.dependency-management' version '1.0.10.RELEASE'
id "nebula.integtest" version "8.2.0" id "nebula.integtest" version "7.0.9"
id 'java' id 'java'
} }
repositories { repositories {
mavenCentral() jcenter()
maven { url "https://repo.spring.io/milestone" }
maven { url "https://repo.spring.io/snapshot" } maven { url "https://repo.spring.io/snapshot" }
} }
@ -24,5 +23,4 @@ dependencies {
tasks.withType(Test).configureEach { tasks.withType(Test).configureEach {
useJUnitPlatform() useJUnitPlatform()
outputs.upToDateWhen { false }
} }

View File

@ -1,2 +1,2 @@
version=6.0.0-SNAPSHOT version=5.5.0
spring-security.version=6.0.0-SNAPSHOT spring-security.version=5.5.0

View File

@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-6.9-bin.zip
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists

View File

@ -24,7 +24,7 @@ import org.openqa.selenium.WebDriver;
import org.openqa.selenium.htmlunit.HtmlUnitDriver; import org.openqa.selenium.htmlunit.HtmlUnitDriver;
import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.boot.web.server.LocalServerPort;
/** /**
* Integration tests. * Integration tests.

View File

@ -51,10 +51,8 @@ public class LoginPage {
private WebDriver webDriver; private WebDriver webDriver;
@FindBy(id = "username")
private WebElement username; private WebElement username;
@FindBy(id = "password")
private WebElement password; private WebElement password;
@FindBy(css = "button[type=submit]") @FindBy(css = "button[type=submit]")

View File

@ -17,7 +17,6 @@
package example; package example;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity; import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity;
import org.springframework.security.config.web.server.ServerHttpSecurity; import org.springframework.security.config.web.server.ServerHttpSecurity;
import org.springframework.security.core.userdetails.MapReactiveUserDetailsService; import org.springframework.security.core.userdetails.MapReactiveUserDetailsService;
@ -33,7 +32,6 @@ import static org.springframework.security.config.Customizer.withDefaults;
* @author Rob Winch * @author Rob Winch
* @since 5.0 * @since 5.0
*/ */
@Configuration
@EnableWebFluxSecurity @EnableWebFluxSecurity
public class SecurityConfiguration { public class SecurityConfiguration {
@ -41,7 +39,7 @@ public class SecurityConfiguration {
SecurityWebFilterChain springWebFilterChain(ServerHttpSecurity http) { SecurityWebFilterChain springWebFilterChain(ServerHttpSecurity http) {
// @formatter:off // @formatter:off
http http
.authorizeExchange((authorize) -> authorize .authorizeExchange((exchanges) -> exchanges
.anyExchange().authenticated() .anyExchange().authenticated()
) )
.formLogin(withDefaults()); .formLogin(withDefaults());

View File

@ -28,7 +28,7 @@ import org.springframework.test.web.reactive.server.WebTestClient;
* @since 5.0 * @since 5.0
*/ */
@SpringBootTest @SpringBootTest
@AutoConfigureWebTestClient(timeout = "36000") @AutoConfigureWebTestClient
public class HelloSecurityTests { public class HelloSecurityTests {
@Autowired @Autowired

View File

@ -1,13 +1,12 @@
plugins { plugins {
id 'org.springframework.boot' version '3.0.0-SNAPSHOT' id 'org.springframework.boot' version '2.5.0'
id 'io.spring.dependency-management' version '1.0.11.RELEASE' id 'io.spring.dependency-management' version '1.0.10.RELEASE'
id "nebula.integtest" version "8.2.0" id "nebula.integtest" version "7.0.9"
id 'java' id 'java'
} }
repositories { repositories {
mavenCentral() jcenter()
maven { url "https://repo.spring.io/milestone" }
maven { url "https://repo.spring.io/snapshot" } maven { url "https://repo.spring.io/snapshot" }
} }
@ -22,5 +21,4 @@ dependencies {
tasks.withType(Test).configureEach { tasks.withType(Test).configureEach {
useJUnitPlatform() useJUnitPlatform()
outputs.upToDateWhen { false }
} }

View File

@ -1,2 +1,2 @@
version=6.0.0-SNAPSHOT version=5.5.0
spring-security.version=6.0.0-SNAPSHOT spring-security.version=5.5.0

View File

@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-6.9-bin.zip
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists

View File

@ -28,7 +28,7 @@ import org.springframework.test.web.reactive.server.WebTestClient;
* @since 5.0 * @since 5.0
*/ */
@SpringBootTest @SpringBootTest
@AutoConfigureWebTestClient(timeout = "36000") @AutoConfigureWebTestClient
public class HelloSecurityTests { public class HelloSecurityTests {
@Autowired @Autowired

View File

@ -1,13 +1,12 @@
plugins { plugins {
id 'org.springframework.boot' version '3.0.0-SNAPSHOT' id 'org.springframework.boot' version '2.5.0'
id 'io.spring.dependency-management' version '1.0.11.RELEASE' id 'io.spring.dependency-management' version '1.0.10.RELEASE'
id "nebula.integtest" version "8.2.0" id "nebula.integtest" version "7.0.9"
id 'java' id 'java'
} }
repositories { repositories {
mavenCentral() jcenter()
maven { url "https://repo.spring.io/milestone" }
maven { url "https://repo.spring.io/snapshot" } maven { url "https://repo.spring.io/snapshot" }
} }
@ -20,5 +19,4 @@ dependencies {
tasks.withType(Test).configureEach { tasks.withType(Test).configureEach {
useJUnitPlatform() useJUnitPlatform()
outputs.upToDateWhen { false }
} }

View File

@ -1,2 +1,2 @@
version=6.0.0-SNAPSHOT version=5.5.0
spring-security.version=6.0.0-SNAPSHOT spring-security.version=5.5.0

View File

@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-6.9-bin.zip
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists

View File

@ -27,7 +27,7 @@ import org.springframework.test.web.reactive.server.WebTestClient;
* @since 5.0 * @since 5.0
*/ */
@SpringBootTest @SpringBootTest
@AutoConfigureWebTestClient(timeout = "36000") @AutoConfigureWebTestClient
public class HelloTests { public class HelloTests {
@Autowired @Autowired

View File

@ -1,13 +1,12 @@
plugins { plugins {
id 'org.springframework.boot' version '3.0.0-SNAPSHOT' id 'org.springframework.boot' version '2.5.0'
id 'io.spring.dependency-management' version '1.0.11.RELEASE' id 'io.spring.dependency-management' version '1.0.10.RELEASE'
id "nebula.integtest" version "8.2.0" id "nebula.integtest" version "7.0.9"
id 'java' id 'java'
} }
repositories { repositories {
mavenCentral() jcenter()
maven { url "https://repo.spring.io/milestone" }
maven { url "https://repo.spring.io/snapshot" } maven { url "https://repo.spring.io/snapshot" }
} }
@ -22,5 +21,4 @@ dependencies {
tasks.withType(Test).configureEach { tasks.withType(Test).configureEach {
useJUnitPlatform() useJUnitPlatform()
outputs.upToDateWhen { false }
} }

View File

@ -1,2 +1,2 @@
version=6.0.0-SNAPSHOT version=5.5.0
spring-security.version=6.0.0-SNAPSHOT spring-security.version=5.5.0

View File

@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-6.5.1-bin.zip
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists

View File

@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-6.9-bin.zip
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists

View File

@ -45,7 +45,7 @@ public class SecurityConfiguration {
http http
// Demonstrate that method security works // Demonstrate that method security works
// Best practice to use both for defense in depth // Best practice to use both for defense in depth
.authorizeExchange((authorize) -> authorize .authorizeExchange((exchanges) -> exchanges
.anyExchange().permitAll() .anyExchange().permitAll()
) )
.httpBasic(withDefaults()); .httpBasic(withDefaults());

View File

@ -28,7 +28,7 @@ import org.springframework.test.web.reactive.server.WebTestClient;
* @since 5.0 * @since 5.0
*/ */
@SpringBootTest @SpringBootTest
@AutoConfigureWebTestClient(timeout = "36000") @AutoConfigureWebTestClient
public class HelloMethodApplicationTests { public class HelloMethodApplicationTests {
@Autowired @Autowired

View File

@ -1,105 +1,18 @@
NOTE: Spring Security Reactive OAuth only supports authentication using a user info endpoint.
Support for JWT validation will be added in https://github.com/spring-projects/spring-security/issues/5330[gh-5330].
= OAuth 2.0 Login Sample = OAuth 2.0 Login Sample
This guide provides instructions on setting up the sample application with OAuth 2.0 Login using an OAuth 2.0 Provider or OpenID Connect 1.0 Provider. This guide provides instructions on setting up the sample application with OAuth 2.0 Login using an OAuth 2.0 Provider or OpenID Connect 1.0 Provider.
The sample application uses Spring Boot 2.5 and the `spring-security-oauth2-client` module which is new in Spring Security 5.0. The sample application uses Spring Boot 2.0.0.M6 and the `spring-security-oauth2-client` module which is new in Spring Security 5.0.
The following sections provide detailed steps for setting up OAuth 2.0 Login for these Providers: The following sections provide detailed steps for setting up OAuth 2.0 Login for these Providers:
* <<spring-login, Spring Authorization Server>>
* <<google-login, Google>> * <<google-login, Google>>
* <<github-login, GitHub>> * <<github-login, GitHub>>
* <<facebook-login, Facebook>> * <<facebook-login, Facebook>>
* <<okta-login, Okta>> * <<okta-login, Okta>>
[[spring-login]]
== Login with Spring Authorization Server
This section shows how to configure the sample application using Spring Authorization Server as the Authentication Provider and covers the following topics:
* <<spring-initial-setup,Initial setup>>
* <<spring-redirect-uri,Setting the redirect URI>>
* <<spring-application-config,Configure application.yml>>
* <<spring-boot-application,Boot up the application>>
[[spring-initial-setup]]
=== Initial setup
The sample application is pre-configured to work out of the box with Spring Authorization Server, which runs locally on port `9000`. See the https://github.com/spring-projects/spring-security-samples/tree/main/servlet/spring-boot/java/oauth2/authorization-server[authorization-server sample] to run the authorization server used in this section.
NOTE: https://github.com/spring-projects-external/spring-authorization-server[Spring Authorization Server] supports the https://openid.net/connect/[OpenID Connect 1.0] specification.
[[spring-redirect-uri]]
=== Setting the redirect URI
The redirect URI is the path in the application that the end-user's user-agent is redirected back to after they have authenticated with Spring Authorization Server
and have granted access to the OAuth Client on the Consent page.
The default redirect URI is `http://127.0.0.1:8080/login/oauth2/code/login-client`. No special setup is required to use the sample locally.
TIP: The default redirect URI template is `{baseUrl}/login/oauth2/code/{registrationId}`.
The *_registrationId_* is a unique identifier for the `ClientRegistration`.
IMPORTANT: If the application is running behind a proxy server, it is recommended to check https://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/#appendix-proxy-server[Proxy Server Configuration] to ensure the application is correctly configured.
Also, see the supported https://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/#oauth2Client-auth-code-redirect-uri[`URI` template variables] for `redirect-uri`.
[[spring-application-config]]
=== Configure application.yml
If you wish to customize the OAuth Client to work with a non-local deployment of Spring Authorization Server, you need to configure the application to use the OAuth Client for the _authentication flow_. To do so:
. Go to `application.yml` and set the following configuration:
+
[source,yaml]
----
spring:
security:
oauth2:
client:
registration: <1>
login-client: <2>
provider: spring <3>
client-id: login-client
client-secret: openid-connect
client-authentication-method: client_secret_basic
authorization-grant-type: authorization_code
redirect-uri: http://127.0.0.1:8080/login/oauth2/code/login-client
scope: openid,profile <4>
client-name: Spring
provider:<5>
spring:
authorization-uri: http://localhost:9000/oauth2/authorize
token-uri: http://localhost:9000/oauth2/token
jwk-set-uri: http://localhost:9000/oauth2/jwks
issuer-uri: http://localhost:9000
----
+
.OAuth Client properties
====
<1> `spring.security.oauth2.client.registration` is the base property prefix for OAuth Client properties.
<2> Following the base property prefix is the ID for the `ClientRegistration`, such as login-client.
<3> The `provider` property specifies which provider configuration is used by this `ClientRegistration`.
<4> The `openid` scope is required by Spring Authorization Server to perform https://openid.net/specs/openid-connect-core-1_0.html#CodeFlowAuth[authentication using OpenID Connect 1.0].
<5> `spring.security.oauth2.client.provider` is the base property prefix for OAuth Provider properties.
====
. Replace the values in the `client-id` and `client-secret` property with the OAuth 2.0 credentials for your Spring Authorization Server. As well, replace `http://localhost:9000` in `authorization-uri`, `token-uri` and `jwk-set-uri` with the actual domain of your authorization server.
[[spring-boot-application]]
=== Boot up the application
Launch the Spring Boot 2.0 sample and go to `http://127.0.0.1:8080`.
You are then redirected to the default _auto-generated_ login page, which displays a link for Spring.
Click on the Spring link, and you are then redirected to the Spring Authorization Server for authentication.
After authenticating with your credentials (`user` and `password` by default), the next page presented to you is the Consent screen.
The Consent screen asks you to either allow or deny access to the OAuth Client. Select "profile" and
click *Submit Consent* to authorize the OAuth Client to access your basic profile information.
At this point, the OAuth Client retrieves your basic profile information via the https://openid.net/specs/openid-connect-core-1_0.html#CodeIDToken[ID Token] and establishes an authenticated session.
NOTE: Spring Authorization Server does not currently support the https://openid.net/specs/openid-connect-core-1_0.html#UserInfo[UserInfo Endpoint], which is optional in OpenID Connect 1.0. See https://github.com/spring-projects-experimental/spring-authorization-server/issues/176[#176] fo more information.
[[google-login]] [[google-login]]
== Login with Google == Login with Google
@ -128,7 +41,7 @@ After completing the "Obtain OAuth 2.0 credentials" instructions, you should hav
The redirect URI is the path in the application that the end-user's user-agent is redirected back to after they have authenticated with Google The redirect URI is the path in the application that the end-user's user-agent is redirected back to after they have authenticated with Google
and have granted access to the OAuth Client _(created in the previous step)_ on the Consent page. and have granted access to the OAuth Client _(created in the previous step)_ on the Consent page.
In the "Set a redirect URI" sub-section, ensure that the *Authorized redirect URIs* field is set to `http://127.0.0.1:8080/login/oauth2/code/google`. In the "Set a redirect URI" sub-section, ensure that the *Authorized redirect URIs* field is set to `http://localhost:8080/login/oauth2/code/google`.
TIP: The default redirect URI template is `{baseUrl}/login/oauth2/code/{registrationId}`. TIP: The default redirect URI template is `{baseUrl}/login/oauth2/code/{registrationId}`.
The *_registrationId_* is a unique identifier for the `ClientRegistration`. The *_registrationId_* is a unique identifier for the `ClientRegistration`.
@ -166,7 +79,7 @@ spring:
[[google-boot-application]] [[google-boot-application]]
=== Boot up the application === Boot up the application
Launch the Spring Boot 2.0 sample and go to `http://127.0.0.1:8080`. Launch the Spring Boot 2.0 sample and go to `http://localhost:8080`.
You are then redirected to the default _auto-generated_ login page, which displays a link for Google. You are then redirected to the default _auto-generated_ login page, which displays a link for Google.
Click on the Google link, and you are then redirected to Google for authentication. Click on the Google link, and you are then redirected to Google for authentication.
@ -192,7 +105,7 @@ This section shows how to configure the sample application using GitHub as the A
To use GitHub's OAuth 2.0 authentication system for login, you must https://github.com/settings/applications/new[Register a new OAuth application]. To use GitHub's OAuth 2.0 authentication system for login, you must https://github.com/settings/applications/new[Register a new OAuth application].
When registering the OAuth application, ensure the *Authorization callback URL* is set to `http://127.0.0.1:8080/login/oauth2/code/github`. When registering the OAuth application, ensure the *Authorization callback URL* is set to `http://localhost:8080/login/oauth2/code/github`.
The Authorization callback URL (redirect URI) is the path in the application that the end-user's user-agent is redirected back to after they have authenticated with GitHub The Authorization callback URL (redirect URI) is the path in the application that the end-user's user-agent is redirected back to after they have authenticated with GitHub
and have granted access to the OAuth application on the _Authorize application_ page. and have granted access to the OAuth application on the _Authorize application_ page.
@ -233,7 +146,7 @@ spring:
[[github-boot-application]] [[github-boot-application]]
=== Boot up the application === Boot up the application
Launch the Spring Boot 2.0 sample and go to `http://127.0.0.1:8080`. Launch the Spring Boot 2.0 sample and go to `http://localhost:8080`.
You are then redirected to the default _auto-generated_ login page, which displays a link for GitHub. You are then redirected to the default _auto-generated_ login page, which displays a link for GitHub.
Click on the GitHub link, and you are then redirected to GitHub for authentication. Click on the GitHub link, and you are then redirected to GitHub for authentication.
@ -270,7 +183,7 @@ NOTE: The selection for the _Category_ field is not relevant but it's a required
The next page presented is "Product Setup". Click the "Get Started" button for the *Facebook Login* product. The next page presented is "Product Setup". Click the "Get Started" button for the *Facebook Login* product.
In the left sidebar, under _Products -> Facebook Login_, select _Settings_. In the left sidebar, under _Products -> Facebook Login_, select _Settings_.
For the field *Valid OAuth redirect URIs*, enter `http://127.0.0.1:8080/login/oauth2/code/facebook` then click _Save Changes_. For the field *Valid OAuth redirect URIs*, enter `http://localhost:8080/login/oauth2/code/facebook` then click _Save Changes_.
The OAuth redirect URI is the path in the application that the end-user's user-agent is redirected back to after they have authenticated with Facebook The OAuth redirect URI is the path in the application that the end-user's user-agent is redirected back to after they have authenticated with Facebook
and have granted access to the application on the _Authorize application_ page. and have granted access to the application on the _Authorize application_ page.
@ -311,7 +224,7 @@ spring:
[[facebook-boot-application]] [[facebook-boot-application]]
=== Boot up the application === Boot up the application
Launch the Spring Boot 2.0 sample and go to `http://127.0.0.1:8080`. Launch the Spring Boot 2.0 sample and go to `http://localhost:8080`.
You are then redirected to the default _auto-generated_ login page, which displays a link for Facebook. You are then redirected to the default _auto-generated_ login page, which displays a link for Facebook.
Click on the Facebook link, and you are then redirected to Facebook for authentication. Click on the Facebook link, and you are then redirected to Facebook for authentication.
@ -346,7 +259,7 @@ From the "Add Application" page, select the "Create New App" button and enter th
Select the _Create_ button. Select the _Create_ button.
On the "General Settings" page, enter the Application Name (for example, "Spring Security Okta Login") and then select the _Next_ button. On the "General Settings" page, enter the Application Name (for example, "Spring Security Okta Login") and then select the _Next_ button.
On the "Configure OpenID Connect" page, enter `http://127.0.0.1:8080/login/oauth2/code/okta` for the field *Redirect URIs* and then select _Finish_. On the "Configure OpenID Connect" page, enter `http://localhost:8080/login/oauth2/code/okta` for the field *Redirect URIs* and then select _Finish_.
The redirect URI is the path in the application that the end-user's user-agent is redirected back to after they have authenticated with Okta The redirect URI is the path in the application that the end-user's user-agent is redirected back to after they have authenticated with Okta
and have granted access to the application on the _Authorize application_ page. and have granted access to the application on the _Authorize application_ page.
@ -402,7 +315,7 @@ As well, replace `https://your-subdomain.oktapreview.com` in `authorization-uri`
[[okta-boot-application]] [[okta-boot-application]]
=== Boot up the application === Boot up the application
Launch the Spring Boot 2.0 sample and go to `http://127.0.0.1:8080`. Launch the Spring Boot 2.0 sample and go to `http://localhost:8080`.
You are then redirected to the default _auto-generated_ login page, which displays a link for Okta. You are then redirected to the default _auto-generated_ login page, which displays a link for Okta.
Click on the Okta link, and you are then redirected to Okta for authentication. Click on the Okta link, and you are then redirected to Okta for authentication.

View File

@ -1,13 +1,12 @@
plugins { plugins {
id 'org.springframework.boot' version '3.0.0-SNAPSHOT' id 'org.springframework.boot' version '2.5.0'
id 'io.spring.dependency-management' version '1.0.11.RELEASE' id 'io.spring.dependency-management' version '1.0.10.RELEASE'
id "nebula.integtest" version "8.2.0" id "nebula.integtest" version "7.0.9"
id 'java' id 'java'
} }
repositories { repositories {
mavenCentral() jcenter()
maven { url "https://repo.spring.io/milestone" }
maven { url "https://repo.spring.io/snapshot" } maven { url "https://repo.spring.io/snapshot" }
} }
@ -15,7 +14,7 @@ dependencies {
implementation 'org.springframework.boot:spring-boot-starter-oauth2-client' implementation 'org.springframework.boot:spring-boot-starter-oauth2-client'
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf' implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'org.springframework.boot:spring-boot-starter-webflux' implementation 'org.springframework.boot:spring-boot-starter-webflux'
implementation 'org.thymeleaf.extras:thymeleaf-extras-springsecurity6' implementation 'org.thymeleaf.extras:thymeleaf-extras-springsecurity5'
testImplementation 'org.springframework.boot:spring-boot-starter-test' testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'org.springframework.security:spring-security-test' testImplementation 'org.springframework.security:spring-security-test'
@ -25,5 +24,4 @@ dependencies {
tasks.withType(Test).configureEach { tasks.withType(Test).configureEach {
useJUnitPlatform() useJUnitPlatform()
outputs.upToDateWhen { false }
} }

View File

@ -1,2 +1,2 @@
version=6.0.0-SNAPSHOT version=5.5.0
spring-security.version=6.0.0-SNAPSHOT spring-security.version=5.5.0

View File

@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-6.9-bin.zip
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists

View File

@ -36,7 +36,7 @@ import static org.springframework.security.test.web.reactive.server.SecurityMock
* @author Rob Winch * @author Rob Winch
*/ */
@SpringBootTest @SpringBootTest
@AutoConfigureWebTestClient(timeout = "36000") @AutoConfigureWebTestClient
public class OAuth2LoginApplicationTests { public class OAuth2LoginApplicationTests {
@Autowired @Autowired

View File

@ -1,65 +0,0 @@
/*
* Copyright 2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package example;
import reactor.core.publisher.Mono;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebFilter;
import org.springframework.web.server.WebFilterChain;
import org.springframework.web.util.UriComponents;
import org.springframework.web.util.UriComponentsBuilder;
/**
* This filter ensures that the loopback IP <code>127.0.0.1</code> is used to access the
* application so that the sample works correctly, due to the fact that redirect URIs with
* "localhost" are rejected by the Spring Authorization Server, because the OAuth 2.1
* draft specification states:
*
* <pre>
* While redirect URIs using localhost (i.e.,
* "http://localhost:{port}/{path}") function similarly to loopback IP
* redirects described in Section 10.3.3, the use of "localhost" is NOT
* RECOMMENDED.
* </pre>
*
* @author Steve Riesenberg
* @see <a href=
* "https://tools.ietf.org/html/draft-ietf-oauth-v2-1-01#section-9.7.1">Loopback Redirect
* Considerations in Native Apps</a>
*/
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class LoopbackIpRedirectWebFilter implements WebFilter {
@Override
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
String host = exchange.getRequest().getURI().getHost();
if (host != null && host.equals("localhost")) {
UriComponents uri = UriComponentsBuilder.fromHttpRequest(exchange.getRequest()).host("127.0.0.1").build();
exchange.getResponse().setStatusCode(HttpStatus.PERMANENT_REDIRECT);
exchange.getResponse().getHeaders().setLocation(uri.toUri());
return Mono.empty();
}
return chain.filter(exchange);
}
}

View File

@ -15,15 +15,6 @@ spring:
oauth2: oauth2:
client: client:
registration: registration:
login-client:
provider: spring
client-id: login-client
client-secret: openid-connect
client-authentication-method: client_secret_basic
authorization-grant-type: authorization_code
redirect-uri: http://127.0.0.1:8080/login/oauth2/code/login-client
scope: openid,profile
client-name: Spring
google: google:
client-id: your-app-client-id client-id: your-app-client-id
client-secret: your-app-client-secret client-secret: your-app-client-secret
@ -37,10 +28,6 @@ spring:
client-id: your-app-client-id client-id: your-app-client-id
client-secret: your-app-client-secret client-secret: your-app-client-secret
provider: provider:
spring:
authorization-uri: http://localhost:9000/oauth2/authorize
token-uri: http://localhost:9000/oauth2/token
jwk-set-uri: http://localhost:9000/oauth2/jwks
okta: okta:
authorization-uri: https://your-subdomain.oktapreview.com/oauth2/v1/authorize authorization-uri: https://your-subdomain.oktapreview.com/oauth2/v1/authorize
token-uri: https://your-subdomain.oktapreview.com/oauth2/v1/token token-uri: https://your-subdomain.oktapreview.com/oauth2/v1/token

View File

@ -1,7 +1,7 @@
= OAuth 2.0 Resource Server Sample = OAuth 2.0 Resource Server Sample
This sample demonstrates integrating Resource Server with the Spring Authorization Server, though it can be modified to integrate This sample demonstrates integrating Resource Server with a mock Authorization Server, though it can be modified to integrate
with a mock server or your favorite Authorization Server. with your favorite Authorization Server.
With it, you can run the integration tests or run the application as a stand-alone service to explore how you can With it, you can run the integration tests or run the application as a stand-alone service to explore how you can
secure your own service with OAuth 2.0 Bearer Tokens using Spring Security. secure your own service with OAuth 2.0 Bearer Tokens using Spring Security.
@ -18,7 +18,7 @@ Or import the project into your IDE and run `ServerOAuth2ResourceServerApplicati
=== What is it doing? === What is it doing?
By default, the tests are pointing at a mock Authorization Server instance via the `test` profile. By default, the tests are pointing at a mock Authorization Server instance.
The tests are configured with a set of hard-coded tokens originally obtained from the mock Authorization Server, The tests are configured with a set of hard-coded tokens originally obtained from the mock Authorization Server,
and each makes a query to the Resource Server with their corresponding token. and each makes a query to the Resource Server with their corresponding token.
@ -31,17 +31,7 @@ Hello, subject!
where "subject" is the value of the `sub` field in the JWT returned by the Authorization Server. where "subject" is the value of the `sub` field in the JWT returned by the Authorization Server.
== 2. Running the app with Spring Authorization Server == 2. Running the app
Before running this application with the default configuration, you will need to start up an Authorization Server, such as the https://github.com/spring-projects/spring-security-samples/tree/main/servlet/spring-boot/java/oauth2/authorization-server[authorization-server sample] in this project which is pre-configured to work with this Resource Server sample out of the box.
To run the Authorization Server as a stand-alone application, navigate to the `servlet/spring-boot/java/oauth2/authorization-server` and do:
```bash
./gradlew bootRun
```
Or import the project into your IDE and run `OAuth2AuthorizationServerApplication` from there. Next, you can run this Resource Server.
To run as a stand-alone application, do: To run as a stand-alone application, do:
@ -51,89 +41,6 @@ To run as a stand-alone application, do:
Or import the project into your IDE and run `ServerOAuth2ResourceServerApplication` from there. Or import the project into your IDE and run `ServerOAuth2ResourceServerApplication` from there.
Once it is up and running, you can issue the following request:
```bash
curl -X POST messaging-client:secret@localhost:9000/oauth2/token -d "grant_type=client_credentials" -d "scope=message:read"
```
This returns something like the following:
```json
{
"access_token": "eyJraWQiOiI4YWY4Zjc2Zi0zMTdkLTQxZmYtYWY5Yi1hZjg5NDg4ODM5YzciLCJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJtZXNzYWdpbmctY2xpZW50IiwiYXVkIjoibWVzc2FnaW5nLWNsaWVudCIsIm5iZiI6MTYyNzMzNDQ1MCwic2NvcGUiOlsibWVzc2FnZTpyZWFkIl0sImlzcyI6Imh0dHA6XC9cL2xvY2FsaG9zdDo5MDAwIiwiZXhwIjoxNjI3MzM0NzUwLCJpYXQiOjE2MjczMzQ0NTAsImp0aSI6IjBiYjYwZjhkLWIzNjItNDk0MC05MGRmLWZhZDg4N2Q1Yzg1ZSJ9.O8dI67B_feRjOn6pJi5ctPJmUJCNpV77SC4OiWqmpa5UHvf4Ud6L6EFe9LKuPIRrEWi8rMdCdMBOPKQMXvxLoI3LMUPf7Yj973uvZN0E988MsKwhGwxyaa_Wam8wFlk8aQlN8SbW3cKdeH-nKloNMdwjfspovefX521mxouaMjmyXdIFrM5WZ15GZK69NIniACSatE-pc9TAjKYBDbC65jVt_zHEvDQbEkZulF2bjrGOZC8C3IbJWnlKgkcshrY44TtrGPyCp2gIS0TSUUsG00iSBBC8E8zPU-YdfaP8gB9_FwUwK9zfy_hU2Ykf2aU3eulpGDVLn2rCwFeK86Rw1w",
"expires_in": 299,
"scope": "message:read",
"token_type": "Bearer"
}
```
Then, export the access token from the response:
```bash
export TOKEN=...
```
Then issue the following request:
```bash
curl -H "Authorization: Bearer $TOKEN" localhost:8080
```
Which will respond with the phrase:
```
Hello, messaging-client!
```
where `messaging-client` is the value of the `sub` field in the JWT returned by the Authorization Server.
Or this to make a GET request to /message:
```bash
curl -H "Authorization: Bearer $TOKEN" localhost:8080/message
```
Will respond with:
```bash
secret message
```
In order to make a POST request to /message, you can use the following request:
```bash
curl -X POST messaging-client:secret@localhost:9000/oauth2/token -d "grant_type=client_credentials" -d "scope=message:write"
```
Then, export the access token from the response:
```bash
export TOKEN=...
```
Then issue the following request:
```bash
curl -H "Authorization: Bearer $TOKEN" -d "my message" localhost:8080/message
```
Which will respond with:
```bash
Message was created. Content: my message
```
== 3. Running the app with a mock Authorization Server
To run as a stand-alone application with an embedded mock Authorization Server, do:
```bash
./gradlew bootRun --args='--spring.profiles.active=test'
```
Or import the project into your IDE and run `ServerOAuth2ResourceServerApplication` from there with the `test` profile active.
Once it is up, you can use the following token: Once it is up, you can use the following token:
```bash ```bash
@ -168,7 +75,7 @@ Will respond with:
secret message secret message
``` ```
== 4. Testing against other Authorization Servers == 2. Testing against other Authorization Servers
_In order to use this sample, your Authorization Server must support JWTs that either use the "scope" or "scp" attribute._ _In order to use this sample, your Authorization Server must support JWTs that either use the "scope" or "scp" attribute._
@ -180,7 +87,7 @@ spring:
oauth2: oauth2:
resourceserver: resourceserver:
jwt: jwt:
jwk-set-uri: http://localhost:9000/oauth2/jwks jwk-set-uri: ${mockwebserver.url}/.well-known/jwks.json
``` ```
And change the property to your Authorization Server's JWK set endpoint: And change the property to your Authorization Server's JWK set endpoint:

View File

@ -1,13 +1,12 @@
plugins { plugins {
id 'org.springframework.boot' version '3.0.0-SNAPSHOT' id 'org.springframework.boot' version '2.5.0'
id 'io.spring.dependency-management' version '1.0.11.RELEASE' id 'io.spring.dependency-management' version '1.0.10.RELEASE'
id "nebula.integtest" version "8.2.0" id "nebula.integtest" version "7.0.9"
id 'java' id 'java'
} }
repositories { repositories {
mavenCentral() jcenter()
maven { url "https://repo.spring.io/milestone" }
maven { url "https://repo.spring.io/snapshot" } maven { url "https://repo.spring.io/snapshot" }
} }
@ -22,5 +21,4 @@ dependencies {
tasks.withType(Test).configureEach { tasks.withType(Test).configureEach {
useJUnitPlatform() useJUnitPlatform()
outputs.upToDateWhen { false }
} }

View File

@ -1,2 +1,2 @@
version=6.0.0-SNAPSHOT version=5.5.0
spring-security.version=6.0.0-SNAPSHOT spring-security.version=5.5.0

View File

@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-6.9-bin.zip
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists

View File

@ -24,7 +24,6 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient; import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient;
import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.HttpHeaders; import org.springframework.http.HttpHeaders;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.web.reactive.server.WebTestClient; import org.springframework.test.web.reactive.server.WebTestClient;
import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.containsString;
@ -36,8 +35,7 @@ import static org.hamcrest.Matchers.containsString;
* @since 5.1 * @since 5.1
*/ */
@SpringBootTest @SpringBootTest
@AutoConfigureWebTestClient(timeout = "36000") @AutoConfigureWebTestClient
@ActiveProfiles("test")
public class ServerOAuth2ResourceServerApplicationITests { public class ServerOAuth2ResourceServerApplicationITests {
Consumer<HttpHeaders> noScopesToken = (http) -> http.setBearerAuth( Consumer<HttpHeaders> noScopesToken = (http) -> http.setBearerAuth(

View File

@ -17,7 +17,6 @@
package example; package example;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod; import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity; import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity;
import org.springframework.security.config.web.server.ServerHttpSecurity; import org.springframework.security.config.web.server.ServerHttpSecurity;
@ -31,7 +30,6 @@ import static org.springframework.security.config.Customizer.withDefaults;
* @author Rob Winch * @author Rob Winch
* @since 5.1 * @since 5.1
*/ */
@Configuration
@EnableWebFluxSecurity @EnableWebFluxSecurity
public class SecurityConfiguration { public class SecurityConfiguration {
@ -39,7 +37,7 @@ public class SecurityConfiguration {
SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) { SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
// @formatter:off // @formatter:off
http http
.authorizeExchange((authorize) -> authorize .authorizeExchange((exchanges) -> exchanges
.pathMatchers(HttpMethod.GET, "/message/**").hasAuthority("SCOPE_message:read") .pathMatchers(HttpMethod.GET, "/message/**").hasAuthority("SCOPE_message:read")
.pathMatchers(HttpMethod.POST, "/message/**").hasAuthority("SCOPE_message:write") .pathMatchers(HttpMethod.POST, "/message/**").hasAuthority("SCOPE_message:write")
.anyExchange().authenticated() .anyExchange().authenticated()

View File

@ -1,6 +0,0 @@
spring:
security:
oauth2:
resourceserver:
jwt:
jwk-set-uri: ${mockwebserver.url}/.well-known/jwks.json

View File

@ -3,4 +3,4 @@ spring:
oauth2: oauth2:
resourceserver: resourceserver:
jwt: jwt:
jwk-set-uri: http://localhost:9000/oauth2/jwks jwk-set-uri: ${mockwebserver.url}/.well-known/jwks.json

View File

@ -1,13 +1,12 @@
plugins { plugins {
id 'org.springframework.boot' version '3.0.0-SNAPSHOT' id 'org.springframework.boot' version '2.5.0'
id 'io.spring.dependency-management' version '1.0.11.RELEASE' id 'io.spring.dependency-management' version '1.0.10.RELEASE'
id "nebula.integtest" version "8.2.0" id "nebula.integtest" version "7.0.9"
id 'java' id 'java'
} }
repositories { repositories {
mavenCentral() jcenter()
maven { url "https://repo.spring.io/milestone" }
maven { url "https://repo.spring.io/snapshot" } maven { url "https://repo.spring.io/snapshot" }
} }
@ -15,7 +14,7 @@ dependencies {
implementation 'org.springframework.boot:spring-boot-starter-oauth2-client' implementation 'org.springframework.boot:spring-boot-starter-oauth2-client'
implementation 'org.springframework:spring-webflux' implementation 'org.springframework:spring-webflux'
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf' implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'org.thymeleaf.extras:thymeleaf-extras-springsecurity6' implementation 'org.thymeleaf.extras:thymeleaf-extras-springsecurity5'
implementation 'io.projectreactor.netty:reactor-netty' implementation 'io.projectreactor.netty:reactor-netty'
testImplementation 'org.springframework.boot:spring-boot-starter-test' testImplementation 'org.springframework.boot:spring-boot-starter-test'
@ -25,5 +24,4 @@ dependencies {
tasks.withType(Test).configureEach { tasks.withType(Test).configureEach {
useJUnitPlatform() useJUnitPlatform()
outputs.upToDateWhen { false }
} }

View File

@ -1,2 +1,2 @@
version=6.0.0-SNAPSHOT version=5.5.0
spring-security.version=6.0.0-SNAPSHOT spring-security.version=5.5.0

View File

@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-6.9-bin.zip
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists

View File

@ -16,7 +16,6 @@
package example; package example;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity; import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity;
import org.springframework.security.config.web.server.ServerHttpSecurity; import org.springframework.security.config.web.server.ServerHttpSecurity;
import org.springframework.security.core.userdetails.MapReactiveUserDetailsService; import org.springframework.security.core.userdetails.MapReactiveUserDetailsService;
@ -31,7 +30,6 @@ import static org.springframework.security.config.Customizer.withDefaults;
* *
* @author Rob Winch * @author Rob Winch
*/ */
@Configuration
@EnableWebFluxSecurity @EnableWebFluxSecurity
public class SecurityConfiguration { public class SecurityConfiguration {
@ -39,7 +37,7 @@ public class SecurityConfiguration {
SecurityWebFilterChain configure(ServerHttpSecurity http) { SecurityWebFilterChain configure(ServerHttpSecurity http) {
// @formatter:off // @formatter:off
http http
.authorizeExchange((authorize) -> authorize .authorizeExchange((exchanges) -> exchanges
.pathMatchers("/", "/public/**").permitAll() .pathMatchers("/", "/public/**").permitAll()
.anyExchange().authenticated() .anyExchange().authenticated()
) )

View File

@ -39,7 +39,7 @@ import static org.springframework.security.test.web.reactive.server.SecurityMock
@WebFluxTest @WebFluxTest
@Import({ SecurityConfiguration.class, OAuth2WebClientController.class }) @Import({ SecurityConfiguration.class, OAuth2WebClientController.class })
@AutoConfigureWebTestClient(timeout = "36000") @AutoConfigureWebTestClient
public class OAuth2WebClientControllerTests { public class OAuth2WebClientControllerTests {
private static MockWebServer web = new MockWebServer(); private static MockWebServer web = new MockWebServer();

View File

@ -27,7 +27,7 @@ import org.springframework.test.web.reactive.server.WebTestClient;
* @author Rob Winch * @author Rob Winch
*/ */
@SpringBootTest @SpringBootTest
@AutoConfigureWebTestClient(timeout = "36000") @AutoConfigureWebTestClient
public class OAuth2WebClientWebFluxApplicationTests { public class OAuth2WebClientWebFluxApplicationTests {
@Autowired @Autowired

View File

@ -39,7 +39,7 @@ import static org.springframework.security.test.web.reactive.server.SecurityMock
@WebFluxTest @WebFluxTest
@Import({ SecurityConfiguration.class, RegisteredOAuth2AuthorizedClientController.class }) @Import({ SecurityConfiguration.class, RegisteredOAuth2AuthorizedClientController.class })
@AutoConfigureWebTestClient(timeout = "36000") @AutoConfigureWebTestClient
public class RegisteredOAuth2AuthorizedClientControllerTests { public class RegisteredOAuth2AuthorizedClientControllerTests {
private static MockWebServer web = new MockWebServer(); private static MockWebServer web = new MockWebServer();

View File

@ -1,10 +1,10 @@
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins { plugins {
id("org.springframework.boot") version "3.0.0-SNAPSHOT" id("org.springframework.boot") version "2.5.0"
id("io.spring.dependency-management") version "1.0.11.RELEASE" id("io.spring.dependency-management") version "1.0.9.RELEASE"
kotlin("jvm") version "1.6.0" kotlin("jvm") version "1.5.0"
kotlin("plugin.spring") version "1.6.0" kotlin("plugin.spring") version "1.5.0"
} }
repositories { repositories {
@ -12,16 +12,13 @@ repositories {
maven { maven {
url = uri("https://repo.spring.io/snapshot") url = uri("https://repo.spring.io/snapshot")
} }
maven {
url = uri("https://repo.spring.io/milestone")
}
} }
dependencies { dependencies {
implementation("org.springframework.boot:spring-boot-starter-security") implementation("org.springframework.boot:spring-boot-starter-security")
implementation("org.springframework.boot:spring-boot-starter-thymeleaf") implementation("org.springframework.boot:spring-boot-starter-thymeleaf")
implementation("org.springframework.boot:spring-boot-starter-webflux") implementation("org.springframework.boot:spring-boot-starter-webflux")
implementation("org.thymeleaf.extras:thymeleaf-extras-springsecurity6") implementation("org.thymeleaf.extras:thymeleaf-extras-springsecurity5")
implementation("io.projectreactor.kotlin:reactor-kotlin-extensions") implementation("io.projectreactor.kotlin:reactor-kotlin-extensions")
implementation("org.jetbrains.kotlin:kotlin-reflect") implementation("org.jetbrains.kotlin:kotlin-reflect")
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8") implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
@ -37,7 +34,7 @@ dependencies {
tasks.withType<KotlinCompile> { tasks.withType<KotlinCompile> {
kotlinOptions { kotlinOptions {
freeCompilerArgs = listOf("-Xjsr305=strict") freeCompilerArgs = listOf("-Xjsr305=strict")
jvmTarget = "17" jvmTarget = "1.8"
} }
} }

View File

@ -1 +1 @@
spring-security.version=6.0.0-SNAPSHOT spring-security.version=5.5.0

View File

@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-6.9-bin.zip
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists

View File

@ -17,7 +17,6 @@
package example package example
import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity
import org.springframework.security.config.web.server.ServerHttpSecurity import org.springframework.security.config.web.server.ServerHttpSecurity
import org.springframework.security.config.web.server.invoke import org.springframework.security.config.web.server.invoke
@ -26,7 +25,6 @@ import org.springframework.security.core.userdetails.ReactiveUserDetailsService
import org.springframework.security.core.userdetails.User import org.springframework.security.core.userdetails.User
import org.springframework.security.web.server.SecurityWebFilterChain import org.springframework.security.web.server.SecurityWebFilterChain
@Configuration
@EnableWebFluxSecurity @EnableWebFluxSecurity
class SecurityConfiguration { class SecurityConfiguration {

View File

@ -4,21 +4,10 @@ plugins {
} }
repositories { repositories {
mavenCentral() jcenter()
maven { url "https://repo.spring.io/milestone" }
maven { url "https://repo.spring.io/snapshot" } maven { url "https://repo.spring.io/snapshot" }
} }
compileJava {
sourceCompatibility "1.8"
targetCompatibility "1.8"
}
compileTestJava {
sourceCompatibility "1.8"
targetCompatibility "1.8"
}
dependencies { dependencies {
aspect platform("org.springframework:spring-framework-bom:5.3.0") aspect platform("org.springframework:spring-framework-bom:5.3.0")
aspect platform("org.springframework.security:spring-security-bom:5.4.0-SNAPSHOT") aspect platform("org.springframework.security:spring-security-bom:5.4.0-SNAPSHOT")
@ -30,7 +19,7 @@ dependencies {
implementation "org.springframework.security:spring-security-config" implementation "org.springframework.security:spring-security-config"
runtimeOnly "org.springframework.security:spring-security-aspects" runtime "org.springframework.security:spring-security-aspects"
testImplementation "org.assertj:assertj-core:3.18.0" testImplementation "org.assertj:assertj-core:3.18.0"
testImplementation "org.springframework:spring-test" testImplementation "org.springframework:spring-test"
@ -42,7 +31,6 @@ dependencies {
tasks.withType(Test).configureEach { tasks.withType(Test).configureEach {
useJUnitPlatform() useJUnitPlatform()
outputs.upToDateWhen { false }
} }

View File

@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-6.9-bin.zip
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists

View File

@ -1,15 +1,14 @@
plugins { plugins {
id "java" id "java"
id "nebula.integtest" version "8.2.0" id "nebula.integtest" version "7.0.9"
id "org.gretty" version "3.0.6" id "org.gretty" version "3.0.3"
id "war" id "war"
} }
apply from: "gradle/gretty.gradle" apply from: "gradle/gretty.gradle"
repositories { repositories {
mavenCentral() jcenter()
maven { url "https://repo.spring.io/milestone" }
maven { url "https://repo.spring.io/snapshot" } maven { url "https://repo.spring.io/snapshot" }
} }
@ -30,10 +29,9 @@ dependencies {
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine") testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine")
integTestImplementation "org.seleniumhq.selenium:htmlunit-driver:3.64.0" integTestImplementation "org.seleniumhq.selenium:htmlunit-driver:2.44.0"
} }
tasks.withType(Test).configureEach { tasks.withType(Test).configureEach {
useJUnitPlatform() useJUnitPlatform()
outputs.upToDateWhen { false }
} }

View File

@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-6.9-bin.zip
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists

View File

@ -16,31 +16,32 @@
package example; package example;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.provisioning.InMemoryUserDetailsManager; import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;
@Configuration
@EnableWebSecurity @EnableWebSecurity
public class SecurityConfiguration { public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Bean // @formatter:off
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { @Override
// @formatter:off protected void configure(HttpSecurity http) throws Exception {
http http
.authorizeHttpRequests((authorize) -> authorize .authorizeRequests((authorizeRequests) ->
.antMatchers("/login", "/resources/**").permitAll() authorizeRequests
.anyRequest().authenticated() .antMatchers("/login", "/resources/**").permitAll()
.anyRequest().authenticated()
) )
.jee((jee) -> jee.mappableRoles("USER", "ADMIN")); .jee((jee) ->
// @formatter:on jee
return http.build(); .mappableRoles("USER", "ADMIN")
);
} }
// @formatter:on
// @formatter:off // @formatter:off
@Bean @Bean

View File

@ -1,15 +1,14 @@
plugins { plugins {
id "java" id "java"
id "nebula.integtest" version "8.2.0" id "nebula.integtest" version "7.0.9"
id "org.gretty" version "3.0.6" id "org.gretty" version "3.0.3"
id "war" id "war"
} }
apply from: "gradle/gretty.gradle" apply from: "gradle/gretty.gradle"
repositories { repositories {
mavenCentral() jcenter()
maven { url "https://repo.spring.io/milestone" }
maven { url "https://repo.spring.io/snapshot" } maven { url "https://repo.spring.io/snapshot" }
} }
@ -30,10 +29,9 @@ dependencies {
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine") testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine")
integTestImplementation "org.seleniumhq.selenium:htmlunit-driver:3.64.0" integTestImplementation "org.seleniumhq.selenium:htmlunit-driver:2.44.0"
} }
tasks.withType(Test).configureEach { tasks.withType(Test).configureEach {
useJUnitPlatform() useJUnitPlatform()
outputs.upToDateWhen { false }
} }

View File

@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-6.9-bin.zip
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists

View File

@ -16,34 +16,33 @@
package example; package example;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.provisioning.InMemoryUserDetailsManager; import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;
@Configuration import static org.springframework.security.config.Customizer.withDefaults;
@EnableWebSecurity @EnableWebSecurity
public class SecurityConfiguration { public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Bean @Override
public SecurityFilterChain securityFilterChain(HttpSecurity http, UserDetailsService users) throws Exception { // @formatter:off
// @formatter:off protected void configure(HttpSecurity http) throws Exception {
http http
.authorizeRequests((authorize) -> authorize .authorizeRequests((requests) -> requests
.anyRequest().authenticated() .anyRequest().authenticated()
) )
.formLogin((form) -> form .formLogin((form) -> form
.loginPage("/login") .loginPage("/login")
.permitAll() .permitAll()
) )
.rememberMe((rememberMe) -> rememberMe.userDetailsService(users)); .rememberMe(withDefaults());
// @formatter:on
return http.build();
} }
// @formatter:on
// @formatter:off // @formatter:off
@Bean @Bean

View File

@ -1,27 +1,26 @@
plugins { plugins {
id "java" id "java"
id "nebula.integtest" version "8.2.0" id "nebula.integtest" version "7.0.9"
id "org.gretty" version "4.0.0" id "org.gretty" version "3.0.3"
id "war" id "war"
} }
apply from: "gradle/gretty.gradle" apply from: "gradle/gretty.gradle"
repositories { repositories {
mavenCentral() jcenter()
maven { url "https://repo.spring.io/milestone" }
maven { url "https://repo.spring.io/snapshot" } maven { url "https://repo.spring.io/snapshot" }
} }
dependencies { dependencies {
implementation platform("org.springframework:spring-framework-bom:6.0.0-SNAPSHOT") implementation platform("org.springframework:spring-framework-bom:5.3.0")
implementation platform("org.springframework.security:spring-security-bom:6.0.0-SNAPSHOT") implementation platform("org.springframework.security:spring-security-bom:5.5.0-SNAPSHOT")
implementation platform("org.junit:junit-bom:5.7.0") implementation platform("org.junit:junit-bom:5.7.0")
implementation "org.springframework.security:spring-security-config" implementation "org.springframework.security:spring-security-config"
implementation "org.springframework.security:spring-security-web" implementation "org.springframework.security:spring-security-web"
implementation "org.springframework:spring-webmvc" implementation "org.springframework:spring-webmvc"
implementation "org.thymeleaf:thymeleaf-spring6:3.1.0.M1" implementation "org.thymeleaf:thymeleaf-spring5:3.0.11.RELEASE"
testImplementation "org.assertj:assertj-core:3.18.0" testImplementation "org.assertj:assertj-core:3.18.0"
testImplementation "org.springframework:spring-test" testImplementation "org.springframework:spring-test"
@ -30,10 +29,9 @@ dependencies {
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine") testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine")
integTestImplementation "org.seleniumhq.selenium:htmlunit-driver:3.64.0" integTestImplementation "org.seleniumhq.selenium:htmlunit-driver:2.44.0"
} }
tasks.withType(Test).configureEach { tasks.withType(Test).configureEach {
useJUnitPlatform() useJUnitPlatform()
outputs.upToDateWhen { false }
} }

View File

@ -1,5 +1,5 @@
gretty { gretty {
servletContainer = "tomcat10" servletContainer = "tomcat9"
contextPath = "/" contextPath = "/"
fileLogEnabled = false fileLogEnabled = false
integrationTestTask = 'integrationTest' integrationTestTask = 'integrationTest'

View File

@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-6.9-bin.zip
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists

View File

@ -16,7 +16,7 @@
package example; package example;
import jakarta.servlet.Filter; import javax.servlet.Filter;
import org.springframework.web.filter.HiddenHttpMethodFilter; import org.springframework.web.filter.HiddenHttpMethodFilter;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer; import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;

View File

@ -16,33 +16,30 @@
package example; package example;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.provisioning.InMemoryUserDetailsManager; import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;
@Configuration
@EnableWebSecurity @EnableWebSecurity
public class SecurityConfiguration { public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Bean @Override
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { // @formatter:off
// @formatter:off protected void configure(HttpSecurity http) throws Exception {
http http
.authorizeRequests((authorize) -> authorize .authorizeRequests((requests) -> requests
.anyRequest().authenticated() .anyRequest().authenticated()
) )
.formLogin((form) -> form .formLogin((form) -> form
.loginPage("/login") .loginPage("/login")
.permitAll() .permitAll()
); );
// @formatter:on
return http.build();
} }
// @formatter:on
// @formatter:off // @formatter:off
@Bean @Bean

View File

@ -16,10 +16,10 @@
package example; package example;
import org.thymeleaf.spring6.ISpringTemplateEngine; import org.thymeleaf.spring5.ISpringTemplateEngine;
import org.thymeleaf.spring6.SpringTemplateEngine; import org.thymeleaf.spring5.SpringTemplateEngine;
import org.thymeleaf.spring6.templateresolver.SpringResourceTemplateResolver; import org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver;
import org.thymeleaf.spring6.view.ThymeleafViewResolver; import org.thymeleaf.spring5.view.ThymeleafViewResolver;
import org.thymeleaf.templatemode.TemplateMode; import org.thymeleaf.templatemode.TemplateMode;
import org.thymeleaf.templateresolver.ITemplateResolver; import org.thymeleaf.templateresolver.ITemplateResolver;

View File

@ -1,15 +1,14 @@
plugins { plugins {
id "java" id "java"
id "nebula.integtest" version "8.2.0" id "nebula.integtest" version "7.0.9"
id "org.gretty" version "3.0.6" id "org.gretty" version "3.0.3"
id "war" id "war"
} }
apply from: "gradle/gretty.gradle" apply from: "gradle/gretty.gradle"
repositories { repositories {
mavenCentral() jcenter()
maven { url "https://repo.spring.io/milestone" }
maven { url "https://repo.spring.io/snapshot" } maven { url "https://repo.spring.io/snapshot" }
} }
@ -30,10 +29,9 @@ dependencies {
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine") testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine")
integTestImplementation "org.seleniumhq.selenium:htmlunit-driver:3.64.0" integTestImplementation "org.seleniumhq.selenium:htmlunit-driver:2.44.0"
} }
tasks.withType(Test).configureEach { tasks.withType(Test).configureEach {
useJUnitPlatform() useJUnitPlatform()
outputs.upToDateWhen { false }
} }

View File

@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-6.9-bin.zip
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists

View File

@ -16,16 +16,15 @@
package example; package example;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.provisioning.InMemoryUserDetailsManager; import org.springframework.security.provisioning.InMemoryUserDetailsManager;
@Configuration
@EnableWebSecurity @EnableWebSecurity
public class SecurityConfiguration { public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
// @formatter:off // @formatter:off
@Bean @Bean

View File

@ -1,15 +1,14 @@
plugins { plugins {
id "java" id "java"
id "nebula.integtest" version "8.2.0" id "nebula.integtest" version "7.0.9"
id "org.gretty" version "3.0.6" id "org.gretty" version "3.0.3"
id "war" id "war"
} }
apply from: "gradle/gretty.gradle" apply from: "gradle/gretty.gradle"
repositories { repositories {
mavenCentral() jcenter()
maven { url "https://repo.spring.io/milestone" }
maven { url "https://repo.spring.io/snapshot" } maven { url "https://repo.spring.io/snapshot" }
} }
@ -32,10 +31,9 @@ dependencies {
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine") testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine")
integTestImplementation "org.seleniumhq.selenium:htmlunit-driver:3.64.0" integTestImplementation "org.seleniumhq.selenium:htmlunit-driver:2.44.0"
} }
tasks.withType(Test).configureEach { tasks.withType(Test).configureEach {
useJUnitPlatform() useJUnitPlatform()
outputs.upToDateWhen { false }
} }

View File

@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-6.9-bin.zip
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists

View File

@ -34,8 +34,7 @@ public class DataSourceConfiguration {
@Bean @Bean
public DataSource dataSource() { public DataSource dataSource() {
EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder(); EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder();
return builder.setType(EmbeddedDatabaseType.HSQL) return builder.setType(EmbeddedDatabaseType.HSQL).build();
.addScript("classpath:org/springframework/security/core/userdetails/jdbc/users.ddl").build();
} }
} }

View File

@ -17,29 +17,28 @@ package example;
import javax.sql.DataSource; import javax.sql.DataSource;
import org.springframework.context.annotation.Bean; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.provisioning.JdbcUserDetailsManager;
import org.springframework.security.provisioning.UserDetailsManager;
@Configuration
@EnableWebSecurity @EnableWebSecurity
public class SecurityConfiguration { public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Bean @Autowired
UserDetailsManager users(DataSource dataSource) { DataSource dataSource;
UserDetails user = User.builder().username("user")
.password("{bcrypt}$2a$10$AiyMWI4UBLozgXq6itzyVuxrtofjcPzn/WS3fOrcqgzdax9jB7Io.").roles("USER").build(); // @formatter:off
UserDetails admin = User.builder().username("admin") @Autowired
.password("{bcrypt}$2a$10$AiyMWI4UBLozgXq6itzyVuxrtofjcPzn/WS3fOrcqgzdax9jB7Io.").roles("USER", "ADMIN") public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
.build(); auth
JdbcUserDetailsManager users = new JdbcUserDetailsManager(dataSource); .jdbcAuthentication()
users.createUser(user); .dataSource(this.dataSource)
users.createUser(admin); .withDefaultSchema()
return users; .withUser(User.withDefaultPasswordEncoder().username("user").password("password").roles("USER"))
.withUser(User.withDefaultPasswordEncoder().username("admin").password("password").roles("ADMIN", "USER"));
} }
// @formatter:on
} }

Some files were not shown because too many files have changed in this diff Show More