Commit 6c8b6b5b authored by Gradl, Tobias's avatar Gradl, Tobias
Browse files

1: Rebase on newer OpenSAML

Task-Url: #1
parent 3a975dc5
Pipeline #17403 passed with stage
in 2 minutes and 26 seconds
plugins {
id 'org.springframework.boot' version '2.3.4.RELEASE'
id 'io.spring.dependency-management' version '1.0.8.RELEASE'
id 'java'
id 'war'
}
ext {
springPac4jVersion = "5.1.0"
pac4jVersion = "4.1.0"
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'org.springframework.boot:spring-boot-starter-web'
compileOnly 'org.projectlombok:lombok'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
annotationProcessor 'org.projectlombok:lombok'
providedRuntime 'org.springframework.boot:spring-boot-starter-tomcat'
implementation "org.pac4j:spring-security-pac4j:$springPac4jVersion"
implementation "org.pac4j:pac4j-saml:$pac4jVersion"
testImplementation librarySets.commonTest
testImplementation('org.springframework.boot:spring-boot-starter-test') {
exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
}
}
<?xml version="1.0" encoding="UTF-8"?><md:EntityDescriptor xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" ID="_aa9a65760954485a9370469105caa57ffd2e6bd" entityID="http://localhost:8080/callback?extraParameter" validUntil="2040-10-27T22:39:19.085Z">
<md:Extensions xmlns:alg="urn:oasis:names:tc:SAML:metadata:algsupport">
<alg:SigningMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
<alg:SigningMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha384"/>
<alg:SigningMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha512"/>
<alg:SigningMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
<alg:SigningMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha256"/>
<alg:SigningMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha384"/>
<alg:SigningMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha512"/>
<alg:SigningMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha1"/>
<alg:SigningMethod Algorithm="http://www.w3.org/2000/09/xmldsig#dsa-sha1"/>
<alg:SigningMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#hmac-sha256"/>
<alg:SigningMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#hmac-sha384"/>
<alg:SigningMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#hmac-sha512"/>
<alg:SigningMethod Algorithm="http://www.w3.org/2000/09/xmldsig#hmac-sha1"/>
<alg:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
<alg:DigestMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#sha384"/>
<alg:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
</md:Extensions>
<md:SPSSODescriptor AuthnRequestsSigned="true" WantAssertionsSigned="true" protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:assertion">
<md:Extensions xmlns:init="urn:oasis:names:tc:SAML:profiles:SSO:request-init">
<init:RequestInitiator Binding="urn:oasis:names:tc:SAML:profiles:SSO:request-init" Location="http://localhost:8080/callback?client_name=SAML2Client"/>
</md:Extensions>
<md:KeyDescriptor use="signing">
<ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:X509Data>
<ds:X509Certificate>MIIDfDCCAmSgAwIBAgIJAOyWJ3PtCGGQMA0GCSqGSIb3DQEBCwUAMGwxEDAOBgNVBAYTB1Vua25v
d24xEDAOBgNVBAgTB1Vua25vd24xEDAOBgNVBAcTB1Vua25vd24xEDAOBgNVBAoTB1Vua25vd24x
EDAOBgNVBAsTB1Vua25vd24xEDAOBgNVBAMTB1Vua25vd24wHhcNMjAxMDI3MTYzNjIxWhcNMzAx
MDI1MTYzNjIxWjBsMRAwDgYDVQQGEwdVbmtub3duMRAwDgYDVQQIEwdVbmtub3duMRAwDgYDVQQH
EwdVbmtub3duMRAwDgYDVQQKEwdVbmtub3duMRAwDgYDVQQLEwdVbmtub3duMRAwDgYDVQQDEwdV
bmtub3duMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAgneJcV7C+lPf36Ar3qg7rfiJ
XrGqFokAFofL/M5SpZEy/UWqHSsUK7v1hxcTC4sRVXE7WD5MCdrB3/TiE7eTaUrD1vyBxqWcVZvh
AJShiiA3n+wTga5u5LffD8loXM7+PCi4kfdm/McJXrlI5IkNnhU5hNwnmkfKkBwgEKBkNDgxGlS0
W5dC7ZM6uep9aefvZWcBc09BYvuQlxGPvY6IsOz0phNbuq/o5xNBaMOaT0pLeSOv2jtT1Ucb/SSD
tkjTHlF5guYGxW40PCpxhGOZhfPxeBv3nmmDNO6IsIMdZv1dbZAf7Xb4sbM1NjAVAfzI8ye8Pkzo
3vBBDXfS6drpswIDAQABoyEwHzAdBgNVHQ4EFgQUTHwtZ6gO9G88wungSnCdToJK/4UwDQYJKoZI
hvcNAQELBQADggEBAHtrTnRmPEZ2i6Alsvz0ASCqJGUTo+xUGwZ7JtywZjNLoqCfl+KdjwtC9/Qx
BfzAHwfIjOSn+NeKmYxDC5AuPx2TF3cxoXdmGnO+xzDf2INsMC9yCbkLELK6Psm4baUo6ipVJcJM
XvTjOJBBNk3PS4YCLKehPjtzcrQK3sEv5TabLnsfAlroWhgiBEXzxBhv3UnarAGL8u7bsTFBHSNE
8DH8+azqL+wq4zCmpwtSsdIyCcbEyyHvbrGbp6Ot2fHnZtjlJe2Z3KaAF/MI+ddhUrTwgwIm21ee
/OpGddSnsI/T6AMJWy7sQP7j4PhV9PRylCOuESc+cSRbFoktZPEdBdE=</ds:X509Certificate>
</ds:X509Data>
</ds:KeyInfo>
</md:KeyDescriptor>
<md:KeyDescriptor use="encryption">
<ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:X509Data>
<ds:X509Certificate>MIIDfDCCAmSgAwIBAgIJAOyWJ3PtCGGQMA0GCSqGSIb3DQEBCwUAMGwxEDAOBgNVBAYTB1Vua25v
d24xEDAOBgNVBAgTB1Vua25vd24xEDAOBgNVBAcTB1Vua25vd24xEDAOBgNVBAoTB1Vua25vd24x
EDAOBgNVBAsTB1Vua25vd24xEDAOBgNVBAMTB1Vua25vd24wHhcNMjAxMDI3MTYzNjIxWhcNMzAx
MDI1MTYzNjIxWjBsMRAwDgYDVQQGEwdVbmtub3duMRAwDgYDVQQIEwdVbmtub3duMRAwDgYDVQQH
EwdVbmtub3duMRAwDgYDVQQKEwdVbmtub3duMRAwDgYDVQQLEwdVbmtub3duMRAwDgYDVQQDEwdV
bmtub3duMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAgneJcV7C+lPf36Ar3qg7rfiJ
XrGqFokAFofL/M5SpZEy/UWqHSsUK7v1hxcTC4sRVXE7WD5MCdrB3/TiE7eTaUrD1vyBxqWcVZvh
AJShiiA3n+wTga5u5LffD8loXM7+PCi4kfdm/McJXrlI5IkNnhU5hNwnmkfKkBwgEKBkNDgxGlS0
W5dC7ZM6uep9aefvZWcBc09BYvuQlxGPvY6IsOz0phNbuq/o5xNBaMOaT0pLeSOv2jtT1Ucb/SSD
tkjTHlF5guYGxW40PCpxhGOZhfPxeBv3nmmDNO6IsIMdZv1dbZAf7Xb4sbM1NjAVAfzI8ye8Pkzo
3vBBDXfS6drpswIDAQABoyEwHzAdBgNVHQ4EFgQUTHwtZ6gO9G88wungSnCdToJK/4UwDQYJKoZI
hvcNAQELBQADggEBAHtrTnRmPEZ2i6Alsvz0ASCqJGUTo+xUGwZ7JtywZjNLoqCfl+KdjwtC9/Qx
BfzAHwfIjOSn+NeKmYxDC5AuPx2TF3cxoXdmGnO+xzDf2INsMC9yCbkLELK6Psm4baUo6ipVJcJM
XvTjOJBBNk3PS4YCLKehPjtzcrQK3sEv5TabLnsfAlroWhgiBEXzxBhv3UnarAGL8u7bsTFBHSNE
8DH8+azqL+wq4zCmpwtSsdIyCcbEyyHvbrGbp6Ot2fHnZtjlJe2Z3KaAF/MI+ddhUrTwgwIm21ee
/OpGddSnsI/T6AMJWy7sQP7j4PhV9PRylCOuESc+cSRbFoktZPEdBdE=</ds:X509Certificate>
</ds:X509Data>
</ds:KeyInfo>
</md:KeyDescriptor>
<md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="http://localhost:8080/callback?client_name=SAML2Client&amp;logoutendpoint=true"/>
<md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST-SimpleSign" Location="http://localhost:8080/callback?client_name=SAML2Client&amp;logoutendpoint=true"/>
<md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="http://localhost:8080/callback?client_name=SAML2Client&amp;logoutendpoint=true"/>
<md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP" Location="http://localhost:8080/callback?client_name=SAML2Client&amp;logoutendpoint=true"/>
<md:NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:transient</md:NameIDFormat>
<md:NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:persistent</md:NameIDFormat>
<md:NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress</md:NameIDFormat>
<md:NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified</md:NameIDFormat>
<md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="http://localhost:8080/callback?client_name=SAML2Client" index="0"/>
</md:SPSSODescriptor>
</md:EntityDescriptor>
/*
* This Java source file was generated by the Gradle 'init' task.
*/
package eu.dariah.de.dariahsp.sample;
public class App {
public String getGreeting() {
return "Hello world.";
}
public static void main(String[] args) {
System.out.println(new App().getGreeting());
}
}
package eu.dariah.de.dariahsp.sample;
//import org.apache.commons.lang.StringUtils;
import org.pac4j.core.authorization.authorizer.ProfileAuthorizer;
import org.pac4j.core.context.WebContext;
import org.pac4j.core.profile.CommonProfile;
import java.util.List;
public class CustomAuthorizer extends ProfileAuthorizer<CommonProfile> {
@Override
public boolean isAuthorized(final WebContext context, final List<CommonProfile> profiles) {
return isAnyAuthorized(context, profiles);
}
@Override
public boolean isProfileAuthorized(final WebContext context, final CommonProfile profile) {
if (profile == null) {
return false;
}
//return StringUtils.startsWith(profile.getUsername(), "jle");
return false;
}
}
package eu.dariah.de.dariahsp.sample;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.ConfigurationPropertiesScan;
@SpringBootApplication
@ConfigurationPropertiesScan
public class DariahSPSampleApplication {
public static void main(String[] args) {
SpringApplication.run(DariahSPSampleApplication.class, args);
}
}
package eu.dariah.de.dariahsp.sample;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
public class ServletInitializer extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(DariahSPSampleApplication.class);
}
}
package eu.dariah.de.dariahsp.sample.config;
import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
import org.opensaml.saml.common.xml.SAMLConstants;
import org.pac4j.core.authorization.authorizer.RequireAnyRoleAuthorizer;
import org.pac4j.core.client.Clients;
import org.pac4j.core.config.Config;
import org.pac4j.saml.client.SAML2Client;
import org.pac4j.saml.config.SAML2Configuration;
import org.pac4j.saml.util.SAML2HttpClientBuilder;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import eu.dariah.de.dariahsp.sample.CustomAuthorizer;
import lombok.Data;
@Data
@Configuration
@ConfigurationProperties(prefix = "saml")
public class SamlConfig {
private String keystore;
private String keystorePassword;
private String privateKeyPassword;
private String identityProviderMetadata;
@Bean
Config config() {
final SAML2Configuration cfg = new SAML2Configuration(this.getKeystore(),
this.getKeystorePassword(),
this.getPrivateKeyPassword(),
this.getIdentityProviderMetadata());
cfg.setMaximumAuthenticationLifetime(3600);
//cfg.setServiceProviderEntityId("http://localhost:8080/callback?client_name=SAML2Client");
cfg.setServiceProviderMetadataPath("/data/_srv/dariahsp/sp_metadata.xml");
cfg.setAuthnRequestBindingType(SAMLConstants.SAML2_REDIRECT_BINDING_URI);
cfg.setResponseBindingType(SAMLConstants.SAML2_POST_BINDING_URI);
// lifetime in seconds
cfg.setMaximumAuthenticationLifetime(600);
// custom SP entity ID
cfg.setServiceProviderEntityId("https://c105-229.cloud.gwdg.de/dme");
cfg.setWantsAssertionsSigned(true);
cfg.setAuthnRequestSigned(true);
SAML2HttpClientBuilder httpClient = new SAML2HttpClientBuilder();
httpClient.setConnectionTimeout(Duration.ofSeconds(2));
httpClient.setSocketTimeout(Duration.ofSeconds(2));
cfg.setHttpClient(httpClient.build());
//cfg.setForceServiceProviderMetadataGeneration(true);
List<String> supportedProtocols = new ArrayList<>();
supportedProtocols.add(SAMLConstants.SAML20_NS);
cfg.setSupportedProtocols(supportedProtocols);
SAML2Client samlClient = new SAML2Client(cfg);
final Config config = new Config(new Clients("http://localhost:8080/callback", samlClient));
config.addAuthorizer("admin", new RequireAnyRoleAuthorizer("ROLE_ADMIN"));
config.addAuthorizer("custom", new CustomAuthorizer());
//config.addMatcher("excludedPath", new PathMatcher().excludeRegex("^/*$"));
return config;
}
}
package eu.dariah.de.dariahsp.sample.config;
import org.pac4j.core.config.Config;
import org.pac4j.springframework.security.web.SecurityFilter;
import org.springframework.beans.factory.annotation.Autowired;
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;
@EnableWebSecurity
public class SecurityConfig {
@Configuration
public static class Saml2WebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter {
@Autowired
private Config config;
protected void configure(final HttpSecurity http) throws Exception {
final SecurityFilter filter = new SecurityFilter(config, "Saml2Client");
http
.antMatcher("/saml/**")
.authorizeRequests()
.antMatchers("/saml/admin.html").hasRole("ADMIN")
.antMatchers("/saml/**").authenticated()
.and()
.addFilterBefore(filter, BasicAuthenticationFilter.class)
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.ALWAYS);
}
}
}
package eu.dariah.de.dariahsp.sample.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
@Controller
public class HomeController {
@GetMapping("/greeting")
public String greeting(@RequestParam(name="name", required=false, defaultValue="World") String name, Model model) {
model.addAttribute("name", name);
return "home";
}
}
logging:
level:
web: DEBUG
saml:
keystore: file:/data/_srv/dariahsp/c105-229.cloud.gwdg.de.jks
keystorePassword: clariah
privateKeyPassword: clariah
identityProviderMetadata: https://aaiproxy.de.dariah.eu/idp/
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="Console"
class="ch.qos.logback.core.ConsoleAppender">
<layout class="ch.qos.logback.classic.PatternLayout">
<pattern>%d{yyyy-MM-dd} %d{HH:mm:ss.SSS} %thread | %5p %logger{36} - %m%n</pattern>
</layout>
</appender>
<!-- LOG everything at INFO level -->
<root level="info">
<appender-ref ref="Console" />
</root>
<!-- LOG "com.baeldung*" at TRACE level -->
<logger name="eu.dariah.de" level="trace" additivity="false">
<appender-ref ref="Console" />
</logger>
</configuration>
\ No newline at end of file
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Getting Started: Serving Web Content</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<p th:text="'Hello, ' + ${name} + '!'" />
</body>
</html>
\ No newline at end of file
/*
* This Java source file was generated by the Gradle 'init' task.
*/
package eu.dariah.de.dariahsp.sample;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
class AppTest {
@Test void appHasAGreeting() {
App classUnderTest = new App();
assertNotNull(classUnderTest.getGreeting(), "app should have a greeting");
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment