Skip to content

Commit 0a7da94

Browse files
committed
Polish saml-extension-federation Configuration
1 parent d058ae6 commit 0a7da94

File tree

4 files changed

+148
-75
lines changed

4 files changed

+148
-75
lines changed
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
/*
2+
* Copyright 2002-2024 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package example;
18+
19+
import java.io.IOException;
20+
import java.io.InputStream;
21+
import java.security.cert.CertificateException;
22+
import java.security.cert.CertificateFactory;
23+
import java.security.cert.X509Certificate;
24+
import java.security.interfaces.RSAPrivateKey;
25+
26+
import org.springframework.boot.context.properties.ConfigurationProperties;
27+
import org.springframework.boot.io.ApplicationResourceLoader;
28+
import org.springframework.core.io.Resource;
29+
import org.springframework.core.io.ResourceLoader;
30+
import org.springframework.security.converter.RsaKeyConverters;
31+
import org.springframework.security.saml2.core.Saml2X509Credential;
32+
import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistration;
33+
import org.springframework.security.saml2.provider.service.registration.Saml2MessageBinding;
34+
import org.springframework.stereotype.Component;
35+
36+
@Component
37+
@ConfigurationProperties("saml2")
38+
public class RelyingPartyMetadata {
39+
40+
private final ResourceLoader resourceLoader = new ApplicationResourceLoader();
41+
42+
private String entityId = "{baseUrl}/saml/metadata";
43+
44+
private String sso = "{baseUrl}/saml/SSO";
45+
46+
private SingleLogout slo = new SingleLogout();
47+
48+
private X509Certificate certificate;
49+
50+
private RSAPrivateKey key;
51+
52+
public RelyingPartyRegistration apply(RelyingPartyRegistration.Builder builder) {
53+
Saml2X509Credential signing = Saml2X509Credential.signing(this.key, this.certificate);
54+
return builder.entityId(this.entityId)
55+
.assertionConsumerServiceLocation(this.sso)
56+
.singleLogoutServiceBinding(this.slo.getBinding())
57+
.singleLogoutServiceLocation(this.slo.getLocation())
58+
.singleLogoutServiceResponseLocation(this.slo.getResponseLocation())
59+
.signingX509Credentials((c) -> c.add(signing))
60+
.build();
61+
}
62+
63+
public void setEntityId(String entityId) {
64+
this.entityId = entityId;
65+
}
66+
67+
public void setSso(String sso) {
68+
this.sso = sso;
69+
}
70+
71+
public void setSlo(SingleLogout slo) {
72+
this.slo = slo;
73+
}
74+
75+
public void setCertificate(String certificate) {
76+
Resource source = this.resourceLoader.getResource(certificate);
77+
try (InputStream in = source.getInputStream()) {
78+
CertificateFactory certificates = CertificateFactory.getInstance("X.509");
79+
this.certificate = (X509Certificate) certificates.generateCertificate(in);
80+
}
81+
catch (CertificateException | IOException ex) {
82+
throw new IllegalArgumentException(ex);
83+
}
84+
}
85+
86+
public void setKey(String key) {
87+
Resource source = this.resourceLoader.getResource(key);
88+
try (InputStream in = source.getInputStream()) {
89+
this.key = RsaKeyConverters.pkcs8().convert(in);
90+
}
91+
catch (IOException ex) {
92+
throw new IllegalArgumentException(ex);
93+
}
94+
}
95+
96+
public static class SingleLogout {
97+
98+
private Saml2MessageBinding binding = Saml2MessageBinding.REDIRECT;
99+
100+
private String location = "{baseUrl}/saml/logout";
101+
102+
private String responseLocation = "{baseUrl}/saml/SingleLogout";
103+
104+
public Saml2MessageBinding getBinding() {
105+
return this.binding;
106+
}
107+
108+
public void setBinding(Saml2MessageBinding binding) {
109+
this.binding = binding;
110+
}
111+
112+
public String getLocation() {
113+
return this.location;
114+
}
115+
116+
public void setLocation(String location) {
117+
this.location = location;
118+
}
119+
120+
public String getResponseLocation() {
121+
if (this.responseLocation == null) {
122+
return this.location;
123+
}
124+
return this.responseLocation;
125+
}
126+
127+
public void setResponseLocation(String responseLocation) {
128+
this.responseLocation = responseLocation;
129+
}
130+
131+
}
132+
133+
}
Lines changed: 10 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2022 the original author or authors.
2+
* Copyright 2002-2024 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -16,26 +16,16 @@
1616

1717
package example;
1818

19-
import java.io.File;
20-
import java.io.FileInputStream;
21-
import java.io.IOException;
22-
import java.io.InputStream;
23-
import java.security.cert.CertificateException;
24-
import java.security.cert.CertificateFactory;
25-
import java.security.cert.X509Certificate;
26-
import java.security.interfaces.RSAPrivateKey;
27-
import java.util.UUID;
28-
import java.util.stream.Collectors;
19+
import java.util.List;
2920

3021
import org.springframework.beans.factory.annotation.Value;
31-
import org.springframework.boot.autoconfigure.security.saml2.Saml2RelyingPartyProperties;
32-
import org.springframework.boot.autoconfigure.security.saml2.Saml2RelyingPartyProperties.Registration;
3322
import org.springframework.context.annotation.Bean;
3423
import org.springframework.context.annotation.Configuration;
3524
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
3625
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
37-
import org.springframework.security.saml2.core.Saml2X509Credential;
3826
import org.springframework.security.saml2.provider.service.registration.InMemoryRelyingPartyRegistrationRepository;
27+
import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistration;
28+
import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistrationRepository;
3929
import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistrations;
4030
import org.springframework.security.web.SecurityFilterChain;
4131

@@ -60,32 +50,13 @@ SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
6050
}
6151

6252
@Bean
63-
InMemoryRelyingPartyRegistrationRepository repository(Saml2RelyingPartyProperties properties,
64-
@Value("classpath:credentials/rp-private.key") RSAPrivateKey key,
65-
@Value("classpath:credentials/rp-certificate.crt") File cert) {
66-
Saml2X509Credential signing = Saml2X509Credential.signing(key, x509Certificate(cert));
67-
Registration registration = properties.getRegistration().values().iterator().next();
68-
return new InMemoryRelyingPartyRegistrationRepository(RelyingPartyRegistrations
69-
.collectionFromMetadataLocation(registration.getAssertingparty().getMetadataUri())
53+
RelyingPartyRegistrationRepository registrations(RelyingPartyMetadata rp,
54+
@Value("${saml2.ap.metadata}") String ap) {
55+
List<RelyingPartyRegistration> registrations = RelyingPartyRegistrations.collectionFromMetadataLocation(ap)
7056
.stream()
71-
.map((builder) -> builder.registrationId(UUID.randomUUID().toString())
72-
.entityId(registration.getEntityId())
73-
.assertionConsumerServiceLocation(registration.getAcs().getLocation())
74-
.singleLogoutServiceBinding(registration.getSinglelogout().getBinding())
75-
.singleLogoutServiceLocation(registration.getSinglelogout().getUrl())
76-
.singleLogoutServiceResponseLocation(registration.getSinglelogout().getResponseUrl())
77-
.signingX509Credentials((credentials) -> credentials.add(signing))
78-
.build())
79-
.collect(Collectors.toList()));
80-
}
81-
82-
X509Certificate x509Certificate(File location) {
83-
try (InputStream source = new FileInputStream(location)) {
84-
return (X509Certificate) CertificateFactory.getInstance("X.509").generateCertificate(source);
85-
}
86-
catch (CertificateException | IOException ex) {
87-
throw new IllegalArgumentException(ex);
88-
}
57+
.map(rp::apply)
58+
.toList();
59+
return new InMemoryRelyingPartyRegistrationRepository(registrations);
8960
}
9061

9162
}

servlet/spring-boot/java/saml2/saml-extension-federation/src/main/resources/application.yml

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,8 @@ spring:
1010
security:
1111
filter:
1212
dispatcher-types: async, error, request, forward
13-
saml2:
14-
relyingparty:
15-
registration:
16-
metadata:
17-
entity-id: "{baseUrl}/saml/metadata"
18-
singlelogout:
19-
binding: REDIRECT
20-
url: "{baseUrl}/saml/logout"
21-
responseUrl: "{baseUrl}/saml/SingleLogout"
22-
acs:
23-
location: "{baseUrl}/saml/SSO"
24-
assertingparty.metadata-uri: http://idp-one.7f000001.nip.io/simplesaml/saml2/idp/metadata.php
13+
14+
saml2:
15+
certificate: classpath:credentials/rp-certificate.crt
16+
key: classpath:credentials/rp-private.key
17+
ap.metadata: http://idp-one.7f000001.nip.io/simplesaml/saml2/idp/metadata.php

servlet/spring-boot/java/saml2/saml-extension-federation/src/main/resources/credentials/idp-certificate.crt

Lines changed: 0 additions & 24 deletions
This file was deleted.

0 commit comments

Comments
 (0)