Commit 6904dd1f authored by Gradl, Tobias's avatar Gradl, Tobias
Browse files

1: Rebase on newer OpenSAML

Task-Url: #1
parent 6c8b6b5b
Pipeline #17448 passed with stage
in 1 minute and 49 seconds
......@@ -86,7 +86,7 @@ subprojects {
apply plugin: "java"
java {
sourceCompatibility = JavaVersion.VERSION_1_8
sourceCompatibility = JavaVersion.VERSION_11
}
tasks.withType(JavaCompile) {
......
......@@ -7,19 +7,23 @@ plugins {
ext {
springPac4jVersion = "5.1.0"
webmvcPac4jVersion = "4.0.1"
pac4jVersion = "4.1.0"
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
//implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.apache.tomcat.embed:tomcat-embed-jasper'
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:spring-webmvc-pac4j:$webmvcPac4jVersion"
implementation "org.pac4j:pac4j-saml:$pac4jVersion"
implementation "org.pac4j:pac4j-http:$pac4jVersion"
testImplementation librarySets.commonTest
......
<?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">
<?xml version="1.0" encoding="UTF-8"?><md:EntityDescriptor xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" ID="_c53f31e55d93419680d6930ed119421b146a023" entityID="https://c105-229.cloud.gwdg.de/dme" validUntil="2040-10-28T07:32:29.593Z">
<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"/>
......@@ -24,44 +24,52 @@
<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:X509Certificate>MIIEOTCCAqGgAwIBAgIUejGvYAjQIqKiG11W7w6PIaNKBIMwDQYJKoZIhvcNAQELBQAwITEfMB0G
A1UEAxMWYzEwNS0yMjkuY2xvdWQuZ3dkZy5kZTAeFw0yMDA0MzAwNzIyMDdaFw0yMzA1MDEwNzIy
MDdaMCExHzAdBgNVBAMTFmMxMDUtMjI5LmNsb3VkLmd3ZGcuZGUwggGiMA0GCSqGSIb3DQEBAQUA
A4IBjwAwggGKAoIBgQDHWlEUUaAnomRLPKUrayShpV0y0Wk7m7vqmZ4WiStLn/dwrDOiIgNqBh/w
boZ6DSfivaiNmb8IfKG2neUn1AyR/9Qony8ydwH0lWT3pFphPpb7tBP0jwiyXSKP425UqlyPsH+4
tHyYkHUlaqyuBBr7tSXN1Zz6c0Y5E3uRHK0KvTtf6akFcRK9PDadztXF+BUn5BaSwnFE/TG9bJ0p
6AmXDhvM54hL62/ueqT3Vg5/gnBIJmrW4VOOX+JCyjD9VcZWm/Q0672dXbZNIHPiWDBpVSVYsO1V
wsATeb7mHAuq2FoWAe03AOkw860cbDiaYpknFxMC6Ac3Jiu1I3MAtW/giFCNsfd9uqL4beq+bgLx
QzLi3HucLxghqI+i4wNBgPd6b9eCHO7X6qB3+X3ibbthxHS7F2xG3pA2VXwMplhGRVnk7t1dDRQz
OtcrnbDab9gPsh8Aw+sxpmDEu4J8GkspSvd4uuwOQ3IJhdNrTqn0QQyoZ34DTGMtA+kfS36ga/8C
AwEAAaNpMGcwRgYDVR0RBD8wPYIWYzEwNS0yMjkuY2xvdWQuZ3dkZy5kZYYjaHR0cHM6Ly9jMTA1
LTIyOS5jbG91ZC5nd2RnLmRlL3NhbWwwHQYDVR0OBBYEFN7qyWPjyg+BTFsq4AtOG0WHX1X9MA0G
CSqGSIb3DQEBCwUAA4IBgQA4Ey0+LtXooX7sxHoP+TogcIpwG3AQ9U64URHMCZH11WM/T73hs/Mp
Ck5AMYjuFXNJ+/+NYmHS7/8Ay6y+X94OzFDECLfMvDQebPNFqxVyQU89lJFh0u68ChUjihW8N/mf
7T3kR69Ekb4l7U9GbpY61fldBOIWuEU1MWyixYTuqwZ57SD5aA+qwIPbP/b4bxZC5vNGecOeAR+U
WdKomI+DM1WppQWECZDu6++PrIhjmvZymUEIgXlOTIxIyGcb/79wvRxwY+5tlvq1hOhDtarSXIPO
pu2ROEtMAexJscrSOE6vBi3QZtRremuZPaPYhOiuoFRVHL6+g1hR/NTeoECQ1tBQKq3g2ppKVt6i
g6vVqLsOeluYvZ/CucQ133ceR50OTGtclQvrPcOBP9Pz89lfcG4JJyfliGrR8t1foUkewciF1aME
DBxjfBjDVW0WKKDlU/qOsVHmNPGavywbKECOkthD/jQWu2OBPspsQQ0Ts8Jp9n7IIJJH7l7dTAyo
rS8=</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:X509Certificate>MIIEOTCCAqGgAwIBAgIUejGvYAjQIqKiG11W7w6PIaNKBIMwDQYJKoZIhvcNAQELBQAwITEfMB0G
A1UEAxMWYzEwNS0yMjkuY2xvdWQuZ3dkZy5kZTAeFw0yMDA0MzAwNzIyMDdaFw0yMzA1MDEwNzIy
MDdaMCExHzAdBgNVBAMTFmMxMDUtMjI5LmNsb3VkLmd3ZGcuZGUwggGiMA0GCSqGSIb3DQEBAQUA
A4IBjwAwggGKAoIBgQDHWlEUUaAnomRLPKUrayShpV0y0Wk7m7vqmZ4WiStLn/dwrDOiIgNqBh/w
boZ6DSfivaiNmb8IfKG2neUn1AyR/9Qony8ydwH0lWT3pFphPpb7tBP0jwiyXSKP425UqlyPsH+4
tHyYkHUlaqyuBBr7tSXN1Zz6c0Y5E3uRHK0KvTtf6akFcRK9PDadztXF+BUn5BaSwnFE/TG9bJ0p
6AmXDhvM54hL62/ueqT3Vg5/gnBIJmrW4VOOX+JCyjD9VcZWm/Q0672dXbZNIHPiWDBpVSVYsO1V
wsATeb7mHAuq2FoWAe03AOkw860cbDiaYpknFxMC6Ac3Jiu1I3MAtW/giFCNsfd9uqL4beq+bgLx
QzLi3HucLxghqI+i4wNBgPd6b9eCHO7X6qB3+X3ibbthxHS7F2xG3pA2VXwMplhGRVnk7t1dDRQz
OtcrnbDab9gPsh8Aw+sxpmDEu4J8GkspSvd4uuwOQ3IJhdNrTqn0QQyoZ34DTGMtA+kfS36ga/8C
AwEAAaNpMGcwRgYDVR0RBD8wPYIWYzEwNS0yMjkuY2xvdWQuZ3dkZy5kZYYjaHR0cHM6Ly9jMTA1
LTIyOS5jbG91ZC5nd2RnLmRlL3NhbWwwHQYDVR0OBBYEFN7qyWPjyg+BTFsq4AtOG0WHX1X9MA0G
CSqGSIb3DQEBCwUAA4IBgQA4Ey0+LtXooX7sxHoP+TogcIpwG3AQ9U64URHMCZH11WM/T73hs/Mp
Ck5AMYjuFXNJ+/+NYmHS7/8Ay6y+X94OzFDECLfMvDQebPNFqxVyQU89lJFh0u68ChUjihW8N/mf
7T3kR69Ekb4l7U9GbpY61fldBOIWuEU1MWyixYTuqwZ57SD5aA+qwIPbP/b4bxZC5vNGecOeAR+U
WdKomI+DM1WppQWECZDu6++PrIhjmvZymUEIgXlOTIxIyGcb/79wvRxwY+5tlvq1hOhDtarSXIPO
pu2ROEtMAexJscrSOE6vBi3QZtRremuZPaPYhOiuoFRVHL6+g1hR/NTeoECQ1tBQKq3g2ppKVt6i
g6vVqLsOeluYvZ/CucQ133ceR50OTGtclQvrPcOBP9Pz89lfcG4JJyfliGrR8t1foUkewciF1aME
DBxjfBjDVW0WKKDlU/qOsVHmNPGavywbKECOkthD/jQWu2OBPspsQQ0Ts8Jp9n7IIJJH7l7dTAyo
rS8=</ds:X509Certificate>
</ds:X509Data>
</ds:KeyInfo>
</md:KeyDescriptor>
......
......@@ -7,7 +7,8 @@ import org.springframework.boot.context.properties.ConfigurationPropertiesScan;
@SpringBootApplication
@ConfigurationPropertiesScan
public class DariahSPSampleApplication {
public static void main(String[] args) {
SpringApplication.run(DariahSPSampleApplication.class, args);
}
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.authenticator;
import org.pac4j.core.context.WebContext;
import org.pac4j.core.credentials.UsernamePasswordCredentials;
import org.pac4j.core.credentials.authenticator.Authenticator;
import org.pac4j.core.exception.CredentialsException;
import org.pac4j.core.profile.CommonProfile;
import org.pac4j.core.util.CommonHelper;
import org.pac4j.core.util.Pac4jConstants;
import org.springframework.security.crypto.password.PasswordEncoder;
import eu.dariah.de.dariahsp.sample.local.LocalUserConf;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class LocalUsernamePasswordAuthenticator implements Authenticator<UsernamePasswordCredentials> {
@Getter @Setter private LocalUserConf[] localUserConfigurations;
@Getter @Setter private PasswordEncoder encoder;
@Override
public void validate(UsernamePasswordCredentials credentials, WebContext context) {
try {
if (credentials == null) {
throw new CredentialsException("No credential");
}
String username = credentials.getUsername();
String password = credentials.getPassword();
if (CommonHelper.isBlank(username)) {
throw new CredentialsException("Username cannot be blank");
}
if (CommonHelper.isBlank(password)) {
throw new CredentialsException("Password cannot be blank");
}
for (LocalUserConf cnf : localUserConfigurations) {
if (cnf.getUsername().equals(username)) {
if (encoder.matches(password, cnf.getPasshash())) {
final CommonProfile profile = new CommonProfile();
profile.setId(username);
profile.addAttribute(Pac4jConstants.USERNAME, username);
profile.setRoles(cnf.getRoles());
credentials.setUserProfile(profile);
log.info("Local authentication succeeded [{}]", profile.toString());
return;
} else {
throw new CredentialsException("Invalid username/password combination");
}
}
}
throw new CredentialsException("Invalid username/password combination");
} catch (CredentialsException e) {
log.info("Local authentication failed{}: {}",
credentials!=null ? "for user" + credentials.getUsername() : "",
e.getMessage());
throw e;
}
}
}
......@@ -8,25 +8,52 @@ 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.http.client.indirect.FormClient;
import org.pac4j.http.client.indirect.IndirectBasicAuthClient;
import org.pac4j.http.credentials.authenticator.test.SimpleTestUsernamePasswordAuthenticator;
import org.pac4j.saml.client.SAML2Client;
import org.pac4j.saml.config.SAML2Configuration;
import org.pac4j.saml.util.SAML2HttpClientBuilder;
import org.pac4j.springframework.annotation.AnnotationConfig;
import org.pac4j.springframework.component.ComponentConfig;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import eu.dariah.de.dariahsp.sample.CustomAuthorizer;
import eu.dariah.de.dariahsp.sample.authenticator.LocalUsernamePasswordAuthenticator;
import eu.dariah.de.dariahsp.sample.local.LocalUserConf;
import eu.dariah.de.dariahsp.sample.local.LocalUserConfService;
import lombok.Data;
@Data
@Configuration
@ConfigurationProperties(prefix = "saml")
@Import({ComponentConfig.class, AnnotationConfig.class})
public class SamlConfig {
private String keystore;
private String keystorePassword;
private String privateKeyPassword;
private String identityProviderMetadata;
private LocalUserConf[] localUserConfigurations;
@Bean
LocalUserConfService localUserConfService() {
return new LocalUserConfService();
}
@Bean
LocalUsernamePasswordAuthenticator localUsernamePasswordAuthenticator() {
LocalUsernamePasswordAuthenticator localAuthenticator = new LocalUsernamePasswordAuthenticator();
localAuthenticator.setLocalUserConfigurations(localUserConfigurations);
localAuthenticator.setEncoder(new BCryptPasswordEncoder());
return localAuthenticator;
}
@Bean
Config config() {
final SAML2Configuration cfg = new SAML2Configuration(this.getKeystore(),
......@@ -37,6 +64,7 @@ public class SamlConfig {
cfg.setMaximumAuthenticationLifetime(3600);
//cfg.setServiceProviderEntityId("http://localhost:8080/callback?client_name=SAML2Client");
cfg.setServiceProviderMetadataPath("/data/_srv/dariahsp/sp_metadata.xml");
//cfg.setServiceProviderMetadataPath("sp_metadata.xml");
cfg.setAuthnRequestBindingType(SAMLConstants.SAML2_REDIRECT_BINDING_URI);
......@@ -58,16 +86,26 @@ public class SamlConfig {
cfg.setHttpClient(httpClient.build());
//cfg.setForceServiceProviderMetadataGeneration(true);
// 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));
// HTTP
final FormClient formClient = new FormClient("/loginForm", localUsernamePasswordAuthenticator());
final Config config = new Config(new Clients("/callback", samlClient, formClient));
config.addAuthorizer("admin", new RequireAnyRoleAuthorizer("ROLE_ADMIN"));
config.addAuthorizer("custom", new CustomAuthorizer());
//config.addMatcher("excludedPath", new PathMatcher().excludeRegex("^/*$"));
......
package eu.dariah.de.dariahsp.sample.config;
import org.pac4j.core.config.Config;
import org.pac4j.springframework.security.web.CallbackFilter;
import org.pac4j.springframework.security.web.LogoutFilter;
import org.pac4j.springframework.security.web.Pac4jEntryPoint;
import org.pac4j.springframework.security.web.SecurityFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
......@@ -14,7 +17,31 @@ import org.springframework.security.web.authentication.www.BasicAuthenticationFi
@EnableWebSecurity
public class SecurityConfig {
/* @Configuration
@Order(5)
public static class FormWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter {
@Autowired
private Config config;
protected void configure(final HttpSecurity http) throws Exception {
//final SecurityFilter filter = new SecurityFilter(config, "DirectBasicAuthClient,AnonymousClient");
final SecurityFilter filter = new SecurityFilter(config, "FormClient");
http
.antMatcher("/form/**")
.authorizeRequests().anyRequest().authenticated()
.and()
.exceptionHandling().authenticationEntryPoint(new Pac4jEntryPoint(config, "FormClient"))
.and()
.addFilterBefore(filter, BasicAuthenticationFilter.class)
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.ALWAYS);
}
}
@Configuration
@Order(7)
public static class Saml2WebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter {
@Autowired
......@@ -34,4 +61,76 @@ public class SecurityConfig {
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.ALWAYS);
}
}
*/
@Configuration
@Order(7)
public static class CombinedSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter {
@Autowired
private Config config;
protected void configure(final HttpSecurity http) throws Exception {
final SecurityFilter filter = new SecurityFilter(config, "Saml2Client, FormClient");
http
.antMatcher("/saml/**")
.authorizeRequests()
.antMatchers("/saml/admin.html").hasRole("ADMIN")
.antMatchers("/saml/**").authenticated()
.and()
.addFilterBefore(filter, BasicAuthenticationFilter.class)
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.ALWAYS);
http
.antMatcher("/form/**")
.authorizeRequests().anyRequest().authenticated()
.and()
.exceptionHandling().authenticationEntryPoint(new Pac4jEntryPoint(config, "FormClient"))
.and()
.addFilterBefore(filter, BasicAuthenticationFilter.class)
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.ALWAYS);
}
}
@Configuration
@Order(15)
public static class DefaultWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter {
@Autowired
private Config config;
protected void configure(final HttpSecurity http) throws Exception {
final CallbackFilter callbackFilter = new CallbackFilter(config);
callbackFilter.setMultiProfile(true);
final LogoutFilter logoutFilter = new LogoutFilter(config, "/?defaulturlafterlogout");
logoutFilter.setDestroySession(true);
logoutFilter.setSuffix("/pac4jLogout");
final LogoutFilter centralLogoutFilter = new LogoutFilter(config, "http://localhost:8080/?defaulturlafterlogoutafteridp");
centralLogoutFilter.setLocalLogout(false);
centralLogoutFilter.setCentralLogout(true);
centralLogoutFilter.setLogoutUrlPattern("http://localhost:8080/.*");
centralLogoutFilter.setSuffix("/pac4jCentralLogout");
http
.authorizeRequests()
.antMatchers("/cas/**").authenticated()
.anyRequest().permitAll()
.and()
.exceptionHandling().authenticationEntryPoint(new Pac4jEntryPoint(config, "CasClient"))
.and()
.addFilterBefore(callbackFilter, BasicAuthenticationFilter.class)
.addFilterBefore(logoutFilter, CallbackFilter.class)
.addFilterAfter(centralLogoutFilter, CallbackFilter.class)
.csrf().disable()
.logout()
.logoutSuccessUrl("/");
}
}
}
package eu.dariah.de.dariahsp.sample.controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.web.ErrorProperties;
import org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController;
import org.springframework.boot.web.servlet.error.ErrorAttributes;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
@Controller
@RequestMapping({"${server.error.path:${error.path:/error}}"})
public class ErrorController extends BasicErrorController {
@Autowired
public ErrorController(ErrorAttributes errorAttributes) {
super(errorAttributes, new ErrorProperties());
}
@RequestMapping(
produces = {"text/html"}
)
@Override
public ModelAndView errorHtml(HttpServletRequest request, HttpServletResponse response) {
final HttpStatus status = getStatus(request);
if (status == HttpStatus.UNAUTHORIZED) {
return new ModelAndView("error401");
} else if (status == HttpStatus.FORBIDDEN) {
return new ModelAndView("error403");
} else {
return new ModelAndView("error500");
}
}
}
\ No newline at end of file
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";
}
}
package eu.dariah.de.dariahsp.sample.controller;
import java.util.Map;
import org.pac4j.core.client.Client;
import org.pac4j.core.config.Config;
import org.pac4j.core.context.JEEContext;
import org.pac4j.core.exception.http.HttpAction;
import org.pac4j.core.http.adapter.JEEHttpActionAdapter;
import org.pac4j.core.profile.ProfileManager;
import org.pac4j.core.util.Pac4jConstants;
import org.pac4j.http.client.indirect.FormClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class SampleController {
private static final String PROFILES = "profiles";
private static final String SESSION_ID = "sessionId";
@Value("${auth.salt}")
private String salt;
@Autowired
private Config config;
@Autowired
private JEEContext jeeContext;
@Autowired
private ProfileManager profileManager;
@GetMapping("/")
public String greeting(@RequestParam(name="name", required=false, defaultValue="World") String name, Model model) {
model.addAttribute("name", name);
return "home";
}
@RequestMapping("/form/index.html")
public String form(Map<String, Object> map) {
return protectedIndex(map);
}
@RequestMapping("/loginForm")
public String loginForm(Map<String, Object> map) {
final FormClient formClient = (FormClient) config.getClients().findClient("FormClient").get();
map.put("callbackUrl", formClient.getCallbackUrl());
return "form";
}
@RequestMapping("/forceLogin")
@ResponseBody
public String forceLogin() {
final Client client = config.getClients().findClient(jeeContext.getRequestParameter(Pac4jConstants.DEFAULT_CLIENT_NAME_PARAMETER).get()).get();
HttpAction action;
try {
action = (HttpAction) client.getRedirectionAction(jeeContext).get();
} catch (final HttpAction e) {
action = e;
}
JEEHttpActionAdapter.INSTANCE.adapt(action, jeeContext);
return null;
}
protected String protectedIndex(Map<String, Object> map) {
map.put(PROFILES, profileManager.getAll(true));
return "protectedIndex";
}
}
package eu.dariah.de.dariahsp.sample.local;
import java.util.Scanner;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
public class BCryptPasswordCreator {
private static BCryptPasswordEncoder encoder;
public static void main(String[] args) {
Scanner scanner = new Scanner (System.in);
System.out.println("CLI Tool to create BCrypt passwords to be used with a dariahsp derived application");
System.out.println("------------------------------------------------------");
System.out.println("Please make sure to provide BCrypt initialization arguments exactly \n as they are configured in the security-context-common.xml");
System.out.println("If you have not changed the default initialization of the BCryptPasswordEncoder \n (and you dont have to), choose the default values for rounds:");
System.out.println("------------------------------------------------------");
System.out.println("Please choose rounds [4-31; default: 10]");