From c8f07f67221dee97ec62c57cdacd4785f7e9934d Mon Sep 17 00:00:00 2001 From: Jj! Date: Thu, 20 Sep 2018 10:54:27 -0500 Subject: [PATCH 01/23] [SHIBUI-808] WIP initial configuration --- pac4j-module/Dockerfile | 0 pac4j-module/build.gradle | 37 +++++++++++++++++++ .../shibui/pac4j/Pac4jConfiguration.java | 33 +++++++++++++++++ .../pac4j/Pac4jConfigurationProperties.java | 23 ++++++++++++ .../net/unicon/shibui/pac4j/WebSecurity.java | 14 +++++++ .../main/resources/META-INF/spring.factories | 1 + settings.gradle | 2 +- 7 files changed, 109 insertions(+), 1 deletion(-) create mode 100644 pac4j-module/Dockerfile create mode 100644 pac4j-module/build.gradle create mode 100644 pac4j-module/src/main/java/net/unicon/shibui/pac4j/Pac4jConfiguration.java create mode 100644 pac4j-module/src/main/java/net/unicon/shibui/pac4j/Pac4jConfigurationProperties.java create mode 100644 pac4j-module/src/main/java/net/unicon/shibui/pac4j/WebSecurity.java create mode 100644 pac4j-module/src/main/resources/META-INF/spring.factories diff --git a/pac4j-module/Dockerfile b/pac4j-module/Dockerfile new file mode 100644 index 000000000..e69de29bb diff --git a/pac4j-module/build.gradle b/pac4j-module/build.gradle new file mode 100644 index 000000000..d783ad01f --- /dev/null +++ b/pac4j-module/build.gradle @@ -0,0 +1,37 @@ +plugins { + id 'java' + id 'org.springframework.boot' version '2.0.0.RELEASE' + id 'com.palantir.docker' version '0.20.1' + id 'jacoco' + id 'io.franzbecker.gradle-lombok' version '1.13' +} + +apply plugin: 'io.spring.dependency-management' + +sourceCompatibility = 1.8 +targetCompatibility = 1.8 + +repositories { + jcenter() + maven { + url 'https://build.shibboleth.net/nexus/content/groups/public' + artifactUrls = ['https://build.shibboleth.net/nexus/content/repositories/thirdparty-snapshots'] + } +} + +lombok { + version = "1.16.20" + sha256 = "c5178b18caaa1a15e17b99ba5e4023d2de2ebc18b58cde0f5a04ca4b31c10e6d" +} + +dependencies { + compileOnly project(':backend') + + compile "org.pac4j:spring-security-pac4j:3.0.0" + compile "org.pac4j:pac4j-saml:2.2.1", { + // opensaml libraries are provided + exclude group: 'org.opensaml' + } + + annotationProcessor "org.springframework.boot:spring-boot-configuration-processor" +} \ No newline at end of file diff --git a/pac4j-module/src/main/java/net/unicon/shibui/pac4j/Pac4jConfiguration.java b/pac4j-module/src/main/java/net/unicon/shibui/pac4j/Pac4jConfiguration.java new file mode 100644 index 000000000..193ccaac2 --- /dev/null +++ b/pac4j-module/src/main/java/net/unicon/shibui/pac4j/Pac4jConfiguration.java @@ -0,0 +1,33 @@ +package net.unicon.shibui.pac4j; + +import org.pac4j.core.client.Clients; +import org.pac4j.core.config.Config; +import org.pac4j.saml.client.SAML2Client; +import org.pac4j.saml.client.SAML2ClientConfiguration; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class Pac4jConfiguration { + @Bean + public Config config(final Pac4jConfigurationProperties pac4jConfigurationProperties) { + final SAML2ClientConfiguration saml2ClientConfiguration = new SAML2ClientConfiguration(); + saml2ClientConfiguration.setKeystorePath(pac4jConfigurationProperties.getKeystorePath()); + saml2ClientConfiguration.setKeystorePassword(pac4jConfigurationProperties.getKeystorePassword()); + saml2ClientConfiguration.setPrivateKeyPassword(pac4jConfigurationProperties.getPrivateKeyPassword()); + saml2ClientConfiguration.setIdentityProviderMetadataPath(pac4jConfigurationProperties.getIdentityProviderMetadataPath()); + saml2ClientConfiguration.setMaximumAuthenticationLifetime(pac4jConfigurationProperties.getMaximumAuthenticationLifetime()); + saml2ClientConfiguration.setServiceProviderEntityId(pac4jConfigurationProperties.getServiceProviderEntityId()); + saml2ClientConfiguration.setServiceProviderMetadataPath(pac4jConfigurationProperties.getServiceProviderMetadataPath()); + saml2ClientConfiguration.setForceServiceProviderMetadataGeneration(pac4jConfigurationProperties.isForceServiceProviderMetadataGeneration()); + saml2ClientConfiguration.setWantsAssertionsSigned(pac4jConfigurationProperties.isWantAssertionsSigned()); + + final SAML2Client saml2Client = new SAML2Client(saml2ClientConfiguration); + saml2Client.setName("Saml2Client"); + + final Clients clients = new Clients(pac4jConfigurationProperties.getCallbackUrl(), saml2Client); + + final Config config = new Config(clients); + return config; + } +} diff --git a/pac4j-module/src/main/java/net/unicon/shibui/pac4j/Pac4jConfigurationProperties.java b/pac4j-module/src/main/java/net/unicon/shibui/pac4j/Pac4jConfigurationProperties.java new file mode 100644 index 000000000..1334c7e72 --- /dev/null +++ b/pac4j-module/src/main/java/net/unicon/shibui/pac4j/Pac4jConfigurationProperties.java @@ -0,0 +1,23 @@ +package net.unicon.shibui.pac4j; + +import lombok.Getter; +import lombok.Setter; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +@Component +@ConfigurationProperties(prefix = "shibui.pac4j") +@Getter +@Setter +public class Pac4jConfigurationProperties { + private String keystorePath = "/tmp/samlKeystore.jks"; + private String keystorePassword = "changeit"; + private String privateKeyPassword = "changeit"; + private String identityProviderMetadataPath = "/tmp/idp-metadata.xml"; + private int maximumAuthenticationLifetime = 3600; + private String serviceProviderEntityId = "https://unicon.net/shibui"; + private String serviceProviderMetadataPath = "/tmp/sp-metadata.xml"; + private boolean forceServiceProviderMetadataGeneration = false; + private String callbackUrl; + private boolean wantAssertionsSigned = true; +} diff --git a/pac4j-module/src/main/java/net/unicon/shibui/pac4j/WebSecurity.java b/pac4j-module/src/main/java/net/unicon/shibui/pac4j/WebSecurity.java new file mode 100644 index 000000000..80a755431 --- /dev/null +++ b/pac4j-module/src/main/java/net/unicon/shibui/pac4j/WebSecurity.java @@ -0,0 +1,14 @@ +package net.unicon.shibui.pac4j; + +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; + +@Configuration +@EnableWebSecurity +public class WebSecurity { + @Configuration + public static class Pac4jSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter { + + } +} diff --git a/pac4j-module/src/main/resources/META-INF/spring.factories b/pac4j-module/src/main/resources/META-INF/spring.factories new file mode 100644 index 000000000..a24bba892 --- /dev/null +++ b/pac4j-module/src/main/resources/META-INF/spring.factories @@ -0,0 +1 @@ +org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer = net.unicon.shibui.pac4j.WebSecurity.Pac4jSecurityConfigurationAdapter \ No newline at end of file diff --git a/settings.gradle b/settings.gradle index adb85a37b..8fae26617 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1 +1 @@ -include 'backend', 'ui' \ No newline at end of file +include 'backend', 'ui', 'pac4j-module' \ No newline at end of file From 1addbbd99a24cce03ac8f25e8dbfefa47c0b4ff7 Mon Sep 17 00:00:00 2001 From: Jj! Date: Tue, 25 Sep 2018 12:06:37 -0500 Subject: [PATCH 02/23] [SHIBUI-808] WIP configuration changes Docker rework --- backend/Dockerfile | 3 +- backend/build.gradle | 35 +++++++++++++++---- .../ui/configuration/WebSecurityConfig.java | 3 ++ pac4j-module/Dockerfile | 3 ++ pac4j-module/build.gradle | 29 +++++++++++---- .../shibui/pac4j/Pac4jConfiguration.java | 1 + .../net/unicon/shibui/pac4j/WebSecurity.java | 34 +++++++++++++++++- .../main/resources/META-INF/spring.factories | 2 +- .../src/test/docker/conf/application.yml | 9 +++++ .../src/test/docker/conf/idp-metadata.xml | 30 ++++++++++++++++ .../src/test/docker/docker-compose.yml | 17 +++++++++ 11 files changed, 150 insertions(+), 16 deletions(-) create mode 100644 pac4j-module/src/test/docker/conf/application.yml create mode 100644 pac4j-module/src/test/docker/conf/idp-metadata.xml create mode 100644 pac4j-module/src/test/docker/docker-compose.yml diff --git a/backend/Dockerfile b/backend/Dockerfile index cec9c4c44..2bce3ec96 100644 --- a/backend/Dockerfile +++ b/backend/Dockerfile @@ -3,7 +3,8 @@ FROM gcr.io/distroless/java ARG JAR_FILE COPY ${JAR_FILE} app.jar +COPY loader.properties loader.properties EXPOSE 8080 -CMD ["app.jar"] \ No newline at end of file +ENTRYPOINT ["/usr/bin/java", "-jar", "app.jar"] \ No newline at end of file diff --git a/backend/build.gradle b/backend/build.gradle index 167bd3994..be652ccd5 100644 --- a/backend/build.gradle +++ b/backend/build.gradle @@ -34,16 +34,36 @@ processResources.dependsOn(':ui:npm_run_buildProd') bootWar.dependsOn(':ui:npm_run_buildProd') bootWar.baseName = 'shibui' bootWar { - manifest { - attributes("Manifest-Version" : "1.0", "Implementation-Version" : "${project.version}") - } - from(tasks.findByPath(':ui:npm_run_buildProd').outputs) { + manifest { + attributes( + "Manifest-Version" : "1.0", + "Implementation-Version" : "${project.version}" + ) + } + from(tasks.findByPath(':ui:npm_run_buildProd').outputs) { // into '/' into '/public' } archiveName = "${baseName}.war" } +bootJar.dependsOn ':ui:npm_run_buildProd' +bootJar.baseName = 'shibui' +bootJar { + manifest { + attributes( + "Manifest-Version" : "1.0", + "Implementation-Version" : "${project.version}", + 'Main-Class': 'org.springframework.boot.loader.PropertiesLauncher' + ) + } + from(tasks.findByPath(':ui:npm_run_buildProd').outputs) { + // into '/' + into '/public' + } + archiveName = "${baseName}.jar" +} + springBoot { mainClassName = 'edu.internet2.tier.shibboleth.admin.ui.ShibbolethUiApplication' buildInfo() @@ -209,12 +229,13 @@ jacocoTestReport { } } -tasks.docker.dependsOn tasks.build +tasks.docker.dependsOn tasks.bootJar docker { name 'unicon/shibui' tags 'latest' pull true noCache true - files tasks.bootWar.outputs - buildArgs(['JAR_FILE': 'shibui.war']) + files tasks.bootJar.outputs + files 'src/main/docker-files/loader.properties' + buildArgs(['JAR_FILE': 'shibui.jar']) } \ No newline at end of file diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/configuration/WebSecurityConfig.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/configuration/WebSecurityConfig.java index 4ef76087f..186021597 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/configuration/WebSecurityConfig.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/configuration/WebSecurityConfig.java @@ -1,6 +1,8 @@ package edu.internet2.tier.shibboleth.admin.ui.configuration; import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Profile; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; @@ -36,6 +38,7 @@ public HttpFirewall allowUrlEncodedSlashHttpFirewall() { @Bean @Profile("default") + @ConditionalOnMissingBean(value = {WebSecurityConfigurerAdapter.class}) public WebSecurityConfigurerAdapter defaultAuth() { return new WebSecurityConfigurerAdapter() { diff --git a/pac4j-module/Dockerfile b/pac4j-module/Dockerfile index e69de29bb..6c78f991e 100644 --- a/pac4j-module/Dockerfile +++ b/pac4j-module/Dockerfile @@ -0,0 +1,3 @@ +FROM unicon/shibui + +COPY *.jar /libs/ \ No newline at end of file diff --git a/pac4j-module/build.gradle b/pac4j-module/build.gradle index d783ad01f..36817e334 100644 --- a/pac4j-module/build.gradle +++ b/pac4j-module/build.gradle @@ -1,17 +1,17 @@ plugins { id 'java' - id 'org.springframework.boot' version '2.0.0.RELEASE' id 'com.palantir.docker' version '0.20.1' id 'jacoco' id 'io.franzbecker.gradle-lombok' version '1.13' + id 'org.springframework.boot' version '2.0.0.RELEASE' apply false + id 'io.spring.dependency-management' version '1.0.6.RELEASE' } -apply plugin: 'io.spring.dependency-management' - sourceCompatibility = 1.8 targetCompatibility = 1.8 repositories { + mavenLocal() jcenter() maven { url 'https://build.shibboleth.net/nexus/content/groups/public' @@ -24,14 +24,31 @@ lombok { sha256 = "c5178b18caaa1a15e17b99ba5e4023d2de2ebc18b58cde0f5a04ca4b31c10e6d" } +dependencyManagement { + imports { + mavenBom org.springframework.boot.gradle.plugin.SpringBootPlugin.BOM_COORDINATES + } +} + dependencies { compileOnly project(':backend') - compile "org.pac4j:spring-security-pac4j:3.0.0" - compile "org.pac4j:pac4j-saml:2.2.1", { + compile "org.pac4j:spring-security-pac4j:4.0.0" + compile "org.pac4j:pac4j-saml:3.2.0-SNAPSHOT", { // opensaml libraries are provided exclude group: 'org.opensaml' } annotationProcessor "org.springframework.boot:spring-boot-configuration-processor" -} \ No newline at end of file + + docker project(':backend') +} + +docker { + name 'unicon/shibui-pac4j' + tags 'latest-pac4j' + files configurations.runtime, tasks.jar.outputs + noCache true +} + +tasks.docker.dependsOn(tasks.jar, ':backend:docker') \ No newline at end of file diff --git a/pac4j-module/src/main/java/net/unicon/shibui/pac4j/Pac4jConfiguration.java b/pac4j-module/src/main/java/net/unicon/shibui/pac4j/Pac4jConfiguration.java index 193ccaac2..1c28b1ee1 100644 --- a/pac4j-module/src/main/java/net/unicon/shibui/pac4j/Pac4jConfiguration.java +++ b/pac4j-module/src/main/java/net/unicon/shibui/pac4j/Pac4jConfiguration.java @@ -4,6 +4,7 @@ import org.pac4j.core.config.Config; import org.pac4j.saml.client.SAML2Client; import org.pac4j.saml.client.SAML2ClientConfiguration; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/pac4j-module/src/main/java/net/unicon/shibui/pac4j/WebSecurity.java b/pac4j-module/src/main/java/net/unicon/shibui/pac4j/WebSecurity.java index 80a755431..28bfa1f58 100644 --- a/pac4j-module/src/main/java/net/unicon/shibui/pac4j/WebSecurity.java +++ b/pac4j-module/src/main/java/net/unicon/shibui/pac4j/WebSecurity.java @@ -1,14 +1,46 @@ package net.unicon.shibui.pac4j; +import org.pac4j.core.config.Config; +import org.pac4j.springframework.security.web.CallbackFilter; +import org.pac4j.springframework.security.web.SecurityFilter; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.context.annotation.Configuration; +import org.springframework.core.annotation.Order; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.config.http.SessionCreationPolicy; +import org.springframework.security.web.authentication.www.BasicAuthenticationFilter; +import org.springframework.security.web.csrf.CookieCsrfTokenRepository; @Configuration -@EnableWebSecurity public class WebSecurity { @Configuration + @Order(1) public static class Pac4jSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter { + private static final Logger logger = LoggerFactory.getLogger(Pac4jSecurityConfigurationAdapter.class); + private final Config config; + + public Pac4jSecurityConfigurationAdapter(Config config) { + logger.info("configuring pac4j authentication"); + this.config = config; + } + + @Override + protected void configure(HttpSecurity http) throws Exception { + final SecurityFilter securityFilter = new SecurityFilter(this.config, "Saml2Client"); + + final CallbackFilter callbackFilter = new CallbackFilter(this.config); + http.antMatcher("/**").addFilterBefore(callbackFilter, BasicAuthenticationFilter.class); + http.authorizeRequests().anyRequest().fullyAuthenticated(); + + http.addFilterBefore(securityFilter, BasicAuthenticationFilter.class); + http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.ALWAYS); + + http.csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()); + } } } diff --git a/pac4j-module/src/main/resources/META-INF/spring.factories b/pac4j-module/src/main/resources/META-INF/spring.factories index a24bba892..9a6e6cbf2 100644 --- a/pac4j-module/src/main/resources/META-INF/spring.factories +++ b/pac4j-module/src/main/resources/META-INF/spring.factories @@ -1 +1 @@ -org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer = net.unicon.shibui.pac4j.WebSecurity.Pac4jSecurityConfigurationAdapter \ No newline at end of file +org.springframework.boot.autoconfigure.EnableAutoConfiguration=net.unicon.shibui.pac4j.Pac4jConfiguration,net.unicon.shibui.pac4j.WebSecurity,net.unicon.shibui.pac4j.WebSecurity.Pac4jSecurityConfigurationAdapter,net.unicon.shibui.pac4j.Pac4jConfigurationProperties \ No newline at end of file diff --git a/pac4j-module/src/test/docker/conf/application.yml b/pac4j-module/src/test/docker/conf/application.yml new file mode 100644 index 000000000..6bd9b0946 --- /dev/null +++ b/pac4j-module/src/test/docker/conf/application.yml @@ -0,0 +1,9 @@ +shibui: + pac4j: + keystorePath: "/conf/samlKeystore.jks" + keystorePassword: "changeit" + privateKeyPassword: "changeit" + serviceProviderEntityId: "https://unicon.net/shibui" + serviceProviderMetadataPath: "/conf/sp-metadata.xml" + forceServiceProviderMetadataGeneration: true + callbackUrl: "http://localhost:8080/callback \ No newline at end of file diff --git a/pac4j-module/src/test/docker/conf/idp-metadata.xml b/pac4j-module/src/test/docker/conf/idp-metadata.xml new file mode 100644 index 000000000..eddc5010c --- /dev/null +++ b/pac4j-module/src/test/docker/conf/idp-metadata.xml @@ -0,0 +1,30 @@ + + + + + + + MIIDdDCCAlygAwIBAgIGAVWm+BpSMA0GCSqGSIb3DQEBCwUAMHsxFDASBgNVBAoTC0dvb2dsZSBJ +bmMuMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MQ8wDQYDVQQDEwZHb29nbGUxGDAWBgNVBAsTD0dv +b2dsZSBGb3IgV29yazELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWEwHhcNMTYwNzAx +MTQ1ODQ0WhcNMjEwNjMwMTQ1ODQ0WjB7MRQwEgYDVQQKEwtHb29nbGUgSW5jLjEWMBQGA1UEBxMN +TW91bnRhaW4gVmlldzEPMA0GA1UEAxMGR29vZ2xlMRgwFgYDVQQLEw9Hb29nbGUgRm9yIFdvcmsx +CzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEAirwyeCS6SZpnYxprfXhpTNXwVfQC+J9OvBlJp8/7ngA627yER1bvfUkBMQxo0CXe +H6HX6Vw1DgalZJeEGDZSErlAY7lWkXkHdsejlMoYayQSZz2b/EfeRetwxh3Ek0hMDScOgDlsdfAn +AiZ4//n3IlypCi4ZMnLPs308FYunvp+R0Wd8Yqj8ctKhiYs6fCSHksDd+JKPe2FC1Zqw9GCGhi32 +DBNRTHfE3tX3rTRs1pT0qbrQmpPfeBYfX00astGa3Dq/XWVO62IlqM7nVjglIPdi0tCIx+5RVZrY +uvULMipA+131TMxTpcGjUFxNwzPdogdpNhtL8+erfhG26C6b8wIDAQABMA0GCSqGSIb3DQEBCwUA +A4IBAQCIOe/bW+mdE9PuarSz60HPGe9ROibyEOTyAWGxvSFfqoNFzaH3oOiEHMNG+ZkHHGtGEeWc +KYQ72V1OKO4aNqy2XaT3onOkd2oh4N8Q5pWrgMRkAB2HvBhBcQeO6yojVamTd43Kbtc+Hly3o+Or +XXOR9cgfxX/0Dbb+xwzTcwcMoJ1CPd3T4zxByKMHNflWrgrmZ9DmDOya4Aqs+xvrvPJB2VHaXoJ6 +r/N+xtG8zO8wNRuxQxNUvtcFKKX2sZAqQRASGi1z8Y1FhU6rWBdBRtaiASAIgkNwOmS603Mm08Yr +0Yq7x6h3XlG8HO0bAOto6pr6q85pLqqv7v7/x7mfdjV3 + + + + urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress + + + + diff --git a/pac4j-module/src/test/docker/docker-compose.yml b/pac4j-module/src/test/docker/docker-compose.yml new file mode 100644 index 000000000..73861c077 --- /dev/null +++ b/pac4j-module/src/test/docker/docker-compose.yml @@ -0,0 +1,17 @@ +version: "3.7" + +services: + shibui: + image: unicon/shibui-pac4j + command: "--shibui.pac4j.callbackUrl=http://localhost:8080/callback" + ports: + - 8080:8080 + - 5005:5005 + volumes: + - ./conf:/conf + - ./conf/application.yml:/application.yml + networks: + - front +networks: + front: + driver: bridge \ No newline at end of file From a8664831242f90b72176576dabc93bbfb735c167 Mon Sep 17 00:00:00 2001 From: Jj! Date: Wed, 26 Sep 2018 16:28:43 -0500 Subject: [PATCH 03/23] [SHIBUI-808] test configuration --- pac4j-module/src/test/docker/conf/application.yml | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/pac4j-module/src/test/docker/conf/application.yml b/pac4j-module/src/test/docker/conf/application.yml index 6bd9b0946..b850afb54 100644 --- a/pac4j-module/src/test/docker/conf/application.yml +++ b/pac4j-module/src/test/docker/conf/application.yml @@ -1,3 +1,10 @@ +server: + port: 8443 + ssl: + key-store: "/conf/keystore.p12" + key-store-password: "changeit" + keyStoreType: "PKCS12" + keyAlias: "tomcat" shibui: pac4j: keystorePath: "/conf/samlKeystore.jks" @@ -5,5 +12,11 @@ shibui: privateKeyPassword: "changeit" serviceProviderEntityId: "https://unicon.net/shibui" serviceProviderMetadataPath: "/conf/sp-metadata.xml" + identityProviderMetadataPath: "/conf/idp-metadata.xml" forceServiceProviderMetadataGeneration: true - callbackUrl: "http://localhost:8080/callback \ No newline at end of file + callbackUrl: "https://localhost:8443/callback" + maximumAuthenticationLifetime: 3600000 +logging: + level: + org.pac4j: "TRACE" + org.opensaml: "INFO" \ No newline at end of file From 7e3072820e7167676031bff93fbca54b17642617 Mon Sep 17 00:00:00 2001 From: Jj! Date: Wed, 26 Sep 2018 16:29:11 -0500 Subject: [PATCH 04/23] [SHIB-UI] test configuration --- pac4j-module/src/test/docker/docker-compose.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pac4j-module/src/test/docker/docker-compose.yml b/pac4j-module/src/test/docker/docker-compose.yml index 73861c077..e6b2f6e70 100644 --- a/pac4j-module/src/test/docker/docker-compose.yml +++ b/pac4j-module/src/test/docker/docker-compose.yml @@ -3,10 +3,11 @@ version: "3.7" services: shibui: image: unicon/shibui-pac4j - command: "--shibui.pac4j.callbackUrl=http://localhost:8080/callback" + entrypoint: ["/usr/bin/java", "-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005", "-jar", "app.jar"] ports: - 8080:8080 - 5005:5005 + - 8443:8443 volumes: - ./conf:/conf - ./conf/application.yml:/application.yml From d61a0072cef9c77369e8f1be2d99ae05734834f1 Mon Sep 17 00:00:00 2001 From: Jj! Date: Wed, 26 Sep 2018 16:29:57 -0500 Subject: [PATCH 05/23] [SHIBUI-808] disable default active profile --- backend/src/main/resources/application.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/main/resources/application.properties b/backend/src/main/resources/application.properties index 634d32c5b..4076dfa9a 100644 --- a/backend/src/main/resources/application.properties +++ b/backend/src/main/resources/application.properties @@ -45,7 +45,7 @@ spring.jpa.hibernate.use-new-id-generator-mappings=true # shibui.metadata-dir=/opt/shibboleth-idp/metadata/generated shibui.logout-url=/dashboard -spring.profiles.active=default +# spring.profiles.active=default #shibui.default-password= From a81483d036a1c18fb1df6d58ff7033d209d04c02 Mon Sep 17 00:00:00 2001 From: Jj! Date: Fri, 28 Sep 2018 12:51:29 -0500 Subject: [PATCH 06/23] [SHIBUI-808] refactor web security configuration (rename, annotations) Domain class enhancements to support pac4j update opensaml initialization initial autoconfiguration setup pac4j sample authentication --- .../admin/ui/ShibbolethUiApplication.java | 10 +- .../{ => auto}/WebSecurityConfig.java | 8 +- .../admin/ui/domain/RequestInitiator.java | 50 +++ .../ui/domain/RequestInitiatorBuilder.java | 43 +++ .../admin/ui/domain/RoleDescriptor.java | 6 +- .../admin/ui/domain/SPSSODescriptor.java | 5 +- .../shibboleth/admin/ui/domain/X509Data.java | 2 +- .../config/InitializationService.java | 7 +- .../JPAXMLObjectProviderInitializer.java | 7 +- .../main/resources/META-INF/spring.factories | 4 +- .../jpa-saml2-metadata-reqinit-config.xml | 15 + .../modified-saml2-assertion-config.xml | 313 ++++++++++++++++++ .../admin/ui/domain/Pac4jTest.groovy | 19 ++ .../test/resources/metadata/SHIBUI-808.xml | 60 ++++ .../shibui/pac4j/Pac4jConfiguration.java | 1 + .../pac4j/Pac4jConfigurationProperties.java | 84 ++++- .../net/unicon/shibui/pac4j/WebSecurity.java | 25 +- .../main/resources/META-INF/spring.factories | 5 +- 18 files changed, 631 insertions(+), 33 deletions(-) rename backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/configuration/{ => auto}/WebSecurityConfig.java (94%) create mode 100644 backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/RequestInitiator.java create mode 100644 backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/RequestInitiatorBuilder.java create mode 100644 backend/src/main/resources/jpa-saml2-metadata-reqinit-config.xml create mode 100644 backend/src/main/resources/modified-saml2-assertion-config.xml create mode 100644 backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/domain/Pac4jTest.groovy create mode 100644 backend/src/test/resources/metadata/SHIBUI-808.xml diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/ShibbolethUiApplication.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/ShibbolethUiApplication.java index 1fc74cf9d..b5c69ef0d 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/ShibbolethUiApplication.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/ShibbolethUiApplication.java @@ -3,21 +3,29 @@ import edu.internet2.tier.shibboleth.admin.ui.repository.MetadataResolverRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.domain.EntityScan; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.context.event.ApplicationStartedEvent; import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.FilterType; import org.springframework.context.annotation.Profile; import org.springframework.context.event.EventListener; import org.springframework.data.jpa.repository.config.EnableJpaAuditing; import org.springframework.scheduling.annotation.EnableScheduling; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.stereotype.Component; -@SpringBootApplication +@Configuration +@EnableAutoConfiguration +@ComponentScan(excludeFilters = @ComponentScan.Filter(type = FilterType.REGEX, pattern = "edu.internet2.tier.shibboleth.admin.ui.configuration.auto.*")) @EntityScan(basePackages = "edu.internet2.tier.shibboleth.admin.ui.domain") @EnableJpaAuditing @EnableScheduling +@EnableWebSecurity public class ShibbolethUiApplication extends SpringBootServletInitializer { @Override diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/configuration/WebSecurityConfig.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/configuration/auto/WebSecurityConfig.java similarity index 94% rename from backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/configuration/WebSecurityConfig.java rename to backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/configuration/auto/WebSecurityConfig.java index 186021597..a466e9706 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/configuration/WebSecurityConfig.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/configuration/auto/WebSecurityConfig.java @@ -1,9 +1,10 @@ -package edu.internet2.tier.shibboleth.admin.ui.configuration; +package edu.internet2.tier.shibboleth.admin.ui.configuration.auto; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Profile; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.builders.HttpSecurity; @@ -20,7 +21,7 @@ * * Workaround for slashes in URL from [https://stackoverflow.com/questions/48453980/spring-5-0-3-requestrejectedexception-the-request-was-rejected-because-the-url] */ -@EnableWebSecurity +@Configuration public class WebSecurityConfig { @Value("${shibui.logout-url:/dashboard}") @@ -37,8 +38,7 @@ public HttpFirewall allowUrlEncodedSlashHttpFirewall() { } @Bean - @Profile("default") - @ConditionalOnMissingBean(value = {WebSecurityConfigurerAdapter.class}) + @ConditionalOnMissingBean(name = "webSecurityConfig") public WebSecurityConfigurerAdapter defaultAuth() { return new WebSecurityConfigurerAdapter() { diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/RequestInitiator.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/RequestInitiator.java new file mode 100644 index 000000000..78fd0028e --- /dev/null +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/RequestInitiator.java @@ -0,0 +1,50 @@ +package edu.internet2.tier.shibboleth.admin.ui.domain; + +import org.opensaml.core.xml.util.AttributeMap; + +import javax.annotation.Nonnull; + +public class RequestInitiator extends AbstractElementExtensibleXMLObject implements org.opensaml.saml.ext.saml2mdreqinit.RequestInitiator { + private String binding; + @Override + public String getBinding() { + return this.binding; + } + + @Override + public void setBinding(String binding) { + this.binding = binding; + } + + private String location; + + @Override + public String getLocation() { + return location; + } + + @Override + public void setLocation(String location) { + this.location = location; + } + + private String responseLocation; + + @Override + public String getResponseLocation() { + return this.responseLocation; + } + + @Override + public void setResponseLocation(String location) { + this.responseLocation = location; + } + + private AttributeMap attributeMap = new AttributeMap(this); + + @Nonnull + @Override + public AttributeMap getUnknownAttributes() { + return this.attributeMap; + } +} diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/RequestInitiatorBuilder.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/RequestInitiatorBuilder.java new file mode 100644 index 000000000..98d554e37 --- /dev/null +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/RequestInitiatorBuilder.java @@ -0,0 +1,43 @@ +package edu.internet2.tier.shibboleth.admin.ui.domain; + +import org.opensaml.saml.common.AbstractSAMLObjectBuilder; +import org.opensaml.saml.common.xml.SAMLConstants; +import org.w3c.dom.Element; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import javax.xml.namespace.QName; + +public class RequestInitiatorBuilder extends AbstractSAMLObjectBuilder { + + /** + * Constructor. + */ + public RequestInitiatorBuilder() { + + } + + /** {@inheritDoc} */ + public RequestInitiator buildObject() { + return buildObject(SAMLConstants.SAML20MDRI_NS, org.opensaml.saml.ext.saml2mdreqinit.RequestInitiator.DEFAULT_ELEMENT_LOCAL_NAME, + SAMLConstants.SAML20MDRI_PREFIX); + } + + /** {@inheritDoc} */ + public RequestInitiator buildObject(final String namespaceURI, final String localName, + final String namespacePrefix) { + RequestInitiator o = new RequestInitiator(); + o.setNamespaceURI(namespaceURI); + o.setElementLocalName(localName); + o.setNamespacePrefix(namespacePrefix); + return o; + } + + @Nonnull + @Override + public RequestInitiator buildObject(@Nullable String namespaceURI, @Nonnull String localName, @Nullable String namespacePrefix, @Nullable QName schemaType) { + RequestInitiator requestInitiator = buildObject(namespaceURI, localName, namespacePrefix); + requestInitiator.setSchemaType(schemaType); + return requestInitiator; + } +} \ No newline at end of file diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/RoleDescriptor.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/RoleDescriptor.java index fa6600543..fc235c110 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/RoleDescriptor.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/RoleDescriptor.java @@ -83,11 +83,7 @@ public void setSupportedProtocols(List supportedProtocols) { @Override public boolean isSupportedProtocol(String s) { - return isSupportedProtocol; - } - - public void setIsSupportedProtocol(boolean isSupportedProtocol) { - this.isSupportedProtocol = isSupportedProtocol; + return this.supportedProtocols.contains(s); } @Override diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/SPSSODescriptor.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/SPSSODescriptor.java index 5688a19cb..7ac151d4a 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/SPSSODescriptor.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/SPSSODescriptor.java @@ -32,6 +32,9 @@ public class SPSSODescriptor extends SSODescriptor implements org.opensaml.saml. @Override public Boolean isAuthnRequestsSigned() { + if (isAuthnRequestsSigned == null) { + return false; + } return isAuthnRequestsSigned; } @@ -55,7 +58,7 @@ public void setAuthnRequestsSigned(XSBooleanValue xsBooleanValue) { @Override public Boolean getWantAssertionsSigned() { - return wantAssertionsSigned; + return wantAssertionsSigned == null ? false : wantAssertionsSigned; } @Override diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/X509Data.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/X509Data.java index 10fc4bdb7..46c58324a 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/X509Data.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/X509Data.java @@ -65,7 +65,7 @@ public List getX509SubjectNames() { @Nonnull @Override public List getX509Certificates() { - return Arrays.asList(this.xmlObjects.stream().filter(i -> i instanceof org.opensaml.xmlsec.signature.X509Certificate).toArray(org.opensaml.xmlsec.signature.X509Certificate[]::new)); + return new ArrayList<>(Arrays.asList(this.xmlObjects.stream().filter(i -> i instanceof org.opensaml.xmlsec.signature.X509Certificate).toArray(org.opensaml.xmlsec.signature.X509Certificate[]::new))); } public void addX509Certificate(edu.internet2.tier.shibboleth.admin.ui.domain.X509Certificate x509Certificate) { diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/opensaml/config/InitializationService.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/opensaml/config/InitializationService.java index 38bdb6784..4a554110c 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/opensaml/config/InitializationService.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/opensaml/config/InitializationService.java @@ -2,7 +2,6 @@ import org.opensaml.core.config.InitializationException; import org.opensaml.core.config.Initializer; -import org.opensaml.core.xml.config.XMLObjectProviderInitializer; import java.util.ServiceLoader; @@ -15,7 +14,11 @@ protected InitializationService() { public static synchronized void initialize() throws InitializationException { final ServiceLoader serviceLoader = ServiceLoader.load(Initializer.class); for (Initializer initializer : serviceLoader) { - if (initializer.getClass().equals(org.opensaml.saml.config.impl.XMLObjectProviderInitializer.class) || initializer.getClass().equals(XMLObjectProviderInitializer.class) || initializer.getClass().equals(org.opensaml.xmlsec.config.impl.XMLObjectProviderInitializer.class)) { + if ( + initializer.getClass().equals(org.opensaml.saml.config.impl.XMLObjectProviderInitializer.class) + || initializer.getClass().equals(org.opensaml.core.xml.config.XMLObjectProviderInitializer.class) + || initializer.getClass().equals(org.opensaml.xmlsec.config.impl.XMLObjectProviderInitializer.class) + ) { continue; } initializer.init(); diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/opensaml/config/JPAXMLObjectProviderInitializer.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/opensaml/config/JPAXMLObjectProviderInitializer.java index f21fdc93d..2b6718dd1 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/opensaml/config/JPAXMLObjectProviderInitializer.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/opensaml/config/JPAXMLObjectProviderInitializer.java @@ -13,7 +13,12 @@ protected String[] getConfigResources() { "/jpa-saml2-assertion-config.xml", "/jpa-schema-config.xml", "/jpa-saml2-metadata-ui-config.xml", - "/jpa-signature-config.xml" + "/jpa-signature-config.xml", + "/encryption-config.xml", + "/saml2-metadata-algorithm-config.xml", + "/jpa-saml2-metadata-reqinit-config.xml", + "/saml2-protocol-config.xml", + "/modified-saml2-assertion-config.xml" }; } } diff --git a/backend/src/main/resources/META-INF/spring.factories b/backend/src/main/resources/META-INF/spring.factories index fc0a891d0..c03acd3ec 100644 --- a/backend/src/main/resources/META-INF/spring.factories +++ b/backend/src/main/resources/META-INF/spring.factories @@ -1,2 +1,4 @@ org.springframework.boot.env.EnvironmentPostProcessor=\ - edu.internet2.tier.shibboleth.admin.ui.configuration.postprocessors.IdpHomeValueSettingEnvironmentPostProcessor \ No newline at end of file + edu.internet2.tier.shibboleth.admin.ui.configuration.postprocessors.IdpHomeValueSettingEnvironmentPostProcessor +org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ + edu.internet2.tier.shibboleth.admin.ui.configuration.auto.WebSecurityConfig \ No newline at end of file diff --git a/backend/src/main/resources/jpa-saml2-metadata-reqinit-config.xml b/backend/src/main/resources/jpa-saml2-metadata-reqinit-config.xml new file mode 100644 index 000000000..868961e13 --- /dev/null +++ b/backend/src/main/resources/jpa-saml2-metadata-reqinit-config.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/backend/src/main/resources/modified-saml2-assertion-config.xml b/backend/src/main/resources/modified-saml2-assertion-config.xml new file mode 100644 index 000000000..1f9d649a0 --- /dev/null +++ b/backend/src/main/resources/modified-saml2-assertion-config.xml @@ -0,0 +1,313 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/domain/Pac4jTest.groovy b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/domain/Pac4jTest.groovy new file mode 100644 index 000000000..16b48b7c8 --- /dev/null +++ b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/domain/Pac4jTest.groovy @@ -0,0 +1,19 @@ +package edu.internet2.tier.shibboleth.admin.ui.domain + +import edu.internet2.tier.shibboleth.admin.ui.opensaml.OpenSamlObjects +import spock.lang.Specification + +class Pac4jTest extends Specification { + OpenSamlObjects openSamlObjects = new OpenSamlObjects().with { + init() + it + } + + def "test unmarshalling pac4j created metadata"() { + when: + def metadata = openSamlObjects.unmarshalFromXml this.class.getResourceAsStream('/metadata/SHIBUI-808.xml').bytes + + then: + noExceptionThrown() + } +} diff --git a/backend/src/test/resources/metadata/SHIBUI-808.xml b/backend/src/test/resources/metadata/SHIBUI-808.xml new file mode 100644 index 000000000..9cfab103c --- /dev/null +++ b/backend/src/test/resources/metadata/SHIBUI-808.xml @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + MIICpzCCAY+gAwIBAgIBATANBgkqhkiG9w0BAQUFADAXMRUwEwYDVQQDDAw1YjhmNDI2MmEzZmQw + HhcNMTgwOTI2MTU0NzQ4WhcNMTkwOTI2MTU0NzQ5WjAXMRUwEwYDVQQDDAw1YjhmNDI2MmEzZmQw + ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCEFup+XxSTiXS/XnT1R7vvPZfUG+jDwbgE + 5JInMzOIyQna0KnynNM/Zxe/ZtlU+ArOVC5b5WtMomyefLxyxKQI/+aCM5OkJ8gpsJAfDnQDhB0r + dwMZ/n9T2iktiKIS963v4n9+nacx/vlD2t+FFvnHSBcoNUIncvp2lKh9JZNzuGMkipeXibb5wGjN + KYC0MBpXX90lHH9L0xP7+B9hHOI3rnwVKzHwh5oEuDSH8h2ZYQMDAEPHmLSbGP4F1N0Zr/FY+tK1 + LlY0LKxoFk1a6OKUDIT2IHljR7oqaBJRGkMFgFJK0cL7DKtrHZoNLUdaiWVWfoNaW/4k2LarBLLZ + cO77AgMBAAEwDQYJKoZIhvcNAQEFBQADggEBAGgJCR5v2F+d8/Jvl92OSaKldY07mUFTDtxHUpKw + dl0lnL3c75g4ISjFPIztuDzsAB9x8vHu4+5+rm383to4i5TL/DoOZmiFAn6WIGe0c+qE+JyNG30G + mmVjHP33s9qy0tqJe/9qtpAqXdQIC0XuqmfW49J62iE/vtClSVn8tUof7TRtrH1QGxkZJjLbG7JC + F9Z1JbvgN2pMvElhpX4SnjALUd10lB2stlKjEc5cB2BnqcOyikTxgA+zDnemy6k6JFxi9/oxKNuW + tGEr1nX42AyL1k6IpSgZikBGlwI3Rj69FoRMQayhG7pK5/XdzZ8D8YbresX2qHA5EbNrcajBsGI= + + + + + + + MIICpzCCAY+gAwIBAgIBATANBgkqhkiG9w0BAQUFADAXMRUwEwYDVQQDDAw1YjhmNDI2MmEzZmQw + HhcNMTgwOTI2MTU0NzQ4WhcNMTkwOTI2MTU0NzQ5WjAXMRUwEwYDVQQDDAw1YjhmNDI2MmEzZmQw + ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCEFup+XxSTiXS/XnT1R7vvPZfUG+jDwbgE + 5JInMzOIyQna0KnynNM/Zxe/ZtlU+ArOVC5b5WtMomyefLxyxKQI/+aCM5OkJ8gpsJAfDnQDhB0r + dwMZ/n9T2iktiKIS963v4n9+nacx/vlD2t+FFvnHSBcoNUIncvp2lKh9JZNzuGMkipeXibb5wGjN + KYC0MBpXX90lHH9L0xP7+B9hHOI3rnwVKzHwh5oEuDSH8h2ZYQMDAEPHmLSbGP4F1N0Zr/FY+tK1 + LlY0LKxoFk1a6OKUDIT2IHljR7oqaBJRGkMFgFJK0cL7DKtrHZoNLUdaiWVWfoNaW/4k2LarBLLZ + cO77AgMBAAEwDQYJKoZIhvcNAQEFBQADggEBAGgJCR5v2F+d8/Jvl92OSaKldY07mUFTDtxHUpKw + dl0lnL3c75g4ISjFPIztuDzsAB9x8vHu4+5+rm383to4i5TL/DoOZmiFAn6WIGe0c+qE+JyNG30G + mmVjHP33s9qy0tqJe/9qtpAqXdQIC0XuqmfW49J62iE/vtClSVn8tUof7TRtrH1QGxkZJjLbG7JC + F9Z1JbvgN2pMvElhpX4SnjALUd10lB2stlKjEc5cB2BnqcOyikTxgA+zDnemy6k6JFxi9/oxKNuW + tGEr1nX42AyL1k6IpSgZikBGlwI3Rj69FoRMQayhG7pK5/XdzZ8D8YbresX2qHA5EbNrcajBsGI= + + + + urn:oasis:names:tc:SAML:2.0:nameid-format:transient + urn:oasis:names:tc:SAML:2.0:nameid-format:persistent + urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress + urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified + + + diff --git a/pac4j-module/src/main/java/net/unicon/shibui/pac4j/Pac4jConfiguration.java b/pac4j-module/src/main/java/net/unicon/shibui/pac4j/Pac4jConfiguration.java index 1c28b1ee1..b7d1e05dd 100644 --- a/pac4j-module/src/main/java/net/unicon/shibui/pac4j/Pac4jConfiguration.java +++ b/pac4j-module/src/main/java/net/unicon/shibui/pac4j/Pac4jConfiguration.java @@ -12,6 +12,7 @@ public class Pac4jConfiguration { @Bean public Config config(final Pac4jConfigurationProperties pac4jConfigurationProperties) { + System.setProperty("skipPac4jOpenSAMLinit", "true"); final SAML2ClientConfiguration saml2ClientConfiguration = new SAML2ClientConfiguration(); saml2ClientConfiguration.setKeystorePath(pac4jConfigurationProperties.getKeystorePath()); saml2ClientConfiguration.setKeystorePassword(pac4jConfigurationProperties.getKeystorePassword()); diff --git a/pac4j-module/src/main/java/net/unicon/shibui/pac4j/Pac4jConfigurationProperties.java b/pac4j-module/src/main/java/net/unicon/shibui/pac4j/Pac4jConfigurationProperties.java index 1334c7e72..afb1369a1 100644 --- a/pac4j-module/src/main/java/net/unicon/shibui/pac4j/Pac4jConfigurationProperties.java +++ b/pac4j-module/src/main/java/net/unicon/shibui/pac4j/Pac4jConfigurationProperties.java @@ -1,14 +1,10 @@ package net.unicon.shibui.pac4j; -import lombok.Getter; -import lombok.Setter; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; @Component @ConfigurationProperties(prefix = "shibui.pac4j") -@Getter -@Setter public class Pac4jConfigurationProperties { private String keystorePath = "/tmp/samlKeystore.jks"; private String keystorePassword = "changeit"; @@ -20,4 +16,84 @@ public class Pac4jConfigurationProperties { private boolean forceServiceProviderMetadataGeneration = false; private String callbackUrl; private boolean wantAssertionsSigned = true; + + public String getKeystorePath() { + return keystorePath; + } + + public void setKeystorePath(String keystorePath) { + this.keystorePath = keystorePath; + } + + public String getKeystorePassword() { + return keystorePassword; + } + + public void setKeystorePassword(String keystorePassword) { + this.keystorePassword = keystorePassword; + } + + public String getPrivateKeyPassword() { + return privateKeyPassword; + } + + public void setPrivateKeyPassword(String privateKeyPassword) { + this.privateKeyPassword = privateKeyPassword; + } + + public String getIdentityProviderMetadataPath() { + return identityProviderMetadataPath; + } + + public void setIdentityProviderMetadataPath(String identityProviderMetadataPath) { + this.identityProviderMetadataPath = identityProviderMetadataPath; + } + + public int getMaximumAuthenticationLifetime() { + return maximumAuthenticationLifetime; + } + + public void setMaximumAuthenticationLifetime(int maximumAuthenticationLifetime) { + this.maximumAuthenticationLifetime = maximumAuthenticationLifetime; + } + + public String getServiceProviderEntityId() { + return serviceProviderEntityId; + } + + public void setServiceProviderEntityId(String serviceProviderEntityId) { + this.serviceProviderEntityId = serviceProviderEntityId; + } + + public String getServiceProviderMetadataPath() { + return serviceProviderMetadataPath; + } + + public void setServiceProviderMetadataPath(String serviceProviderMetadataPath) { + this.serviceProviderMetadataPath = serviceProviderMetadataPath; + } + + public boolean isForceServiceProviderMetadataGeneration() { + return forceServiceProviderMetadataGeneration; + } + + public void setForceServiceProviderMetadataGeneration(boolean forceServiceProviderMetadataGeneration) { + this.forceServiceProviderMetadataGeneration = forceServiceProviderMetadataGeneration; + } + + public String getCallbackUrl() { + return callbackUrl; + } + + public void setCallbackUrl(String callbackUrl) { + this.callbackUrl = callbackUrl; + } + + public boolean isWantAssertionsSigned() { + return wantAssertionsSigned; + } + + public void setWantAssertionsSigned(boolean wantAssertionsSigned) { + this.wantAssertionsSigned = wantAssertionsSigned; + } } diff --git a/pac4j-module/src/main/java/net/unicon/shibui/pac4j/WebSecurity.java b/pac4j-module/src/main/java/net/unicon/shibui/pac4j/WebSecurity.java index 28bfa1f58..5d624ddd5 100644 --- a/pac4j-module/src/main/java/net/unicon/shibui/pac4j/WebSecurity.java +++ b/pac4j-module/src/main/java/net/unicon/shibui/pac4j/WebSecurity.java @@ -3,29 +3,26 @@ import org.pac4j.core.config.Config; import org.pac4j.springframework.security.web.CallbackFilter; import org.pac4j.springframework.security.web.SecurityFilter; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.annotation.Order; import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.web.authentication.www.BasicAuthenticationFilter; -import org.springframework.security.web.csrf.CookieCsrfTokenRepository; @Configuration public class WebSecurity { - @Configuration - @Order(1) - public static class Pac4jSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter { - private static final Logger logger = LoggerFactory.getLogger(Pac4jSecurityConfigurationAdapter.class); + @Bean("webSecurityConfig") + public WebSecurityConfigurerAdapter webSecurityConfigurerAdapter(final Config config) { + return new Pac4jWebSecurityConfigurerAdapter(config); + } + @Order(1) + public static class Pac4jWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter { private final Config config; - public Pac4jSecurityConfigurationAdapter(Config config) { - logger.info("configuring pac4j authentication"); + public Pac4jWebSecurityConfigurerAdapter(final Config config) { this.config = config; } @@ -34,13 +31,17 @@ protected void configure(HttpSecurity http) throws Exception { final SecurityFilter securityFilter = new SecurityFilter(this.config, "Saml2Client"); final CallbackFilter callbackFilter = new CallbackFilter(this.config); + // http.regexMatcher("/callback").addFilterBefore(callbackFilter, BasicAuthenticationFilter.class); http.antMatcher("/**").addFilterBefore(callbackFilter, BasicAuthenticationFilter.class); http.authorizeRequests().anyRequest().fullyAuthenticated(); http.addFilterBefore(securityFilter, BasicAuthenticationFilter.class); http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.ALWAYS); - http.csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()); + // http.csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()); + + http.csrf().disable(); + http.headers().frameOptions().disable(); } } } diff --git a/pac4j-module/src/main/resources/META-INF/spring.factories b/pac4j-module/src/main/resources/META-INF/spring.factories index 9a6e6cbf2..90f792d84 100644 --- a/pac4j-module/src/main/resources/META-INF/spring.factories +++ b/pac4j-module/src/main/resources/META-INF/spring.factories @@ -1 +1,4 @@ -org.springframework.boot.autoconfigure.EnableAutoConfiguration=net.unicon.shibui.pac4j.Pac4jConfiguration,net.unicon.shibui.pac4j.WebSecurity,net.unicon.shibui.pac4j.WebSecurity.Pac4jSecurityConfigurationAdapter,net.unicon.shibui.pac4j.Pac4jConfigurationProperties \ No newline at end of file +org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ + net.unicon.shibui.pac4j.Pac4jConfiguration,\ + net.unicon.shibui.pac4j.WebSecurity,\ + net.unicon.shibui.pac4j.Pac4jConfigurationProperties \ No newline at end of file From f239b7111472aca07886fb255ac223c7b25aa592 Mon Sep 17 00:00:00 2001 From: Jj! Date: Fri, 28 Sep 2018 13:20:57 -0500 Subject: [PATCH 07/23] [SHIBUI-808] updated configuration --- .../tier/shibboleth/admin/ui/ShibbolethUiApplication.java | 3 +-- .../admin/ui/configuration/auto/WebSecurityConfig.java | 1 + 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/ShibbolethUiApplication.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/ShibbolethUiApplication.java index b5c69ef0d..a1ccd6c25 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/ShibbolethUiApplication.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/ShibbolethUiApplication.java @@ -19,8 +19,7 @@ import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.stereotype.Component; -@Configuration -@EnableAutoConfiguration +@SpringBootApplication @ComponentScan(excludeFilters = @ComponentScan.Filter(type = FilterType.REGEX, pattern = "edu.internet2.tier.shibboleth.admin.ui.configuration.auto.*")) @EntityScan(basePackages = "edu.internet2.tier.shibboleth.admin.ui.domain") @EnableJpaAuditing diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/configuration/auto/WebSecurityConfig.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/configuration/auto/WebSecurityConfig.java index a466e9706..4fdaf6707 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/configuration/auto/WebSecurityConfig.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/configuration/auto/WebSecurityConfig.java @@ -39,6 +39,7 @@ public HttpFirewall allowUrlEncodedSlashHttpFirewall() { @Bean @ConditionalOnMissingBean(name = "webSecurityConfig") + @Profile("!no-auth") public WebSecurityConfigurerAdapter defaultAuth() { return new WebSecurityConfigurerAdapter() { From 74969b2d232b2d78ca23babc60e0315ea4ec1a06 Mon Sep 17 00:00:00 2001 From: Jj! Date: Tue, 2 Oct 2018 09:11:42 -0500 Subject: [PATCH 08/23] [SHIBUI-808] disable pac4j for now --- settings.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/settings.gradle b/settings.gradle index 8fae26617..385e9beb4 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1 +1 @@ -include 'backend', 'ui', 'pac4j-module' \ No newline at end of file +include 'backend', 'ui' // , 'pac4j-module' \ No newline at end of file From 48e5769c9c36c3bf4c125a924ec8bc4c1e032f54 Mon Sep 17 00:00:00 2001 From: Jj! Date: Tue, 2 Oct 2018 09:20:24 -0500 Subject: [PATCH 09/23] [SHIBUI-808] tighten return --- .../tier/shibboleth/admin/ui/domain/SPSSODescriptor.java | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/SPSSODescriptor.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/SPSSODescriptor.java index 7ac151d4a..cda00fe4f 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/SPSSODescriptor.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/SPSSODescriptor.java @@ -32,10 +32,7 @@ public class SPSSODescriptor extends SSODescriptor implements org.opensaml.saml. @Override public Boolean isAuthnRequestsSigned() { - if (isAuthnRequestsSigned == null) { - return false; - } - return isAuthnRequestsSigned; + return this.isAuthnRequestsSigned == null ? false : this.isAuthnRequestsSigned; } @Override From b3de46bc318923534a2f067385f9e9afc47edd36 Mon Sep 17 00:00:00 2001 From: Jj! Date: Tue, 2 Oct 2018 16:10:01 -0500 Subject: [PATCH 10/23] [SHIBUI-808] custom configuration manager for pac4j --- .../net/unicon/shibui/pac4j/Pac4jConfiguration.java | 1 - .../shibui/pac4j/Pac4jSAMLConfigurationManager.java | 13 +++++++++++++ .../org.pac4j.saml.util.ConfigurationManager | 1 + 3 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 pac4j-module/src/main/java/net/unicon/shibui/pac4j/Pac4jSAMLConfigurationManager.java create mode 100644 pac4j-module/src/main/resources/META-INF/services/org.pac4j.saml.util.ConfigurationManager diff --git a/pac4j-module/src/main/java/net/unicon/shibui/pac4j/Pac4jConfiguration.java b/pac4j-module/src/main/java/net/unicon/shibui/pac4j/Pac4jConfiguration.java index b7d1e05dd..1c28b1ee1 100644 --- a/pac4j-module/src/main/java/net/unicon/shibui/pac4j/Pac4jConfiguration.java +++ b/pac4j-module/src/main/java/net/unicon/shibui/pac4j/Pac4jConfiguration.java @@ -12,7 +12,6 @@ public class Pac4jConfiguration { @Bean public Config config(final Pac4jConfigurationProperties pac4jConfigurationProperties) { - System.setProperty("skipPac4jOpenSAMLinit", "true"); final SAML2ClientConfiguration saml2ClientConfiguration = new SAML2ClientConfiguration(); saml2ClientConfiguration.setKeystorePath(pac4jConfigurationProperties.getKeystorePath()); saml2ClientConfiguration.setKeystorePassword(pac4jConfigurationProperties.getKeystorePassword()); diff --git a/pac4j-module/src/main/java/net/unicon/shibui/pac4j/Pac4jSAMLConfigurationManager.java b/pac4j-module/src/main/java/net/unicon/shibui/pac4j/Pac4jSAMLConfigurationManager.java new file mode 100644 index 000000000..dd3f0b10b --- /dev/null +++ b/pac4j-module/src/main/java/net/unicon/shibui/pac4j/Pac4jSAMLConfigurationManager.java @@ -0,0 +1,13 @@ +package net.unicon.shibui.pac4j; + +import org.pac4j.saml.util.ConfigurationManager; + +import javax.annotation.Priority; + +@Priority(1) +public class Pac4jSAMLConfigurationManager implements ConfigurationManager { + @Override + public void configure() { + // do nothing. we already configuration opensaml elsewhere + } +} diff --git a/pac4j-module/src/main/resources/META-INF/services/org.pac4j.saml.util.ConfigurationManager b/pac4j-module/src/main/resources/META-INF/services/org.pac4j.saml.util.ConfigurationManager new file mode 100644 index 000000000..5289f3cb2 --- /dev/null +++ b/pac4j-module/src/main/resources/META-INF/services/org.pac4j.saml.util.ConfigurationManager @@ -0,0 +1 @@ +net.unicon.shibui.pac4j.Pac4jSAMLConfigurationManager \ No newline at end of file From 5d24f3d826270178510bae95f291bc57b33200eb Mon Sep 17 00:00:00 2001 From: Jj! Date: Wed, 3 Oct 2018 10:00:00 -0500 Subject: [PATCH 11/23] [SHIBUI-808] add missing file --- backend/src/main/docker-files/loader.properties | 1 + 1 file changed, 1 insertion(+) create mode 100644 backend/src/main/docker-files/loader.properties diff --git a/backend/src/main/docker-files/loader.properties b/backend/src/main/docker-files/loader.properties new file mode 100644 index 000000000..646068881 --- /dev/null +++ b/backend/src/main/docker-files/loader.properties @@ -0,0 +1 @@ +loader.path=libs/ From a54ba7c164b21d1221e50d4459ca20d2b967cbc8 Mon Sep 17 00:00:00 2001 From: Jj! Date: Fri, 5 Oct 2018 16:51:59 -0500 Subject: [PATCH 12/23] [SHIBUI-808] fix conditional configuration --- .../admin/ui/configuration/auto/WebSecurityConfig.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/configuration/auto/WebSecurityConfig.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/configuration/auto/WebSecurityConfig.java index 4fdaf6707..0a0c9b9f5 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/configuration/auto/WebSecurityConfig.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/configuration/auto/WebSecurityConfig.java @@ -1,7 +1,7 @@ package edu.internet2.tier.shibboleth.admin.ui.configuration.auto; import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.AutoConfigureOrder; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -9,7 +9,6 @@ import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.builders.WebSecurity; -import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.web.csrf.CookieCsrfTokenRepository; import org.springframework.security.web.firewall.HttpFirewall; @@ -22,6 +21,8 @@ * Workaround for slashes in URL from [https://stackoverflow.com/questions/48453980/spring-5-0-3-requestrejectedexception-the-request-was-rejected-because-the-url] */ @Configuration +@AutoConfigureOrder(Integer.MAX_VALUE - 100) +@ConditionalOnMissingBean(WebSecurityConfigurerAdapter.class) public class WebSecurityConfig { @Value("${shibui.logout-url:/dashboard}") @@ -38,7 +39,6 @@ public HttpFirewall allowUrlEncodedSlashHttpFirewall() { } @Bean - @ConditionalOnMissingBean(name = "webSecurityConfig") @Profile("!no-auth") public WebSecurityConfigurerAdapter defaultAuth() { return new WebSecurityConfigurerAdapter() { From e4b8be45740c7f69958b7f8047991ce82ea61fbe Mon Sep 17 00:00:00 2001 From: Jj! Date: Fri, 5 Oct 2018 16:53:26 -0500 Subject: [PATCH 13/23] [SHIBUI-808] add missing firewall --- .../main/java/net/unicon/shibui/pac4j/WebSecurity.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/pac4j-module/src/main/java/net/unicon/shibui/pac4j/WebSecurity.java b/pac4j-module/src/main/java/net/unicon/shibui/pac4j/WebSecurity.java index 5d624ddd5..ba157b27d 100644 --- a/pac4j-module/src/main/java/net/unicon/shibui/pac4j/WebSecurity.java +++ b/pac4j-module/src/main/java/net/unicon/shibui/pac4j/WebSecurity.java @@ -10,6 +10,7 @@ import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.web.authentication.www.BasicAuthenticationFilter; +import org.springframework.security.web.firewall.StrictHttpFirewall; @Configuration public class WebSecurity { @@ -43,5 +44,14 @@ protected void configure(HttpSecurity http) throws Exception { http.csrf().disable(); http.headers().frameOptions().disable(); } + + @Override + public void configure(org.springframework.security.config.annotation.web.builders.WebSecurity web) throws Exception { + super.configure(web); + + StrictHttpFirewall firewall = new StrictHttpFirewall(); + firewall.setAllowUrlEncodedSlash(true); + web.httpFirewall(firewall); + } } } From 1d026767d129a7476ca221fb974a3fd1193853e8 Mon Sep 17 00:00:00 2001 From: Jj! Date: Sun, 7 Oct 2018 21:36:09 -0500 Subject: [PATCH 14/23] [SHIBUI-808] fix configuration ordering --- .../ui/configuration/auto/WebSecurityConfig.java | 4 +++- .../java/net/unicon/shibui/pac4j/WebSecurity.java | 12 ++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/configuration/auto/WebSecurityConfig.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/configuration/auto/WebSecurityConfig.java index 0a0c9b9f5..34551abad 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/configuration/auto/WebSecurityConfig.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/configuration/auto/WebSecurityConfig.java @@ -1,8 +1,10 @@ package edu.internet2.tier.shibboleth.admin.ui.configuration.auto; import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.autoconfigure.AutoConfigureBefore; import org.springframework.boot.autoconfigure.AutoConfigureOrder; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.security.servlet.SpringBootWebSecurityConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Profile; @@ -21,7 +23,7 @@ * Workaround for slashes in URL from [https://stackoverflow.com/questions/48453980/spring-5-0-3-requestrejectedexception-the-request-was-rejected-because-the-url] */ @Configuration -@AutoConfigureOrder(Integer.MAX_VALUE - 100) +@AutoConfigureBefore(SpringBootWebSecurityConfiguration.class) @ConditionalOnMissingBean(WebSecurityConfigurerAdapter.class) public class WebSecurityConfig { diff --git a/pac4j-module/src/main/java/net/unicon/shibui/pac4j/WebSecurity.java b/pac4j-module/src/main/java/net/unicon/shibui/pac4j/WebSecurity.java index ba157b27d..3f6a806b7 100644 --- a/pac4j-module/src/main/java/net/unicon/shibui/pac4j/WebSecurity.java +++ b/pac4j-module/src/main/java/net/unicon/shibui/pac4j/WebSecurity.java @@ -1,8 +1,10 @@ package net.unicon.shibui.pac4j; +import edu.internet2.tier.shibboleth.admin.ui.configuration.auto.WebSecurityConfig; import org.pac4j.core.config.Config; import org.pac4j.springframework.security.web.CallbackFilter; import org.pac4j.springframework.security.web.SecurityFilter; +import org.springframework.boot.autoconfigure.AutoConfigureBefore; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.annotation.Order; @@ -13,12 +15,22 @@ import org.springframework.security.web.firewall.StrictHttpFirewall; @Configuration +@AutoConfigureBefore(WebSecurityConfig.class) public class WebSecurity { @Bean("webSecurityConfig") public WebSecurityConfigurerAdapter webSecurityConfigurerAdapter(final Config config) { return new Pac4jWebSecurityConfigurerAdapter(config); } + @Configuration + @Order(0) + public static class FaviconSecurityConfiguration extends WebSecurityConfigurerAdapter { + @Override + protected void configure(HttpSecurity http) throws Exception { + http.authorizeRequests().antMatchers("/favicon.ico").permitAll(); + } + } + @Order(1) public static class Pac4jWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter { private final Config config; From 78c6b60fcb9e85bd7c6fd61968b048148b54eac7 Mon Sep 17 00:00:00 2001 From: Jj! Date: Mon, 8 Oct 2018 10:09:29 -0500 Subject: [PATCH 15/23] [SHIBUI-808] updated settings --- settings.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/settings.gradle b/settings.gradle index 385e9beb4..8fae26617 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1 +1 @@ -include 'backend', 'ui' // , 'pac4j-module' \ No newline at end of file +include 'backend', 'ui', 'pac4j-module' \ No newline at end of file From a56632a79412dd24e8a680be2d879d07a5427d28 Mon Sep 17 00:00:00 2001 From: Jj! Date: Mon, 8 Oct 2018 12:48:00 -0500 Subject: [PATCH 16/23] [SHIBUI-808] updated settings --- .../admin/ui/configuration/auto/WebSecurityConfig.java | 1 - .../src/main/java/net/unicon/shibui/pac4j/WebSecurity.java | 7 +++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/configuration/auto/WebSecurityConfig.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/configuration/auto/WebSecurityConfig.java index 34551abad..2e334f75f 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/configuration/auto/WebSecurityConfig.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/configuration/auto/WebSecurityConfig.java @@ -2,7 +2,6 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.AutoConfigureBefore; -import org.springframework.boot.autoconfigure.AutoConfigureOrder; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.security.servlet.SpringBootWebSecurityConfiguration; import org.springframework.context.annotation.Bean; diff --git a/pac4j-module/src/main/java/net/unicon/shibui/pac4j/WebSecurity.java b/pac4j-module/src/main/java/net/unicon/shibui/pac4j/WebSecurity.java index 3f6a806b7..e3ff9d4b6 100644 --- a/pac4j-module/src/main/java/net/unicon/shibui/pac4j/WebSecurity.java +++ b/pac4j-module/src/main/java/net/unicon/shibui/pac4j/WebSecurity.java @@ -1,10 +1,9 @@ package net.unicon.shibui.pac4j; -import edu.internet2.tier.shibboleth.admin.ui.configuration.auto.WebSecurityConfig; import org.pac4j.core.config.Config; import org.pac4j.springframework.security.web.CallbackFilter; import org.pac4j.springframework.security.web.SecurityFilter; -import org.springframework.boot.autoconfigure.AutoConfigureBefore; +import org.springframework.boot.autoconfigure.AutoConfigureOrder; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.annotation.Order; @@ -15,7 +14,7 @@ import org.springframework.security.web.firewall.StrictHttpFirewall; @Configuration -@AutoConfigureBefore(WebSecurityConfig.class) +@AutoConfigureOrder(-1) public class WebSecurity { @Bean("webSecurityConfig") public WebSecurityConfigurerAdapter webSecurityConfigurerAdapter(final Config config) { @@ -27,7 +26,7 @@ public WebSecurityConfigurerAdapter webSecurityConfigurerAdapter(final Config co public static class FaviconSecurityConfiguration extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { - http.authorizeRequests().antMatchers("/favicon.ico").permitAll(); + http.antMatcher("/favicon.ico").authorizeRequests().antMatchers("/favicon.ico").permitAll(); } } From a81a2dcc938c667cd62f648fffcaf430cb017893 Mon Sep 17 00:00:00 2001 From: Jj! Date: Tue, 9 Oct 2018 09:56:05 -0500 Subject: [PATCH 17/23] [SHIBUI-467] doc --- docs/customizations.md | 48 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 docs/customizations.md diff --git a/docs/customizations.md b/docs/customizations.md new file mode 100644 index 000000000..0423fbce9 --- /dev/null +++ b/docs/customizations.md @@ -0,0 +1,48 @@ +# Custom Development + +For a full example of creating a custom module for the application, see the `pac4j-module` project. + +As a Spring Boot application built with gradle, there are many opportunities available for +custom development against the application. Note that most customizations should be done in +separate modules, not directly modifying the source to the base application. + +## Application Classpath + +To get customizations in the application, one must make the changes available on the application +classpath. Depending on the deployment method, one has a few options for doing this. + +1. Take advantage of the `Properties Launcher` in the executable JAR +2. Put resources in the appropriate `WEB-INF` directory for a WAR deployment + +If one is adding Spring configuration, register the configuration classes with the Spring +Autoconfiguration service by adding a file called `META-INF/spring.factories` to the JAR +file containing the custom java class and referencing any configuration classes: + +```properties +org.springframework.boot.autoconfigure.EnableAutoConfiguration=org.example.SomeConfiguration +``` + +For more information, see [https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-developing-auto-configuration.html#boot-features-locating-auto-configuration-candidates] + +### Executable JAR + +The executable JAR uses the Properties Launcher provided by Spring Boot ([https://docs.spring.io/spring-boot/docs/current/reference/html/executable-jar.html#executable-jar-property-launcher-features]). +The easiest way to add something to the classpath is to create a file named `loader.properties` in the same directory +as the jar with the following: + +```properties +loader.path=libs/ +``` + +The noted directory will be added to the classpath, along with any JAR files contained in the directory. + +### WAR + +If deploying a WAR, one would use the standard packaging for providing items to the classpath. + +* JAR files should be placed in `WEB-INF/lib` +* all other resources should be placed `WEB-INF/classes` + +It is highly recommended that a WAR overlay be used to prevent changing the version fingerprint. Overlay +methods exist for both Maven ([https://maven.apache.org/plugins/maven-war-plugin/overlays.html]) and +Gradle ([https://github.com/scalding/gradle-waroverlay-plugin]) projects. \ No newline at end of file From 0e10d864988b4050af3b6ec1a7f72634c35edf7e Mon Sep 17 00:00:00 2001 From: Jj! Date: Tue, 9 Oct 2018 11:57:23 -0500 Subject: [PATCH 18/23] [SHIBUI-467] doc --- docs/{customizations.md => CUSTOMIZATIONS.md} | 0 INTERNATIONALIZATION.md => docs/INTERNATIONALIZATION.md | 5 +++++ 2 files changed, 5 insertions(+) rename docs/{customizations.md => CUSTOMIZATIONS.md} (100%) rename INTERNATIONALIZATION.md => docs/INTERNATIONALIZATION.md (88%) diff --git a/docs/customizations.md b/docs/CUSTOMIZATIONS.md similarity index 100% rename from docs/customizations.md rename to docs/CUSTOMIZATIONS.md diff --git a/INTERNATIONALIZATION.md b/docs/INTERNATIONALIZATION.md similarity index 88% rename from INTERNATIONALIZATION.md rename to docs/INTERNATIONALIZATION.md index c6aadf2e1..08bc37874 100644 --- a/INTERNATIONALIZATION.md +++ b/docs/INTERNATIONALIZATION.md @@ -4,6 +4,11 @@ The Shibboleth UI leverages the messages_*_*.properties files common to Java/Spring applications. The default files are located in `backend > src > main > resources > i18n`. +To use a custom file, it is recommended that you make a copy of the appropriate file and add it to the classpath in the +`i18n` package. See [CUSTOMIZATIONS] for more information. For instance, if using the executable JAR and wanting to +customize the English file, one would create a file called `1ibs/i18n/messages_en.properties` in the same directory as the +JAR file and set the appropriate `loader.properties`. + This will allow any piece of static text in the application to be modified dynamically. ## Usage From e8e81c7ed03d04a1162824e53a88d81546b95bf2 Mon Sep 17 00:00:00 2001 From: Jj! Date: Wed, 10 Oct 2018 12:09:44 -0500 Subject: [PATCH 19/23] [SHIBUI-808] temp for pac4j snapshot --- pac4j-module/build.gradle | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/pac4j-module/build.gradle b/pac4j-module/build.gradle index 36817e334..ff573c575 100644 --- a/pac4j-module/build.gradle +++ b/pac4j-module/build.gradle @@ -11,7 +11,9 @@ sourceCompatibility = 1.8 targetCompatibility = 1.8 repositories { - mavenLocal() + maven () { + url 'https://oss.sonatype.org/content/groups/public' + } jcenter() maven { url 'https://build.shibboleth.net/nexus/content/groups/public' @@ -34,7 +36,7 @@ dependencies { compileOnly project(':backend') compile "org.pac4j:spring-security-pac4j:4.0.0" - compile "org.pac4j:pac4j-saml:3.2.0-SNAPSHOT", { + compile "org.pac4j:pac4j-saml:3.3.0-SNAPSHOT", { // opensaml libraries are provided exclude group: 'org.opensaml' } From e00b3d9115b8eefc01b26483aefeb2075694585b Mon Sep 17 00:00:00 2001 From: Jj! Date: Thu, 11 Oct 2018 09:19:20 -0500 Subject: [PATCH 20/23] [SHIBUI-808] update config --- pac4j-module/build.gradle | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pac4j-module/build.gradle b/pac4j-module/build.gradle index ff573c575..657add297 100644 --- a/pac4j-module/build.gradle +++ b/pac4j-module/build.gradle @@ -36,6 +36,7 @@ dependencies { compileOnly project(':backend') compile "org.pac4j:spring-security-pac4j:4.0.0" + compile "org.pac4j:pac4j-core:3.3.0-SNAPSHOT" compile "org.pac4j:pac4j-saml:3.3.0-SNAPSHOT", { // opensaml libraries are provided exclude group: 'org.opensaml' @@ -53,4 +54,9 @@ docker { noCache true } +task testme(type: Copy) { + from configurations.runtime + into temporaryDir +} + tasks.docker.dependsOn(tasks.jar, ':backend:docker') \ No newline at end of file From db828bf37936545157e4b7107e5caffcd78e14fa Mon Sep 17 00:00:00 2001 From: Jj! Date: Thu, 11 Oct 2018 09:47:27 -0500 Subject: [PATCH 21/23] [SHIBUI-920] file for this to run --- pac4j-module/src/test/docker/conf/keystore.p12 | Bin 0 -> 2591 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 pac4j-module/src/test/docker/conf/keystore.p12 diff --git a/pac4j-module/src/test/docker/conf/keystore.p12 b/pac4j-module/src/test/docker/conf/keystore.p12 new file mode 100644 index 0000000000000000000000000000000000000000..57f9c162a6953c21e77cf24451d52a9d3fa5cd54 GIT binary patch literal 2591 zcmY+EXEYlM8^+#;9KJd*1inb3Z)iIp_EPKhMV>97D|oBqN7osHVVFVlnzLKj_FP$qF%41Q3R* z^9r}YF%+)Wm1*z9WVf@%JDMN3TvEX07$;TX^lxG0$V|M==T7l`GEyXPdw zXm@Syfq*ghPdN9rC^82iIiSk~gaP$MoHrr;heS_|UuGmN=cS{B0tJIUb0I?8*yTo7 z<;eF;9*tyN_u(*2@@PrdCWF2Dy0D}1o_X_!#ZZ`{?D%G$xW!6I082tT@kNaVWLI$y zQ?{iJZ+N@ftfv2ER`h<1Ps33b3x`zD#Xa^Yls;WQ*yFh6Z4hzUNZY5VhP!2ryOY5V zKGpR+arsS!Krgf}A<6#C2})#Ie`zQ4&PMp_lE|YAC+E}i=UDu!=&HTo~B0gi(9cejrUwu@8hK)P4Ppc|?PGVI38Hao~@kTe57RrfAV`uiHpU&|;rw>h&9Ew=! zLMynJ&c~u{@IoN*@p6@(O;6g*)m@_r4f!y92e%+LL89f0jf2D#yd<5tn%y@)<=-63 z6_0Wk384``Yo}vPAw_V9)L#x);zJ`87Rrq4-DfRRQ`^s@Lrj#H(Pe=Mp7Po8fC#js zcSJ_PtVsY!pJk}CFP;k7O zc_`Dqty6pqp_B4@A5ys8D~azqv>9f*uX6D_`SXt6#4yP$g|~+Vfroy_?Yb-~gYqI0 z5mLA&`cD56Gh6EF>7>Bz6Bov(Oh|U|)q=+_KUMmMQaoWc_bHRFt>yS2`2PdR_MWAzBqHlq;FHp;4?3i-pX#W148gm~V-UUZ|n*JjzAkUSFq zttV7Z>+Y5zw~xD0q0bHr6tPBYk<@ZRYqSC5C5LJiSzj9x*Jfz5<(#IULa0K099m|`{ksz@rub0J!&%HoKuFUrr zWXg;<+Bqmkm+RPThvHeaFl2lIUw}{=`hIFH2F^riQ@cgPRe##VOlhq{C!$y zVj2oh;|;i+c{#2fJ1b-;B#$QNMnLR@eci$$qQ-ms7bc++#f`<^nCMftG;_6g7RkDG zS)Avgii(ZQLOp!MllH-jXVki-(HWhVnKy&7Tl@B)y!#8xCT>ULqi)rNN;h#Q7CxqR zte=q-)bmc(SCU!-g{|J;c?pUaD+SJP9LH%`RA><;$y;@hzcxf~7(I>Z(q(f{zf_Xe zf^+??N-7p<2rn(b58wsx0N4W_0sP?n|Aeg4EFh+Pt{#q1X?a;iWkm%Ac?CFJ`bwTg zf0ro1S3Xt0Ldrlgz}1rZCn5WnVZr|~tkqHEp57>;w2?YVbCA+_xIaH;_`imYz>t%= zKLnhg96NO9Of%ipR@Ct?o8CRsk7X;lAXwe>=H7+*|55nmS)}2Ts|&f1Nl>z1 zPp%bXaadZ_SSnSH-ijLuA8bkgxt3k0e=KaXxvasg01EAO&U?ELSmNRS@Vih`O`n~! zm(iL%2^WSEvkM+EsF_lT1D_e@M-l3VUhD?z3@NL5yD$To`Q|y$2lZz@8Gr zH4a-TtEoQ|2cur+F-BXgKL4tkHyAja?^>!LPV8%yz$IX7t45YvZQo#J^&uiR-_S?` zVVZok0mHxl`d(kE5k+c?f|#$W$oE!N?wV_-Lx@?LcLHxvUivKu_Ty)u3Fn#qSoD1Z z)q5K^gp<}bKZ1pR>6t{YF4aubO9b>EsG|8Ic|MxD@?c@p>&n6>r)Kdcl7DnwQx*!? zqN|mP_On)F72tRv9Ka}`BR`D!)Z6uX6A@!OR6q&@dJtSP&2tHt*YNx*)eyv6=1@=1 z0Ny4nsx!gKdBZ)?43Q@1JQD0EntJm%-;=l00}SIaB7KE>E%tK`$J1|Vk{ZzCy#=0( zrOIhoXp~QXrmT;gp5{^Jz8Ls+TQIjTzYevT&yv94>ouv1?~>VU#n%gf$6Xt~E(ERD zK;m4byGfL*a9YtUngDy?_Brb@jq?t0C5>?`p)fW$*MQBkF|Ww#RnhSC@RkIWjKknZ zBLec1=wR==k~K5LiB(-Ox;}hz-_=vlV^IAz9_d%ru;Fawb=wBT7=0Z)%sJL=ETE z1K}_i-IeO_F;spY)>~=*tiy^f*X(CwGuxLIb|s@IL$=*RKp0_k{sq}UzfGV^$P=R# z0ouf)?@zmvOBRng}=n%+lMZ$8fk6z%zIgz@9-Z^#c&dEhz zjy_f~4KC~7h);(y-@3i8#%7D{ip3I?%)J>p*up#)iL;26E8bS&fw=+*E z&@<&p2yJD Date: Thu, 11 Oct 2018 11:01:17 -0500 Subject: [PATCH 22/23] [SHIBUI-920] write metadata-providers.xml file --- Jenkinsfile | 2 +- gradle.properties | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index dc2a92cae..f84defc02 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -36,7 +36,7 @@ pipeline { steps { sh ''' docker stop shibui || true && docker rm shibui || true - docker run -d --restart always --name shibui -p 8080:8080 -v /etc/shibui/application.properties:/application.properties -m 3GB --memory-swap=3GB unicon/shibui:latest + docker run -d --restart always --name shibui -p 8080:8080 -v /etc/shibui:/conf -v /etc/shibui/application.properties:/application.properties -m 3GB --memory-swap=3GB unicon/shibui-pac4j:latest ''' } } diff --git a/gradle.properties b/gradle.properties index ad64aeafd..678f56673 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,9 +2,8 @@ name=shibui group=edu.internet2.tier.shibboleth.admin.ui version=1.0.1-SNAPSHOT -shibboleth.version=3.4.0-SNAPSHOT -opensaml.version=3.4.0-SNAPSHOT -xmltooling.version=1.4.7-SNAPSHOT +shibboleth.version=3.4.0 +opensaml.version=3.4.0 spring-boot.version=2.0.0.RELEASE From 26a9a84213dbf3fdcd06b430233b7f1f8df14ae8 Mon Sep 17 00:00:00 2001 From: Jj! Date: Thu, 11 Oct 2018 11:07:36 -0500 Subject: [PATCH 23/23] [SHIBUI-920] update docker deploy configuration --- Jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Jenkinsfile b/Jenkinsfile index f84defc02..6179b6acf 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -36,7 +36,7 @@ pipeline { steps { sh ''' docker stop shibui || true && docker rm shibui || true - docker run -d --restart always --name shibui -p 8080:8080 -v /etc/shibui:/conf -v /etc/shibui/application.properties:/application.properties -m 3GB --memory-swap=3GB unicon/shibui-pac4j:latest + docker run -d --restart always --name shibui -p 8080:8080 -v /etc/shibui:/conf -v /etc/shibui/application.yml:/application.yml -m 3GB --memory-swap=3GB unicon/shibui-pac4j:latest ''' } }