getAttributes() {
71 | return samlCredential.getAttributes().stream()
72 | .collect(Collectors.toMap(Attribute::getName, this::getValue));
73 | }
74 |
75 | private String getValue(Attribute attribute) {
76 | return Optional.ofNullable(getAttribute(attribute.getName())).orElse("");
77 | }
78 | };
79 | }
80 | };
81 | }
82 |
83 | @Bean
84 | public static SAMLBootstrap SAMLBootstrap() {
85 | return new CustomSAMLBootstrap();
86 | }
87 |
88 | @Configuration
89 | public static class MyServiceProviderConfig extends ServiceProviderConfigurerAdapter {
90 |
91 | @Autowired
92 | SAMLUserDetailsService userDetailsService;
93 |
94 | @Override
95 | public void configure(HttpSecurity http) throws Exception {
96 | // @formatter:off
97 | http.authorizeRequests()
98 | .antMatchers("/unprotected/**")
99 | .permitAll()
100 | .and()
101 | .anonymous();
102 | // @formatter:on
103 | }
104 |
105 | @Override
106 | public void configure(ServiceProviderBuilder serviceProvider) throws Exception {
107 | // @formatter:off
108 | serviceProvider
109 | .metadataGenerator()
110 | .entityId("localhost-demo")
111 | .bindingsSSO("post")
112 | .and()
113 | .sso()
114 | .defaultSuccessURL("/home")
115 | .idpSelectionPageURL("/idpselection")
116 | .and()
117 | .metadataManager()
118 | .metadataLocations("classpath:/idp-auth0-new.xml")
119 | .refreshCheckInterval(0)
120 | .and()
121 | .extendedMetadata()
122 | .idpDiscoveryEnabled(true)//set to false for no IDP Selection page.
123 | .and()
124 | .keyManager()
125 | .storeLocation("classpath:/KeyStore.jks")
126 | .storePass("123456")
127 | .defaultKey("localhost")
128 | .keyPassword("localhost", "123456")
129 | .and()
130 | .authenticationProvider()
131 | .userDetailsService(userDetailsService);
132 | // @formatter:on
133 |
134 | }
135 | }
136 | }
137 |
--------------------------------------------------------------------------------
/spring-boot-security-saml-demo-auth0/src/main/java/com/github/ulisesbocchio/demo/controller/HomeController.java:
--------------------------------------------------------------------------------
1 | package com.github.ulisesbocchio.demo.controller;
2 |
3 | /**
4 | * @author Ulises Bocchio
5 | */
6 |
7 | import com.github.ulisesbocchio.spring.boot.security.saml.annotation.SAMLUser;
8 | import com.github.ulisesbocchio.spring.boot.security.saml.user.SAMLUserDetails;
9 | import org.springframework.stereotype.Controller;
10 | import org.springframework.web.bind.annotation.RequestMapping;
11 | import org.springframework.web.servlet.ModelAndView;
12 |
13 | @Controller
14 | public class HomeController {
15 |
16 | @RequestMapping("/home")
17 | public ModelAndView home(@SAMLUser SAMLUserDetails user) {
18 | ModelAndView homeView = new ModelAndView("home");
19 | homeView.addObject("userId", user.getUsername());
20 | homeView.addObject("samlAttributes", user.getAttributes());
21 | return homeView;
22 | }
23 |
24 | }
25 |
--------------------------------------------------------------------------------
/spring-boot-security-saml-demo-auth0/src/main/java/com/github/ulisesbocchio/demo/controller/IdPSelectionController.java:
--------------------------------------------------------------------------------
1 | package com.github.ulisesbocchio.demo.controller;
2 |
3 | /**
4 | * @author Ulises Bocchio
5 | */
6 |
7 | import lombok.extern.slf4j.Slf4j;
8 | import org.springframework.security.authentication.AuthenticationServiceException;
9 | import org.springframework.security.saml.SAMLConstants;
10 | import org.springframework.security.saml.SAMLDiscovery;
11 | import org.springframework.stereotype.Controller;
12 | import org.springframework.web.bind.annotation.RequestMapping;
13 | import org.springframework.web.servlet.ModelAndView;
14 |
15 | import javax.servlet.http.HttpServletRequest;
16 | import java.util.Collections;
17 |
18 | @Controller
19 | @RequestMapping("/idpselection")
20 | @Slf4j
21 | public class IdPSelectionController {
22 |
23 | @RequestMapping
24 | public ModelAndView idpSelection(HttpServletRequest request) {
25 |
26 | if (comesFromDiscoveryFilter(request)) {
27 | ModelAndView idpSelection = new ModelAndView("idpselection");
28 | idpSelection.addObject(SAMLDiscovery.RETURN_URL, request.getAttribute(SAMLDiscovery.RETURN_URL));
29 | idpSelection.addObject(SAMLDiscovery.RETURN_PARAM, request.getAttribute(SAMLDiscovery.RETURN_PARAM));
30 | idpSelection.addObject("idpNameAliasMap", Collections.singletonMap("urn:ulisesbocchio.auth0.com", "Auth0"));
31 | return idpSelection;
32 | }
33 | throw new AuthenticationServiceException("SP Discovery flow not detected");
34 | }
35 |
36 | private boolean comesFromDiscoveryFilter(HttpServletRequest request) {
37 | return request.getAttribute(SAMLConstants.LOCAL_ENTITY_ID) != null &&
38 | request.getAttribute(SAMLDiscovery.RETURN_URL) != null &&
39 | request.getAttribute(SAMLDiscovery.RETURN_PARAM) != null;
40 | }
41 |
42 | }
43 |
--------------------------------------------------------------------------------
/spring-boot-security-saml-demo-auth0/src/main/resources/KeyStore.jks:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ulisesbocchio/spring-boot-security-saml-samples/9ef34b596d6f5ffe9ddad04cabdc896cad73e4f9/spring-boot-security-saml-demo-auth0/src/main/resources/KeyStore.jks
--------------------------------------------------------------------------------
/spring-boot-security-saml-demo-auth0/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | security.user.name=user
2 | security.user.password=password
3 | logging.level.org.springframework.security.saml= DEBUG
--------------------------------------------------------------------------------
/spring-boot-security-saml-demo-auth0/src/main/resources/idp-auth0-new.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | MIIC9jCCAd6gAwIBAgIJNrKFCkHWDRQWMA0GCSqGSIb3DQEBCwUAMCIxIDAeBgNVBAMTF3VsaXNlc2JvY2NoaW8uYXV0aDAuY29tMB4XDTE3MDMwMzEyNTY0NVoXDTMwMTExMDEyNTY0NVowIjEgMB4GA1UEAxMXdWxpc2VzYm9jY2hpby5hdXRoMC5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCZNXivxdRqrnnmwLG4msH4tU2e+hXAS/CCXh1KAF9loBzzrGgG/fM6/KffpNKlEmrX1MdEVlCZLMkXg/F/riC5OkkERyl18A+BSsOOxBBVf5VwnYX3g2o4WQmPGBqUCHUK2VgCqRvTE2dyAgEvvhcD5b8MZ7KpTxt2WE34MtvD5rGERkVUVUcnq9RICMQSjf16nOip/XXXvM5Yx+fJGVs0/4Bz8HnedQZlBdOrqBh1UJb2Z3f4tIhktjavSllCOhKGgTMiHpuXoZtsc36UMjQdfUD5ejxrRhs8JPLBlHRz3oANTdk1fuEHT77CJjyS8MrAeymFgN6DUTg3WJ5G2+AdAgMBAAGjLzAtMAwGA1UdEwQFMAMBAf8wHQYDVR0OBBYEFI2587DMoucJtI6F0AVTLdKufEVfMA0GCSqGSIb3DQEBCwUAA4IBAQAWaB6NQNIkJhukz/GhqyAzQFr5z+PzzOQI5/mXV8iX95juoM8BKPXWoZL1GNol2D7ruMB1U5jGklE2nlPFvbepoTW3N6xrN9hw48IloA1BbbvQlHFgFwP27Hm9XcM9CGOpswCKyogs/rOSGekehw5tjAtaZZmuNq74YzI3LZK20Dp/kDtKawZb6bqTMDBaFJooHycRvcaPFDXjoceTKiPC2LNjU5zniSXQDg8J6obxMWsY4VixG32Y+YElErij/Llfj9EbF7SeLZeC3mgcozlmqGRVWXrR3fAAuQZR3sla3BFMVQVvyJwAWi7IPCa8i7+jzsD5pPBtx5wKoepBIkeF
7 |
8 |
9 |
10 |
11 |
12 | urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress
13 | urn:oasis:names:tc:SAML:2.0:nameid-format:persistent
14 | urn:oasis:names:tc:SAML:2.0:nameid-format:transient
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/spring-boot-security-saml-demo-auth0/src/main/resources/idp-auth0.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | MIIC9jCCAd6gAwIBAgIJAGE1wODgykkSMA0GCSqGSIb3DQEBBQUAMCIxIDAeBgNVBAMTF3VsaXNlc2JvY2NoaW8uYXV0aDAuY29tMB4XDTE3MDEyMjAzNTgwMFoXDTMwMTAwMTAzNTgwMFowIjEgMB4GA1UEAxMXdWxpc2VzYm9jY2hpby5hdXRoMC5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDoKTJgvsDDDlAjOdREP/azN+Ba+yjVxVP0Qh/VMgbQBEkOfRhjLVCo5G34dUhn0S1ltEYS+NJTW9+Wwog88Lu6KBZsOeBOzSDgCBLAALCMl/V6fG7OR0Vn76fT9pxhnOnLsX/CpXui2c8w71z6kQ/lpA9g052RkB9QW3Lpb7O4wrYavS46hOznr2aSDiFBTUExjPKPvmRDtDItx4wMpKJOgjuDNEokmU0aZUIDD4OBiT5D31nnyd7WQVPkvXfc07NNDcG9OEldafn25A1GXtjjAXjMZQGmrh/nhLwY4fcVO8zZyQpTWMjyGb3nUV2S5Nk1QatQF9gwWphXweEn2MTVAgMBAAGjLzAtMAwGA1UdEwQFMAMBAf8wHQYDVR0OBBYEFD2x4FRsBryW/4mjkWkjlmAe77NTMA0GCSqGSIb3DQEBBQUAA4IBAQCaqA+hlGdeX/eWFee5QXAcGosdjRC7F0E4KZuQ9FUQ1KyKKzavBZWCskW1V01u0D+MLwEYLL6WAvjMcL/RJA4eDMaQzHl8WM4FUKWlPzV74q+KXfAQhnzTubnkpDTx0iKFdJT8D1RWO5Cm557o7KGTbob3Ip4JVQTNV1wIlsDhi72FugFUzUxSgAecknMV4ernrGmVNh00tNTFOV/jSJcKNZfxCpboOGiWaOjeiGJykT8fyABHwFuJSgyMVOxJ2GNRhSCBLYG42eGRMpQHCU/v8/YlRrkPyeFapWG0z5ILJt0q6HF1nVxjjN1Ph1Z2fneCKpGeKUJ7f3fLor6Wg6Ce
7 |
8 |
9 |
10 |
11 |
12 | urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress
13 | urn:oasis:names:tc:SAML:2.0:nameid-format:persistent
14 | urn:oasis:names:tc:SAML:2.0:nameid-format:transient
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/spring-boot-security-saml-demo-auth0/src/main/resources/localhost.cert:
--------------------------------------------------------------------------------
1 | -----BEGIN CERTIFICATE-----
2 | MIIC+zCCAeOgAwIBAgIJAIU7CnmezGizMA0GCSqGSIb3DQEBBQUAMBQxEjAQBgNV
3 | BAMMCWxvY2FsaG9zdDAeFw0xNjA0MDMwMjEwMjVaFw0yNjA0MDEwMjEwMjVaMBQx
4 | EjAQBgNVBAMMCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
5 | ggEBAN1NO3L/yCCb+MYFkypvJXcjlQuyRG7UFATYOYQZzIxsD9AtnXPh67uVkZTI
6 | oK7Ps5X4a5qVARtdN+GCFZ/ITahlAlIx8rmVsbz+7XPWpGPf75tKbem3pON2NlYW
7 | wIEQqyuValZHDUMgIXPdGIAZeNejVu7gYMLJwiSMtB0uBM69ptzgigJcbnup/cSL
8 | W4fBh4ck5kj0SVmX58knfaizrVf+ghGyNFha9Xy+DoilCofxwFIpVskv/hczZ5L+
9 | e81R+u2UbNzRwf8paF5fdVwaHPGLOYSBGjSm71VDdJqlvKrJCBoCQODhtmJOmDHD
10 | jtf6gwwbdg3g9GvyqIJnRqBO908CAwEAAaNQME4wHQYDVR0OBBYEFMNtl5fAchs3
11 | 5gZS4EF8/0C7QfBQMB8GA1UdIwQYMBaAFMNtl5fAchs35gZS4EF8/0C7QfBQMAwG
12 | A1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAADVL8LgYGlmaHlyrKyKfsQF
13 | TVbdT1Fk3WaGocVbhmvFeEBHScSJNR0syDcDM1C18pZ6Jc73cW7UdtLbLbRNPXS+
14 | qcp5GZroafndPIL2QzdKXfc5MiGH7CRCZit9kiNJ6YYgsztappXnwKblioJHB1Bc
15 | oLRzMeD295DAGLEVuc5tSY7JHBD3YQS9Pwt3ivrvvCzFKOU9nHqChMCplO4StGpS
16 | bbSR6XNgsPA0XLWlleuTqLGvJ4bHXPKC+0Y+0AiQYx3GeWLVrwJ4w+PFEK73vyuB
17 | 9H10x+zy1nFWvqoa+K66EA4u7DpEoHJBlqH0AVWAd8q9488DpCo1x4ujTGw7AHE=
18 | -----END CERTIFICATE-----
19 |
--------------------------------------------------------------------------------
/spring-boot-security-saml-demo-auth0/src/main/resources/localhost.jks:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ulisesbocchio/spring-boot-security-saml-samples/9ef34b596d6f5ffe9ddad04cabdc896cad73e4f9/spring-boot-security-saml-demo-auth0/src/main/resources/localhost.jks
--------------------------------------------------------------------------------
/spring-boot-security-saml-demo-auth0/src/main/resources/localhost.key.der:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ulisesbocchio/spring-boot-security-saml-samples/9ef34b596d6f5ffe9ddad04cabdc896cad73e4f9/spring-boot-security-saml-demo-auth0/src/main/resources/localhost.key.der
--------------------------------------------------------------------------------
/spring-boot-security-saml-demo-auth0/src/main/resources/logback.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/spring-boot-security-saml-demo-auth0/src/main/resources/templates/help.html:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 | Help Page
6 |
7 |
8 | Help Page
9 |
10 | This is an UNPROTECTED Resource
11 |
12 | Home
13 |
14 |
--------------------------------------------------------------------------------
/spring-boot-security-saml-demo-auth0/src/main/resources/templates/home.html:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 | Home Page
6 |
7 |
8 | This is the Home Page
9 |
10 | Current User: unknown
11 |
12 |
13 |
14 | | SAML Attributes |
15 |
16 |
17 | | Attribute Name |
18 | Attribute Value |
19 |
20 |
21 |
22 | | key |
23 | value |
24 |
25 |
26 |
27 | Idp Single Logout - Local Logout
28 |
29 |
30 |
--------------------------------------------------------------------------------
/spring-boot-security-saml-demo-auth0/src/main/resources/templates/idpselection.html:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 | IdP Selection
6 |
7 |
8 | Select an IdP:
9 |
21 |
22 |
--------------------------------------------------------------------------------
/spring-boot-security-saml-demo-auth0/src/main/resources/templates/index.html:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 | Sample SAML Spring Boot Application
6 |
7 |
8 | Hi, Click here to start the Single Sign On process
9 |
10 |
--------------------------------------------------------------------------------
/spring-boot-security-saml-demo-auth0/src/main/resources/templates/protected.html:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 | Protected Resource
6 |
7 |
8 | Protected Resource
9 |
10 | This is a Protected Resource
11 |
12 | Home
13 |
14 |
--------------------------------------------------------------------------------
/spring-boot-security-saml-demo-auth0/src/test/java/com/github/ulisesbocchio/demo/SpringBootSecuritySamlDemoApplicationTests.java:
--------------------------------------------------------------------------------
1 | package com.github.ulisesbocchio.demo;
2 |
3 | import org.junit.Test;
4 | import org.junit.runner.RunWith;
5 | import org.springframework.boot.test.context.SpringBootTest;
6 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
7 | import org.springframework.test.context.web.WebAppConfiguration;
8 |
9 | @RunWith(SpringJUnit4ClassRunner.class)
10 | @SpringBootTest(classes = Auth0SSODemoApplication.class)
11 | @WebAppConfiguration
12 | public class SpringBootSecuritySamlDemoApplicationTests {
13 |
14 | @Test
15 | public void contextLoads() {
16 | }
17 |
18 | }
19 |
--------------------------------------------------------------------------------
/spring-boot-security-saml-demo-dsl/.mvn/wrapper/maven-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.3.3/apache-maven-3.3.3-bin.zip
--------------------------------------------------------------------------------
/spring-boot-security-saml-demo-dsl/mvnw.cmd:
--------------------------------------------------------------------------------
1 | @REM ----------------------------------------------------------------------------
2 | @REM Licensed to the Apache Software Foundation (ASF) under one
3 | @REM or more contributor license agreements. See the NOTICE file
4 | @REM distributed with this work for additional information
5 | @REM regarding copyright ownership. The ASF licenses this file
6 | @REM to you under the Apache License, Version 2.0 (the
7 | @REM "License"); you may not use this file except in compliance
8 | @REM with the License. You may obtain a copy of the License at
9 | @REM
10 | @REM http://www.apache.org/licenses/LICENSE-2.0
11 | @REM
12 | @REM Unless required by applicable law or agreed to in writing,
13 | @REM software distributed under the License is distributed on an
14 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | @REM KIND, either express or implied. See the License for the
16 | @REM specific language governing permissions and limitations
17 | @REM under the License.
18 | @REM ----------------------------------------------------------------------------
19 |
20 | @REM ----------------------------------------------------------------------------
21 | @REM Maven2 Start Up Batch script
22 | @REM
23 | @REM Required ENV vars:
24 | @REM JAVA_HOME - location of a JDK home dir
25 | @REM
26 | @REM Optional ENV vars
27 | @REM M2_HOME - location of maven2's installed home dir
28 | @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
29 | @REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending
30 | @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
31 | @REM e.g. to debug Maven itself, use
32 | @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
33 | @REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
34 | @REM ----------------------------------------------------------------------------
35 |
36 | @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
37 | @echo off
38 | @REM enable echoing my setting MAVEN_BATCH_ECHO to 'on'
39 | @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
40 |
41 | @REM set %HOME% to equivalent of $HOME
42 | if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
43 |
44 | @REM Execute a user defined script before this one
45 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
46 | @REM check for pre script, once with legacy .bat ending and once with .cmd ending
47 | if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat"
48 | if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd"
49 | :skipRcPre
50 |
51 | @setlocal
52 |
53 | set ERROR_CODE=0
54 |
55 | @REM To isolate internal variables from possible post scripts, we use another setlocal
56 | @setlocal
57 |
58 | @REM ==== START VALIDATION ====
59 | if not "%JAVA_HOME%" == "" goto OkJHome
60 |
61 | echo.
62 | echo Error: JAVA_HOME not found in your environment. >&2
63 | echo Please set the JAVA_HOME variable in your environment to match the >&2
64 | echo location of your Java installation. >&2
65 | echo.
66 | goto error
67 |
68 | :OkJHome
69 | if exist "%JAVA_HOME%\bin\java.exe" goto init
70 |
71 | echo.
72 | echo Error: JAVA_HOME is set to an invalid directory. >&2
73 | echo JAVA_HOME = "%JAVA_HOME%" >&2
74 | echo Please set the JAVA_HOME variable in your environment to match the >&2
75 | echo location of your Java installation. >&2
76 | echo.
77 | goto error
78 |
79 | @REM ==== END VALIDATION ====
80 |
81 | :init
82 |
83 | set MAVEN_CMD_LINE_ARGS=%*
84 |
85 | @REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
86 | @REM Fallback to current working directory if not found.
87 |
88 | set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
89 | IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
90 |
91 | set EXEC_DIR=%CD%
92 | set WDIR=%EXEC_DIR%
93 | :findBaseDir
94 | IF EXIST "%WDIR%"\.mvn goto baseDirFound
95 | cd ..
96 | IF "%WDIR%"=="%CD%" goto baseDirNotFound
97 | set WDIR=%CD%
98 | goto findBaseDir
99 |
100 | :baseDirFound
101 | set MAVEN_PROJECTBASEDIR=%WDIR%
102 | cd "%EXEC_DIR%"
103 | goto endDetectBaseDir
104 |
105 | :baseDirNotFound
106 | set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
107 | cd "%EXEC_DIR%"
108 |
109 | :endDetectBaseDir
110 |
111 | IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
112 |
113 | @setlocal EnableExtensions EnableDelayedExpansion
114 | for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
115 | @endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
116 |
117 | :endReadAdditionalConfig
118 |
119 | SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
120 |
121 | set WRAPPER_JAR="".\.mvn\wrapper\maven-wrapper.jar""
122 | set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
123 |
124 | %MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CMD_LINE_ARGS%
125 | if ERRORLEVEL 1 goto error
126 | goto end
127 |
128 | :error
129 | set ERROR_CODE=1
130 |
131 | :end
132 | @endlocal & set ERROR_CODE=%ERROR_CODE%
133 |
134 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost
135 | @REM check for post script, once with legacy .bat ending and once with .cmd ending
136 | if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat"
137 | if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd"
138 | :skipRcPost
139 |
140 | @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
141 | if "%MAVEN_BATCH_PAUSE%" == "on" pause
142 |
143 | if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE%
144 |
145 | exit /B %ERROR_CODE%
--------------------------------------------------------------------------------
/spring-boot-security-saml-demo-dsl/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 4.0.0
4 |
5 | spring-boot-security-saml-demo-dsl
6 | jar
7 |
8 | Spring Boot Security SAML Demo with Java DSL
9 | Demo project for Spring Boot
10 |
11 |
12 | com.github.ulisesbocchio
13 | spring-boot-security-saml-samples-parent
14 | 1.3-SNAPSHOT
15 |
16 |
17 |
18 | UTF-8
19 | 1.8
20 | com.github.ulisesbocchio.demo.SpringBootSecuritySAMLDemoApplication
21 |
22 |
23 |
24 |
25 | org.projectlombok
26 | lombok
27 | 1.16.6
28 |
29 |
30 | com.github.ulisesbocchio
31 | spring-boot-security-saml
32 |
33 |
34 | org.springframework.boot
35 | spring-boot-starter-web
36 |
37 |
38 | org.springframework.boot
39 | spring-boot-starter-thymeleaf
40 |
41 |
42 | org.springframework.boot
43 | spring-boot-starter-test
44 | test
45 |
46 |
47 |
48 |
49 |
50 |
51 | org.springframework.boot
52 | spring-boot-maven-plugin
53 |
54 |
55 |
56 |
57 |
--------------------------------------------------------------------------------
/spring-boot-security-saml-demo-dsl/src/main/java/com/github/ulisesbocchio/demo/EnableSAMLSSOWhenNotInTest.java:
--------------------------------------------------------------------------------
1 | package com.github.ulisesbocchio.demo;
2 |
3 | import com.github.ulisesbocchio.spring.boot.security.saml.annotation.EnableSAMLSSO;
4 | import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass;
5 |
6 | import java.lang.annotation.ElementType;
7 | import java.lang.annotation.Retention;
8 | import java.lang.annotation.RetentionPolicy;
9 | import java.lang.annotation.Target;
10 |
11 | @ConditionalOnMissingClass("org.junit.Test")
12 | @EnableSAMLSSO
13 | @Target(ElementType.TYPE)
14 | @Retention(RetentionPolicy.RUNTIME)
15 | public @interface EnableSAMLSSOWhenNotInTest {
16 | }
17 |
--------------------------------------------------------------------------------
/spring-boot-security-saml-demo-dsl/src/main/java/com/github/ulisesbocchio/demo/SpringBootSecuritySAMLDemoApplication.java:
--------------------------------------------------------------------------------
1 | package com.github.ulisesbocchio.demo;
2 |
3 | import com.github.ulisesbocchio.spring.boot.security.saml.configurer.ServiceProviderBuilder;
4 | import com.github.ulisesbocchio.spring.boot.security.saml.configurer.ServiceProviderConfigurerAdapter;
5 | import org.springframework.boot.SpringApplication;
6 | import org.springframework.boot.autoconfigure.SpringBootApplication;
7 | import org.springframework.context.annotation.Configuration;
8 | import org.springframework.security.config.annotation.web.builders.HttpSecurity;
9 | import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
10 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
11 |
12 | @SpringBootApplication
13 | @EnableSAMLSSOWhenNotInTest
14 | public class SpringBootSecuritySAMLDemoApplication {
15 |
16 | public static void main(String[] args) {
17 | SpringApplication.run(SpringBootSecuritySAMLDemoApplication.class, args);
18 | }
19 |
20 | @Configuration
21 | public static class MvcConfig implements WebMvcConfigurer {
22 |
23 | @Override
24 | public void addViewControllers(ViewControllerRegistry registry) {
25 | registry.addViewController("/").setViewName("index");
26 | registry.addViewController("/protected").setViewName("protected");
27 | registry.addViewController("/afterlogout").setViewName("afterlogout");
28 |
29 | }
30 | }
31 |
32 | @Configuration
33 | public static class MyServiceProviderConfig extends ServiceProviderConfigurerAdapter {
34 |
35 | @Override
36 | public void configure(HttpSecurity http) throws Exception {
37 | http.authorizeRequests()
38 | .regexMatchers("/")
39 | .permitAll();
40 | }
41 |
42 | @Override
43 | public void configure(ServiceProviderBuilder serviceProvider) throws Exception {
44 | // @formatter:off
45 | serviceProvider
46 | .metadataGenerator()
47 | .entityId("localhost-demo")
48 | .and()
49 | .sso()
50 | .defaultSuccessURL("/home")
51 | .idpSelectionPageURL("/idpselection")
52 | .and()
53 | .logout()
54 | .defaultTargetURL("/afterlogout")
55 | .and()
56 | .metadataManager()
57 | .metadataLocations("classpath:/idp-ssocircle.xml")
58 | .refreshCheckInterval(0)
59 | .and()
60 | .extendedMetadata()
61 | .idpDiscoveryEnabled(true)
62 | .and()
63 | .keyManager()
64 | .privateKeyDERLocation("classpath:/localhost.key.der")
65 | .publicKeyPEMLocation("classpath:/localhost.cert")
66 | .and()
67 | .samlContextProviderLb()
68 | .scheme("http")
69 | .contextPath("/")
70 | .serverName("localhost")
71 | .serverPort(8080)
72 | .includeServerPortInRequestURL(true)
73 | .and();
74 | // @formatter:on
75 |
76 | }
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/spring-boot-security-saml-demo-dsl/src/main/java/com/github/ulisesbocchio/demo/controller/HomeController.java:
--------------------------------------------------------------------------------
1 | package com.github.ulisesbocchio.demo.controller;
2 |
3 | /**
4 | * @author Ulises Bocchio
5 | */
6 |
7 | import com.github.ulisesbocchio.spring.boot.security.saml.annotation.SAMLUser;
8 | import com.github.ulisesbocchio.spring.boot.security.saml.user.SAMLUserDetails;
9 | import org.springframework.stereotype.Controller;
10 | import org.springframework.web.bind.annotation.RequestMapping;
11 | import org.springframework.web.servlet.ModelAndView;
12 |
13 | @Controller
14 | public class HomeController {
15 |
16 | @RequestMapping("/home")
17 | public ModelAndView home(@SAMLUser SAMLUserDetails user) {
18 | ModelAndView homeView = new ModelAndView("home");
19 | homeView.addObject("userId", user.getUsername());
20 | homeView.addObject("samlAttributes", user.getAttributes());
21 | return homeView;
22 | }
23 |
24 | }
25 |
--------------------------------------------------------------------------------
/spring-boot-security-saml-demo-dsl/src/main/java/com/github/ulisesbocchio/demo/controller/IdPSelectionController.java:
--------------------------------------------------------------------------------
1 | package com.github.ulisesbocchio.demo.controller;
2 |
3 | /**
4 | * @author Ulises Bocchio
5 | */
6 |
7 | import lombok.extern.slf4j.Slf4j;
8 | import org.springframework.security.authentication.AuthenticationServiceException;
9 | import org.springframework.security.saml.SAMLConstants;
10 | import org.springframework.security.saml.SAMLDiscovery;
11 | import org.springframework.stereotype.Controller;
12 | import org.springframework.web.bind.annotation.RequestMapping;
13 | import org.springframework.web.servlet.ModelAndView;
14 |
15 | import javax.servlet.http.HttpServletRequest;
16 | import java.util.Collections;
17 |
18 | @Controller
19 | @RequestMapping("/idpselection")
20 | @Slf4j
21 | public class IdPSelectionController {
22 |
23 | @RequestMapping
24 | public ModelAndView idpSelection(HttpServletRequest request) {
25 |
26 | if (comesFromDiscoveryFilter(request)) {
27 | ModelAndView idpSelection = new ModelAndView("idpselection");
28 | idpSelection.addObject(SAMLDiscovery.RETURN_URL, request.getAttribute(SAMLDiscovery.RETURN_URL));
29 | idpSelection.addObject(SAMLDiscovery.RETURN_PARAM, request.getAttribute(SAMLDiscovery.RETURN_PARAM));
30 | idpSelection.addObject("idpNameAliasMap", Collections.singletonMap("http://idp.ssocircle.com", "SSO Circle"));
31 | return idpSelection;
32 | }
33 | throw new AuthenticationServiceException("SP Discovery flow not detected");
34 | }
35 |
36 | private boolean comesFromDiscoveryFilter(HttpServletRequest request) {
37 | return request.getAttribute(SAMLConstants.LOCAL_ENTITY_ID) != null &&
38 | request.getAttribute(SAMLDiscovery.RETURN_URL) != null &&
39 | request.getAttribute(SAMLDiscovery.RETURN_PARAM) != null;
40 | }
41 |
42 | }
43 |
--------------------------------------------------------------------------------
/spring-boot-security-saml-demo-dsl/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | security.user.name=user
2 | security.user.password=password
3 | logging.level.org.springframework.security.saml= DEBUG
4 | # Alternatively use below properties to configure the LB context provider
5 | #saml.sso.context-provider.lb.context-path=/
6 | #saml.sso.context-provider.lb.include-server-port-in-request-url=true
7 | #saml.sso.context-provider.lb.scheme=http
8 | #saml.sso.context-provider.lb.server-name=localhost
9 | #saml.sso.context-provider.lb.server-port=8080
--------------------------------------------------------------------------------
/spring-boot-security-saml-demo-dsl/src/main/resources/localhost.cert:
--------------------------------------------------------------------------------
1 | -----BEGIN CERTIFICATE-----
2 | MIIC+zCCAeOgAwIBAgIJAIU7CnmezGizMA0GCSqGSIb3DQEBBQUAMBQxEjAQBgNV
3 | BAMMCWxvY2FsaG9zdDAeFw0xNjA0MDMwMjEwMjVaFw0yNjA0MDEwMjEwMjVaMBQx
4 | EjAQBgNVBAMMCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
5 | ggEBAN1NO3L/yCCb+MYFkypvJXcjlQuyRG7UFATYOYQZzIxsD9AtnXPh67uVkZTI
6 | oK7Ps5X4a5qVARtdN+GCFZ/ITahlAlIx8rmVsbz+7XPWpGPf75tKbem3pON2NlYW
7 | wIEQqyuValZHDUMgIXPdGIAZeNejVu7gYMLJwiSMtB0uBM69ptzgigJcbnup/cSL
8 | W4fBh4ck5kj0SVmX58knfaizrVf+ghGyNFha9Xy+DoilCofxwFIpVskv/hczZ5L+
9 | e81R+u2UbNzRwf8paF5fdVwaHPGLOYSBGjSm71VDdJqlvKrJCBoCQODhtmJOmDHD
10 | jtf6gwwbdg3g9GvyqIJnRqBO908CAwEAAaNQME4wHQYDVR0OBBYEFMNtl5fAchs3
11 | 5gZS4EF8/0C7QfBQMB8GA1UdIwQYMBaAFMNtl5fAchs35gZS4EF8/0C7QfBQMAwG
12 | A1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAADVL8LgYGlmaHlyrKyKfsQF
13 | TVbdT1Fk3WaGocVbhmvFeEBHScSJNR0syDcDM1C18pZ6Jc73cW7UdtLbLbRNPXS+
14 | qcp5GZroafndPIL2QzdKXfc5MiGH7CRCZit9kiNJ6YYgsztappXnwKblioJHB1Bc
15 | oLRzMeD295DAGLEVuc5tSY7JHBD3YQS9Pwt3ivrvvCzFKOU9nHqChMCplO4StGpS
16 | bbSR6XNgsPA0XLWlleuTqLGvJ4bHXPKC+0Y+0AiQYx3GeWLVrwJ4w+PFEK73vyuB
17 | 9H10x+zy1nFWvqoa+K66EA4u7DpEoHJBlqH0AVWAd8q9488DpCo1x4ujTGw7AHE=
18 | -----END CERTIFICATE-----
19 |
--------------------------------------------------------------------------------
/spring-boot-security-saml-demo-dsl/src/main/resources/localhost.key.der:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ulisesbocchio/spring-boot-security-saml-samples/9ef34b596d6f5ffe9ddad04cabdc896cad73e4f9/spring-boot-security-saml-demo-dsl/src/main/resources/localhost.key.der
--------------------------------------------------------------------------------
/spring-boot-security-saml-demo-dsl/src/main/resources/logback.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/spring-boot-security-saml-demo-dsl/src/main/resources/templates/afterlogout.html:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 | Sample SAML Spring Boot Application
6 |
7 |
8 | Goodbye! Click here if you wanna log back in
9 |
10 |
--------------------------------------------------------------------------------
/spring-boot-security-saml-demo-dsl/src/main/resources/templates/home.html:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 | Home Page
6 |
7 |
8 | This is the Home Page
9 |
10 | Current User: unknown
11 |
12 |
13 |
14 | | SAML Attributes |
15 |
16 |
17 | | Attribute Name |
18 | Attribute Value |
19 |
20 |
21 |
22 | | key |
23 | value |
24 |
25 |
26 |
27 | Idp Single Logout - Local Logout
28 |
29 |
30 |
--------------------------------------------------------------------------------
/spring-boot-security-saml-demo-dsl/src/main/resources/templates/idpselection.html:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 | IdP Selection
6 |
7 |
8 | Select an IdP:
9 |
21 |
22 |
--------------------------------------------------------------------------------
/spring-boot-security-saml-demo-dsl/src/main/resources/templates/index.html:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 | Sample SAML Spring Boot Application
6 |
7 |
8 | Hi, Click here to start the Single Sign On process
9 |
10 |
--------------------------------------------------------------------------------
/spring-boot-security-saml-demo-dsl/src/main/resources/templates/protected.html:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 | Protected Resource
6 |
7 |
8 | Protected Resource
9 |
10 | This is a Protected Resource
11 |
12 | Home
13 |
14 |
--------------------------------------------------------------------------------
/spring-boot-security-saml-demo-dsl/src/test/java/com/github/ulisesbocchio/demo/SpringBootSecuritySamlDemoApplicationTests.java:
--------------------------------------------------------------------------------
1 | package com.github.ulisesbocchio.demo;
2 |
3 | import org.junit.Test;
4 | import org.junit.runner.RunWith;
5 | import org.springframework.boot.test.context.SpringBootTest;
6 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
7 | import org.springframework.test.context.web.WebAppConfiguration;
8 |
9 | @RunWith(SpringJUnit4ClassRunner.class)
10 | @SpringBootTest(classes = SpringBootSecuritySAMLDemoApplication.class)
11 | @WebAppConfiguration
12 | public class SpringBootSecuritySamlDemoApplicationTests {
13 |
14 | @Test
15 | public void contextLoads() {
16 | }
17 |
18 | }
19 |
--------------------------------------------------------------------------------
/spring-boot-security-saml-demo-okta/.mvn/wrapper/maven-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.3.3/apache-maven-3.3.3-bin.zip
--------------------------------------------------------------------------------
/spring-boot-security-saml-demo-okta/README.md:
--------------------------------------------------------------------------------
1 | ## Spring Boot Security SAML Sample with OKTA as IDP ##
2 |
3 | Simply run the Spring Boot app and login with the following credentials:
4 |
5 | - user: dough1234321@gmail.com pass: Test1234!
--------------------------------------------------------------------------------
/spring-boot-security-saml-demo-okta/mvnw.cmd:
--------------------------------------------------------------------------------
1 | @REM ----------------------------------------------------------------------------
2 | @REM Licensed to the Apache Software Foundation (ASF) under one
3 | @REM or more contributor license agreements. See the NOTICE file
4 | @REM distributed with this work for additional information
5 | @REM regarding copyright ownership. The ASF licenses this file
6 | @REM to you under the Apache License, Version 2.0 (the
7 | @REM "License"); you may not use this file except in compliance
8 | @REM with the License. You may obtain a copy of the License at
9 | @REM
10 | @REM http://www.apache.org/licenses/LICENSE-2.0
11 | @REM
12 | @REM Unless required by applicable law or agreed to in writing,
13 | @REM software distributed under the License is distributed on an
14 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | @REM KIND, either express or implied. See the License for the
16 | @REM specific language governing permissions and limitations
17 | @REM under the License.
18 | @REM ----------------------------------------------------------------------------
19 |
20 | @REM ----------------------------------------------------------------------------
21 | @REM Maven2 Start Up Batch script
22 | @REM
23 | @REM Required ENV vars:
24 | @REM JAVA_HOME - location of a JDK home dir
25 | @REM
26 | @REM Optional ENV vars
27 | @REM M2_HOME - location of maven2's installed home dir
28 | @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
29 | @REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending
30 | @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
31 | @REM e.g. to debug Maven itself, use
32 | @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
33 | @REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
34 | @REM ----------------------------------------------------------------------------
35 |
36 | @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
37 | @echo off
38 | @REM enable echoing my setting MAVEN_BATCH_ECHO to 'on'
39 | @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
40 |
41 | @REM set %HOME% to equivalent of $HOME
42 | if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
43 |
44 | @REM Execute a user defined script before this one
45 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
46 | @REM check for pre script, once with legacy .bat ending and once with .cmd ending
47 | if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat"
48 | if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd"
49 | :skipRcPre
50 |
51 | @setlocal
52 |
53 | set ERROR_CODE=0
54 |
55 | @REM To isolate internal variables from possible post scripts, we use another setlocal
56 | @setlocal
57 |
58 | @REM ==== START VALIDATION ====
59 | if not "%JAVA_HOME%" == "" goto OkJHome
60 |
61 | echo.
62 | echo Error: JAVA_HOME not found in your environment. >&2
63 | echo Please set the JAVA_HOME variable in your environment to match the >&2
64 | echo location of your Java installation. >&2
65 | echo.
66 | goto error
67 |
68 | :OkJHome
69 | if exist "%JAVA_HOME%\bin\java.exe" goto init
70 |
71 | echo.
72 | echo Error: JAVA_HOME is set to an invalid directory. >&2
73 | echo JAVA_HOME = "%JAVA_HOME%" >&2
74 | echo Please set the JAVA_HOME variable in your environment to match the >&2
75 | echo location of your Java installation. >&2
76 | echo.
77 | goto error
78 |
79 | @REM ==== END VALIDATION ====
80 |
81 | :init
82 |
83 | set MAVEN_CMD_LINE_ARGS=%*
84 |
85 | @REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
86 | @REM Fallback to current working directory if not found.
87 |
88 | set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
89 | IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
90 |
91 | set EXEC_DIR=%CD%
92 | set WDIR=%EXEC_DIR%
93 | :findBaseDir
94 | IF EXIST "%WDIR%"\.mvn goto baseDirFound
95 | cd ..
96 | IF "%WDIR%"=="%CD%" goto baseDirNotFound
97 | set WDIR=%CD%
98 | goto findBaseDir
99 |
100 | :baseDirFound
101 | set MAVEN_PROJECTBASEDIR=%WDIR%
102 | cd "%EXEC_DIR%"
103 | goto endDetectBaseDir
104 |
105 | :baseDirNotFound
106 | set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
107 | cd "%EXEC_DIR%"
108 |
109 | :endDetectBaseDir
110 |
111 | IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
112 |
113 | @setlocal EnableExtensions EnableDelayedExpansion
114 | for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
115 | @endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
116 |
117 | :endReadAdditionalConfig
118 |
119 | SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
120 |
121 | set WRAPPER_JAR="".\.mvn\wrapper\maven-wrapper.jar""
122 | set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
123 |
124 | %MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CMD_LINE_ARGS%
125 | if ERRORLEVEL 1 goto error
126 | goto end
127 |
128 | :error
129 | set ERROR_CODE=1
130 |
131 | :end
132 | @endlocal & set ERROR_CODE=%ERROR_CODE%
133 |
134 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost
135 | @REM check for post script, once with legacy .bat ending and once with .cmd ending
136 | if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat"
137 | if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd"
138 | :skipRcPost
139 |
140 | @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
141 | if "%MAVEN_BATCH_PAUSE%" == "on" pause
142 |
143 | if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE%
144 |
145 | exit /B %ERROR_CODE%
--------------------------------------------------------------------------------
/spring-boot-security-saml-demo-okta/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 4.0.0
4 |
5 | spring-boot-security-saml-demo-okta
6 | jar
7 |
8 | Spring Boot Security SAML Demo with Okta IDP
9 | Demo project for Spring Boot
10 |
11 |
12 | com.github.ulisesbocchio
13 | spring-boot-security-saml-samples-parent
14 | 1.3-SNAPSHOT
15 |
16 |
17 |
18 | UTF-8
19 | 1.8
20 | com.github.ulisesbocchio.demo.OktaSSODemoApplication
21 |
22 |
23 |
24 |
25 | org.projectlombok
26 | lombok
27 | 1.16.6
28 |
29 |
30 | com.github.ulisesbocchio
31 | spring-boot-security-saml
32 |
33 |
34 | org.springframework.boot
35 | spring-boot-starter-web
36 |
37 |
38 | org.springframework.boot
39 | spring-boot-starter-thymeleaf
40 |
41 |
42 | org.springframework.boot
43 | spring-boot-starter-test
44 | test
45 |
46 |
47 |
48 |
49 |
50 |
51 | org.springframework.boot
52 | spring-boot-maven-plugin
53 |
54 |
55 |
56 |
57 |
--------------------------------------------------------------------------------
/spring-boot-security-saml-demo-okta/src/main/java/com/github/ulisesbocchio/demo/OktaSSODemoApplication.java:
--------------------------------------------------------------------------------
1 | package com.github.ulisesbocchio.demo;
2 |
3 | import com.github.ulisesbocchio.spring.boot.security.saml.annotation.EnableSAMLSSO;
4 | import com.github.ulisesbocchio.spring.boot.security.saml.configurer.ServiceProviderConfigurerAdapter;
5 | import com.github.ulisesbocchio.spring.boot.security.saml.configurer.ServiceProviderBuilder;
6 |
7 | import org.springframework.boot.SpringApplication;
8 | import org.springframework.boot.autoconfigure.SpringBootApplication;
9 | import org.springframework.context.annotation.Configuration;
10 | import org.springframework.security.config.annotation.web.builders.HttpSecurity;
11 | import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
12 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
13 |
14 | @SpringBootApplication
15 | @EnableSAMLSSO
16 | public class OktaSSODemoApplication {
17 |
18 | public static void main(String[] args) {
19 | SpringApplication.run(OktaSSODemoApplication.class, args);
20 | }
21 |
22 | @Configuration
23 | public static class MvcConfig implements WebMvcConfigurer {
24 |
25 | @Override
26 | public void addViewControllers(ViewControllerRegistry registry) {
27 | registry.addViewController("/").setViewName("index");
28 | registry.addViewController("/protected").setViewName("protected");
29 | registry.addViewController("/unprotected/help").setViewName("help");
30 |
31 | }
32 | }
33 |
34 | @Configuration
35 | public static class MyServiceProviderConfig extends ServiceProviderConfigurerAdapter {
36 |
37 | @Override
38 | public void configure(HttpSecurity http) throws Exception {
39 | // @formatter:off
40 | http.authorizeRequests()
41 | .antMatchers("/unprotected/**")
42 | .permitAll()
43 | .and()
44 | .anonymous();
45 | // @formatter:on
46 | }
47 |
48 | @Override
49 | public void configure(ServiceProviderBuilder serviceProvider) throws Exception {
50 | // @formatter:off
51 | serviceProvider
52 | .metadataGenerator()
53 | .entityId("localhost-demo")
54 | .bindingsSSO("artifact", "post", "paos")
55 | .and()
56 | .ecpProfile()
57 | .and()
58 | .sso()
59 | .defaultSuccessURL("/home")
60 | .idpSelectionPageURL("/idpselection")
61 | .and()
62 | .metadataManager()
63 | .metadataLocations("classpath:/idp-okta.xml")
64 | .refreshCheckInterval(0)
65 | .and()
66 | .extendedMetadata()
67 | .ecpEnabled(true)
68 | .idpDiscoveryEnabled(true)//set to false for no IDP Selection page.
69 | .and()
70 | .keyManager()
71 | .privateKeyDERLocation("classpath:/localhost.key.der")
72 | .publicKeyPEMLocation("classpath:/localhost.cert");
73 | // @formatter:on
74 |
75 | }
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/spring-boot-security-saml-demo-okta/src/main/java/com/github/ulisesbocchio/demo/controller/HomeController.java:
--------------------------------------------------------------------------------
1 | package com.github.ulisesbocchio.demo.controller;
2 |
3 | /**
4 | * @author Ulises Bocchio
5 | */
6 |
7 | import com.github.ulisesbocchio.spring.boot.security.saml.annotation.SAMLUser;
8 | import com.github.ulisesbocchio.spring.boot.security.saml.user.SAMLUserDetails;
9 | import org.springframework.stereotype.Controller;
10 | import org.springframework.web.bind.annotation.RequestMapping;
11 | import org.springframework.web.servlet.ModelAndView;
12 |
13 | @Controller
14 | public class HomeController {
15 |
16 | @RequestMapping("/home")
17 | public ModelAndView home(@SAMLUser SAMLUserDetails user) {
18 | ModelAndView homeView = new ModelAndView("home");
19 | homeView.addObject("userId", user.getUsername());
20 | homeView.addObject("samlAttributes", user.getAttributes());
21 | return homeView;
22 | }
23 |
24 | }
25 |
--------------------------------------------------------------------------------
/spring-boot-security-saml-demo-okta/src/main/java/com/github/ulisesbocchio/demo/controller/IdPSelectionController.java:
--------------------------------------------------------------------------------
1 | package com.github.ulisesbocchio.demo.controller;
2 |
3 | /**
4 | * @author Ulises Bocchio
5 | */
6 |
7 | import lombok.extern.slf4j.Slf4j;
8 | import org.springframework.security.authentication.AuthenticationServiceException;
9 | import org.springframework.security.saml.SAMLConstants;
10 | import org.springframework.security.saml.SAMLDiscovery;
11 | import org.springframework.stereotype.Controller;
12 | import org.springframework.web.bind.annotation.RequestMapping;
13 | import org.springframework.web.servlet.ModelAndView;
14 |
15 | import javax.servlet.http.HttpServletRequest;
16 | import java.util.Collections;
17 |
18 | @Controller
19 | @RequestMapping("/idpselection")
20 | @Slf4j
21 | public class IdPSelectionController {
22 |
23 | @RequestMapping
24 | public ModelAndView idpSelection(HttpServletRequest request) {
25 |
26 | if (comesFromDiscoveryFilter(request)) {
27 | ModelAndView idpSelection = new ModelAndView("idpselection");
28 | idpSelection.addObject(SAMLDiscovery.RETURN_URL, request.getAttribute(SAMLDiscovery.RETURN_URL));
29 | idpSelection.addObject(SAMLDiscovery.RETURN_PARAM, request.getAttribute(SAMLDiscovery.RETURN_PARAM));
30 | idpSelection.addObject("idpNameAliasMap", Collections.singletonMap("http://www.okta.com/exk62w7tqv0xkRl9p0h7", "Okta"));
31 | return idpSelection;
32 | }
33 | throw new AuthenticationServiceException("SP Discovery flow not detected");
34 | }
35 |
36 | private boolean comesFromDiscoveryFilter(HttpServletRequest request) {
37 | return request.getAttribute(SAMLConstants.LOCAL_ENTITY_ID) != null &&
38 | request.getAttribute(SAMLDiscovery.RETURN_URL) != null &&
39 | request.getAttribute(SAMLDiscovery.RETURN_PARAM) != null;
40 | }
41 |
42 | }
43 |
--------------------------------------------------------------------------------
/spring-boot-security-saml-demo-okta/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | security.user.name=user
2 | security.user.password=password
3 | logging.level.org.springframework.security.saml= DEBUG
--------------------------------------------------------------------------------
/spring-boot-security-saml-demo-okta/src/main/resources/idp-okta.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
9 | MIIDpDCCAoygAwIBAgIGAVO669oLMA0GCSqGSIb3DQEBBQUAMIGSMQswCQYDVQQGEwJVUzETMBEG
10 | A1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzENMAsGA1UECgwET2t0YTEU
11 | MBIGA1UECwwLU1NPUHJvdmlkZXIxEzARBgNVBAMMCmRldi04MzkyMjgxHDAaBgkqhkiG9w0BCQEW
12 | DWluZm9Ab2t0YS5jb20wHhcNMTYwMzI4MDE1MTEyWhcNMjYwMzI4MDE1MjEyWjCBkjELMAkGA1UE
13 | BhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNVBAcMDVNhbiBGcmFuY2lzY28xDTALBgNV
14 | BAoMBE9rdGExFDASBgNVBAsMC1NTT1Byb3ZpZGVyMRMwEQYDVQQDDApkZXYtODM5MjI4MRwwGgYJ
15 | KoZIhvcNAQkBFg1pbmZvQG9rdGEuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
16 | 0H9hcvueaxQsH+GjDBPJdQ3FotGgPFOyFuZFvDwBeXiTMPAMoB8s+9Ey7ugYoAvLJMm7ryXAhOGa
17 | tblP4BcxPWrFJx+Tddswkb9pmM9rbmfrBBW3gsiwPQ/bEuwnvNxICIaeWD7h50Qej8UgrSunqmEq
18 | pBYi530/mWy7fdyRWniC0NtqlGDc+7jM4itchIjxuJXm0MX8BTzUkk8yU/Ul/YwNCwTAZNwispES
19 | ADsU9Mc+qcI6Fc68NC8pzPTpV4XEIiDwK8bfdQa1kwM3teL+1cHTXkEMvfhzBLZLedaB7b2Ictp+
20 | /mPtX/m9+zu/oqeZs1ZfCPfOpaNQCw4ug/G7PQIDAQABMA0GCSqGSIb3DQEBBQUAA4IBAQAxlYaA
21 | PPB8kvNZgLX1V/WGxfpQTZMVLJGCfVA50I7wzRn+bDgkLhl2L3Rn7V7epQ7yOGYoIZ2QZGqu8fto
22 | xyXLmbx+gKvrejPp8QGCDl4Ga9UppIRtvdnLpXKeBw1m2GbLbgIlMmCbSGo05YSxBM7m6C7ZBDbA
23 | Sn8kNrM+77jWPs+uRO/Oe9UlMGIMIvxaUyy7H9TpUNHAMQKwYPiua/32T53iv9TZ6YYgdK1b2haA
24 | N3ESCsNEmU5BRZBQgBMRiw1qfWt5tGpAxjCKkVFEwR6gQwqH5QhAnzA9lyVAq8FGr7HDxMyLoObB
25 | avSvuMAJ1fZFZh4v3XJussihq2MjHH3g
26 |
27 |
28 |
29 |
30 |
32 |
34 | urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress
35 | urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified
36 |
38 |
40 |
41 |
--------------------------------------------------------------------------------
/spring-boot-security-saml-demo-okta/src/main/resources/localhost.cert:
--------------------------------------------------------------------------------
1 | -----BEGIN CERTIFICATE-----
2 | MIIC+zCCAeOgAwIBAgIJAIU7CnmezGizMA0GCSqGSIb3DQEBBQUAMBQxEjAQBgNV
3 | BAMMCWxvY2FsaG9zdDAeFw0xNjA0MDMwMjEwMjVaFw0yNjA0MDEwMjEwMjVaMBQx
4 | EjAQBgNVBAMMCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
5 | ggEBAN1NO3L/yCCb+MYFkypvJXcjlQuyRG7UFATYOYQZzIxsD9AtnXPh67uVkZTI
6 | oK7Ps5X4a5qVARtdN+GCFZ/ITahlAlIx8rmVsbz+7XPWpGPf75tKbem3pON2NlYW
7 | wIEQqyuValZHDUMgIXPdGIAZeNejVu7gYMLJwiSMtB0uBM69ptzgigJcbnup/cSL
8 | W4fBh4ck5kj0SVmX58knfaizrVf+ghGyNFha9Xy+DoilCofxwFIpVskv/hczZ5L+
9 | e81R+u2UbNzRwf8paF5fdVwaHPGLOYSBGjSm71VDdJqlvKrJCBoCQODhtmJOmDHD
10 | jtf6gwwbdg3g9GvyqIJnRqBO908CAwEAAaNQME4wHQYDVR0OBBYEFMNtl5fAchs3
11 | 5gZS4EF8/0C7QfBQMB8GA1UdIwQYMBaAFMNtl5fAchs35gZS4EF8/0C7QfBQMAwG
12 | A1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAADVL8LgYGlmaHlyrKyKfsQF
13 | TVbdT1Fk3WaGocVbhmvFeEBHScSJNR0syDcDM1C18pZ6Jc73cW7UdtLbLbRNPXS+
14 | qcp5GZroafndPIL2QzdKXfc5MiGH7CRCZit9kiNJ6YYgsztappXnwKblioJHB1Bc
15 | oLRzMeD295DAGLEVuc5tSY7JHBD3YQS9Pwt3ivrvvCzFKOU9nHqChMCplO4StGpS
16 | bbSR6XNgsPA0XLWlleuTqLGvJ4bHXPKC+0Y+0AiQYx3GeWLVrwJ4w+PFEK73vyuB
17 | 9H10x+zy1nFWvqoa+K66EA4u7DpEoHJBlqH0AVWAd8q9488DpCo1x4ujTGw7AHE=
18 | -----END CERTIFICATE-----
19 |
--------------------------------------------------------------------------------
/spring-boot-security-saml-demo-okta/src/main/resources/localhost.key.der:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ulisesbocchio/spring-boot-security-saml-samples/9ef34b596d6f5ffe9ddad04cabdc896cad73e4f9/spring-boot-security-saml-demo-okta/src/main/resources/localhost.key.der
--------------------------------------------------------------------------------
/spring-boot-security-saml-demo-okta/src/main/resources/logback.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/spring-boot-security-saml-demo-okta/src/main/resources/templates/help.html:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 | Help Page
6 |
7 |
8 | Help Page
9 |
10 | This is an UNPROTECTED Resource
11 |
12 | Home
13 |
14 |
--------------------------------------------------------------------------------
/spring-boot-security-saml-demo-okta/src/main/resources/templates/home.html:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 | Home Page
6 |
7 |
8 | This is the Home Page
9 |
10 | Current User: unknown
11 |
12 |
13 |
14 | | SAML Attributes |
15 |
16 |
17 | | Attribute Name |
18 | Attribute Value |
19 |
20 |
21 |
22 | | key |
23 | value |
24 |
25 |
26 |
27 | Idp Single Logout - Local Logout
28 |
29 |
30 |
--------------------------------------------------------------------------------
/spring-boot-security-saml-demo-okta/src/main/resources/templates/idpselection.html:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 | IdP Selection
6 |
7 |
8 | Select an IdP:
9 |
21 |
22 |
--------------------------------------------------------------------------------
/spring-boot-security-saml-demo-okta/src/main/resources/templates/index.html:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 | Sample SAML Spring Boot Application
6 |
7 |
8 | Hi, Click here to start the Single Sign On process
9 |
10 |
--------------------------------------------------------------------------------
/spring-boot-security-saml-demo-okta/src/main/resources/templates/protected.html:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 | Protected Resource
6 |
7 |
8 | Protected Resource
9 |
10 | This is a Protected Resource
11 |
12 | Home
13 |
14 |
--------------------------------------------------------------------------------
/spring-boot-security-saml-demo-okta/src/test/java/com/github/ulisesbocchio/demo/SpringBootSecuritySamlDemoApplicationTests.java:
--------------------------------------------------------------------------------
1 | package com.github.ulisesbocchio.demo;
2 |
3 | import org.junit.Test;
4 | import org.junit.runner.RunWith;
5 | import org.springframework.boot.test.context.SpringBootTest;
6 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
7 | import org.springframework.test.context.web.WebAppConfiguration;
8 |
9 | @RunWith(SpringJUnit4ClassRunner.class)
10 | @SpringBootTest(classes = OktaSSODemoApplication.class)
11 | @WebAppConfiguration
12 | public class SpringBootSecuritySamlDemoApplicationTests {
13 |
14 | @Test
15 | public void contextLoads() {
16 | }
17 |
18 | }
19 |
--------------------------------------------------------------------------------
/spring-boot-security-saml-demo-okta2/.mvn/wrapper/maven-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.3.3/apache-maven-3.3.3-bin.zip
--------------------------------------------------------------------------------
/spring-boot-security-saml-demo-okta2/README.md:
--------------------------------------------------------------------------------
1 | ## Spring Boot Security SAML Sample with OKTA as IDP ##
2 |
3 | Simply run the Spring Boot app and login with the following credentials:
4 |
5 | - user: dough1234321@gmail.com pass: Test1234!
6 |
7 | This sample showcases the use of SAMLConfigurerBean instead of ServiceProviderConfigurer
--------------------------------------------------------------------------------
/spring-boot-security-saml-demo-okta2/mvnw.cmd:
--------------------------------------------------------------------------------
1 | @REM ----------------------------------------------------------------------------
2 | @REM Licensed to the Apache Software Foundation (ASF) under one
3 | @REM or more contributor license agreements. See the NOTICE file
4 | @REM distributed with this work for additional information
5 | @REM regarding copyright ownership. The ASF licenses this file
6 | @REM to you under the Apache License, Version 2.0 (the
7 | @REM "License"); you may not use this file except in compliance
8 | @REM with the License. You may obtain a copy of the License at
9 | @REM
10 | @REM http://www.apache.org/licenses/LICENSE-2.0
11 | @REM
12 | @REM Unless required by applicable law or agreed to in writing,
13 | @REM software distributed under the License is distributed on an
14 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | @REM KIND, either express or implied. See the License for the
16 | @REM specific language governing permissions and limitations
17 | @REM under the License.
18 | @REM ----------------------------------------------------------------------------
19 |
20 | @REM ----------------------------------------------------------------------------
21 | @REM Maven2 Start Up Batch script
22 | @REM
23 | @REM Required ENV vars:
24 | @REM JAVA_HOME - location of a JDK home dir
25 | @REM
26 | @REM Optional ENV vars
27 | @REM M2_HOME - location of maven2's installed home dir
28 | @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
29 | @REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending
30 | @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
31 | @REM e.g. to debug Maven itself, use
32 | @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
33 | @REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
34 | @REM ----------------------------------------------------------------------------
35 |
36 | @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
37 | @echo off
38 | @REM enable echoing my setting MAVEN_BATCH_ECHO to 'on'
39 | @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
40 |
41 | @REM set %HOME% to equivalent of $HOME
42 | if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
43 |
44 | @REM Execute a user defined script before this one
45 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
46 | @REM check for pre script, once with legacy .bat ending and once with .cmd ending
47 | if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat"
48 | if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd"
49 | :skipRcPre
50 |
51 | @setlocal
52 |
53 | set ERROR_CODE=0
54 |
55 | @REM To isolate internal variables from possible post scripts, we use another setlocal
56 | @setlocal
57 |
58 | @REM ==== START VALIDATION ====
59 | if not "%JAVA_HOME%" == "" goto OkJHome
60 |
61 | echo.
62 | echo Error: JAVA_HOME not found in your environment. >&2
63 | echo Please set the JAVA_HOME variable in your environment to match the >&2
64 | echo location of your Java installation. >&2
65 | echo.
66 | goto error
67 |
68 | :OkJHome
69 | if exist "%JAVA_HOME%\bin\java.exe" goto init
70 |
71 | echo.
72 | echo Error: JAVA_HOME is set to an invalid directory. >&2
73 | echo JAVA_HOME = "%JAVA_HOME%" >&2
74 | echo Please set the JAVA_HOME variable in your environment to match the >&2
75 | echo location of your Java installation. >&2
76 | echo.
77 | goto error
78 |
79 | @REM ==== END VALIDATION ====
80 |
81 | :init
82 |
83 | set MAVEN_CMD_LINE_ARGS=%*
84 |
85 | @REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
86 | @REM Fallback to current working directory if not found.
87 |
88 | set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
89 | IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
90 |
91 | set EXEC_DIR=%CD%
92 | set WDIR=%EXEC_DIR%
93 | :findBaseDir
94 | IF EXIST "%WDIR%"\.mvn goto baseDirFound
95 | cd ..
96 | IF "%WDIR%"=="%CD%" goto baseDirNotFound
97 | set WDIR=%CD%
98 | goto findBaseDir
99 |
100 | :baseDirFound
101 | set MAVEN_PROJECTBASEDIR=%WDIR%
102 | cd "%EXEC_DIR%"
103 | goto endDetectBaseDir
104 |
105 | :baseDirNotFound
106 | set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
107 | cd "%EXEC_DIR%"
108 |
109 | :endDetectBaseDir
110 |
111 | IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
112 |
113 | @setlocal EnableExtensions EnableDelayedExpansion
114 | for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
115 | @endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
116 |
117 | :endReadAdditionalConfig
118 |
119 | SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
120 |
121 | set WRAPPER_JAR="".\.mvn\wrapper\maven-wrapper.jar""
122 | set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
123 |
124 | %MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CMD_LINE_ARGS%
125 | if ERRORLEVEL 1 goto error
126 | goto end
127 |
128 | :error
129 | set ERROR_CODE=1
130 |
131 | :end
132 | @endlocal & set ERROR_CODE=%ERROR_CODE%
133 |
134 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost
135 | @REM check for post script, once with legacy .bat ending and once with .cmd ending
136 | if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat"
137 | if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd"
138 | :skipRcPost
139 |
140 | @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
141 | if "%MAVEN_BATCH_PAUSE%" == "on" pause
142 |
143 | if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE%
144 |
145 | exit /B %ERROR_CODE%
--------------------------------------------------------------------------------
/spring-boot-security-saml-demo-okta2/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 4.0.0
4 |
5 | spring-boot-security-saml-demo-okta2
6 | jar
7 |
8 | Spring Boot Security SAML Demo with Okta IDP 2
9 | Demo project for Spring Boot
10 |
11 |
12 | com.github.ulisesbocchio
13 | spring-boot-security-saml-samples-parent
14 | 1.3-SNAPSHOT
15 |
16 |
17 |
18 | UTF-8
19 | 1.8
20 | com.github.ulisesbocchio.demo.OktaSSODemoApplication2
21 |
22 |
23 |
24 |
25 | org.projectlombok
26 | lombok
27 | 1.16.6
28 |
29 |
30 | com.github.ulisesbocchio
31 | spring-boot-security-saml
32 |
33 |
34 | org.springframework.boot
35 | spring-boot-starter-web
36 |
37 |
38 | org.springframework.boot
39 | spring-boot-starter-thymeleaf
40 |
41 |
42 | org.springframework.boot
43 | spring-boot-starter-test
44 | test
45 |
46 |
47 |
48 |
49 |
50 |
51 | org.springframework.boot
52 | spring-boot-maven-plugin
53 |
54 |
55 |
56 |
57 |
--------------------------------------------------------------------------------
/spring-boot-security-saml-demo-okta2/src/main/java/com/github/ulisesbocchio/demo/OktaSSODemoApplication2.java:
--------------------------------------------------------------------------------
1 | package com.github.ulisesbocchio.demo;
2 |
3 | import com.github.ulisesbocchio.spring.boot.security.saml.annotation.EnableSAMLSSO;
4 | import com.github.ulisesbocchio.spring.boot.security.saml.bean.SAMLConfigurerBean;
5 |
6 | import org.springframework.boot.SpringApplication;
7 | import org.springframework.boot.autoconfigure.SpringBootApplication;
8 | import org.springframework.context.annotation.Bean;
9 | import org.springframework.context.annotation.Configuration;
10 | import org.springframework.security.authentication.AuthenticationManager;
11 | import org.springframework.security.config.annotation.web.builders.HttpSecurity;
12 | import org.springframework.security.config.annotation.web.builders.WebSecurity;
13 | import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
14 | import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
15 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
16 |
17 | @SpringBootApplication
18 | @EnableSAMLSSO
19 | public class OktaSSODemoApplication2 {
20 |
21 | public static void main(String[] args) {
22 | SpringApplication.run(OktaSSODemoApplication2.class, args);
23 | }
24 |
25 | @Configuration
26 | public static class MvcConfig implements WebMvcConfigurer {
27 |
28 | @Override
29 | public void addViewControllers(ViewControllerRegistry registry) {
30 | registry.addViewController("/").setViewName("index");
31 | registry.addViewController("/protected").setViewName("protected");
32 | registry.addViewController("/unprotected/help").setViewName("help");
33 |
34 | }
35 | }
36 |
37 | @Configuration
38 | public static class MyServiceProviderConfig extends WebSecurityConfigurerAdapter {
39 |
40 | public MyServiceProviderConfig() {
41 | super(false);
42 | }
43 |
44 | @Bean
45 | SAMLConfigurerBean saml() {
46 | return new SAMLConfigurerBean();
47 | }
48 |
49 | @Override
50 | public void configure(WebSecurity web) throws Exception {
51 | super.configure(web);
52 | }
53 |
54 | @Bean
55 | public AuthenticationManager authenticationManagerBean() throws Exception {
56 | return super.authenticationManagerBean();
57 | }
58 |
59 | @Override
60 | protected void configure(HttpSecurity http) throws Exception {
61 | // @formatter:off
62 | http.authorizeRequests()
63 | .antMatchers("/unprotected/**")
64 | .permitAll()
65 | .and()
66 | .httpBasic()
67 | .disable()
68 | .csrf()
69 | .disable()
70 | .anonymous()
71 | .and()
72 | .apply(saml())
73 | .serviceProvider()
74 | .metadataGenerator()
75 | .entityId("localhost-demo")
76 | .bindingsSSO("artifact", "post", "paos")
77 | .and()
78 | .ecpProfile()
79 | .and()
80 | .sso()
81 | .defaultSuccessURL("/home")
82 | .idpSelectionPageURL("/idpselection")
83 | .and()
84 | .metadataManager()
85 | .metadataLocations("classpath:/idp-okta.xml")
86 | .refreshCheckInterval(0)
87 | .and()
88 | .extendedMetadata()
89 | .ecpEnabled(true)
90 | .idpDiscoveryEnabled(true)//set to false for no IDP Selection page.
91 | .and()
92 | .keyManager()
93 | .privateKeyDERLocation("classpath:/localhost.key.der")
94 | .publicKeyPEMLocation("classpath:/localhost.cert")
95 | .and()
96 | .http()
97 | .authorizeRequests()
98 | .requestMatchers(saml().endpointsMatcher()).permitAll()
99 | .and()
100 | .authorizeRequests()
101 | .anyRequest()
102 | .authenticated();
103 | // @formatter:on
104 | }
105 | }
106 | }
107 |
--------------------------------------------------------------------------------
/spring-boot-security-saml-demo-okta2/src/main/java/com/github/ulisesbocchio/demo/controller/HomeController.java:
--------------------------------------------------------------------------------
1 | package com.github.ulisesbocchio.demo.controller;
2 |
3 | /**
4 | * @author Ulises Bocchio
5 | */
6 |
7 | import com.github.ulisesbocchio.spring.boot.security.saml.annotation.SAMLUser;
8 | import com.github.ulisesbocchio.spring.boot.security.saml.user.SAMLUserDetails;
9 | import org.springframework.stereotype.Controller;
10 | import org.springframework.web.bind.annotation.RequestMapping;
11 | import org.springframework.web.servlet.ModelAndView;
12 |
13 | @Controller
14 | public class HomeController {
15 |
16 | @RequestMapping("/home")
17 | public ModelAndView home(@SAMLUser SAMLUserDetails user) {
18 | ModelAndView homeView = new ModelAndView("home");
19 | homeView.addObject("userId", user.getUsername());
20 | homeView.addObject("samlAttributes", user.getAttributes());
21 | return homeView;
22 | }
23 |
24 | }
25 |
--------------------------------------------------------------------------------
/spring-boot-security-saml-demo-okta2/src/main/java/com/github/ulisesbocchio/demo/controller/IdPSelectionController.java:
--------------------------------------------------------------------------------
1 | package com.github.ulisesbocchio.demo.controller;
2 |
3 | /**
4 | * @author Ulises Bocchio
5 | */
6 |
7 | import lombok.extern.slf4j.Slf4j;
8 | import org.springframework.security.authentication.AuthenticationServiceException;
9 | import org.springframework.security.saml.SAMLConstants;
10 | import org.springframework.security.saml.SAMLDiscovery;
11 | import org.springframework.stereotype.Controller;
12 | import org.springframework.web.bind.annotation.RequestMapping;
13 | import org.springframework.web.servlet.ModelAndView;
14 |
15 | import javax.servlet.http.HttpServletRequest;
16 | import java.util.Collections;
17 |
18 | @Controller
19 | @RequestMapping("/idpselection")
20 | @Slf4j
21 | public class IdPSelectionController {
22 |
23 | @RequestMapping
24 | public ModelAndView idpSelection(HttpServletRequest request) {
25 |
26 | if (comesFromDiscoveryFilter(request)) {
27 | ModelAndView idpSelection = new ModelAndView("idpselection");
28 | idpSelection.addObject(SAMLDiscovery.RETURN_URL, request.getAttribute(SAMLDiscovery.RETURN_URL));
29 | idpSelection.addObject(SAMLDiscovery.RETURN_PARAM, request.getAttribute(SAMLDiscovery.RETURN_PARAM));
30 | idpSelection.addObject("idpNameAliasMap", Collections.singletonMap("http://www.okta.com/exk62w7tqv0xkRl9p0h7", "Okta"));
31 | return idpSelection;
32 | }
33 | throw new AuthenticationServiceException("SP Discovery flow not detected");
34 | }
35 |
36 | private boolean comesFromDiscoveryFilter(HttpServletRequest request) {
37 | return request.getAttribute(SAMLConstants.LOCAL_ENTITY_ID) != null &&
38 | request.getAttribute(SAMLDiscovery.RETURN_URL) != null &&
39 | request.getAttribute(SAMLDiscovery.RETURN_PARAM) != null;
40 | }
41 |
42 | }
43 |
--------------------------------------------------------------------------------
/spring-boot-security-saml-demo-okta2/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | security.user.name=user
2 | security.user.password=password
3 | logging.level.org.springframework.security.saml= DEBUG
--------------------------------------------------------------------------------
/spring-boot-security-saml-demo-okta2/src/main/resources/idp-okta.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
9 | MIIDpDCCAoygAwIBAgIGAVO669oLMA0GCSqGSIb3DQEBBQUAMIGSMQswCQYDVQQGEwJVUzETMBEG
10 | A1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzENMAsGA1UECgwET2t0YTEU
11 | MBIGA1UECwwLU1NPUHJvdmlkZXIxEzARBgNVBAMMCmRldi04MzkyMjgxHDAaBgkqhkiG9w0BCQEW
12 | DWluZm9Ab2t0YS5jb20wHhcNMTYwMzI4MDE1MTEyWhcNMjYwMzI4MDE1MjEyWjCBkjELMAkGA1UE
13 | BhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNVBAcMDVNhbiBGcmFuY2lzY28xDTALBgNV
14 | BAoMBE9rdGExFDASBgNVBAsMC1NTT1Byb3ZpZGVyMRMwEQYDVQQDDApkZXYtODM5MjI4MRwwGgYJ
15 | KoZIhvcNAQkBFg1pbmZvQG9rdGEuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
16 | 0H9hcvueaxQsH+GjDBPJdQ3FotGgPFOyFuZFvDwBeXiTMPAMoB8s+9Ey7ugYoAvLJMm7ryXAhOGa
17 | tblP4BcxPWrFJx+Tddswkb9pmM9rbmfrBBW3gsiwPQ/bEuwnvNxICIaeWD7h50Qej8UgrSunqmEq
18 | pBYi530/mWy7fdyRWniC0NtqlGDc+7jM4itchIjxuJXm0MX8BTzUkk8yU/Ul/YwNCwTAZNwispES
19 | ADsU9Mc+qcI6Fc68NC8pzPTpV4XEIiDwK8bfdQa1kwM3teL+1cHTXkEMvfhzBLZLedaB7b2Ictp+
20 | /mPtX/m9+zu/oqeZs1ZfCPfOpaNQCw4ug/G7PQIDAQABMA0GCSqGSIb3DQEBBQUAA4IBAQAxlYaA
21 | PPB8kvNZgLX1V/WGxfpQTZMVLJGCfVA50I7wzRn+bDgkLhl2L3Rn7V7epQ7yOGYoIZ2QZGqu8fto
22 | xyXLmbx+gKvrejPp8QGCDl4Ga9UppIRtvdnLpXKeBw1m2GbLbgIlMmCbSGo05YSxBM7m6C7ZBDbA
23 | Sn8kNrM+77jWPs+uRO/Oe9UlMGIMIvxaUyy7H9TpUNHAMQKwYPiua/32T53iv9TZ6YYgdK1b2haA
24 | N3ESCsNEmU5BRZBQgBMRiw1qfWt5tGpAxjCKkVFEwR6gQwqH5QhAnzA9lyVAq8FGr7HDxMyLoObB
25 | avSvuMAJ1fZFZh4v3XJussihq2MjHH3g
26 |
27 |
28 |
29 |
30 |
32 |
34 | urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress
35 | urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified
36 |
38 |
40 |
41 |
--------------------------------------------------------------------------------
/spring-boot-security-saml-demo-okta2/src/main/resources/localhost.cert:
--------------------------------------------------------------------------------
1 | -----BEGIN CERTIFICATE-----
2 | MIIC+zCCAeOgAwIBAgIJAIU7CnmezGizMA0GCSqGSIb3DQEBBQUAMBQxEjAQBgNV
3 | BAMMCWxvY2FsaG9zdDAeFw0xNjA0MDMwMjEwMjVaFw0yNjA0MDEwMjEwMjVaMBQx
4 | EjAQBgNVBAMMCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
5 | ggEBAN1NO3L/yCCb+MYFkypvJXcjlQuyRG7UFATYOYQZzIxsD9AtnXPh67uVkZTI
6 | oK7Ps5X4a5qVARtdN+GCFZ/ITahlAlIx8rmVsbz+7XPWpGPf75tKbem3pON2NlYW
7 | wIEQqyuValZHDUMgIXPdGIAZeNejVu7gYMLJwiSMtB0uBM69ptzgigJcbnup/cSL
8 | W4fBh4ck5kj0SVmX58knfaizrVf+ghGyNFha9Xy+DoilCofxwFIpVskv/hczZ5L+
9 | e81R+u2UbNzRwf8paF5fdVwaHPGLOYSBGjSm71VDdJqlvKrJCBoCQODhtmJOmDHD
10 | jtf6gwwbdg3g9GvyqIJnRqBO908CAwEAAaNQME4wHQYDVR0OBBYEFMNtl5fAchs3
11 | 5gZS4EF8/0C7QfBQMB8GA1UdIwQYMBaAFMNtl5fAchs35gZS4EF8/0C7QfBQMAwG
12 | A1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAADVL8LgYGlmaHlyrKyKfsQF
13 | TVbdT1Fk3WaGocVbhmvFeEBHScSJNR0syDcDM1C18pZ6Jc73cW7UdtLbLbRNPXS+
14 | qcp5GZroafndPIL2QzdKXfc5MiGH7CRCZit9kiNJ6YYgsztappXnwKblioJHB1Bc
15 | oLRzMeD295DAGLEVuc5tSY7JHBD3YQS9Pwt3ivrvvCzFKOU9nHqChMCplO4StGpS
16 | bbSR6XNgsPA0XLWlleuTqLGvJ4bHXPKC+0Y+0AiQYx3GeWLVrwJ4w+PFEK73vyuB
17 | 9H10x+zy1nFWvqoa+K66EA4u7DpEoHJBlqH0AVWAd8q9488DpCo1x4ujTGw7AHE=
18 | -----END CERTIFICATE-----
19 |
--------------------------------------------------------------------------------
/spring-boot-security-saml-demo-okta2/src/main/resources/localhost.key.der:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ulisesbocchio/spring-boot-security-saml-samples/9ef34b596d6f5ffe9ddad04cabdc896cad73e4f9/spring-boot-security-saml-demo-okta2/src/main/resources/localhost.key.der
--------------------------------------------------------------------------------
/spring-boot-security-saml-demo-okta2/src/main/resources/logback.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/spring-boot-security-saml-demo-okta2/src/main/resources/templates/help.html:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 | Help Page
6 |
7 |
8 | Help Page
9 |
10 | This is an UNPROTECTED Resource
11 |
12 | Home
13 |
14 |
--------------------------------------------------------------------------------
/spring-boot-security-saml-demo-okta2/src/main/resources/templates/home.html:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 | Home Page
6 |
7 |
8 | This is the Home Page
9 |
10 | Current User: unknown
11 |
12 |
13 |
14 | | SAML Attributes |
15 |
16 |
17 | | Attribute Name |
18 | Attribute Value |
19 |
20 |
21 |
22 | | key |
23 | value |
24 |
25 |
26 |
27 | Idp Single Logout - Local Logout
28 |
29 |
30 |
--------------------------------------------------------------------------------
/spring-boot-security-saml-demo-okta2/src/main/resources/templates/idpselection.html:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 | IdP Selection
6 |
7 |
8 | Select an IdP:
9 |
21 |
22 |
--------------------------------------------------------------------------------
/spring-boot-security-saml-demo-okta2/src/main/resources/templates/index.html:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 | Sample SAML Spring Boot Application
6 |
7 |
8 | Hi, Click here to start the Single Sign On process
9 |
10 |
--------------------------------------------------------------------------------
/spring-boot-security-saml-demo-okta2/src/main/resources/templates/protected.html:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 | Protected Resource
6 |
7 |
8 | Protected Resource
9 |
10 | This is a Protected Resource
11 |
12 | Home
13 |
14 |
--------------------------------------------------------------------------------
/spring-boot-security-saml-demo-okta2/src/test/java/com/github/ulisesbocchio/demo/SpringBootSecuritySamlDemoApplicationTests.java:
--------------------------------------------------------------------------------
1 | package com.github.ulisesbocchio.demo;
2 |
3 | import org.junit.Test;
4 | import org.junit.runner.RunWith;
5 | import org.springframework.boot.test.context.SpringBootTest;
6 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
7 | import org.springframework.test.context.web.WebAppConfiguration;
8 |
9 | @RunWith(SpringJUnit4ClassRunner.class)
10 | @SpringBootTest(classes = OktaSSODemoApplication2.class)
11 | @WebAppConfiguration
12 | public class SpringBootSecuritySamlDemoApplicationTests {
13 |
14 | @Test
15 | public void contextLoads() {
16 | }
17 |
18 | }
19 |
--------------------------------------------------------------------------------
/spring-boot-security-saml-demo-props/.mvn/wrapper/maven-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.3.3/apache-maven-3.3.3-bin.zip
--------------------------------------------------------------------------------
/spring-boot-security-saml-demo-props/mvnw.cmd:
--------------------------------------------------------------------------------
1 | @REM ----------------------------------------------------------------------------
2 | @REM Licensed to the Apache Software Foundation (ASF) under one
3 | @REM or more contributor license agreements. See the NOTICE file
4 | @REM distributed with this work for additional information
5 | @REM regarding copyright ownership. The ASF licenses this file
6 | @REM to you under the Apache License, Version 2.0 (the
7 | @REM "License"); you may not use this file except in compliance
8 | @REM with the License. You may obtain a copy of the License at
9 | @REM
10 | @REM http://www.apache.org/licenses/LICENSE-2.0
11 | @REM
12 | @REM Unless required by applicable law or agreed to in writing,
13 | @REM software distributed under the License is distributed on an
14 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | @REM KIND, either express or implied. See the License for the
16 | @REM specific language governing permissions and limitations
17 | @REM under the License.
18 | @REM ----------------------------------------------------------------------------
19 |
20 | @REM ----------------------------------------------------------------------------
21 | @REM Maven2 Start Up Batch script
22 | @REM
23 | @REM Required ENV vars:
24 | @REM JAVA_HOME - location of a JDK home dir
25 | @REM
26 | @REM Optional ENV vars
27 | @REM M2_HOME - location of maven2's installed home dir
28 | @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
29 | @REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending
30 | @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
31 | @REM e.g. to debug Maven itself, use
32 | @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
33 | @REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
34 | @REM ----------------------------------------------------------------------------
35 |
36 | @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
37 | @echo off
38 | @REM enable echoing my setting MAVEN_BATCH_ECHO to 'on'
39 | @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
40 |
41 | @REM set %HOME% to equivalent of $HOME
42 | if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
43 |
44 | @REM Execute a user defined script before this one
45 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
46 | @REM check for pre script, once with legacy .bat ending and once with .cmd ending
47 | if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat"
48 | if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd"
49 | :skipRcPre
50 |
51 | @setlocal
52 |
53 | set ERROR_CODE=0
54 |
55 | @REM To isolate internal variables from possible post scripts, we use another setlocal
56 | @setlocal
57 |
58 | @REM ==== START VALIDATION ====
59 | if not "%JAVA_HOME%" == "" goto OkJHome
60 |
61 | echo.
62 | echo Error: JAVA_HOME not found in your environment. >&2
63 | echo Please set the JAVA_HOME variable in your environment to match the >&2
64 | echo location of your Java installation. >&2
65 | echo.
66 | goto error
67 |
68 | :OkJHome
69 | if exist "%JAVA_HOME%\bin\java.exe" goto init
70 |
71 | echo.
72 | echo Error: JAVA_HOME is set to an invalid directory. >&2
73 | echo JAVA_HOME = "%JAVA_HOME%" >&2
74 | echo Please set the JAVA_HOME variable in your environment to match the >&2
75 | echo location of your Java installation. >&2
76 | echo.
77 | goto error
78 |
79 | @REM ==== END VALIDATION ====
80 |
81 | :init
82 |
83 | set MAVEN_CMD_LINE_ARGS=%*
84 |
85 | @REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
86 | @REM Fallback to current working directory if not found.
87 |
88 | set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
89 | IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
90 |
91 | set EXEC_DIR=%CD%
92 | set WDIR=%EXEC_DIR%
93 | :findBaseDir
94 | IF EXIST "%WDIR%"\.mvn goto baseDirFound
95 | cd ..
96 | IF "%WDIR%"=="%CD%" goto baseDirNotFound
97 | set WDIR=%CD%
98 | goto findBaseDir
99 |
100 | :baseDirFound
101 | set MAVEN_PROJECTBASEDIR=%WDIR%
102 | cd "%EXEC_DIR%"
103 | goto endDetectBaseDir
104 |
105 | :baseDirNotFound
106 | set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
107 | cd "%EXEC_DIR%"
108 |
109 | :endDetectBaseDir
110 |
111 | IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
112 |
113 | @setlocal EnableExtensions EnableDelayedExpansion
114 | for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
115 | @endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
116 |
117 | :endReadAdditionalConfig
118 |
119 | SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
120 |
121 | set WRAPPER_JAR="".\.mvn\wrapper\maven-wrapper.jar""
122 | set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
123 |
124 | %MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CMD_LINE_ARGS%
125 | if ERRORLEVEL 1 goto error
126 | goto end
127 |
128 | :error
129 | set ERROR_CODE=1
130 |
131 | :end
132 | @endlocal & set ERROR_CODE=%ERROR_CODE%
133 |
134 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost
135 | @REM check for post script, once with legacy .bat ending and once with .cmd ending
136 | if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat"
137 | if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd"
138 | :skipRcPost
139 |
140 | @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
141 | if "%MAVEN_BATCH_PAUSE%" == "on" pause
142 |
143 | if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE%
144 |
145 | exit /B %ERROR_CODE%
--------------------------------------------------------------------------------
/spring-boot-security-saml-demo-props/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 4.0.0
4 |
5 | spring-boot-security-saml-demo-props
6 | jar
7 |
8 | Spring Boot Security SAML Demo wiht Properties
9 | Demo project for Spring Boot
10 |
11 |
12 | com.github.ulisesbocchio
13 | spring-boot-security-saml-samples-parent
14 | 1.3-SNAPSHOT
15 |
16 |
17 |
18 | UTF-8
19 | 1.8
20 | com.github.ulisesbocchio.demo.SpringBootSecuritySAMLDemoApplication
21 |
22 |
23 |
24 |
25 | org.projectlombok
26 | lombok
27 | 1.16.6
28 |
29 |
30 | com.github.ulisesbocchio
31 | spring-boot-security-saml
32 |
33 |
34 | org.springframework.boot
35 | spring-boot-starter-web
36 |
37 |
38 | org.springframework.boot
39 | spring-boot-starter-thymeleaf
40 |
41 |
42 | org.springframework.boot
43 | spring-boot-starter-test
44 | test
45 |
46 |
47 |
48 |
49 |
50 |
51 | org.springframework.boot
52 | spring-boot-maven-plugin
53 |
54 |
55 |
56 |
57 |
--------------------------------------------------------------------------------
/spring-boot-security-saml-demo-props/src/main/java/com/github/ulisesbocchio/demo/SpringBootSecuritySAMLDemoApplication.java:
--------------------------------------------------------------------------------
1 | package com.github.ulisesbocchio.demo;
2 |
3 | import com.github.ulisesbocchio.spring.boot.security.saml.annotation.EnableSAMLSSO;
4 | import org.springframework.boot.SpringApplication;
5 | import org.springframework.boot.autoconfigure.SpringBootApplication;
6 | import org.springframework.context.annotation.Configuration;
7 | import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
8 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
9 |
10 | @SpringBootApplication
11 | @EnableSAMLSSO
12 | public class SpringBootSecuritySAMLDemoApplication {
13 |
14 | public static void main(String[] args) {
15 | SpringApplication.run(SpringBootSecuritySAMLDemoApplication.class, args);
16 | }
17 |
18 | @Configuration
19 | public static class MvcConfig implements WebMvcConfigurer {
20 |
21 | @Override
22 | public void addViewControllers(ViewControllerRegistry registry) {
23 | registry.addViewController("/").setViewName("index");
24 | registry.addViewController("/protected").setViewName("protected");
25 |
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/spring-boot-security-saml-demo-props/src/main/java/com/github/ulisesbocchio/demo/controller/HomeController.java:
--------------------------------------------------------------------------------
1 | package com.github.ulisesbocchio.demo.controller;
2 |
3 | /**
4 | * @author Ulises Bocchio
5 | */
6 |
7 | import com.github.ulisesbocchio.spring.boot.security.saml.annotation.SAMLUser;
8 | import com.github.ulisesbocchio.spring.boot.security.saml.user.SAMLUserDetails;
9 | import org.springframework.stereotype.Controller;
10 | import org.springframework.web.bind.annotation.RequestMapping;
11 | import org.springframework.web.servlet.ModelAndView;
12 |
13 | @Controller
14 | public class HomeController {
15 |
16 | @RequestMapping("/home")
17 | public ModelAndView home(@SAMLUser SAMLUserDetails user) {
18 | ModelAndView homeView = new ModelAndView("home");
19 | homeView.addObject("userId", user.getUsername());
20 | homeView.addObject("samlAttributes", user.getAttributes());
21 | return homeView;
22 | }
23 |
24 | }
25 |
--------------------------------------------------------------------------------
/spring-boot-security-saml-demo-props/src/main/java/com/github/ulisesbocchio/demo/controller/IdPSelectionController.java:
--------------------------------------------------------------------------------
1 | package com.github.ulisesbocchio.demo.controller;
2 |
3 | /**
4 | * @author Ulises Bocchio
5 | */
6 |
7 | import lombok.extern.slf4j.Slf4j;
8 | import org.springframework.security.authentication.AuthenticationServiceException;
9 | import org.springframework.security.saml.SAMLConstants;
10 | import org.springframework.security.saml.SAMLDiscovery;
11 | import org.springframework.stereotype.Controller;
12 | import org.springframework.web.bind.annotation.RequestMapping;
13 | import org.springframework.web.servlet.ModelAndView;
14 |
15 | import javax.servlet.http.HttpServletRequest;
16 | import java.util.Collections;
17 |
18 | @Controller
19 | @RequestMapping("/idpselection")
20 | @Slf4j
21 | public class IdPSelectionController {
22 |
23 | @RequestMapping
24 | public ModelAndView idpSelection(HttpServletRequest request) {
25 |
26 | if (comesFromDiscoveryFilter(request)) {
27 | ModelAndView idpSelection = new ModelAndView("idpselection");
28 | idpSelection.addObject(SAMLDiscovery.RETURN_URL, request.getAttribute(SAMLDiscovery.RETURN_URL));
29 | idpSelection.addObject(SAMLDiscovery.RETURN_PARAM, request.getAttribute(SAMLDiscovery.RETURN_PARAM));
30 | idpSelection.addObject("idpNameAliasMap", Collections.singletonMap("http://idp.ssocircle.com", "SSO Circle"));
31 | return idpSelection;
32 | }
33 | throw new AuthenticationServiceException("SP Discovery flow not detected");
34 | }
35 |
36 | private boolean comesFromDiscoveryFilter(HttpServletRequest request) {
37 | return request.getAttribute(SAMLConstants.LOCAL_ENTITY_ID) != null &&
38 | request.getAttribute(SAMLDiscovery.RETURN_URL) != null &&
39 | request.getAttribute(SAMLDiscovery.RETURN_PARAM) != null;
40 | }
41 |
42 | }
43 |
--------------------------------------------------------------------------------
/spring-boot-security-saml-demo-props/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | security.user.name=user
2 | security.user.password=password
3 | logging.level.org.springframework.security.saml= DEBUG
4 |
5 | saml.sso.metadata-generator.entity-id=localhost-demo
6 | saml.sso.default-success-url=/home
7 | saml.sso.idp-selection-page-url=/idpselection
8 | saml.sso.logout.default-target-url=/
9 | saml.sso.idp.metadata-location=classpath:/idp-ssocircle.xml
10 | saml.sso.metadata-manager.refresh-check-interval=0
11 | saml.sso.extended-metadata.idp-discovery-enabled=true
12 | saml.sso.key-manager.private-key-der-location=classpath:/localhost.key.der
13 | saml.sso.key-manager.public-key-pem-location=classpath:/localhost.cert
14 |
--------------------------------------------------------------------------------
/spring-boot-security-saml-demo-props/src/main/resources/localhost.cert:
--------------------------------------------------------------------------------
1 | -----BEGIN CERTIFICATE-----
2 | MIIC+zCCAeOgAwIBAgIJAIU7CnmezGizMA0GCSqGSIb3DQEBBQUAMBQxEjAQBgNV
3 | BAMMCWxvY2FsaG9zdDAeFw0xNjA0MDMwMjEwMjVaFw0yNjA0MDEwMjEwMjVaMBQx
4 | EjAQBgNVBAMMCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
5 | ggEBAN1NO3L/yCCb+MYFkypvJXcjlQuyRG7UFATYOYQZzIxsD9AtnXPh67uVkZTI
6 | oK7Ps5X4a5qVARtdN+GCFZ/ITahlAlIx8rmVsbz+7XPWpGPf75tKbem3pON2NlYW
7 | wIEQqyuValZHDUMgIXPdGIAZeNejVu7gYMLJwiSMtB0uBM69ptzgigJcbnup/cSL
8 | W4fBh4ck5kj0SVmX58knfaizrVf+ghGyNFha9Xy+DoilCofxwFIpVskv/hczZ5L+
9 | e81R+u2UbNzRwf8paF5fdVwaHPGLOYSBGjSm71VDdJqlvKrJCBoCQODhtmJOmDHD
10 | jtf6gwwbdg3g9GvyqIJnRqBO908CAwEAAaNQME4wHQYDVR0OBBYEFMNtl5fAchs3
11 | 5gZS4EF8/0C7QfBQMB8GA1UdIwQYMBaAFMNtl5fAchs35gZS4EF8/0C7QfBQMAwG
12 | A1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAADVL8LgYGlmaHlyrKyKfsQF
13 | TVbdT1Fk3WaGocVbhmvFeEBHScSJNR0syDcDM1C18pZ6Jc73cW7UdtLbLbRNPXS+
14 | qcp5GZroafndPIL2QzdKXfc5MiGH7CRCZit9kiNJ6YYgsztappXnwKblioJHB1Bc
15 | oLRzMeD295DAGLEVuc5tSY7JHBD3YQS9Pwt3ivrvvCzFKOU9nHqChMCplO4StGpS
16 | bbSR6XNgsPA0XLWlleuTqLGvJ4bHXPKC+0Y+0AiQYx3GeWLVrwJ4w+PFEK73vyuB
17 | 9H10x+zy1nFWvqoa+K66EA4u7DpEoHJBlqH0AVWAd8q9488DpCo1x4ujTGw7AHE=
18 | -----END CERTIFICATE-----
19 |
--------------------------------------------------------------------------------
/spring-boot-security-saml-demo-props/src/main/resources/localhost.key.der:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ulisesbocchio/spring-boot-security-saml-samples/9ef34b596d6f5ffe9ddad04cabdc896cad73e4f9/spring-boot-security-saml-demo-props/src/main/resources/localhost.key.der
--------------------------------------------------------------------------------
/spring-boot-security-saml-demo-props/src/main/resources/logback.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/spring-boot-security-saml-demo-props/src/main/resources/templates/home.html:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 | Home Page
6 |
7 |
8 | This is the Home Page
9 |
10 | Current User: unknown
11 |
12 |
13 |
14 | | SAML Attributes |
15 |
16 |
17 | | Attribute Name |
18 | Attribute Value |
19 |
20 |
21 |
22 | | key |
23 | value |
24 |
25 |
26 |
27 | Idp Single Logout - Local Logout
28 |
29 |
30 |
--------------------------------------------------------------------------------
/spring-boot-security-saml-demo-props/src/main/resources/templates/idpselection.html:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 | IdP Selection
6 |
7 |
8 | Select an IdP:
9 |
21 |
22 |
--------------------------------------------------------------------------------
/spring-boot-security-saml-demo-props/src/main/resources/templates/index.html:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 | Sample SAML Spring Boot Application
6 |
7 |
8 | Hi, Click here to start the Single Sign On process
9 |
10 |
--------------------------------------------------------------------------------
/spring-boot-security-saml-demo-props/src/main/resources/templates/protected.html:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 | Protected Resource
6 |
7 |
8 | Protected Resource
9 |
10 | This is a Protected Resource
11 |
12 | Home
13 |
14 |
--------------------------------------------------------------------------------
/spring-boot-security-saml-demo-props/src/test/java/com/github/ulisesbocchio/demo/SpringBootSecuritySamlDemoApplicationTests.java:
--------------------------------------------------------------------------------
1 | package com.github.ulisesbocchio.demo;
2 |
3 | import org.junit.Test;
4 | import org.junit.runner.RunWith;
5 | import org.springframework.boot.test.context.SpringBootTest;
6 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
7 | import org.springframework.test.context.web.WebAppConfiguration;
8 |
9 | @RunWith(SpringJUnit4ClassRunner.class)
10 | @SpringBootTest(classes = SpringBootSecuritySAMLDemoApplication.class)
11 | @WebAppConfiguration
12 | public class SpringBootSecuritySamlDemoApplicationTests {
13 |
14 | @Test
15 | public void contextLoads() {
16 | }
17 |
18 | }
19 |
--------------------------------------------------------------------------------
/spring-boot-security-saml-demo-static-metadata/mvnw.cmd:
--------------------------------------------------------------------------------
1 | @REM ----------------------------------------------------------------------------
2 | @REM Licensed to the Apache Software Foundation (ASF) under one
3 | @REM or more contributor license agreements. See the NOTICE file
4 | @REM distributed with this work for additional information
5 | @REM regarding copyright ownership. The ASF licenses this file
6 | @REM to you under the Apache License, Version 2.0 (the
7 | @REM "License"); you may not use this file except in compliance
8 | @REM with the License. You may obtain a copy of the License at
9 | @REM
10 | @REM http://www.apache.org/licenses/LICENSE-2.0
11 | @REM
12 | @REM Unless required by applicable law or agreed to in writing,
13 | @REM software distributed under the License is distributed on an
14 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | @REM KIND, either express or implied. See the License for the
16 | @REM specific language governing permissions and limitations
17 | @REM under the License.
18 | @REM ----------------------------------------------------------------------------
19 |
20 | @REM ----------------------------------------------------------------------------
21 | @REM Maven2 Start Up Batch script
22 | @REM
23 | @REM Required ENV vars:
24 | @REM JAVA_HOME - location of a JDK home dir
25 | @REM
26 | @REM Optional ENV vars
27 | @REM M2_HOME - location of maven2's installed home dir
28 | @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
29 | @REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending
30 | @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
31 | @REM e.g. to debug Maven itself, use
32 | @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
33 | @REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
34 | @REM ----------------------------------------------------------------------------
35 |
36 | @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
37 | @echo off
38 | @REM enable echoing my setting MAVEN_BATCH_ECHO to 'on'
39 | @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
40 |
41 | @REM set %HOME% to equivalent of $HOME
42 | if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
43 |
44 | @REM Execute a user defined script before this one
45 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
46 | @REM check for pre script, once with legacy .bat ending and once with .cmd ending
47 | if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat"
48 | if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd"
49 | :skipRcPre
50 |
51 | @setlocal
52 |
53 | set ERROR_CODE=0
54 |
55 | @REM To isolate internal variables from possible post scripts, we use another setlocal
56 | @setlocal
57 |
58 | @REM ==== START VALIDATION ====
59 | if not "%JAVA_HOME%" == "" goto OkJHome
60 |
61 | echo.
62 | echo Error: JAVA_HOME not found in your environment. >&2
63 | echo Please set the JAVA_HOME variable in your environment to match the >&2
64 | echo location of your Java installation. >&2
65 | echo.
66 | goto error
67 |
68 | :OkJHome
69 | if exist "%JAVA_HOME%\bin\java.exe" goto init
70 |
71 | echo.
72 | echo Error: JAVA_HOME is set to an invalid directory. >&2
73 | echo JAVA_HOME = "%JAVA_HOME%" >&2
74 | echo Please set the JAVA_HOME variable in your environment to match the >&2
75 | echo location of your Java installation. >&2
76 | echo.
77 | goto error
78 |
79 | @REM ==== END VALIDATION ====
80 |
81 | :init
82 |
83 | set MAVEN_CMD_LINE_ARGS=%*
84 |
85 | @REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
86 | @REM Fallback to current working directory if not found.
87 |
88 | set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
89 | IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
90 |
91 | set EXEC_DIR=%CD%
92 | set WDIR=%EXEC_DIR%
93 | :findBaseDir
94 | IF EXIST "%WDIR%"\.mvn goto baseDirFound
95 | cd ..
96 | IF "%WDIR%"=="%CD%" goto baseDirNotFound
97 | set WDIR=%CD%
98 | goto findBaseDir
99 |
100 | :baseDirFound
101 | set MAVEN_PROJECTBASEDIR=%WDIR%
102 | cd "%EXEC_DIR%"
103 | goto endDetectBaseDir
104 |
105 | :baseDirNotFound
106 | set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
107 | cd "%EXEC_DIR%"
108 |
109 | :endDetectBaseDir
110 |
111 | IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
112 |
113 | @setlocal EnableExtensions EnableDelayedExpansion
114 | for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
115 | @endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
116 |
117 | :endReadAdditionalConfig
118 |
119 | SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
120 |
121 | set WRAPPER_JAR="".\.mvn\wrapper\maven-wrapper.jar""
122 | set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
123 |
124 | %MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CMD_LINE_ARGS%
125 | if ERRORLEVEL 1 goto error
126 | goto end
127 |
128 | :error
129 | set ERROR_CODE=1
130 |
131 | :end
132 | @endlocal & set ERROR_CODE=%ERROR_CODE%
133 |
134 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost
135 | @REM check for post script, once with legacy .bat ending and once with .cmd ending
136 | if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat"
137 | if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd"
138 | :skipRcPost
139 |
140 | @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
141 | if "%MAVEN_BATCH_PAUSE%" == "on" pause
142 |
143 | if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE%
144 |
145 | exit /B %ERROR_CODE%
--------------------------------------------------------------------------------
/spring-boot-security-saml-demo-static-metadata/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 4.0.0
4 |
5 | spring-boot-security-saml-demo-static-metadata
6 | jar
7 |
8 | Spring Boot Security SAML Demo with static metadata
9 | Demo project for Spring Boot
10 |
11 |
12 | com.github.ulisesbocchio
13 | spring-boot-security-saml-samples-parent
14 | 1.3-SNAPSHOT
15 |
16 |
17 |
18 | UTF-8
19 | 1.8
20 | com.github.ulisesbocchio.demo.SpringBootSecuritySAMLDemoApplication
21 |
22 |
23 |
24 |
25 | org.projectlombok
26 | lombok
27 | 1.16.6
28 |
29 |
30 | com.github.ulisesbocchio
31 | spring-boot-security-saml
32 |
33 |
34 | org.springframework.boot
35 | spring-boot-starter-web
36 |
37 |
38 | org.springframework.boot
39 | spring-boot-starter-thymeleaf
40 |
41 |
42 | org.springframework.boot
43 | spring-boot-starter-test
44 | test
45 |
46 |
47 |
48 |
49 |
50 |
51 | org.springframework.boot
52 | spring-boot-maven-plugin
53 |
54 |
55 |
56 |
57 |
--------------------------------------------------------------------------------
/spring-boot-security-saml-demo-static-metadata/src/main/java/com/github/ulisesbocchio/demo/SpringBootSecuritySAMLDemoApplication.java:
--------------------------------------------------------------------------------
1 | package com.github.ulisesbocchio.demo;
2 |
3 | import com.github.ulisesbocchio.spring.boot.security.saml.annotation.EnableSAMLSSO;
4 | import com.github.ulisesbocchio.spring.boot.security.saml.configurer.ServiceProviderBuilder;
5 | import com.github.ulisesbocchio.spring.boot.security.saml.configurer.ServiceProviderConfigurerAdapter;
6 | import org.springframework.boot.SpringApplication;
7 | import org.springframework.boot.autoconfigure.SpringBootApplication;
8 | import org.springframework.context.annotation.Configuration;
9 | import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
10 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
11 |
12 | @SpringBootApplication
13 | @EnableSAMLSSO
14 | public class SpringBootSecuritySAMLDemoApplication {
15 |
16 | public static void main(String[] args) {
17 | SpringApplication.run(SpringBootSecuritySAMLDemoApplication.class, args);
18 | }
19 |
20 | @Configuration
21 | public static class MvcConfig implements WebMvcConfigurer {
22 |
23 | @Override
24 | public void addViewControllers(ViewControllerRegistry registry) {
25 | registry.addViewController("/").setViewName("index");
26 | registry.addViewController("/protected").setViewName("protected");
27 |
28 | }
29 | }
30 |
31 | @Configuration
32 | public static class MyServiceProviderConfig extends ServiceProviderConfigurerAdapter {
33 | @Override
34 | public void configure(ServiceProviderBuilder serviceProvider) throws Exception {
35 | // @formatter:off
36 | serviceProvider
37 | .metadataGenerator()
38 | .entityId("localhost-demo")
39 | .and()
40 | .sso()
41 | .defaultSuccessURL("/home")
42 | .idpSelectionPageURL("/idpselection")
43 | .and()
44 | .logout()
45 | .defaultTargetURL("/")
46 | .and()
47 | .metadataManager()
48 | .metadataLocations("classpath:/idp-ssocircle.xml")
49 | .localMetadataLocation("classpath:/sp-ssocircle.xml")
50 | .refreshCheckInterval(0)
51 | .and()
52 | .extendedMetadata()
53 | .idpDiscoveryEnabled(true)
54 | .and()
55 | .localExtendedMetadata()
56 | .securityProfile("metaiop")
57 | .sslSecurityProfile("pkix")
58 | .signMetadata(true)
59 | .signingKey("localhost")
60 | .encryptionKey("localhost")
61 | .requireArtifactResolveSigned(false)
62 | .requireLogoutRequestSigned(false)
63 | .idpDiscoveryEnabled(true)
64 | .and()
65 | //This Keystore contains also the public key of idp.ssocircle.com
66 | .keyManager()
67 | .storeLocation("classpath:/localhost.jks")
68 | .storePass("foobar")
69 | .defaultKey("localhost")
70 | .keyPassword("localhost", "foobar");
71 | // @formatter:on
72 | }
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/spring-boot-security-saml-demo-static-metadata/src/main/java/com/github/ulisesbocchio/demo/controller/HomeController.java:
--------------------------------------------------------------------------------
1 | package com.github.ulisesbocchio.demo.controller;
2 |
3 | /**
4 | * @author Ulises Bocchio
5 | */
6 |
7 | import com.github.ulisesbocchio.spring.boot.security.saml.annotation.SAMLUser;
8 | import com.github.ulisesbocchio.spring.boot.security.saml.user.SAMLUserDetails;
9 | import org.springframework.stereotype.Controller;
10 | import org.springframework.web.bind.annotation.RequestMapping;
11 | import org.springframework.web.servlet.ModelAndView;
12 |
13 | @Controller
14 | public class HomeController {
15 |
16 | @RequestMapping("/home")
17 | public ModelAndView home(@SAMLUser SAMLUserDetails user) {
18 | ModelAndView homeView = new ModelAndView("home");
19 | homeView.addObject("userId", user.getUsername());
20 | homeView.addObject("samlAttributes", user.getAttributes());
21 | return homeView;
22 | }
23 |
24 | }
25 |
--------------------------------------------------------------------------------
/spring-boot-security-saml-demo-static-metadata/src/main/java/com/github/ulisesbocchio/demo/controller/IdPSelectionController.java:
--------------------------------------------------------------------------------
1 | package com.github.ulisesbocchio.demo.controller;
2 |
3 | /**
4 | * @author Ulises Bocchio
5 | */
6 |
7 | import lombok.extern.slf4j.Slf4j;
8 | import org.springframework.security.authentication.AuthenticationServiceException;
9 | import org.springframework.security.saml.SAMLConstants;
10 | import org.springframework.security.saml.SAMLDiscovery;
11 | import org.springframework.stereotype.Controller;
12 | import org.springframework.web.bind.annotation.RequestMapping;
13 | import org.springframework.web.servlet.ModelAndView;
14 |
15 | import javax.servlet.http.HttpServletRequest;
16 | import java.util.Collections;
17 |
18 | @Controller
19 | @RequestMapping("/idpselection")
20 | @Slf4j
21 | public class IdPSelectionController {
22 |
23 | @RequestMapping
24 | public ModelAndView idpSelection(HttpServletRequest request) {
25 |
26 | if (comesFromDiscoveryFilter(request)) {
27 | ModelAndView idpSelection = new ModelAndView("idpselection");
28 | idpSelection.addObject(SAMLDiscovery.RETURN_URL, request.getAttribute(SAMLDiscovery.RETURN_URL));
29 | idpSelection.addObject(SAMLDiscovery.RETURN_PARAM, request.getAttribute(SAMLDiscovery.RETURN_PARAM));
30 | idpSelection.addObject("idpNameAliasMap", Collections.singletonMap("http://idp.ssocircle.com", "SSO Circle"));
31 | return idpSelection;
32 | }
33 | throw new AuthenticationServiceException("SP Discovery flow not detected");
34 | }
35 |
36 | private boolean comesFromDiscoveryFilter(HttpServletRequest request) {
37 | return request.getAttribute(SAMLConstants.LOCAL_ENTITY_ID) != null &&
38 | request.getAttribute(SAMLDiscovery.RETURN_URL) != null &&
39 | request.getAttribute(SAMLDiscovery.RETURN_PARAM) != null;
40 | }
41 |
42 | }
43 |
--------------------------------------------------------------------------------
/spring-boot-security-saml-demo-static-metadata/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | security.user.name=user
2 | security.user.password=password
3 | logging.level.org.springframework.security.saml= DEBUG
--------------------------------------------------------------------------------
/spring-boot-security-saml-demo-static-metadata/src/main/resources/idp.ssocircle.com.cer:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ulisesbocchio/spring-boot-security-saml-samples/9ef34b596d6f5ffe9ddad04cabdc896cad73e4f9/spring-boot-security-saml-demo-static-metadata/src/main/resources/idp.ssocircle.com.cer
--------------------------------------------------------------------------------
/spring-boot-security-saml-demo-static-metadata/src/main/resources/idp.ssocircle.com.pem:
--------------------------------------------------------------------------------
1 | -----BEGIN CERTIFICATE-----
2 | MIIFBjCCA+6gAwIBAgISA9yR8yaG/Xf8oUS21yNFGZv3MA0GCSqGSIb3DQEBCwUA
3 | MEoxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MSMwIQYDVQQD
4 | ExpMZXQncyBFbmNyeXB0IEF1dGhvcml0eSBYMzAeFw0xNjEyMDUwODE0MDBaFw0x
5 | NzAzMDUwODE0MDBaMBwxGjAYBgNVBAMTEWlkcC5zc29jaXJjbGUuY29tMIIBIjAN
6 | BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA+6ROg4GNOw90IX3Ufvy7SsFJNEif
7 | bF4Con/7K473obrQfhc2kc5HrWDXhdmxN+R9dtlnPjtoizGl2AscuZn1V16tPWWq
8 | HaaG4+BikzWFBxG3b4PibiQ/9+vHvO9colR72NdKR3ZELyWXmWUWqBmEcCnthCq4
9 | Z1P7JzVW94xZ/lfjH/YMJtf1zXAZXUSX3ZLRSpRC030CCJbuLmrF1PXeqI2f3tYF
10 | OQK6k+hnWf0OnZzbOBBsesn2PFDuY5dmwY7PUMF7yfdEifPDr69uC91Dt1YoxsmA
11 | 5t728ZDArhn+mT9eFbxzrKQxlFZe8/osj7WU+bye7xlJxw+NvyeQEJKpGwIDAQAB
12 | o4ICEjCCAg4wDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggr
13 | BgEFBQcDAjAMBgNVHRMBAf8EAjAAMB0GA1UdDgQWBBSzxM1upXhdoqep9J74YGLP
14 | snt5STAfBgNVHSMEGDAWgBSoSmpjBH3duubRObemRWXv86jsoTBwBggrBgEFBQcB
15 | AQRkMGIwLwYIKwYBBQUHMAGGI2h0dHA6Ly9vY3NwLmludC14My5sZXRzZW5jcnlw
16 | dC5vcmcvMC8GCCsGAQUFBzAChiNodHRwOi8vY2VydC5pbnQteDMubGV0c2VuY3J5
17 | cHQub3JnLzAcBgNVHREEFTATghFpZHAuc3NvY2lyY2xlLmNvbTCB/gYDVR0gBIH2
18 | MIHzMAgGBmeBDAECATCB5gYLKwYBBAGC3xMBAQEwgdYwJgYIKwYBBQUHAgEWGmh0
19 | dHA6Ly9jcHMubGV0c2VuY3J5cHQub3JnMIGrBggrBgEFBQcCAjCBngyBm1RoaXMg
20 | Q2VydGlmaWNhdGUgbWF5IG9ubHkgYmUgcmVsaWVkIHVwb24gYnkgUmVseWluZyBQ
21 | YXJ0aWVzIGFuZCBvbmx5IGluIGFjY29yZGFuY2Ugd2l0aCB0aGUgQ2VydGlmaWNh
22 | dGUgUG9saWN5IGZvdW5kIGF0IGh0dHBzOi8vbGV0c2VuY3J5cHQub3JnL3JlcG9z
23 | aXRvcnkvMA0GCSqGSIb3DQEBCwUAA4IBAQBZx+VeJpYirkWDAglodWLqpul7Rkbv
24 | RPLRTbLtZmaD3MULCtwf92TT1gpxRNFskiEWcAoN1Ooc4bAM3VRBoFJCGCaQtodh
25 | WGayQaIOhBDuCCqWi7jPx5wCt4rx3MuRznzDP3HUiuIt2ciD6jRrh66fV8Iwiu2L
26 | ivT6l1xYyu9GSwsWaIgoEgU/YAhRhkh5EEV6QVugLkEJ+LPOXLWykzR40ndSClRl
27 | 9PuZqIOf/boHpdlmNotcJpKQiEZ2iXinQyYuU9kUTR/NL8YtTELo/ijZfzfZAQ2L
28 | MeC3M2CbSVYLHzU6Ue7YdxitDNTFZs5BdGhrtzAb7PmcOfLEgIIK7AER
29 | -----END CERTIFICATE-----
30 |
--------------------------------------------------------------------------------
/spring-boot-security-saml-demo-static-metadata/src/main/resources/localhost.cert:
--------------------------------------------------------------------------------
1 | -----BEGIN CERTIFICATE-----
2 | MIIC+zCCAeOgAwIBAgIJAIU7CnmezGizMA0GCSqGSIb3DQEBBQUAMBQxEjAQBgNV
3 | BAMMCWxvY2FsaG9zdDAeFw0xNjA0MDMwMjEwMjVaFw0yNjA0MDEwMjEwMjVaMBQx
4 | EjAQBgNVBAMMCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
5 | ggEBAN1NO3L/yCCb+MYFkypvJXcjlQuyRG7UFATYOYQZzIxsD9AtnXPh67uVkZTI
6 | oK7Ps5X4a5qVARtdN+GCFZ/ITahlAlIx8rmVsbz+7XPWpGPf75tKbem3pON2NlYW
7 | wIEQqyuValZHDUMgIXPdGIAZeNejVu7gYMLJwiSMtB0uBM69ptzgigJcbnup/cSL
8 | W4fBh4ck5kj0SVmX58knfaizrVf+ghGyNFha9Xy+DoilCofxwFIpVskv/hczZ5L+
9 | e81R+u2UbNzRwf8paF5fdVwaHPGLOYSBGjSm71VDdJqlvKrJCBoCQODhtmJOmDHD
10 | jtf6gwwbdg3g9GvyqIJnRqBO908CAwEAAaNQME4wHQYDVR0OBBYEFMNtl5fAchs3
11 | 5gZS4EF8/0C7QfBQMB8GA1UdIwQYMBaAFMNtl5fAchs35gZS4EF8/0C7QfBQMAwG
12 | A1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAADVL8LgYGlmaHlyrKyKfsQF
13 | TVbdT1Fk3WaGocVbhmvFeEBHScSJNR0syDcDM1C18pZ6Jc73cW7UdtLbLbRNPXS+
14 | qcp5GZroafndPIL2QzdKXfc5MiGH7CRCZit9kiNJ6YYgsztappXnwKblioJHB1Bc
15 | oLRzMeD295DAGLEVuc5tSY7JHBD3YQS9Pwt3ivrvvCzFKOU9nHqChMCplO4StGpS
16 | bbSR6XNgsPA0XLWlleuTqLGvJ4bHXPKC+0Y+0AiQYx3GeWLVrwJ4w+PFEK73vyuB
17 | 9H10x+zy1nFWvqoa+K66EA4u7DpEoHJBlqH0AVWAd8q9488DpCo1x4ujTGw7AHE=
18 | -----END CERTIFICATE-----
19 |
--------------------------------------------------------------------------------
/spring-boot-security-saml-demo-static-metadata/src/main/resources/localhost.jks:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ulisesbocchio/spring-boot-security-saml-samples/9ef34b596d6f5ffe9ddad04cabdc896cad73e4f9/spring-boot-security-saml-demo-static-metadata/src/main/resources/localhost.jks
--------------------------------------------------------------------------------
/spring-boot-security-saml-demo-static-metadata/src/main/resources/localhost.key.der:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ulisesbocchio/spring-boot-security-saml-samples/9ef34b596d6f5ffe9ddad04cabdc896cad73e4f9/spring-boot-security-saml-demo-static-metadata/src/main/resources/localhost.key.der
--------------------------------------------------------------------------------
/spring-boot-security-saml-demo-static-metadata/src/main/resources/localhost.key.pem:
--------------------------------------------------------------------------------
1 | -----BEGIN RSA PRIVATE KEY-----
2 | MIIEpQIBAAKCAQEA3U07cv/IIJv4xgWTKm8ldyOVC7JEbtQUBNg5hBnMjGwP0C2d
3 | c+Hru5WRlMigrs+zlfhrmpUBG1034YIVn8hNqGUCUjHyuZWxvP7tc9akY9/vm0pt
4 | 6bek43Y2VhbAgRCrK5VqVkcNQyAhc90YgBl416NW7uBgwsnCJIy0HS4Ezr2m3OCK
5 | Alxue6n9xItbh8GHhyTmSPRJWZfnySd9qLOtV/6CEbI0WFr1fL4OiKUKh/HAUilW
6 | yS/+FzNnkv57zVH67ZRs3NHB/yloXl91XBoc8Ys5hIEaNKbvVUN0mqW8qskIGgJA
7 | 4OG2Yk6YMcOO1/qDDBt2DeD0a/KogmdGoE73TwIDAQABAoIBAQDG0OH9+OnU0gt3
8 | 6/5A+0XPeTooHen5H7M0fwV9Nqhb56F1R+XS/D8Kcd8uqegh5RvUOjCB2if6a48O
9 | nA3NVOjfxo+FRLZqIKBjySuPDGD4EXF0NDP26zPJ3qQGR75+tXjyWPQFuyOhELa9
10 | Hv8p5rh4EpjBVvfXR+eRao9OP8+142Sedn5yKobQ6Qe9h4TIgBoCi1XCs86ySChr
11 | 7ITG3vEeB3Eq5hSbeN255m+VGjDySeeXsKHmnDHEq0ayLa8LbmD0XLmiLTrbV8IO
12 | Zy7qDxxnlIxjAmmbQj42orNNhDQwoGzy1wa8Yh5/3gwdxGXhufo7ItkkeRnCKCmh
13 | ThP0GSqBAoGBAPZNtNEHDxo5Getm4DbywTHYv+XBlWfLDkJSRjMSTCKzv9MemoX4
14 | vE5sx4ax8oLRcz4pQnfbXQeDePvvLyWApS6qhWbS9qf8oaIt2exPolqmCJibdGpM
15 | Y0Xk3ZFpUA7a+2jPK1PbrwLj/w7zNmFU8Rh/8RZS0QmBIcxovPH7kZ7vAoGBAOYD
16 | jXGVxcxsTdK8Ns6hltVPEE+XmWGfInCVfpAvECN+plwna1abdXafYnMXlmg/tC4q
17 | 2Ufkcw3PEtFKCAMQ1P0n8jSKXpjj1Lxlrunj2404eH93uHJih6zYE2gb/P+7jm49
18 | 377SQOObrueWZUy4mIIZmbT6464rq6sKP6tb1i2hAoGBAIQG31f0yrmpxiUTPjj2
19 | I21O3H6SKD488GXIqGyT8E/hvn+yte3+iSIY2VNwa6iIEZhOkZyh79opNV8GtWUK
20 | 8oBzU5Lsnt8pYpMGtPwhK8wfmBgFrH+Wdthud/6MTyfHZmCmPHl1FvkbsgsXgBzo
21 | ZVxWqKrotbi8iZuCwVWNHl/tAoGAEms2aGIV9Mi3cqifuuw1p98s7zK0lZyopVtT
22 | Rzh9kloR+E8vyT+pqFYbDBxXbwGq7AeCXr9sdy6d0ySaf6RZaexI+OwbpyKXZn6+
23 | Avy8GBLtk0eC/aXmN3EWHMAhAlmCjlFmGWG80H0nBGSGuB4QGFr0dAmjMc9Nb+Ti
24 | NFamUAECgYEA7uPN2cpwvVlt4Q4BHxjvvo1XDRe5c+RwDVa/dYkLu85HVvRd42SJ
25 | QgIdcZR9kLRXuOFCWv1shFmfHPqfmH0q6hn39TgVnUyHxzBlAbP5Dx/n4FRs8EP8
26 | qqNS0ft5Mqoy1UuJL6N5iDYY+i8Is90bsC9mMPj007kfFcyJcRULrSA=
27 | -----END RSA PRIVATE KEY-----
28 |
--------------------------------------------------------------------------------
/spring-boot-security-saml-demo-static-metadata/src/main/resources/localhost.p12:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ulisesbocchio/spring-boot-security-saml-samples/9ef34b596d6f5ffe9ddad04cabdc896cad73e4f9/spring-boot-security-saml-demo-static-metadata/src/main/resources/localhost.p12
--------------------------------------------------------------------------------
/spring-boot-security-saml-demo-static-metadata/src/main/resources/logback.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/spring-boot-security-saml-demo-static-metadata/src/main/resources/sp-ssocircle.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
6 |
9 |
10 |
11 |
12 |
13 | MIIC+zCCAeOgAwIBAgIJAIU7CnmezGizMA0GCSqGSIb3DQEBBQUAMBQxEjAQBgNVBAMMCWxvY2Fs
14 | aG9zdDAeFw0xNjA0MDMwMjEwMjVaFw0yNjA0MDEwMjEwMjVaMBQxEjAQBgNVBAMMCWxvY2FsaG9z
15 | dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAN1NO3L/yCCb+MYFkypvJXcjlQuyRG7U
16 | FATYOYQZzIxsD9AtnXPh67uVkZTIoK7Ps5X4a5qVARtdN+GCFZ/ITahlAlIx8rmVsbz+7XPWpGPf
17 | 75tKbem3pON2NlYWwIEQqyuValZHDUMgIXPdGIAZeNejVu7gYMLJwiSMtB0uBM69ptzgigJcbnup
18 | /cSLW4fBh4ck5kj0SVmX58knfaizrVf+ghGyNFha9Xy+DoilCofxwFIpVskv/hczZ5L+e81R+u2U
19 | bNzRwf8paF5fdVwaHPGLOYSBGjSm71VDdJqlvKrJCBoCQODhtmJOmDHDjtf6gwwbdg3g9GvyqIJn
20 | RqBO908CAwEAAaNQME4wHQYDVR0OBBYEFMNtl5fAchs35gZS4EF8/0C7QfBQMB8GA1UdIwQYMBaA
21 | FMNtl5fAchs35gZS4EF8/0C7QfBQMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAADV
22 | L8LgYGlmaHlyrKyKfsQFTVbdT1Fk3WaGocVbhmvFeEBHScSJNR0syDcDM1C18pZ6Jc73cW7UdtLb
23 | LbRNPXS+qcp5GZroafndPIL2QzdKXfc5MiGH7CRCZit9kiNJ6YYgsztappXnwKblioJHB1BcoLRz
24 | MeD295DAGLEVuc5tSY7JHBD3YQS9Pwt3ivrvvCzFKOU9nHqChMCplO4StGpSbbSR6XNgsPA0XLWl
25 | leuTqLGvJ4bHXPKC+0Y+0AiQYx3GeWLVrwJ4w+PFEK73vyuB9H10x+zy1nFWvqoa+K66EA4u7DpE
26 | oHJBlqH0AVWAd8q9488DpCo1x4ujTGw7AHE=
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 | MIIC+zCCAeOgAwIBAgIJAIU7CnmezGizMA0GCSqGSIb3DQEBBQUAMBQxEjAQBgNVBAMMCWxvY2Fs
35 | aG9zdDAeFw0xNjA0MDMwMjEwMjVaFw0yNjA0MDEwMjEwMjVaMBQxEjAQBgNVBAMMCWxvY2FsaG9z
36 | dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAN1NO3L/yCCb+MYFkypvJXcjlQuyRG7U
37 | FATYOYQZzIxsD9AtnXPh67uVkZTIoK7Ps5X4a5qVARtdN+GCFZ/ITahlAlIx8rmVsbz+7XPWpGPf
38 | 75tKbem3pON2NlYWwIEQqyuValZHDUMgIXPdGIAZeNejVu7gYMLJwiSMtB0uBM69ptzgigJcbnup
39 | /cSLW4fBh4ck5kj0SVmX58knfaizrVf+ghGyNFha9Xy+DoilCofxwFIpVskv/hczZ5L+e81R+u2U
40 | bNzRwf8paF5fdVwaHPGLOYSBGjSm71VDdJqlvKrJCBoCQODhtmJOmDHDjtf6gwwbdg3g9GvyqIJn
41 | RqBO908CAwEAAaNQME4wHQYDVR0OBBYEFMNtl5fAchs35gZS4EF8/0C7QfBQMB8GA1UdIwQYMBaA
42 | FMNtl5fAchs35gZS4EF8/0C7QfBQMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAADV
43 | L8LgYGlmaHlyrKyKfsQFTVbdT1Fk3WaGocVbhmvFeEBHScSJNR0syDcDM1C18pZ6Jc73cW7UdtLb
44 | LbRNPXS+qcp5GZroafndPIL2QzdKXfc5MiGH7CRCZit9kiNJ6YYgsztappXnwKblioJHB1BcoLRz
45 | MeD295DAGLEVuc5tSY7JHBD3YQS9Pwt3ivrvvCzFKOU9nHqChMCplO4StGpSbbSR6XNgsPA0XLWl
46 | leuTqLGvJ4bHXPKC+0Y+0AiQYx3GeWLVrwJ4w+PFEK73vyuB9H10x+zy1nFWvqoa+K66EA4u7DpE
47 | oHJBlqH0AVWAd8q9488DpCo1x4ujTGw7AHE=
48 |
49 |
50 |
51 |
52 |
54 |
56 | urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress
57 | urn:oasis:names:tc:SAML:2.0:nameid-format:transient
58 | urn:oasis:names:tc:SAML:2.0:nameid-format:persistent
59 | urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified
60 | urn:oasis:names:tc:SAML:1.1:nameid-format:X509SubjectName
61 |
63 |
65 |
67 |
68 |
--------------------------------------------------------------------------------
/spring-boot-security-saml-demo-static-metadata/src/main/resources/templates/home.html:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 | Home Page
6 |
7 |
8 | This is the Home Page
9 |
10 | Current User: unknown
11 |
12 |
13 |
14 | | SAML Attributes |
15 |
16 |
17 | | Attribute Name |
18 | Attribute Value |
19 |
20 |
21 |
22 | | key |
23 | value |
24 |
25 |
26 |
27 | Idp Single Logout - Local Logout
28 |
29 |
30 |
--------------------------------------------------------------------------------
/spring-boot-security-saml-demo-static-metadata/src/main/resources/templates/idpselection.html:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 | IdP Selection
6 |
7 |
8 | Select an IdP:
9 |
21 |
22 |
--------------------------------------------------------------------------------
/spring-boot-security-saml-demo-static-metadata/src/main/resources/templates/index.html:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 | Sample SAML Spring Boot Application
6 |
7 |
8 | Hi, Click here to start the Single Sign On process
9 |
10 |
--------------------------------------------------------------------------------
/spring-boot-security-saml-demo-static-metadata/src/main/resources/templates/protected.html:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 | Protected Resource
6 |
7 |
8 | Protected Resource
9 |
10 | This is a Protected Resource
11 |
12 | Home
13 |
14 |
--------------------------------------------------------------------------------
/spring-boot-security-saml-demo-static-metadata/src/test/java/com/github/ulisesbocchio/demo/SpringBootSecuritySamlDemoApplicationTests.java:
--------------------------------------------------------------------------------
1 | package com.github.ulisesbocchio.demo;
2 |
3 | import org.junit.Test;
4 | import org.junit.runner.RunWith;
5 | import org.springframework.boot.test.context.SpringBootTest;
6 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
7 | import org.springframework.test.context.web.WebAppConfiguration;
8 |
9 | @RunWith(SpringJUnit4ClassRunner.class)
10 | @SpringBootTest(classes = SpringBootSecuritySAMLDemoApplication.class)
11 | @WebAppConfiguration
12 | public class SpringBootSecuritySamlDemoApplicationTests {
13 |
14 | @Test
15 | public void contextLoads() {
16 | }
17 |
18 | }
19 |
--------------------------------------------------------------------------------
/spring-security-saml-sample/.mvn/wrapper/maven-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.3.3/apache-maven-3.3.3-bin.zip
--------------------------------------------------------------------------------
/spring-security-saml-sample/README.md:
--------------------------------------------------------------------------------
1 | ## Spring Security SAML Sample with Spring Boot ##
2 | This sample uses the plain old spring-security-saml library to add SP capabilities to a Spring Boot app, allowing it to authenticate against different IdPs.
3 | The main purpose of this module is to expose the extensive configuration required to use Spring Security SAML, in comparison with the `spring-boot-security-saml` plugin for Spring Boot, that deals with all this complexities internally.
4 |
5 | ### Availabe IdPs ####
6 |
7 | - [SSO Circle](http://www.ssocircle.com/en/)
8 | - [OneLogin](https://www.onelogin.com/)
9 | - [Ping One Clound] (https://www.pingidentity.com/en/products/pingone.html)
10 | - [OKTA](https://www.okta.com)
11 |
12 | ### Credentials ###
13 |
14 | Use the following credentials:
15 |
16 | - *SSO Circle:* Register with [SSO Circle] (http://www.ssocircle.com/en/) and use those credentials to login in the application.
17 | - *OneLogin:* The user must be created in your OneLogin account. See below.
18 | - *Ping One:* user: dough1234321@gmail.com pass: Test1234!
19 | - *OKTA:* user: dough1234321@gmail.com pass: Test1234!
20 |
21 | ### OneLogin configuration ###
22 |
23 | To use OneLogin with this sample application, you'll have to:
24 | - Create an [OneLogin developers account](https://www.onelogin.com/developer-signup)
25 | - Add a SAML Test Connector (IdP)
26 | - Configure the OneLogin application with:
27 | - *RelayState:* You can use anything here.
28 | - *Audience:* localhost-demo
29 | - *Recipient:* http://localhost:8080/saml/SSO
30 | - *ACS (Consumer) URL Validator:* ^http://localhost:8080/saml/SSO.*$
31 | - *ACS (Consumer) URL:* http://localhost:8080/saml/SSO
32 | - *Single Logout URL:* http://localhost:8080/saml/SingleLogout
33 | - *Parameters:* You can add additional parameters like firstName, lastName.
34 | - In the SSO tab:
35 | - *X.509 Certificate:* Copy-paste the existing X.509 PEM cerficate into idp-onelogin.xml (ds:X509Certificate).
36 | - *SAML Signature algorythm:* Use the SHA-256, although SHA-1 will still work.
37 | - *Issuer URL:* Replace the entityID in the idp-onelogin.xml with this value.
38 | - *SAML 2.0 Endpoint (HTTP):* Replace the location for the HTTP-Redirect and HTTP-POST binding in the idp-onelogin.xml with this value.
39 | - *SLO Endpoint (HTTP):* Replace the location for the HTTP-Redirect binding in the idp-onelogin.xml with this value.
40 |
--------------------------------------------------------------------------------
/spring-security-saml-sample/mvnw.cmd:
--------------------------------------------------------------------------------
1 | @REM ----------------------------------------------------------------------------
2 | @REM Licensed to the Apache Software Foundation (ASF) under one
3 | @REM or more contributor license agreements. See the NOTICE file
4 | @REM distributed with this work for additional information
5 | @REM regarding copyright ownership. The ASF licenses this file
6 | @REM to you under the Apache License, Version 2.0 (the
7 | @REM "License"); you may not use this file except in compliance
8 | @REM with the License. You may obtain a copy of the License at
9 | @REM
10 | @REM http://www.apache.org/licenses/LICENSE-2.0
11 | @REM
12 | @REM Unless required by applicable law or agreed to in writing,
13 | @REM software distributed under the License is distributed on an
14 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | @REM KIND, either express or implied. See the License for the
16 | @REM specific language governing permissions and limitations
17 | @REM under the License.
18 | @REM ----------------------------------------------------------------------------
19 |
20 | @REM ----------------------------------------------------------------------------
21 | @REM Maven2 Start Up Batch script
22 | @REM
23 | @REM Required ENV vars:
24 | @REM JAVA_HOME - location of a JDK home dir
25 | @REM
26 | @REM Optional ENV vars
27 | @REM M2_HOME - location of maven2's installed home dir
28 | @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
29 | @REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending
30 | @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
31 | @REM e.g. to debug Maven itself, use
32 | @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
33 | @REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
34 | @REM ----------------------------------------------------------------------------
35 |
36 | @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
37 | @echo off
38 | @REM enable echoing my setting MAVEN_BATCH_ECHO to 'on'
39 | @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
40 |
41 | @REM set %HOME% to equivalent of $HOME
42 | if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
43 |
44 | @REM Execute a user defined script before this one
45 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
46 | @REM check for pre script, once with legacy .bat ending and once with .cmd ending
47 | if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat"
48 | if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd"
49 | :skipRcPre
50 |
51 | @setlocal
52 |
53 | set ERROR_CODE=0
54 |
55 | @REM To isolate internal variables from possible post scripts, we use another setlocal
56 | @setlocal
57 |
58 | @REM ==== START VALIDATION ====
59 | if not "%JAVA_HOME%" == "" goto OkJHome
60 |
61 | echo.
62 | echo Error: JAVA_HOME not found in your environment. >&2
63 | echo Please set the JAVA_HOME variable in your environment to match the >&2
64 | echo location of your Java installation. >&2
65 | echo.
66 | goto error
67 |
68 | :OkJHome
69 | if exist "%JAVA_HOME%\bin\java.exe" goto init
70 |
71 | echo.
72 | echo Error: JAVA_HOME is set to an invalid directory. >&2
73 | echo JAVA_HOME = "%JAVA_HOME%" >&2
74 | echo Please set the JAVA_HOME variable in your environment to match the >&2
75 | echo location of your Java installation. >&2
76 | echo.
77 | goto error
78 |
79 | @REM ==== END VALIDATION ====
80 |
81 | :init
82 |
83 | set MAVEN_CMD_LINE_ARGS=%*
84 |
85 | @REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
86 | @REM Fallback to current working directory if not found.
87 |
88 | set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
89 | IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
90 |
91 | set EXEC_DIR=%CD%
92 | set WDIR=%EXEC_DIR%
93 | :findBaseDir
94 | IF EXIST "%WDIR%"\.mvn goto baseDirFound
95 | cd ..
96 | IF "%WDIR%"=="%CD%" goto baseDirNotFound
97 | set WDIR=%CD%
98 | goto findBaseDir
99 |
100 | :baseDirFound
101 | set MAVEN_PROJECTBASEDIR=%WDIR%
102 | cd "%EXEC_DIR%"
103 | goto endDetectBaseDir
104 |
105 | :baseDirNotFound
106 | set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
107 | cd "%EXEC_DIR%"
108 |
109 | :endDetectBaseDir
110 |
111 | IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
112 |
113 | @setlocal EnableExtensions EnableDelayedExpansion
114 | for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
115 | @endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
116 |
117 | :endReadAdditionalConfig
118 |
119 | SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
120 |
121 | set WRAPPER_JAR="".\.mvn\wrapper\maven-wrapper.jar""
122 | set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
123 |
124 | %MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CMD_LINE_ARGS%
125 | if ERRORLEVEL 1 goto error
126 | goto end
127 |
128 | :error
129 | set ERROR_CODE=1
130 |
131 | :end
132 | @endlocal & set ERROR_CODE=%ERROR_CODE%
133 |
134 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost
135 | @REM check for post script, once with legacy .bat ending and once with .cmd ending
136 | if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat"
137 | if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd"
138 | :skipRcPost
139 |
140 | @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
141 | if "%MAVEN_BATCH_PAUSE%" == "on" pause
142 |
143 | if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE%
144 |
145 | exit /B %ERROR_CODE%
--------------------------------------------------------------------------------
/spring-security-saml-sample/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 4.0.0
4 |
5 | spring-security-saml-sample
6 | jar
7 |
8 | Spring Security SAML Sample
9 | Demo project for Spring Boot
10 |
11 |
12 | com.github.ulisesbocchio
13 | spring-boot-security-saml-samples-parent
14 | 1.3-SNAPSHOT
15 |
16 |
17 |
18 | 1.8
19 | com.ulisesbocchio.security.saml.SamlServiceProviderApplication
20 |
21 |
22 |
23 |
24 | ch.qos.logback
25 | logback-access
26 |
27 |
28 | org.springframework.boot
29 | spring-boot-starter-web
30 |
31 |
32 | org.springframework.boot
33 | spring-boot-starter-thymeleaf
34 |
35 |
36 | org.springframework.boot
37 | spring-boot-starter-security
38 |
39 |
40 | org.springframework.security.extensions
41 | spring-security-saml2-core
42 | 1.0.9.RELEASE
43 |
44 |
45 | org.springframework.boot
46 | spring-boot-actuator
47 |
48 |
49 | com.google.guava
50 | guava
51 | 27.1-jre
52 |
53 |
54 | org.projectlombok
55 | lombok
56 | provided
57 |
58 |
59 | org.springframework.boot
60 | spring-boot-starter-test
61 | test
62 |
63 |
64 |
65 |
66 |
67 | org.springframework.boot
68 | spring-boot-maven-plugin
69 |
70 |
71 |
72 |
73 |
--------------------------------------------------------------------------------
/spring-security-saml-sample/src/main/java/com/ulisesbocchio/security/saml/SamlServiceProviderApplication.java:
--------------------------------------------------------------------------------
1 | package com.ulisesbocchio.security.saml;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 |
6 | /**
7 | * @author Ulises Bocchio
8 | */
9 | @SpringBootApplication
10 | public class SamlServiceProviderApplication {
11 |
12 | public static void main(String[] args) {
13 | SpringApplication.run(SamlServiceProviderApplication.class, args);
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/spring-security-saml-sample/src/main/java/com/ulisesbocchio/security/saml/certificate/KeystoreFactory.java:
--------------------------------------------------------------------------------
1 | package com.ulisesbocchio.security.saml.certificate;
2 |
3 | import lombok.SneakyThrows;
4 | import org.springframework.core.io.DefaultResourceLoader;
5 | import org.springframework.core.io.Resource;
6 | import org.springframework.core.io.ResourceLoader;
7 | import org.springframework.util.StreamUtils;
8 |
9 | import java.security.KeyFactory;
10 | import java.security.KeyStore;
11 | import java.security.cert.Certificate;
12 | import java.security.cert.CertificateFactory;
13 | import java.security.cert.X509Certificate;
14 | import java.security.interfaces.RSAPrivateKey;
15 | import java.security.spec.PKCS8EncodedKeySpec;
16 |
17 | /**
18 | * @author Ulises Bocchio
19 | */
20 | public class KeystoreFactory {
21 |
22 | private ResourceLoader resourceLoader;
23 |
24 | public KeystoreFactory() {
25 | resourceLoader = new DefaultResourceLoader();
26 | }
27 |
28 | public KeystoreFactory(ResourceLoader resourceLoader) {
29 | this.resourceLoader = resourceLoader;
30 | }
31 |
32 | @SneakyThrows
33 | public KeyStore loadKeystore(String certResourceLocation, String privateKeyResourceLocation, String alias, String keyPassword) {
34 | KeyStore keystore = createEmptyKeystore();
35 | X509Certificate cert = loadCert(certResourceLocation);
36 | RSAPrivateKey privateKey = loadPrivateKey(privateKeyResourceLocation);
37 | addKeyToKeystore(keystore, cert, privateKey, alias, keyPassword);
38 | return keystore;
39 | }
40 |
41 | @SneakyThrows
42 | public void addKeyToKeystore(KeyStore keyStore, X509Certificate cert, RSAPrivateKey privateKey, String alias, String password) {
43 | KeyStore.PasswordProtection pass = new KeyStore.PasswordProtection(password.toCharArray());
44 | Certificate[] certificateChain = {cert};
45 | keyStore.setEntry(alias, new KeyStore.PrivateKeyEntry(privateKey, certificateChain), pass);
46 | }
47 |
48 | @SneakyThrows
49 | public KeyStore createEmptyKeystore() {
50 | KeyStore keyStore = KeyStore.getInstance("JKS");
51 | keyStore.load(null, "".toCharArray());
52 | return keyStore;
53 | }
54 |
55 | @SneakyThrows
56 | public X509Certificate loadCert(String certLocation) {
57 | CertificateFactory cf = CertificateFactory.getInstance("X509");
58 | Resource certRes = resourceLoader.getResource(certLocation);
59 | X509Certificate cert = (X509Certificate) cf.generateCertificate(certRes.getInputStream());
60 | return cert;
61 | }
62 |
63 | @SneakyThrows
64 | public RSAPrivateKey loadPrivateKey(String privateKeyLocation) {
65 | Resource keyRes = resourceLoader.getResource(privateKeyLocation);
66 | byte[] keyBytes = StreamUtils.copyToByteArray(keyRes.getInputStream());
67 | PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(keyBytes);
68 | KeyFactory keyFactory = KeyFactory.getInstance("RSA");
69 | RSAPrivateKey privateKey = (RSAPrivateKey) keyFactory.generatePrivate(privateKeySpec);
70 | return privateKey;
71 | }
72 |
73 | public void setResourceLoader(DefaultResourceLoader resourceLoader) {
74 | this.resourceLoader = resourceLoader;
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/spring-security-saml-sample/src/main/java/com/ulisesbocchio/security/saml/config/FilterCleanupConfig.java:
--------------------------------------------------------------------------------
1 | package com.ulisesbocchio.security.saml.config;
2 |
3 | import com.google.common.collect.ImmutableSet;
4 | import org.springframework.beans.BeansException;
5 | import org.springframework.beans.factory.config.BeanDefinition;
6 | import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
7 | import org.springframework.beans.factory.support.BeanDefinitionBuilder;
8 | import org.springframework.beans.factory.support.BeanDefinitionRegistry;
9 | import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
10 | import org.springframework.beans.factory.support.DefaultListableBeanFactory;
11 | import org.springframework.boot.web.servlet.FilterRegistrationBean;
12 | import org.springframework.boot.web.servlet.ServletRegistrationBean;
13 | import org.springframework.context.annotation.Bean;
14 | import org.springframework.context.annotation.Configuration;
15 |
16 | import java.util.Arrays;
17 | import java.util.Set;
18 |
19 | /**
20 | * @author Ulises Bocchio
21 | */
22 | @Configuration
23 | public class FilterCleanupConfig {
24 | @Bean
25 | public static BeanDefinitionRegistryPostProcessor removeUnwantedAutomaticFilterRegistration() {
26 | return new BeanDefinitionRegistryPostProcessor() {
27 | @Override
28 | public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
29 | }
30 |
31 | @Override
32 | public void postProcessBeanFactory(ConfigurableListableBeanFactory bf) throws BeansException {
33 | DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) bf;
34 | Set filtersToDisable = ImmutableSet.of("samlEntryPoint", "samlFilter", "samlIDPDiscovery", "metadataDisplayFilter",
35 | "samlWebSSOHoKProcessingFilter", "samlWebSSOProcessingFilter",
36 | "samlLogoutProcessingFilter", "samlLogoutFilter", "metadataGeneratorFilter");
37 | Arrays.stream(beanFactory.getBeanNamesForType(javax.servlet.Filter.class))
38 | .filter(filtersToDisable::contains)
39 | .forEach(name -> {
40 | BeanDefinition definition = BeanDefinitionBuilder
41 | .genericBeanDefinition(FilterRegistrationBean.class)
42 | .setScope(BeanDefinition.SCOPE_SINGLETON)
43 | .addConstructorArgReference(name)
44 | .addConstructorArgValue(new ServletRegistrationBean[]{})
45 | .addPropertyValue("enabled", false)
46 | .getBeanDefinition();
47 | beanFactory.registerBeanDefinition(name + "FilterRegistrationBean", definition);
48 | });
49 | }
50 | };
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/spring-security-saml-sample/src/main/java/com/ulisesbocchio/security/saml/config/MvcConfig.java:
--------------------------------------------------------------------------------
1 | package com.ulisesbocchio.security.saml.config;
2 |
3 | import org.springframework.context.annotation.Configuration;
4 | import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
5 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
6 |
7 | /**
8 | * @author Ulises Bocchio
9 | */
10 | @Configuration
11 | public class MvcConfig implements WebMvcConfigurer {
12 |
13 | @Override
14 | public void addViewControllers(ViewControllerRegistry registry) {
15 | registry.addViewController("/").setViewName("index");
16 | registry.addViewController("/protected").setViewName("protected");
17 |
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/spring-security-saml-sample/src/main/java/com/ulisesbocchio/security/saml/config/SAMLConfigDefaults.java:
--------------------------------------------------------------------------------
1 | package com.ulisesbocchio.security.saml.config;
2 |
3 | import org.opensaml.saml2.metadata.provider.MetadataProvider;
4 | import org.opensaml.saml2.metadata.provider.MetadataProviderException;
5 | import org.springframework.context.annotation.Bean;
6 | import org.springframework.context.annotation.Configuration;
7 | import org.springframework.security.saml.SAMLBootstrap;
8 | import org.springframework.security.saml.context.SAMLContextProviderImpl;
9 | import org.springframework.security.saml.log.SAMLDefaultLogger;
10 | import org.springframework.security.saml.metadata.CachingMetadataManager;
11 | import org.springframework.security.saml.parser.ParserPoolHolder;
12 | import org.springframework.security.saml.websso.*;
13 |
14 | import java.util.List;
15 |
16 | /**
17 | * @author Ulises Bocchio
18 | */
19 | @Configuration
20 | public class SAMLConfigDefaults {
21 | @Bean
22 | public static SAMLBootstrap sAMLBootstrap() {
23 | return new SAMLBootstrap();
24 | }
25 |
26 | @Bean
27 | public ParserPoolHolder parserPoolHolder() {
28 | return new ParserPoolHolder();
29 | }
30 |
31 | @Bean
32 | public SAMLContextProviderImpl contextProvider() {
33 | return new SAMLContextProviderImpl();
34 | }
35 |
36 | @Bean
37 | public SAMLDefaultLogger samlLogger() {
38 | return new SAMLDefaultLogger();
39 | }
40 |
41 | @Bean
42 | public WebSSOProfileConsumer webSSOprofileConsumer() {
43 | return new WebSSOProfileConsumerImpl();
44 | }
45 |
46 | @Bean
47 | public WebSSOProfileConsumerHoKImpl hokWebSSOprofileConsumer() {
48 | return new WebSSOProfileConsumerHoKImpl();
49 | }
50 |
51 | @Bean
52 | public WebSSOProfile webSSOprofile() {
53 | return new WebSSOProfileImpl();
54 | }
55 |
56 | @Bean
57 | public WebSSOProfileECPImpl ecpProfile() {
58 | return new WebSSOProfileECPImpl();
59 | }
60 |
61 | @Bean
62 | public WebSSOProfileHoKImpl hokWebSSOProfile() {
63 | return new WebSSOProfileHoKImpl();
64 | }
65 |
66 | @Bean
67 | public SingleLogoutProfile logoutProfile() {
68 | return new SingleLogoutProfileImpl();
69 | }
70 |
71 | @Bean
72 | public CachingMetadataManager metadataManager(List metadataProviders) throws MetadataProviderException {
73 | return new CachingMetadataManager(metadataProviders);
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/spring-security-saml-sample/src/main/java/com/ulisesbocchio/security/saml/config/WebSecurityConfig.java:
--------------------------------------------------------------------------------
1 | package com.ulisesbocchio.security.saml.config;
2 |
3 | import org.springframework.beans.factory.annotation.Autowired;
4 | import org.springframework.context.annotation.Configuration;
5 | import org.springframework.security.authentication.AuthenticationManager;
6 | import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
7 | import org.springframework.security.config.annotation.web.builders.HttpSecurity;
8 | import org.springframework.security.config.annotation.web.builders.WebSecurity;
9 | import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
10 | import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
11 | import org.springframework.security.saml.*;
12 | import org.springframework.security.saml.metadata.MetadataDisplayFilter;
13 | import org.springframework.security.saml.metadata.MetadataGeneratorFilter;
14 | import org.springframework.security.web.authentication.logout.LogoutFilter;
15 | import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
16 | import org.springframework.security.web.context.HttpSessionSecurityContextRepository;
17 |
18 | /**
19 | * @author Ulises Bocchio
20 | */
21 | @Configuration
22 | @EnableWebSecurity
23 | @EnableGlobalMethodSecurity(securedEnabled = true)
24 | public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
25 |
26 | @Autowired
27 | private SAMLLogoutFilter samlLogoutFilter;
28 |
29 | @Autowired
30 | private SAMLLogoutProcessingFilter samlLogoutProcessingFilter;
31 |
32 | @Autowired
33 | private MetadataDisplayFilter metadataDisplayFilter;
34 |
35 | @Autowired
36 | private MetadataGeneratorFilter metadataGeneratorFilter;
37 |
38 | @Autowired
39 | private SAMLProcessingFilter samlWebSSOProcessingFilter;
40 |
41 | @Autowired
42 | private SAMLWebSSOHoKProcessingFilter samlWebSSOHoKProcessingFilter;
43 |
44 | @Autowired
45 | private SAMLEntryPoint samlEntryPoint;
46 |
47 | @Autowired
48 | private SAMLDiscovery samlIDPDiscovery;
49 |
50 | @Autowired
51 | private AuthenticationManager authenticationManager;
52 |
53 |
54 | @Override
55 | public void init(WebSecurity web) throws Exception {
56 | super.init(web);
57 | }
58 |
59 |
60 | /**
61 | * Defines the web based security configuration.
62 | *
63 | * @param http It allows configuring web based security for specific http requests.
64 | */
65 | @Override
66 | protected void configure(HttpSecurity http) throws Exception {
67 | HttpSessionSecurityContextRepository securityContextRepository = new HttpSessionSecurityContextRepository();
68 | securityContextRepository.setSpringSecurityContextKey("SPRING_SECURITY_CONTEXT_SAML");
69 | http
70 | .securityContext()
71 | .securityContextRepository(securityContextRepository);
72 | http
73 | .httpBasic()
74 | .disable();
75 | http
76 | .csrf()
77 | .disable();
78 | http
79 | .addFilterAfter(metadataGeneratorFilter, BasicAuthenticationFilter.class)
80 | .addFilterAfter(metadataDisplayFilter, MetadataGeneratorFilter.class)
81 | .addFilterAfter(samlEntryPoint, MetadataDisplayFilter.class)
82 | .addFilterAfter(samlWebSSOProcessingFilter, SAMLEntryPoint.class)
83 | .addFilterAfter(samlWebSSOHoKProcessingFilter, SAMLProcessingFilter.class)
84 | .addFilterAfter(samlLogoutProcessingFilter, SAMLWebSSOHoKProcessingFilter.class)
85 | .addFilterAfter(samlIDPDiscovery, SAMLLogoutProcessingFilter.class)
86 | .addFilterAfter(samlLogoutFilter, LogoutFilter.class);
87 | http
88 | .authorizeRequests()
89 | .antMatchers("/", "/error", "/saml/**", "/idpselection").permitAll()
90 | .anyRequest().authenticated();
91 | http
92 | .exceptionHandling()
93 | .authenticationEntryPoint(samlEntryPoint);
94 | http
95 | .logout()
96 | .disable();
97 | }
98 |
99 | @Override
100 | protected AuthenticationManager authenticationManager() throws Exception {
101 | return authenticationManager;
102 | }
103 | }
104 |
--------------------------------------------------------------------------------
/spring-security-saml-sample/src/main/java/com/ulisesbocchio/security/saml/spring/SpringResourceWrapperOpenSAMLResource.java:
--------------------------------------------------------------------------------
1 | package com.ulisesbocchio.security.saml.spring;
2 |
3 | import lombok.SneakyThrows;
4 | import org.joda.time.DateTime;
5 | import org.opensaml.util.resource.ResourceException;
6 | import org.springframework.core.io.Resource;
7 |
8 | import java.io.IOException;
9 | import java.io.InputStream;
10 |
11 | /**
12 | * @author Ulises Bocchio
13 | */
14 | public class SpringResourceWrapperOpenSAMLResource implements org.opensaml.util.resource.Resource {
15 |
16 | private Resource springDelegate;
17 |
18 | public SpringResourceWrapperOpenSAMLResource(Resource springDelegate) throws ResourceException {
19 | this.springDelegate = springDelegate;
20 | exists();
21 | }
22 |
23 | @Override
24 | @SneakyThrows
25 | public String getLocation() {
26 | return springDelegate.getURL().toString();
27 | }
28 |
29 | @Override
30 | public boolean exists() throws ResourceException {
31 | return springDelegate.exists();
32 | }
33 |
34 | @Override
35 | public InputStream getInputStream() throws ResourceException {
36 | try {
37 | return springDelegate.getInputStream();
38 | } catch (IOException e) {
39 | throw new ResourceException(e);
40 | }
41 | }
42 |
43 | @Override
44 | public DateTime getLastModifiedTime() throws ResourceException {
45 | try {
46 | return new DateTime(springDelegate.lastModified());
47 | } catch (IOException e) {
48 | throw new ResourceException(e);
49 | }
50 | }
51 |
52 | public int hashCode() {
53 | return getLocation().hashCode();
54 | }
55 |
56 | public boolean equals(Object o) {
57 | if (o == this) {
58 | return true;
59 | }
60 |
61 | if (o instanceof SpringResourceWrapperOpenSAMLResource) {
62 | return getLocation().equals(((SpringResourceWrapperOpenSAMLResource) o).getLocation());
63 | }
64 |
65 | return false;
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/spring-security-saml-sample/src/main/java/com/ulisesbocchio/security/saml/spring/mvc/HomeController.java:
--------------------------------------------------------------------------------
1 | package com.ulisesbocchio.security.saml.spring.mvc;
2 |
3 | /**
4 | * @author Ulises Bocchio
5 | */
6 |
7 | import com.ulisesbocchio.security.saml.spring.security.SAMLUserDetails;
8 | import org.springframework.stereotype.Controller;
9 | import org.springframework.web.bind.annotation.RequestMapping;
10 | import org.springframework.web.servlet.ModelAndView;
11 |
12 | @Controller
13 | public class HomeController {
14 |
15 | @RequestMapping("/home")
16 | public ModelAndView home(@SAMLUser SAMLUserDetails user) {
17 | ModelAndView homeView = new ModelAndView("home");
18 | homeView.addObject("userId", user.getUsername());
19 | homeView.addObject("samlAttributes", user.getAttributes());
20 | return homeView;
21 | }
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/spring-security-saml-sample/src/main/java/com/ulisesbocchio/security/saml/spring/mvc/IdPSelectionController.java:
--------------------------------------------------------------------------------
1 | package com.ulisesbocchio.security.saml.spring.mvc;
2 |
3 | /**
4 | * @author Ulises Bocchio
5 | */
6 |
7 | import lombok.SneakyThrows;
8 | import lombok.extern.slf4j.Slf4j;
9 | import org.springframework.beans.factory.annotation.Autowired;
10 | import org.springframework.security.authentication.AuthenticationServiceException;
11 | import org.springframework.security.saml.SAMLConstants;
12 | import org.springframework.security.saml.SAMLDiscovery;
13 | import org.springframework.security.saml.metadata.MetadataManager;
14 | import org.springframework.stereotype.Controller;
15 | import org.springframework.web.bind.annotation.RequestMapping;
16 | import org.springframework.web.servlet.ModelAndView;
17 |
18 | import javax.servlet.http.HttpServletRequest;
19 | import java.util.Map;
20 |
21 | import static java.util.function.Function.identity;
22 | import static java.util.stream.Collectors.toMap;
23 |
24 | @Controller
25 | @RequestMapping("/idpselection")
26 | @Slf4j
27 | public class IdPSelectionController {
28 |
29 | @Autowired
30 | private MetadataManager metadataManager;
31 |
32 | @RequestMapping
33 | public ModelAndView idpSelection(HttpServletRequest request) {
34 |
35 | if (comesFromDiscoveryFilter(request)) {
36 | ModelAndView idpSelection = new ModelAndView("idpselection");
37 | idpSelection.addObject(SAMLDiscovery.RETURN_URL, request.getAttribute(SAMLDiscovery.RETURN_URL));
38 | idpSelection.addObject(SAMLDiscovery.RETURN_PARAM, request.getAttribute(SAMLDiscovery.RETURN_PARAM));
39 | Map idpNameAliasMap = metadataManager.getIDPEntityNames().stream()
40 | .collect(toMap(identity(), this::getAlias));
41 | idpSelection.addObject("idpNameAliasMap", idpNameAliasMap);
42 | return idpSelection;
43 | }
44 | throw new AuthenticationServiceException("SP Discovery flow not detected");
45 | }
46 |
47 | @SneakyThrows
48 | private String getAlias(String entityId) {
49 | return metadataManager.getExtendedMetadata(entityId).getAlias();
50 | }
51 |
52 | private boolean comesFromDiscoveryFilter(HttpServletRequest request) {
53 | return request.getAttribute(SAMLConstants.LOCAL_ENTITY_ID) != null &&
54 | request.getAttribute(SAMLDiscovery.RETURN_URL) != null &&
55 | request.getAttribute(SAMLDiscovery.RETURN_PARAM) != null;
56 | }
57 |
58 | }
59 |
--------------------------------------------------------------------------------
/spring-security-saml-sample/src/main/java/com/ulisesbocchio/security/saml/spring/mvc/SAMLUser.java:
--------------------------------------------------------------------------------
1 | package com.ulisesbocchio.security.saml.spring.mvc;
2 |
3 | import org.springframework.security.core.annotation.AuthenticationPrincipal;
4 |
5 | import java.lang.annotation.*;
6 |
7 | /**
8 | * @author Ulises Bocchio
9 | */
10 | @Target({ElementType.PARAMETER, ElementType.ANNOTATION_TYPE})
11 | @Retention(RetentionPolicy.RUNTIME)
12 | @Documented
13 | @AuthenticationPrincipal
14 | public @interface SAMLUser {
15 | }
16 |
--------------------------------------------------------------------------------
/spring-security-saml-sample/src/main/java/com/ulisesbocchio/security/saml/spring/security/SAMLUserDetails.java:
--------------------------------------------------------------------------------
1 | package com.ulisesbocchio.security.saml.spring.security;
2 |
3 | import java.util.Collection;
4 | import java.util.Collections;
5 | import java.util.Map;
6 | import java.util.stream.Collectors;
7 |
8 | import org.opensaml.saml2.core.Attribute;
9 | import org.springframework.security.core.GrantedAuthority;
10 | import org.springframework.security.core.authority.SimpleGrantedAuthority;
11 | import org.springframework.security.core.userdetails.UserDetails;
12 | import org.springframework.security.saml.SAMLCredential;
13 | import org.springframework.security.saml.userdetails.SAMLUserDetailsService;
14 |
15 | /**
16 | * Default Implementation of {@link UserDetails} for Spring Boot Security SAML. This simple implementation hardly covers all security aspects since it's mostly
17 | * hardcoded. I.E. accounts are never locked, expired, or disabled, and always eturn the same granted authority "ROLE_USER". Consider implementing your own
18 | * {@link UserDetails} and {@link SAMLUserDetailsService}.
19 | *
20 | * @author Ulises Bocchio
21 | */
22 | public class SAMLUserDetails implements UserDetails {
23 |
24 | private SAMLCredential samlCredential;
25 |
26 | public SAMLUserDetails(SAMLCredential samlCredential) {
27 | this.samlCredential = samlCredential;
28 | }
29 |
30 | @Override
31 | public Collection extends GrantedAuthority> getAuthorities() {
32 | return Collections.singletonList(new SimpleGrantedAuthority("ROLE_USER"));
33 | }
34 |
35 | @Override
36 | public String getPassword() {
37 | return "";
38 | }
39 |
40 | @Override
41 | public String getUsername() {
42 | return samlCredential.getNameID().getValue();
43 | }
44 |
45 | @Override
46 | public boolean isAccountNonExpired() {
47 | return true;
48 | }
49 |
50 | @Override
51 | public boolean isAccountNonLocked() {
52 | return true;
53 | }
54 |
55 | @Override
56 | public boolean isCredentialsNonExpired() {
57 | return true;
58 | }
59 |
60 | @Override
61 | public boolean isEnabled() {
62 | return true;
63 | }
64 |
65 | public String getAttribute(String name) {
66 | return samlCredential.getAttributeAsString(name);
67 | }
68 |
69 | public String[] getAttributeArray(String name) {
70 | return samlCredential.getAttributeAsStringArray(name);
71 | }
72 |
73 | public Map getAttributes() {
74 | return samlCredential.getAttributes().stream()
75 | .collect(Collectors.toMap(Attribute::getName, this::getString));
76 | }
77 |
78 | private String getString(Attribute attribute) {
79 | String value = getValue(attribute);
80 | return value == null ? "" : value;
81 | }
82 |
83 | public Map getAttributesArrays() {
84 | return samlCredential.getAttributes().stream()
85 | .collect(Collectors.toMap(Attribute::getName, this::getValueArray));
86 | }
87 |
88 | private String getValue(Attribute attribute) {
89 | return getAttribute(attribute.getName());
90 | }
91 |
92 | private String[] getValueArray(Attribute attribute) {
93 | return getAttributeArray(attribute.getName());
94 | }
95 | }
96 |
--------------------------------------------------------------------------------
/spring-security-saml-sample/src/main/java/com/ulisesbocchio/security/saml/spring/security/SAMLUserDetailsServiceImpl.java:
--------------------------------------------------------------------------------
1 | package com.ulisesbocchio.security.saml.spring.security;
2 |
3 | import lombok.extern.slf4j.Slf4j;
4 |
5 | import org.springframework.security.core.GrantedAuthority;
6 | import org.springframework.security.core.authority.SimpleGrantedAuthority;
7 | import org.springframework.security.core.userdetails.User;
8 | import org.springframework.security.core.userdetails.UsernameNotFoundException;
9 | import org.springframework.security.saml.SAMLCredential;
10 | import org.springframework.security.saml.userdetails.SAMLUserDetailsService;
11 | import org.springframework.stereotype.Service;
12 |
13 | import java.util.ArrayList;
14 | import java.util.List;
15 |
16 | /**
17 | * @author Ulises Bocchio
18 | */
19 | @Slf4j
20 | @Service
21 | public class SAMLUserDetailsServiceImpl implements SAMLUserDetailsService {
22 |
23 | public Object loadUserBySAML(SAMLCredential credential) throws UsernameNotFoundException {
24 | log.info("Login received for user {}", credential.getNameID().getValue());
25 | return new SAMLUserDetails(credential);
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/spring-security-saml-sample/src/main/resources/application.yml:
--------------------------------------------------------------------------------
1 | management:
2 | security:
3 | enabled: false
4 | context-path: "/manage"
5 |
6 | logging.level.org.springframework.security.saml: DEBUG
--------------------------------------------------------------------------------
/spring-security-saml-sample/src/main/resources/idp-okta.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
9 | MIIDpDCCAoygAwIBAgIGAVO669oLMA0GCSqGSIb3DQEBBQUAMIGSMQswCQYDVQQGEwJVUzETMBEG
10 | A1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzENMAsGA1UECgwET2t0YTEU
11 | MBIGA1UECwwLU1NPUHJvdmlkZXIxEzARBgNVBAMMCmRldi04MzkyMjgxHDAaBgkqhkiG9w0BCQEW
12 | DWluZm9Ab2t0YS5jb20wHhcNMTYwMzI4MDE1MTEyWhcNMjYwMzI4MDE1MjEyWjCBkjELMAkGA1UE
13 | BhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNVBAcMDVNhbiBGcmFuY2lzY28xDTALBgNV
14 | BAoMBE9rdGExFDASBgNVBAsMC1NTT1Byb3ZpZGVyMRMwEQYDVQQDDApkZXYtODM5MjI4MRwwGgYJ
15 | KoZIhvcNAQkBFg1pbmZvQG9rdGEuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
16 | 0H9hcvueaxQsH+GjDBPJdQ3FotGgPFOyFuZFvDwBeXiTMPAMoB8s+9Ey7ugYoAvLJMm7ryXAhOGa
17 | tblP4BcxPWrFJx+Tddswkb9pmM9rbmfrBBW3gsiwPQ/bEuwnvNxICIaeWD7h50Qej8UgrSunqmEq
18 | pBYi530/mWy7fdyRWniC0NtqlGDc+7jM4itchIjxuJXm0MX8BTzUkk8yU/Ul/YwNCwTAZNwispES
19 | ADsU9Mc+qcI6Fc68NC8pzPTpV4XEIiDwK8bfdQa1kwM3teL+1cHTXkEMvfhzBLZLedaB7b2Ictp+
20 | /mPtX/m9+zu/oqeZs1ZfCPfOpaNQCw4ug/G7PQIDAQABMA0GCSqGSIb3DQEBBQUAA4IBAQAxlYaA
21 | PPB8kvNZgLX1V/WGxfpQTZMVLJGCfVA50I7wzRn+bDgkLhl2L3Rn7V7epQ7yOGYoIZ2QZGqu8fto
22 | xyXLmbx+gKvrejPp8QGCDl4Ga9UppIRtvdnLpXKeBw1m2GbLbgIlMmCbSGo05YSxBM7m6C7ZBDbA
23 | Sn8kNrM+77jWPs+uRO/Oe9UlMGIMIvxaUyy7H9TpUNHAMQKwYPiua/32T53iv9TZ6YYgdK1b2haA
24 | N3ESCsNEmU5BRZBQgBMRiw1qfWt5tGpAxjCKkVFEwR6gQwqH5QhAnzA9lyVAq8FGr7HDxMyLoObB
25 | avSvuMAJ1fZFZh4v3XJussihq2MjHH3g
26 |
27 |
28 |
29 |
30 |
32 |
34 | urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress
35 | urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified
36 |
38 |
40 |
41 |
--------------------------------------------------------------------------------
/spring-security-saml-sample/src/main/resources/idp-onelogin.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
6 |
7 |
8 | MIIEKTCCAxGgAwIBAgIUMZQydOi0ZordvxMyczVbCIvGGpgwDQYJKoZIhvcNAQEF
9 | BQAwXjELMAkGA1UEBhMCVVMxFzAVBgNVBAoMDlVsaXNlcyBCb2NjaGlvMRUwEwYD
10 | VQQLDAxPbmVMb2dpbiBJZFAxHzAdBgNVBAMMFk9uZUxvZ2luIEFjY291bnQgODA5
11 | NDAwHhcNMTYwMzI2MTY0NDExWhcNMjEwMzI3MTY0NDExWjBeMQswCQYDVQQGEwJV
12 | UzEXMBUGA1UECgwOVWxpc2VzIEJvY2NoaW8xFTATBgNVBAsMDE9uZUxvZ2luIElk
13 | UDEfMB0GA1UEAwwWT25lTG9naW4gQWNjb3VudCA4MDk0MDCCASIwDQYJKoZIhvcN
14 | AQEBBQADggEPADCCAQoCggEBAKjdXtawZwsmmtrb9Z82Yov9uqmiNh8QyyQ+cpW2
15 | f4IgfQygEDJoAvb2W1mHPB6W3DsMjorvXlCp5+Yn2w54eLHUfExB2uCeEJY+myY/
16 | hyyQzdHH5uC6hWerz1V4JjVGDcxs2U8Suclc8m0ge8tXaJU4ByLeB3yMjS/qneWl
17 | iFqxcZ4gUpdCRcSXnezwC8QPIy1wMZfJyQOqnuavqkpnB31MHGfjOwE0PMyBTWaC
18 | onZ7dsTAAX0/PSaZcT+BA7Qeol0GGUwgVMuuvf0ymiHaHN2Y88RVm3kPwKr5C3Bt
19 | yVlC3IZM9VhxoaxgmSIEKfwKZgRTbbmjjt8w6J1CkIq6ClMCAwEAAaOB3jCB2zAM
20 | BgNVHRMBAf8EAjAAMB0GA1UdDgQWBBTX8TN/N7vhy/hHsAFaJ1+VOR9cxzCBmwYD
21 | VR0jBIGTMIGQgBTX8TN/N7vhy/hHsAFaJ1+VOR9cx6FipGAwXjELMAkGA1UEBhMC
22 | VVMxFzAVBgNVBAoMDlVsaXNlcyBCb2NjaGlvMRUwEwYDVQQLDAxPbmVMb2dpbiBJ
23 | ZFAxHzAdBgNVBAMMFk9uZUxvZ2luIEFjY291bnQgODA5NDCCFDGUMnTotGaK3b8T
24 | MnM1WwiLxhqYMA4GA1UdDwEB/wQEAwIHgDANBgkqhkiG9w0BAQUFAAOCAQEAGk2m
25 | COTJa4N3iIWpspUTxVeaev4Bxjpmoe+1OQnQqvHYdXO4xZwQIj56B7mErXZJ9XGH
26 | 6t28Kw0yq8UZYCVdjkyV5KmaoTIDBhKr2+mjbtlZH9RYA6VvOxupFt/Rf7cax5vq
27 | 7RneWhT1dL/u49r5eUMNFJbeR3FE2SUp/9qhqOQkexfRgGHPDTEv4nYIiXWkk2qj
28 | ZfEP8eCIZp0yJcL0k4Ulo/CxusWVYhNNTNBdcmmYZbWUjQlr9toBVMQa/YcJs24b
29 | EUEb/XLDntIXEmjhUI1bYB+lU9V1lW+8YHIvtZKCoSCkYU8qlZSkoBOMPMVyrhw3
30 | zsJ4ayogap7/2aUL2g==
31 |
32 |
33 |
34 |
35 | urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified
36 |
38 |
40 |
42 |
44 |
45 |
46 | Support
47 | support@onelogin.com
48 |
49 |
50 |
--------------------------------------------------------------------------------
/spring-security-saml-sample/src/main/resources/idp-pingone.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
7 |
8 | MIIDbjCCAlagAwIBAgIGAVO7a/mHMA0GCSqGSIb3DQEBCwUAMHgxCzAJBgNVBAYTAlVTMQswCQYD
9 | VQQIEwJDTzEPMA0GA1UEBxMGRGVudmVyMRYwFAYDVQQKEw1QaW5nIElkZW50aXR5MTMwMQYDVQQD
10 | EypodHRwc3BpbmdvbmVjb21pZHBjZDYxNzYxMjExMnVsaXNlc2JvY2NoaW8wHhcNMTYwMzI4MDQx
11 | MjA4WhcNMTkwMzI4MDQxMjA4WjB4MQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ08xDzANBgNVBAcT
12 | BkRlbnZlcjEWMBQGA1UEChMNUGluZyBJZGVudGl0eTEzMDEGA1UEAxMqaHR0cHNwaW5nb25lY29t
13 | aWRwY2Q2MTc2MTIxMTJ1bGlzZXNib2NjaGlvMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
14 | AQEAhjQMpQYdTErsPdJ2iLVpKXVnAlr/W2vHXxwVEi/P4dilEP2svWPVfTYr0omM28mOPh1DZkl9
15 | KQvSxJCKWy/ronG+FS5hQ2SeKb0vnQMG/ipWaA9IsLZDx9QM0R456AKqe+D+ioYltgQxqvR3TeFb
16 | /xlOnUs3/MNRbhS+BPi9DSkpADMEkfadk3U7GX3Imna3Jj+SV4gAOwqjS+Q2bmWrv96d7RXQKAKT
17 | DjO1CVH+n5ku0l6+WzQKAeLp4daB0JKSJfaeCTI1gO5b2nq0U6/0ilNbMzGXSgu9yFhk59PF7CwK
18 | JNxTKQuvoTayUvlXOzwcNj1phiUtn48TNy1ZdEBsMQIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQAb
19 | 9hZQ9yaWDW1/x5TwMx7xiKpQzYNv1y1Ftwj1DrJMC4NvtZzurOYeya81fqoPKGtIn5PMaZu4bl5g
20 | ytyWlqtRhwbI2Vrwyy1RUQml+il94W5u83e1FXV7PY7xJXHJ+KE2z3Pyeo5sDBnXDVnT+ytNDtam
21 | 0IDZXzQ81tCMQ/rcieIqbihtMPf9qMTB6Xv5EwlAeSWMCD0PvWx5Ng2Y1bp95kiwp5YU/8j7PwOJ
22 | 1mRrjju+S6ixQeD+VJrF4y6vMhORUrJXqEU7EKMuqeQB5fzDX7VNsnePnRqBifqDTt9QnafeIJ8u
23 | XCtHy2m5UXZ8eDEAbo9jWhkZC+6IVbgSoeFa
24 |
25 |
26 |
27 |
28 |
29 |
30 |
32 |
35 |
38 |
40 |
42 |
43 |
--------------------------------------------------------------------------------
/spring-security-saml-sample/src/main/resources/idp-ssocircle.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | MIICjDCCAXSgAwIBAgIFAJRvxcMwDQYJKoZIhvcNAQEEBQAwLjELMAkGA1UEBhMCREUxEjAQBgNV
9 | BAoTCVNTT0NpcmNsZTELMAkGA1UEAxMCQ0EwHhcNMTEwNTE3MTk1NzIxWhcNMTYwODE3MTk1NzIx
10 | WjBLMQswCQYDVQQGEwJERTESMBAGA1UEChMJU1NPQ2lyY2xlMQwwCgYDVQQLEwNpZHAxGjAYBgNV
11 | BAMTEWlkcC5zc29jaXJjbGUuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCbzDRkudC/
12 | aC2gMqRVVaLdPJJEwpFB4o71fR5bnNd2ocnnNzJ/W9CoCargzKx+EJ4Nm3vWmX/IZRCFvrvy9C78
13 | fP1cmt6Sa091K9luaMAyWn7oC8h/YBXH7rB42tdvWLY4Kl9VJy6UCclvasyrfKx+SR4KU6zCsM62
14 | 2Kvp5wW67QIDAQABoxgwFjAUBglghkgBhvhCAQEBAf8EBAMCBHAwDQYJKoZIhvcNAQEEBQADggEB
15 | AJ0heua7mFO3QszdGu1NblGaTDXtf6Txte0zpYIt+8YUcza2SaZXXvCLb9DvGxW1TJWaZpPGpHz5
16 | tLXJbdYQn7xTAnL4yQOKN6uNqUA/aTVgyyUJkWZt2giwEsWUvG0UBMSPS1tp2pV2c6/olIcbdYU6
17 | ZecUz6N24sSS7itEBC6nwCVBoHOL8u6MsfxMLDzJIPBI68UZjz3IMKTDUDv6U9DtYmXLc8iMVZBn
18 | cYJn9NgNi3ghl9fYPpHcc6QbXeDUjhdzXXUqG+hB6FabGqdTdkIZwoi4gNpyr3kacKRVWJssDgak
19 | eL2MoDNqJyQ0fXC6Ze3f79CKy/WjeU5FLwDZR0Q=
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 | MIICjDCCAXSgAwIBAgIFAJRvxcMwDQYJKoZIhvcNAQEEBQAwLjELMAkGA1UEBhMCREUxEjAQBgNV
29 | BAoTCVNTT0NpcmNsZTELMAkGA1UEAxMCQ0EwHhcNMTEwNTE3MTk1NzIxWhcNMTYwODE3MTk1NzIx
30 | WjBLMQswCQYDVQQGEwJERTESMBAGA1UEChMJU1NPQ2lyY2xlMQwwCgYDVQQLEwNpZHAxGjAYBgNV
31 | BAMTEWlkcC5zc29jaXJjbGUuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCbzDRkudC/
32 | aC2gMqRVVaLdPJJEwpFB4o71fR5bnNd2ocnnNzJ/W9CoCargzKx+EJ4Nm3vWmX/IZRCFvrvy9C78
33 | fP1cmt6Sa091K9luaMAyWn7oC8h/YBXH7rB42tdvWLY4Kl9VJy6UCclvasyrfKx+SR4KU6zCsM62
34 | 2Kvp5wW67QIDAQABoxgwFjAUBglghkgBhvhCAQEBAf8EBAMCBHAwDQYJKoZIhvcNAQEEBQADggEB
35 | AJ0heua7mFO3QszdGu1NblGaTDXtf6Txte0zpYIt+8YUcza2SaZXXvCLb9DvGxW1TJWaZpPGpHz5
36 | tLXJbdYQn7xTAnL4yQOKN6uNqUA/aTVgyyUJkWZt2giwEsWUvG0UBMSPS1tp2pV2c6/olIcbdYU6
37 | ZecUz6N24sSS7itEBC6nwCVBoHOL8u6MsfxMLDzJIPBI68UZjz3IMKTDUDv6U9DtYmXLc8iMVZBn
38 | cYJn9NgNi3ghl9fYPpHcc6QbXeDUjhdzXXUqG+hB6FabGqdTdkIZwoi4gNpyr3kacKRVWJssDgak
39 | eL2MoDNqJyQ0fXC6Ze3f79CKy/WjeU5FLwDZR0Q=
40 |
41 |
42 |
43 |
44 | 128
45 |
46 |
47 |
49 |
52 |
55 |
57 |
60 |
63 |
65 | urn:oasis:names:tc:SAML:2.0:nameid-format:persistent
66 | urn:oasis:names:tc:SAML:2.0:nameid-format:transient
67 | urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified
68 | urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress
69 | urn:oasis:names:tc:SAML:2.0:nameid-format:kerberos
70 |
72 |
74 |
76 |
78 |
79 |
80 |
--------------------------------------------------------------------------------
/spring-security-saml-sample/src/main/resources/localhost.cert:
--------------------------------------------------------------------------------
1 | -----BEGIN CERTIFICATE-----
2 | MIIC+zCCAeOgAwIBAgIJAIU7CnmezGizMA0GCSqGSIb3DQEBBQUAMBQxEjAQBgNV
3 | BAMMCWxvY2FsaG9zdDAeFw0xNjA0MDMwMjEwMjVaFw0yNjA0MDEwMjEwMjVaMBQx
4 | EjAQBgNVBAMMCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
5 | ggEBAN1NO3L/yCCb+MYFkypvJXcjlQuyRG7UFATYOYQZzIxsD9AtnXPh67uVkZTI
6 | oK7Ps5X4a5qVARtdN+GCFZ/ITahlAlIx8rmVsbz+7XPWpGPf75tKbem3pON2NlYW
7 | wIEQqyuValZHDUMgIXPdGIAZeNejVu7gYMLJwiSMtB0uBM69ptzgigJcbnup/cSL
8 | W4fBh4ck5kj0SVmX58knfaizrVf+ghGyNFha9Xy+DoilCofxwFIpVskv/hczZ5L+
9 | e81R+u2UbNzRwf8paF5fdVwaHPGLOYSBGjSm71VDdJqlvKrJCBoCQODhtmJOmDHD
10 | jtf6gwwbdg3g9GvyqIJnRqBO908CAwEAAaNQME4wHQYDVR0OBBYEFMNtl5fAchs3
11 | 5gZS4EF8/0C7QfBQMB8GA1UdIwQYMBaAFMNtl5fAchs35gZS4EF8/0C7QfBQMAwG
12 | A1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAADVL8LgYGlmaHlyrKyKfsQF
13 | TVbdT1Fk3WaGocVbhmvFeEBHScSJNR0syDcDM1C18pZ6Jc73cW7UdtLbLbRNPXS+
14 | qcp5GZroafndPIL2QzdKXfc5MiGH7CRCZit9kiNJ6YYgsztappXnwKblioJHB1Bc
15 | oLRzMeD295DAGLEVuc5tSY7JHBD3YQS9Pwt3ivrvvCzFKOU9nHqChMCplO4StGpS
16 | bbSR6XNgsPA0XLWlleuTqLGvJ4bHXPKC+0Y+0AiQYx3GeWLVrwJ4w+PFEK73vyuB
17 | 9H10x+zy1nFWvqoa+K66EA4u7DpEoHJBlqH0AVWAd8q9488DpCo1x4ujTGw7AHE=
18 | -----END CERTIFICATE-----
19 |
--------------------------------------------------------------------------------
/spring-security-saml-sample/src/main/resources/localhost.key:
--------------------------------------------------------------------------------
1 | -----BEGIN RSA PRIVATE KEY-----
2 | MIIEpQIBAAKCAQEA3U07cv/IIJv4xgWTKm8ldyOVC7JEbtQUBNg5hBnMjGwP0C2d
3 | c+Hru5WRlMigrs+zlfhrmpUBG1034YIVn8hNqGUCUjHyuZWxvP7tc9akY9/vm0pt
4 | 6bek43Y2VhbAgRCrK5VqVkcNQyAhc90YgBl416NW7uBgwsnCJIy0HS4Ezr2m3OCK
5 | Alxue6n9xItbh8GHhyTmSPRJWZfnySd9qLOtV/6CEbI0WFr1fL4OiKUKh/HAUilW
6 | yS/+FzNnkv57zVH67ZRs3NHB/yloXl91XBoc8Ys5hIEaNKbvVUN0mqW8qskIGgJA
7 | 4OG2Yk6YMcOO1/qDDBt2DeD0a/KogmdGoE73TwIDAQABAoIBAQDG0OH9+OnU0gt3
8 | 6/5A+0XPeTooHen5H7M0fwV9Nqhb56F1R+XS/D8Kcd8uqegh5RvUOjCB2if6a48O
9 | nA3NVOjfxo+FRLZqIKBjySuPDGD4EXF0NDP26zPJ3qQGR75+tXjyWPQFuyOhELa9
10 | Hv8p5rh4EpjBVvfXR+eRao9OP8+142Sedn5yKobQ6Qe9h4TIgBoCi1XCs86ySChr
11 | 7ITG3vEeB3Eq5hSbeN255m+VGjDySeeXsKHmnDHEq0ayLa8LbmD0XLmiLTrbV8IO
12 | Zy7qDxxnlIxjAmmbQj42orNNhDQwoGzy1wa8Yh5/3gwdxGXhufo7ItkkeRnCKCmh
13 | ThP0GSqBAoGBAPZNtNEHDxo5Getm4DbywTHYv+XBlWfLDkJSRjMSTCKzv9MemoX4
14 | vE5sx4ax8oLRcz4pQnfbXQeDePvvLyWApS6qhWbS9qf8oaIt2exPolqmCJibdGpM
15 | Y0Xk3ZFpUA7a+2jPK1PbrwLj/w7zNmFU8Rh/8RZS0QmBIcxovPH7kZ7vAoGBAOYD
16 | jXGVxcxsTdK8Ns6hltVPEE+XmWGfInCVfpAvECN+plwna1abdXafYnMXlmg/tC4q
17 | 2Ufkcw3PEtFKCAMQ1P0n8jSKXpjj1Lxlrunj2404eH93uHJih6zYE2gb/P+7jm49
18 | 377SQOObrueWZUy4mIIZmbT6464rq6sKP6tb1i2hAoGBAIQG31f0yrmpxiUTPjj2
19 | I21O3H6SKD488GXIqGyT8E/hvn+yte3+iSIY2VNwa6iIEZhOkZyh79opNV8GtWUK
20 | 8oBzU5Lsnt8pYpMGtPwhK8wfmBgFrH+Wdthud/6MTyfHZmCmPHl1FvkbsgsXgBzo
21 | ZVxWqKrotbi8iZuCwVWNHl/tAoGAEms2aGIV9Mi3cqifuuw1p98s7zK0lZyopVtT
22 | Rzh9kloR+E8vyT+pqFYbDBxXbwGq7AeCXr9sdy6d0ySaf6RZaexI+OwbpyKXZn6+
23 | Avy8GBLtk0eC/aXmN3EWHMAhAlmCjlFmGWG80H0nBGSGuB4QGFr0dAmjMc9Nb+Ti
24 | NFamUAECgYEA7uPN2cpwvVlt4Q4BHxjvvo1XDRe5c+RwDVa/dYkLu85HVvRd42SJ
25 | QgIdcZR9kLRXuOFCWv1shFmfHPqfmH0q6hn39TgVnUyHxzBlAbP5Dx/n4FRs8EP8
26 | qqNS0ft5Mqoy1UuJL6N5iDYY+i8Is90bsC9mMPj007kfFcyJcRULrSA=
27 | -----END RSA PRIVATE KEY-----
28 |
--------------------------------------------------------------------------------
/spring-security-saml-sample/src/main/resources/localhost.key.der:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ulisesbocchio/spring-boot-security-saml-samples/9ef34b596d6f5ffe9ddad04cabdc896cad73e4f9/spring-security-saml-sample/src/main/resources/localhost.key.der
--------------------------------------------------------------------------------
/spring-security-saml-sample/src/main/resources/logback.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/spring-security-saml-sample/src/main/resources/templates/home.html:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 | Home Page
6 |
7 |
8 | This is the Home Page
9 |
10 | Current User: unknown
11 |
12 |
13 |
14 | | SAML Attributes |
15 |
16 |
17 | | Attribute Name |
18 | Attribute Value |
19 |
20 |
21 |
22 | | key |
23 | value |
24 |
25 |
26 |
27 | Idp Single Logout - Local Logout
28 |
29 |
30 |
--------------------------------------------------------------------------------
/spring-security-saml-sample/src/main/resources/templates/idpselection.html:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 | IdP Selection
6 |
7 |
8 | Select an IdP:
9 |
21 |
22 |
--------------------------------------------------------------------------------
/spring-security-saml-sample/src/main/resources/templates/index.html:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 | Sample SAML Spring Boot Application
6 |
7 |
8 | Hi, Click here to start the Single Sign On process
9 |
10 |
--------------------------------------------------------------------------------
/spring-security-saml-sample/src/main/resources/templates/protected.html:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 | Protected Resource
6 |
7 |
8 | Protected Resource
9 |
10 | This is a Protected Resource
11 |
12 | Home
13 |
14 |
--------------------------------------------------------------------------------
/spring-security-saml-sample/src/test/java/com/ulisesbocchio/security/saml/SamlSpSampleApplicationTests.java:
--------------------------------------------------------------------------------
1 | package com.ulisesbocchio.security.saml;
2 |
3 | import org.junit.Test;
4 | import org.junit.runner.RunWith;
5 | import org.springframework.boot.test.context.SpringBootTest;
6 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
7 |
8 | @RunWith(SpringJUnit4ClassRunner.class)
9 | @SpringBootTest(classes = SamlServiceProviderApplication.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
10 | public class SamlSpSampleApplicationTests {
11 |
12 | @Test
13 | public void contextLoads() {
14 | }
15 |
16 | }
17 |
--------------------------------------------------------------------------------