23
23
import java .util .Arrays ;
24
24
import java .util .Collection ;
25
25
import java .util .List ;
26
+ import java .util .Set ;
26
27
27
28
import net .shibboleth .utilities .java .support .xml .ParserPool ;
28
29
import org .opensaml .core .config .ConfigurationService ;
31
32
import org .opensaml .core .xml .io .Unmarshaller ;
32
33
import org .opensaml .saml .common .xml .SAMLConstants ;
33
34
import org .opensaml .saml .ext .saml2alg .SigningMethod ;
35
+ import org .opensaml .saml .metadata .resolver .filter .MetadataFilter ;
36
+ import org .opensaml .saml .metadata .resolver .filter .MetadataFilterContext ;
37
+ import org .opensaml .saml .metadata .resolver .filter .impl .SignatureValidationFilter ;
34
38
import org .opensaml .saml .saml2 .metadata .EntitiesDescriptor ;
35
39
import org .opensaml .saml .saml2 .metadata .EntityDescriptor ;
36
40
import org .opensaml .saml .saml2 .metadata .Extensions ;
37
41
import org .opensaml .saml .saml2 .metadata .IDPSSODescriptor ;
38
42
import org .opensaml .saml .saml2 .metadata .KeyDescriptor ;
39
43
import org .opensaml .saml .saml2 .metadata .SingleLogoutService ;
40
44
import org .opensaml .saml .saml2 .metadata .SingleSignOnService ;
45
+ import org .opensaml .security .credential .Credential ;
46
+ import org .opensaml .security .credential .CredentialResolver ;
41
47
import org .opensaml .security .credential .UsageType ;
48
+ import org .opensaml .security .credential .impl .CollectionCredentialResolver ;
49
+ import org .opensaml .xmlsec .config .impl .DefaultSecurityConfigurationBootstrap ;
42
50
import org .opensaml .xmlsec .keyinfo .KeyInfoSupport ;
51
+ import org .opensaml .xmlsec .signature .support .SignatureTrustEngine ;
52
+ import org .opensaml .xmlsec .signature .support .impl .ExplicitKeySignatureTrustEngine ;
43
53
import org .w3c .dom .Document ;
44
54
import org .w3c .dom .Element ;
45
55
56
+ import org .springframework .core .convert .converter .Converter ;
46
57
import org .springframework .security .saml2 .Saml2Exception ;
47
58
import org .springframework .security .saml2 .core .OpenSamlInitializationService ;
48
59
import org .springframework .security .saml2 .core .Saml2X509Credential ;
60
+ import org .springframework .util .Assert ;
49
61
50
- class OpenSamlMetadataRelyingPartyRegistrationConverter {
62
+ public final class OpenSamlRelyingPartyRegistrationsDecoder implements RelyingPartyRegistrationsDecoder {
51
63
52
64
static {
53
65
OpenSamlInitializationService .initialize ();
@@ -57,12 +69,32 @@ class OpenSamlMetadataRelyingPartyRegistrationConverter {
57
69
58
70
private final ParserPool parserPool ;
59
71
72
+ private final MetadataFilter filter ;
73
+
74
+ private Converter <RelyingPartyRegistration .Builder , RelyingPartyRegistration > relyingPartyRegistrationBuilder = RelyingPartyRegistration .Builder ::build ;
75
+
60
76
/**
61
- * Creates a {@link OpenSamlMetadataRelyingPartyRegistrationConverter }
77
+ * Creates a {@link OpenSamlRelyingPartyRegistrationsDecoder }
62
78
*/
63
- OpenSamlMetadataRelyingPartyRegistrationConverter () {
79
+ public OpenSamlRelyingPartyRegistrationsDecoder () {
80
+ this ((xmlObject , metadataFilterContent ) -> xmlObject );
81
+ }
82
+
83
+ public OpenSamlRelyingPartyRegistrationsDecoder (Set <Credential > verificationCredentials ) {
84
+ this (metadataFilter (verificationCredentials ));
85
+ }
86
+
87
+ static MetadataFilter metadataFilter (Set <Credential > credentials ) {
88
+ CredentialResolver credentialsResolver = new CollectionCredentialResolver (credentials );
89
+ SignatureTrustEngine engine = new ExplicitKeySignatureTrustEngine (credentialsResolver ,
90
+ DefaultSecurityConfigurationBootstrap .buildBasicInlineKeyInfoCredentialResolver ());
91
+ return new SignatureValidationFilter (engine );
92
+ }
93
+
94
+ OpenSamlRelyingPartyRegistrationsDecoder (MetadataFilter filter ) {
64
95
this .registry = ConfigurationService .get (XMLObjectProviderRegistry .class );
65
96
this .parserPool = this .registry .getParserPool ();
97
+ this .filter = filter ;
66
98
}
67
99
68
100
OpenSamlRelyingPartyRegistration .Builder convert (EntityDescriptor descriptor ) {
@@ -152,24 +184,25 @@ else if (singleLogoutService.getBinding().equals(Saml2MessageBinding.REDIRECT.ge
152
184
return builder ;
153
185
}
154
186
155
- Collection <RelyingPartyRegistration .Builder > convert (InputStream inputStream ) {
156
- List <RelyingPartyRegistration .Builder > builders = new ArrayList <>();
187
+ @ Override
188
+ public Collection <RelyingPartyRegistration > decode (InputStream inputStream ) {
189
+ List <RelyingPartyRegistration > registrations = new ArrayList <>();
157
190
XMLObject xmlObject = xmlObject (inputStream );
158
191
if (xmlObject instanceof EntitiesDescriptor ) {
159
192
EntitiesDescriptor descriptors = (EntitiesDescriptor ) xmlObject ;
160
193
for (EntityDescriptor descriptor : descriptors .getEntityDescriptors ()) {
161
194
if (descriptor .getIDPSSODescriptor (SAMLConstants .SAML20P_NS ) != null ) {
162
- builders .add (convert (descriptor ));
195
+ registrations .add (this . relyingPartyRegistrationBuilder . convert (convert ( descriptor ) ));
163
196
}
164
197
}
165
- if (builders .isEmpty ()) {
198
+ if (registrations .isEmpty ()) {
166
199
throw new Saml2Exception ("Metadata contains no IDPSSODescriptor elements" );
167
200
}
168
- return builders ;
201
+ return registrations ;
169
202
}
170
203
if (xmlObject instanceof EntityDescriptor ) {
171
204
EntityDescriptor descriptor = (EntityDescriptor ) xmlObject ;
172
- return Arrays .asList (convert (descriptor ));
205
+ return Arrays .asList (this . relyingPartyRegistrationBuilder . convert (convert ( descriptor ) ));
173
206
}
174
207
throw new Saml2Exception ("Unsupported element of type " + xmlObject .getClass ());
175
208
}
@@ -202,7 +235,7 @@ private XMLObject xmlObject(InputStream inputStream) {
202
235
throw new Saml2Exception ("Unsupported element of type " + element .getTagName ());
203
236
}
204
237
try {
205
- return unmarshaller .unmarshall (element );
238
+ return this . filter . filter ( unmarshaller .unmarshall (element ), new MetadataFilterContext () );
206
239
}
207
240
catch (Exception ex ) {
208
241
throw new Saml2Exception (ex );
@@ -225,4 +258,10 @@ private <T> List<T> signingMethods(Extensions extensions) {
225
258
return new ArrayList <>();
226
259
}
227
260
261
+ public void setRelyingPartyRegistrationBuilder (
262
+ Converter <RelyingPartyRegistration .Builder , RelyingPartyRegistration > relyingPartyRegistrationBuilder ) {
263
+ Assert .notNull (relyingPartyRegistrationBuilder , "relyingPartyRegistrationBuilder cannot be null" );
264
+ this .relyingPartyRegistrationBuilder = relyingPartyRegistrationBuilder ;
265
+ }
266
+
228
267
}
0 commit comments