Merge pull request #13659 from muasif80/master

BAEL-6035
This commit is contained in:
davidmartinezbarua
2023-03-22 14:05:07 -03:00
committed by GitHub
13 changed files with 800 additions and 0 deletions
+2
View File
@@ -972,6 +972,7 @@
<module>persistence-modules/java-mongodb</module>
<module>messaging-modules</module>
<module>spring-boot-modules/spring-boot-redis</module>
<module>spring-security-modules/spring-security-saml2</module>
<module>persistence-modules/questdb</module>
</modules>
@@ -1247,6 +1248,7 @@
<module>libraries-2</module>
<module>messaging-modules</module>
<module>spring-boot-modules/spring-boot-redis</module>
<module>spring-security-modules/spring-security-saml2</module>
<module>persistence-modules/questdb</module>
</modules>
@@ -0,0 +1,2 @@
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.6/apache-maven-3.8.6-bin.zip
wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar
File diff suppressed because it is too large Load Diff
+188
View File
@@ -0,0 +1,188 @@
@REM ----------------------------------------------------------------------------
@REM Licensed to the Apache Software Foundation (ASF) under one
@REM or more contributor license agreements. See the NOTICE file
@REM distributed with this work for additional information
@REM regarding copyright ownership. The ASF licenses this file
@REM to you under the Apache License, Version 2.0 (the
@REM "License"); you may not use this file except in compliance
@REM with the License. You may obtain a copy of the License at
@REM
@REM https://www.apache.org/licenses/LICENSE-2.0
@REM
@REM Unless required by applicable law or agreed to in writing,
@REM software distributed under the License is distributed on an
@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@REM KIND, either express or implied. See the License for the
@REM specific language governing permissions and limitations
@REM under the License.
@REM ----------------------------------------------------------------------------
@REM ----------------------------------------------------------------------------
@REM Maven Start Up Batch script
@REM
@REM Required ENV vars:
@REM JAVA_HOME - location of a JDK home dir
@REM
@REM Optional ENV vars
@REM M2_HOME - location of maven2's installed home dir
@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending
@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
@REM e.g. to debug Maven itself, use
@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
@REM ----------------------------------------------------------------------------
@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
@echo off
@REM set title of command window
title %0
@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on'
@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
@REM set %HOME% to equivalent of $HOME
if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
@REM Execute a user defined script before this one
if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
@REM check for pre script, once with legacy .bat ending and once with .cmd ending
if exist "%USERPROFILE%\mavenrc_pre.bat" call "%USERPROFILE%\mavenrc_pre.bat" %*
if exist "%USERPROFILE%\mavenrc_pre.cmd" call "%USERPROFILE%\mavenrc_pre.cmd" %*
:skipRcPre
@setlocal
set ERROR_CODE=0
@REM To isolate internal variables from possible post scripts, we use another setlocal
@setlocal
@REM ==== START VALIDATION ====
if not "%JAVA_HOME%" == "" goto OkJHome
echo.
echo Error: JAVA_HOME not found in your environment. >&2
echo Please set the JAVA_HOME variable in your environment to match the >&2
echo location of your Java installation. >&2
echo.
goto error
:OkJHome
if exist "%JAVA_HOME%\bin\java.exe" goto init
echo.
echo Error: JAVA_HOME is set to an invalid directory. >&2
echo JAVA_HOME = "%JAVA_HOME%" >&2
echo Please set the JAVA_HOME variable in your environment to match the >&2
echo location of your Java installation. >&2
echo.
goto error
@REM ==== END VALIDATION ====
:init
@REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
@REM Fallback to current working directory if not found.
set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
set EXEC_DIR=%CD%
set WDIR=%EXEC_DIR%
:findBaseDir
IF EXIST "%WDIR%"\.mvn goto baseDirFound
cd ..
IF "%WDIR%"=="%CD%" goto baseDirNotFound
set WDIR=%CD%
goto findBaseDir
:baseDirFound
set MAVEN_PROJECTBASEDIR=%WDIR%
cd "%EXEC_DIR%"
goto endDetectBaseDir
:baseDirNotFound
set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
cd "%EXEC_DIR%"
:endDetectBaseDir
IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
@setlocal EnableExtensions EnableDelayedExpansion
for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
:endReadAdditionalConfig
SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar"
FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B
)
@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
@REM This allows using the maven wrapper in projects that prohibit checking in binary data.
if exist %WRAPPER_JAR% (
if "%MVNW_VERBOSE%" == "true" (
echo Found %WRAPPER_JAR%
)
) else (
if not "%MVNW_REPOURL%" == "" (
SET DOWNLOAD_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar"
)
if "%MVNW_VERBOSE%" == "true" (
echo Couldn't find %WRAPPER_JAR%, downloading it ...
echo Downloading from: %DOWNLOAD_URL%
)
powershell -Command "&{"^
"$webclient = new-object System.Net.WebClient;"^
"if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^
"$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^
"}"^
"[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^
"}"
if "%MVNW_VERBOSE%" == "true" (
echo Finished downloading %WRAPPER_JAR%
)
)
@REM End of extension
@REM Provide a "standardized" way to retrieve the CLI args that will
@REM work with both Windows and non-Windows executions.
set MAVEN_CMD_LINE_ARGS=%*
%MAVEN_JAVA_EXE% ^
%JVM_CONFIG_MAVEN_PROPS% ^
%MAVEN_OPTS% ^
%MAVEN_DEBUG_OPTS% ^
-classpath %WRAPPER_JAR% ^
"-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" ^
%WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
if ERRORLEVEL 1 goto error
goto end
:error
set ERROR_CODE=1
:end
@endlocal & set ERROR_CODE=%ERROR_CODE%
if not "%MAVEN_SKIP_RC%"=="" goto skipRcPost
@REM check for post script, once with legacy .bat ending and once with .cmd ending
if exist "%USERPROFILE%\mavenrc_post.bat" call "%USERPROFILE%\mavenrc_post.bat"
if exist "%USERPROFILE%\mavenrc_post.cmd" call "%USERPROFILE%\mavenrc_post.cmd"
:skipRcPost
@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
if "%MAVEN_BATCH_PAUSE%"=="on" pause
if "%MAVEN_TERMINATE_CMD%"=="on" exit %ERROR_CODE%
cmd /C exit /B %ERROR_CODE%
@@ -0,0 +1,88 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>spring-security-saml2</artifactId>
<version>1.0-SNAPSHOT</version>
<name>spring-security-saml2</name>
<repositories>
<repository>
<id>shib-build-releases</id>
<name>Shibboleth Build Releases Repository</name>
<url>https://build.shibboleth.net/nexus/content/repositories/releases/</url>
</repository>
</repositories>
<parent>
<groupId>com.baeldung</groupId>
<artifactId>parent-boot-3</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../../parent-boot-3</relativePath>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity6</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.opensaml</groupId>
<artifactId>opensaml-core</artifactId>
<version>${opensaml.version}</version>
</dependency>
<dependency>
<groupId>org.opensaml</groupId>
<artifactId>opensaml-saml-impl</artifactId>
<version>${opensaml.version}</version>
</dependency>
<dependency>
<groupId>org.opensaml</groupId>
<artifactId>opensaml-saml-api</artifactId>
<version>${opensaml.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-saml2-service-provider</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<properties>
<java.version>17</java.version>
<opensaml.version>4.1.1</opensaml.version>
</properties>
</project>
@@ -0,0 +1,12 @@
package com.baeldung.saml;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
@@ -0,0 +1,19 @@
package com.baeldung.saml;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.saml2.provider.service.authentication.Saml2AuthenticatedPrincipal;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class MainController {
@GetMapping("/")
public String index(Model model, @AuthenticationPrincipal Saml2AuthenticatedPrincipal principal) {
String emailAddress = principal.getFirstAttribute("email");
model.addAttribute("emailAddress", emailAddress);
model.addAttribute("userAttributes", principal.getAttributes());
return "index";
}
}
@@ -0,0 +1,38 @@
package com.baeldung.saml;
import static org.springframework.security.config.Customizer.withDefaults;
import org.springframework.beans.factory.annotation.Autowired;
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.configuration.EnableWebSecurity;
import org.springframework.security.saml2.provider.service.metadata.OpenSamlMetadataResolver;
import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistrationRepository;
import org.springframework.security.saml2.provider.service.web.DefaultRelyingPartyRegistrationResolver;
import org.springframework.security.saml2.provider.service.web.Saml2MetadataFilter;
import org.springframework.security.saml2.provider.service.web.authentication.Saml2WebSsoAuthenticationFilter;
import org.springframework.security.web.DefaultSecurityFilterChain;
import org.springframework.security.web.SecurityFilterChain;
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Autowired
private RelyingPartyRegistrationRepository relyingPartyRegistrationRepository;
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
DefaultRelyingPartyRegistrationResolver relyingPartyRegistrationResolver = new DefaultRelyingPartyRegistrationResolver(this.relyingPartyRegistrationRepository);
Saml2MetadataFilter filter = new Saml2MetadataFilter(relyingPartyRegistrationResolver, new OpenSamlMetadataResolver());
http.authorizeHttpRequests(authorize -> authorize.anyRequest()
.authenticated())
.saml2Login(withDefaults())
.saml2Logout(withDefaults())
.addFilterBefore(filter, Saml2WebSsoAuthenticationFilter.class);
DefaultSecurityFilterChain chain = http.build();
return chain;
}
}
@@ -0,0 +1,16 @@
spring:
security:
saml2:
relyingparty:
registration:
okta:
signing:
credentials:
- private-key-location: classpath:local.key
certificate-location: classpath:local.crt
singlelogout:
url: https://dev-56617222.okta.com/app/dev-56617222_springbootsaml_1/exk8b5jr6vYQqVXp45d7/slo/saml
binding: POST
response-url: "{baseUrl}/logout/saml2/slo"
assertingparty:
metadata-uri: "classpath:metadata/metadata-idp-okta.xml"
@@ -0,0 +1,23 @@
-----BEGIN CERTIFICATE-----
MIID0zCCArugAwIBAgIUZUPwSIv1Qo6ipHBb7dPLIB0p2wEwDQYJKoZIhvcNAQEL
BQAweTELMAkGA1UEBhMCUEsxEzARBgNVBAgMClNvbWUtU3RhdGUxGDAWBgNVBAoM
D3NraWxsc3VpdGVzLmNvbTEYMBYGA1UEAwwPc2tpbGxzdWl0ZXMuY29tMSEwHwYJ
KoZIhvcNAQkBFhJtdWFzaWY4MEBnbWFpbC5jb20wHhcNMjMwMjEyMTkwODAwWhcN
MjQwMjEyMTkwODAwWjB5MQswCQYDVQQGEwJQSzETMBEGA1UECAwKU29tZS1TdGF0
ZTEYMBYGA1UECgwPc2tpbGxzdWl0ZXMuY29tMRgwFgYDVQQDDA9za2lsbHN1aXRl
cy5jb20xITAfBgkqhkiG9w0BCQEWEm11YXNpZjgwQGdtYWlsLmNvbTCCASIwDQYJ
KoZIhvcNAQEBBQADggEPADCCAQoCggEBANuEo5Dmc4BSY4kKQhVd1jYwuwDxQQaH
0Jeb2dgb+tnPNLhUMygQczTst/JiMjySHIHrgSvFe6BUCOqBb+lXZJlvFGQucVMA
JgRhsT59oRGuZUvicyTt7esEehp1Rqx77FDeAN+ZRf5lk8iCM3QfDvtrJOh+QEl4
MKLgJLw5Wrj3JYh8NsUwAkiAvlGNURXwM4Azogy8Ix6WUK8UaarErJB/S3/zhzPJ
Dafp8UNgckS5IeYPsuWWyV//ri4FtAYKW2R11WarLJkuYRiLQeFQ95EuyXd6NQ1+
cx1y8/8B6MCibXup//gsr71H40FCgAx+09iRmilEM9my6B0zP7EnwjMCAwEAAaNT
MFEwHQYDVR0OBBYEFIlHP6JdPAzZorbbNFcFdM16vj2oMB8GA1UdIwQYMBaAFIlH
P6JdPAzZorbbNFcFdM16vj2oMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEL
BQADggEBAB7Zm1n6498V9EP9pCgcyPjtGXcqBrU7JTgieKMgMm3vwGJPoR5s4kbM
fppQGlqq140ErU78Tly14jGk2bbFjQngy9cY/colxwe7HeqKbyQ1HXfttaPHuZfH
2TgJC7EeJ20yHCCOibA+DgCwt4yZurS3le4ilNhOkoUBdxVQkaH8rueb8gbtZfKs
6ArGha90GT2ZwXjA32BERACa68IRpl+vokb2bEPeiVKa+rvPPt++yMcWRkXeOl2w
SoHNhxPlZkg3F5pQ5qQOQ6N+6X+DQj9p4FRr2m05CpCODsqqHju2XQN6LvZS35Xu
rvMRkpysY2cYLaJ6vZGVcfueMwAmoJU=
-----END CERTIFICATE-----
@@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDbhKOQ5nOAUmOJ
CkIVXdY2MLsA8UEGh9CXm9nYG/rZzzS4VDMoEHM07LfyYjI8khyB64ErxXugVAjq
gW/pV2SZbxRkLnFTACYEYbE+faERrmVL4nMk7e3rBHoadUase+xQ3gDfmUX+ZZPI
gjN0Hw77ayTofkBJeDCi4CS8OVq49yWIfDbFMAJIgL5RjVEV8DOAM6IMvCMellCv
FGmqxKyQf0t/84czyQ2n6fFDYHJEuSHmD7Lllslf/64uBbQGCltkddVmqyyZLmEY
i0HhUPeRLsl3ejUNfnMdcvP/AejAom17qf/4LK+9R+NBQoAMftPYkZopRDPZsugd
Mz+xJ8IzAgMBAAECggEAfMv5WUVKYKd2ItCMJS2FvKUTi0OcniPUOHzH6g5uHCmq
ZSipNJu1g18YbFnbCYhfYJUMiF/rGojr0LXpc5TVgk0eIJ4umus4scEATPCLA0xM
FkoU/+esHLIc4LHPjfudq5Oql3PB0RDaZWFv8xI9KD4Pa4Vq8tm7fL1E5SUOKJx7
M3Xjf6LuBqGI4x27tXWgQqDwaAdSY9ycbM0W04A/UKqOqpKtNZ6MxGGL7i5Cxo8H
8A/5YXmgdaDzrYKIdy6sL1cVu6wT4P7m2Wvyg+aIWJ7P3Wx1rCW2Dja1Pz5WFhWM
CmKSvvGqFIa++BCyiS5CmDavpzBTvsvnGAKwq03jcQKBgQD0oVvWFujhxEo5k4Nh
WvBZpGU0CSyeorLd6asxqxNxnq+sahKow7xFQNmXIrklKvPtEv/P+aqBARG/+jEQ
SeP4lX3xbuICWJS2rKfuOc5FmZTEDdTBOG4tYrzCDz/kz5uEvWRebwBi1KXBBCfV
yozPEhGC+vdRsrzszlGJmcbkVwKBgQDluH4JYYoboJfeyg8OehYyjD7foFFReqwb
dVp2XqfvXvb4KsxagycqMrfoBAcQDZGaBuJAxQMtZn3XdM0qApjxmgZ9qspkI9w/
MLWbhq/5MqgoiSCEt5BOKt5obInJpR5drK2RXWNfEwkXptnsHDRPyjAq++UOWj+c
tW0UARlHhQKBgQDuwFT7G5zqS0MN8nR1HeYZ9yJ2qMWNhckAYEAe15LAf1mA8n2H
jJFBHcu/f7onFka/CJ32gvrvsPV74ljkRtliEbS7X7bhB0cNCnFTRcOVlhDlT4Jn
mgWd8hG7bFq1nBFyec1thPRhgJzNRpsCQw8uQboplXqvl7xfefWGUDkXPQKBgQDH
Ue0J9rf+gLlFdczaotPfyBBFuLTWHbp3mLuFOVw9NgjUC06Euoeg9aDcj6IRK7TK
EG8AA/Fd0zAdYhsh+F78QsifATHa8cKIkZsB9zt43ZtKkLDGdv+e01NnB8YGUF6o
qMtw9bbjJ4EcJImxdEdvc9+XbDiy21uWfVTHpqxogQKBgQCtMpVN0ViPL3Q6FB/x
VR0E2Ct1i7GSfMEVt+T2dgk6uAXBeS9bW9/rmJ5VfwmsEMvngOEBUkUL8Zy+a3SW
D+9u5144cQ9NYyC23fT3VEW5w0Bd6GTH26GmIO7UZOCQ6n/c+lXtTez1RrKeF8uy
oYdCjFgW8kaAdHfHduYf5PdlbQ==
-----END PRIVATE KEY-----
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?><md:EntityDescriptor entityID="http://www.okta.com/exk8fja0pn7zO0b165d7" xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata"><md:IDPSSODescriptor WantAuthnRequestsSigned="false" protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol"><md:KeyDescriptor use="signing"><ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#"><ds:X509Data><ds:X509Certificate>MIIDqDCCApCgAwIBAgIGAYZ6plFwMA0GCSqGSIb3DQEBCwUAMIGUMQswCQYDVQQGEwJVUzETMBEG
A1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzENMAsGA1UECgwET2t0YTEU
MBIGA1UECwwLU1NPUHJvdmlkZXIxFTATBgNVBAMMDGRldi01NjYxNzIyMjEcMBoGCSqGSIb3DQEJ
ARYNaW5mb0Bva3RhLmNvbTAeFw0yMzAyMjIxOTQxNDVaFw0zMzAyMjIxOTQyNDVaMIGUMQswCQYD
VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzENMAsG
A1UECgwET2t0YTEUMBIGA1UECwwLU1NPUHJvdmlkZXIxFTATBgNVBAMMDGRldi01NjYxNzIyMjEc
MBoGCSqGSIb3DQEJARYNaW5mb0Bva3RhLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
ggEBAMCoER+Qlx6xBBUAcIxRk5ItmfldF+Rc+z+FCY/Ow7+cNBOIenRGfQLirQMwKzvZAg2o52xm
OrtqsHX3NLEnSQDyQp/sE7MueHQCGcDnCAQEeOVbDSPW7bDOeK/qNyecTPKZreL70TQLPpeA9x7l
WA59zxOX9or9BLuQJrXKOU/cZ4BXzue351R2qmuj7IqbXmsbetKegVFShYJZ9e9ta42OK1T8oDez
dKZbPj5el1kj2jJ08GzO3TDg9j5B21x3sz2bxg6vFMP7e10hgLicxKVw1P5ZG995wUA+E8YbFehi
YXRlcJiiKhmjRvHFl1F5vM4DPLaL4b8BJ1E21Byhb2cCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEA
FMy00eWU4klEdV2PhoOPZE8Phj6tVDtEjr+ol7L7RJh6u2WPwLm6U9vE9wQ0/OYhOjThUsZqxqjL
SqhZeMiFwohL6K5cmW2wTkxgfICyPY9g3BVDtogsZgbI0clIG5slwgiy9Kn7wQpSHWDvpEZXwmyV
KodcWIpgBf0dUdBhsx+o34eG7ajsLb9HEisF0ntxlKdG2LJqlkJBtiUgI2Wo2jNshfzA7Cp9cNio
+j3f1dwyWmmwWkyxGkEw8UwuwKMDHfuAwyBmZJmmG9zkHMlHkgQxxq3iI8Bs9E3lKYXtwLE7K+xe
rTdWegAfIP7LXC3JKN1N/Meke5FJLXmWAMXKIw==</ds:X509Certificate></ds:X509Data></ds:KeyInfo></md:KeyDescriptor><md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://dev-56617222.okta.com/app/dev-56617222_baeldungspringsecuritysaml2app_1/exk8fja0pn7zO0b165d7/slo/saml"/><md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://dev-56617222.okta.com/app/dev-56617222_baeldungspringsecuritysaml2app_1/exk8fja0pn7zO0b165d7/slo/saml"/><md:NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified</md:NameIDFormat><md:NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress</md:NameIDFormat><md:SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://dev-56617222.okta.com/app/dev-56617222_baeldungspringsecuritysaml2app_1/exk8fja0pn7zO0b165d7/sso/saml"/><md:SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://dev-56617222.okta.com/app/dev-56617222_baeldungspringsecuritysaml2app_1/exk8fja0pn7zO0b165d7/sso/saml"/></md:IDPSSODescriptor></md:EntityDescriptor>
@@ -0,0 +1,51 @@
<!doctype html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="https://www.thymeleaf.org"
xmlns:sec="https://www.thymeleaf.org/thymeleaf-extras-springsecurity5">
<head>
<title>Baeldung Example for Spring Security - SAML 2.0 Login/Logout</title>
<meta charset="utf-8" />
<style>
span,
dt {
font-weight: bold;
}
</style>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css"
integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
</head>
<body>
<div class="container">
<ul class="nav">
<li class="nav-item">
<form th:action="@{/logout}" method="post">
<button class="btn btn-primary" id="rp_logout_button" type="submit">
Logout
</button>
</form>
</li>
</ul>
</div>
<main role="main" class="container">
<h1 class="mt-5">Baeldung Example for SAML 2.0 Login/Logout with Spring Security</h1>
<p class="lead">You are successfully logged in as <span sec:authentication="name"></span></p>
<h2 class="mt-2">User Identity Attributes</h2>
<table class='table table-striped'>
<thead>
<tr>
<th>Attribute</th>
<th>Value</th>
</tr>
</thead>
<tbody>
<tr th:each="userAttribute : ${userAttributes}">
<th th:text="${userAttribute.key}"></th>
<td th:text="${userAttribute.value}"></td>
</tr>
</tbody>
</table>
</main>
</body>
</html>