From 28a4a94b9abebc6a1af342a827b81ae942ffea68 Mon Sep 17 00:00:00 2001 From: Josh Cummings Date: Wed, 27 Jul 2022 16:42:42 -0600 Subject: [PATCH] Simplify Saml2 Login Sample --- .../example/Saml2LoginApplicationITests.java | 25 +---- .../java/example/SecurityConfiguration.java | 104 ------------------ .../login/src/main/resources/application.yml | 14 +++ .../resources/credentials/idp-certificate.crt | 24 ---- 4 files changed, 15 insertions(+), 152 deletions(-) delete mode 100644 servlet/spring-boot/java/saml2/login/src/main/java/example/SecurityConfiguration.java delete mode 100644 servlet/spring-boot/java/saml2/login/src/main/resources/credentials/idp-certificate.crt diff --git a/servlet/spring-boot/java/saml2/login/src/integTest/java/example/Saml2LoginApplicationITests.java b/servlet/spring-boot/java/saml2/login/src/integTest/java/example/Saml2LoginApplicationITests.java index e67a13a..c422451 100644 --- a/servlet/spring-boot/java/saml2/login/src/integTest/java/example/Saml2LoginApplicationITests.java +++ b/servlet/spring-boot/java/saml2/login/src/integTest/java/example/Saml2LoginApplicationITests.java @@ -55,8 +55,7 @@ public class Saml2LoginApplicationITests { } private void performLogin(String registrationId) throws Exception { - HtmlPage login = this.webClient.getPage("/"); - login.getAnchorByHref("/saml2/authenticate/" + registrationId).click(); + this.webClient.getPage("/"); this.webClient.waitForBackgroundJavaScript(10000); HtmlPage okta = (HtmlPage) this.webClient.getCurrentWindow().getEnclosedPage(); this.webClient.waitForBackgroundJavaScript(10000); @@ -108,26 +107,4 @@ public class Saml2LoginApplicationITests { } - @DisplayName("Tenant two tests") - @Nested - class TenantTwoTests { - - @Test - void authenticationAttemptWhenValidThenShowsUserEmailAddress() throws Exception { - performLogin("two"); - HtmlPage home = (HtmlPage) Saml2LoginApplicationITests.this.webClient.getCurrentWindow().getEnclosedPage(); - assertThat(home.asNormalizedText()).contains("You're email address is testuser@spring.security.saml"); - } - - @Test - void logoutWhenRelyingPartyInitiatedLogoutThenLoginPageWithLogoutParam() throws Exception { - performLogin("two"); - HtmlPage home = (HtmlPage) Saml2LoginApplicationITests.this.webClient.getCurrentWindow().getEnclosedPage(); - HtmlElement rpLogoutButton = home.getHtmlElementById("rp_logout_button"); - HtmlPage loginPage = rpLogoutButton.click(); - assertThat(loginPage.getUrl().getFile()).isEqualTo("/login?logout"); - } - - } - } diff --git a/servlet/spring-boot/java/saml2/login/src/main/java/example/SecurityConfiguration.java b/servlet/spring-boot/java/saml2/login/src/main/java/example/SecurityConfiguration.java deleted file mode 100644 index 20c1302..0000000 --- a/servlet/spring-boot/java/saml2/login/src/main/java/example/SecurityConfiguration.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright 2002-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package example; - -import java.io.InputStream; -import java.security.cert.CertificateFactory; -import java.security.cert.X509Certificate; -import java.security.interfaces.RSAPrivateKey; - -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.web.servlet.FilterRegistrationBean; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.core.io.ClassPathResource; -import org.springframework.core.io.Resource; -import org.springframework.security.config.Customizer; -import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.saml2.core.Saml2X509Credential; -import org.springframework.security.saml2.provider.service.metadata.OpenSamlMetadataResolver; -import org.springframework.security.saml2.provider.service.registration.InMemoryRelyingPartyRegistrationRepository; -import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistration; -import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistrationRepository; -import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistrations; -import org.springframework.security.saml2.provider.service.web.DefaultRelyingPartyRegistrationResolver; -import org.springframework.security.saml2.provider.service.web.RelyingPartyRegistrationResolver; -import org.springframework.security.saml2.provider.service.web.Saml2MetadataFilter; -import org.springframework.security.web.SecurityFilterChain; - -@Configuration -public class SecurityConfiguration { - - @Value("classpath:credentials/rp-private.key") - RSAPrivateKey privateKey; - - @Bean - SecurityFilterChain app(HttpSecurity http) throws Exception { - // @formatter:off - http - .authorizeHttpRequests((authorize) -> authorize - .anyRequest().authenticated() - ) - .saml2Login(Customizer.withDefaults()) - .saml2Logout(Customizer.withDefaults()); - // @formatter:on - - return http.build(); - } - - @Bean - RelyingPartyRegistrationResolver relyingPartyRegistrationResolver( - RelyingPartyRegistrationRepository registrations) { - return new DefaultRelyingPartyRegistrationResolver(registrations); - } - - @Bean - FilterRegistrationBean metadata(RelyingPartyRegistrationResolver registrations) { - Saml2MetadataFilter metadata = new Saml2MetadataFilter(registrations, new OpenSamlMetadataResolver()); - FilterRegistrationBean filter = new FilterRegistrationBean<>(metadata); - filter.setOrder(-101); - return filter; - } - - @Bean - RelyingPartyRegistrationRepository repository() { - RelyingPartyRegistration one = addRelyingPartyDetails(RelyingPartyRegistrations - .fromMetadataLocation("https://dev-05937739.okta.com/app/exk46xofd8NZvFCpS5d7/sso/saml/metadata") - .registrationId("one")).build(); - RelyingPartyRegistration two = addRelyingPartyDetails(RelyingPartyRegistrations - .fromMetadataLocation("https://dev-05937739.okta.com/app/exk4842vmapcMkohr5d7/sso/saml/metadata") - .registrationId("two")).build(); - return new InMemoryRelyingPartyRegistrationRepository(one, two); - } - - RelyingPartyRegistration.Builder addRelyingPartyDetails(RelyingPartyRegistration.Builder builder) { - Saml2X509Credential signing = Saml2X509Credential.signing(this.privateKey, relyingPartyCertificate()); - return builder.signingX509Credentials((c) -> c.add(signing)) - .singleLogoutServiceLocation("http://localhost:8080/logout/saml2/slo"); - } - - X509Certificate relyingPartyCertificate() { - Resource resource = new ClassPathResource("credentials/rp-certificate.crt"); - try (InputStream is = resource.getInputStream()) { - return (X509Certificate) CertificateFactory.getInstance("X.509").generateCertificate(is); - } - catch (Exception ex) { - throw new UnsupportedOperationException(ex); - } - } - -} diff --git a/servlet/spring-boot/java/saml2/login/src/main/resources/application.yml b/servlet/spring-boot/java/saml2/login/src/main/resources/application.yml index e112d19..e618ee2 100644 --- a/servlet/spring-boot/java/saml2/login/src/main/resources/application.yml +++ b/servlet/spring-boot/java/saml2/login/src/main/resources/application.yml @@ -1,2 +1,16 @@ logging.level: org.springframework.security: TRACE + +spring: + security: + saml2: + relyingparty: + registration: + one: + signing.credentials: + - private-key-location: classpath:credentials/rp-private.key + certificate-location: classpath:credentials/rp-certificate.crt + singlelogout: + binding: POST + response-url: "{baseUrl}/logout/saml2/slo" + assertingparty.metadata-uri: https://dev-05937739.okta.com/app/exk46xofd8NZvFCpS5d7/sso/saml/metadata diff --git a/servlet/spring-boot/java/saml2/login/src/main/resources/credentials/idp-certificate.crt b/servlet/spring-boot/java/saml2/login/src/main/resources/credentials/idp-certificate.crt deleted file mode 100644 index 9c4ee07..0000000 --- a/servlet/spring-boot/java/saml2/login/src/main/resources/credentials/idp-certificate.crt +++ /dev/null @@ -1,24 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIEEzCCAvugAwIBAgIJAIc1qzLrv+5nMA0GCSqGSIb3DQEBCwUAMIGfMQswCQYD -VQQGEwJVUzELMAkGA1UECAwCQ08xFDASBgNVBAcMC0Nhc3RsZSBSb2NrMRwwGgYD -VQQKDBNTYW1sIFRlc3RpbmcgU2VydmVyMQswCQYDVQQLDAJJVDEgMB4GA1UEAwwX -c2ltcGxlc2FtbHBocC5jZmFwcHMuaW8xIDAeBgkqhkiG9w0BCQEWEWZoYW5pa0Bw -aXZvdGFsLmlvMB4XDTE1MDIyMzIyNDUwM1oXDTI1MDIyMjIyNDUwM1owgZ8xCzAJ -BgNVBAYTAlVTMQswCQYDVQQIDAJDTzEUMBIGA1UEBwwLQ2FzdGxlIFJvY2sxHDAa -BgNVBAoME1NhbWwgVGVzdGluZyBTZXJ2ZXIxCzAJBgNVBAsMAklUMSAwHgYDVQQD -DBdzaW1wbGVzYW1scGhwLmNmYXBwcy5pbzEgMB4GCSqGSIb3DQEJARYRZmhhbmlr -QHBpdm90YWwuaW8wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC4cn62 -E1xLqpN34PmbrKBbkOXFjzWgJ9b+pXuaRft6A339uuIQeoeH5qeSKRVTl32L0gdz -2ZivLwZXW+cqvftVW1tvEHvzJFyxeTW3fCUeCQsebLnA2qRa07RkxTo6Nf244mWW -RDodcoHEfDUSbxfTZ6IExSojSIU2RnD6WllYWFdD1GFpBJOmQB8rAc8wJIBdHFdQ -nX8Ttl7hZ6rtgqEYMzYVMuJ2F2r1HSU1zSAvwpdYP6rRGFRJEfdA9mm3WKfNLSc5 -cljz0X/TXy0vVlAV95l9qcfFzPmrkNIst9FZSwpvB49LyAVke04FQPPwLgVH4gph -iJH3jvZ7I+J5lS8VAgMBAAGjUDBOMB0GA1UdDgQWBBTTyP6Cc5HlBJ5+ucVCwGc5 -ogKNGzAfBgNVHSMEGDAWgBTTyP6Cc5HlBJ5+ucVCwGc5ogKNGzAMBgNVHRMEBTAD -AQH/MA0GCSqGSIb3DQEBCwUAA4IBAQAvMS4EQeP/ipV4jOG5lO6/tYCb/iJeAduO -nRhkJk0DbX329lDLZhTTL/x/w/9muCVcvLrzEp6PN+VWfw5E5FWtZN0yhGtP9R+v -ZnrV+oc2zGD+no1/ySFOe3EiJCO5dehxKjYEmBRv5sU/LZFKZpozKN/BMEa6CqLu -xbzb7ykxVr7EVFXwltPxzE9TmL9OACNNyF5eJHWMRMllarUvkcXlh4pux4ks9e6z -V9DQBy2zds9f1I3qxg0eX6JnGrXi/ZiCT+lJgVe3ZFXiejiLAiKB04sXW3ti0LW3 -lx13Y1YlQ4/tlpgTgfIJxKV6nyPiLoK0nywbMd+vpAirDt2Oc+hk ------END CERTIFICATE-----