|
16 | 16 |
|
17 | 17 | package org.springframework.security.saml2.provider.service.authentication;
|
18 | 18 |
|
| 19 | +import java.io.ByteArrayInputStream; |
| 20 | +import java.nio.charset.Charset; |
| 21 | +import java.nio.charset.StandardCharsets; |
| 22 | +import java.util.HashMap; |
| 23 | +import java.util.LinkedHashMap; |
| 24 | +import java.util.List; |
| 25 | +import java.util.Map; |
| 26 | +import javax.xml.XMLConstants; |
| 27 | +import javax.xml.namespace.QName; |
| 28 | + |
19 | 29 | import net.shibboleth.utilities.java.support.component.ComponentInitializationException;
|
20 | 30 | import net.shibboleth.utilities.java.support.xml.BasicParserPool;
|
21 | 31 | import net.shibboleth.utilities.java.support.xml.SerializeSupport;
|
|
24 | 34 | import org.opensaml.core.config.InitializationException;
|
25 | 35 | import org.opensaml.core.config.InitializationService;
|
26 | 36 | import org.opensaml.core.xml.XMLObject;
|
| 37 | +import org.opensaml.core.xml.XMLObjectBuilderFactory; |
27 | 38 | import org.opensaml.core.xml.config.XMLObjectProviderRegistry;
|
28 | 39 | import org.opensaml.core.xml.config.XMLObjectProviderRegistrySupport;
|
29 | 40 | import org.opensaml.core.xml.io.MarshallerFactory;
|
30 | 41 | import org.opensaml.core.xml.io.MarshallingException;
|
31 | 42 | import org.opensaml.core.xml.io.UnmarshallerFactory;
|
32 | 43 | import org.opensaml.core.xml.io.UnmarshallingException;
|
33 |
| -import org.opensaml.saml.common.SignableSAMLObject; |
| 44 | +import org.opensaml.saml.saml2.core.AuthnRequest; |
34 | 45 | import org.opensaml.saml.saml2.encryption.EncryptedElementTypeEncryptedKeyResolver;
|
35 | 46 | import org.opensaml.security.SecurityException;
|
36 | 47 | import org.opensaml.security.credential.BasicCredential;
|
|
47 | 58 | import org.opensaml.xmlsec.signature.support.SignatureConstants;
|
48 | 59 | import org.opensaml.xmlsec.signature.support.SignatureException;
|
49 | 60 | import org.opensaml.xmlsec.signature.support.SignatureSupport;
|
| 61 | +import org.w3c.dom.Document; |
| 62 | +import org.w3c.dom.Element; |
| 63 | + |
50 | 64 | import org.springframework.security.saml2.Saml2Exception;
|
51 | 65 | import org.springframework.security.saml2.credentials.Saml2X509Credential;
|
52 |
| -import org.springframework.security.saml2.provider.service.authentication.Saml2Utils; |
53 | 66 | import org.springframework.util.Assert;
|
54 | 67 | import org.springframework.web.util.UriUtils;
|
55 |
| -import org.w3c.dom.Document; |
56 |
| -import org.w3c.dom.Element; |
57 |
| - |
58 |
| -import javax.xml.XMLConstants; |
59 |
| -import javax.xml.namespace.QName; |
60 |
| -import java.io.ByteArrayInputStream; |
61 |
| -import java.nio.charset.Charset; |
62 |
| -import java.nio.charset.StandardCharsets; |
63 |
| -import java.util.HashMap; |
64 |
| -import java.util.LinkedHashMap; |
65 |
| -import java.util.List; |
66 |
| -import java.util.Map; |
67 | 68 |
|
68 | 69 | import static java.lang.Boolean.FALSE;
|
69 | 70 | import static java.lang.Boolean.TRUE;
|
70 | 71 | import static java.util.Arrays.asList;
|
71 |
| -import static org.opensaml.core.xml.config.XMLObjectProviderRegistrySupport.getBuilderFactory; |
72 | 72 | import static org.springframework.util.StringUtils.hasText;
|
73 | 73 |
|
74 | 74 | /**
|
75 | 75 | * @since 5.2
|
76 | 76 | */
|
77 | 77 | final class OpenSamlImplementation {
|
78 | 78 | private static OpenSamlImplementation instance = new OpenSamlImplementation();
|
| 79 | + private static XMLObjectBuilderFactory xmlObjectBuilderFactory = |
| 80 | + XMLObjectProviderRegistrySupport.getBuilderFactory(); |
79 | 81 |
|
80 | 82 | private final BasicParserPool parserPool = new BasicParserPool();
|
81 | 83 | private final EncryptedKeyResolver encryptedKeyResolver = new ChainingEncryptedKeyResolver(
|
@@ -167,37 +169,31 @@ EncryptedKeyResolver getEncryptedKeyResolver() {
|
167 | 169 | return this.encryptedKeyResolver;
|
168 | 170 | }
|
169 | 171 |
|
170 |
| - <T> T buildSAMLObject(final Class<T> clazz) { |
171 |
| - try { |
172 |
| - QName defaultElementName = (QName) clazz.getDeclaredField("DEFAULT_ELEMENT_NAME").get(null); |
173 |
| - return (T) getBuilderFactory().getBuilder(defaultElementName).buildObject(defaultElementName); |
174 |
| - } |
175 |
| - catch (NoSuchFieldException | IllegalAccessException e) { |
176 |
| - throw new Saml2Exception("Could not create SAML object", e); |
177 |
| - } |
| 172 | + <T> T buildSamlObject(QName qName) { |
| 173 | + return (T) xmlObjectBuilderFactory.getBuilder(qName).buildObject(qName); |
178 | 174 | }
|
179 | 175 |
|
180 | 176 | XMLObject resolve(String xml) {
|
181 | 177 | return resolve(xml.getBytes(StandardCharsets.UTF_8));
|
182 | 178 | }
|
183 | 179 |
|
184 |
| - String toXml(XMLObject object, List<Saml2X509Credential> signingCredentials, String localSpEntityId) { |
185 |
| - if (object instanceof SignableSAMLObject && null != hasSigningCredential(signingCredentials)) { |
186 |
| - signXmlObject( |
187 |
| - (SignableSAMLObject) object, |
188 |
| - signingCredentials, |
189 |
| - localSpEntityId |
190 |
| - ); |
191 |
| - } |
| 180 | + String serialize(XMLObject xmlObject) { |
192 | 181 | final MarshallerFactory marshallerFactory = XMLObjectProviderRegistrySupport.getMarshallerFactory();
|
193 | 182 | try {
|
194 |
| - Element element = marshallerFactory.getMarshaller(object).marshall(object); |
| 183 | + Element element = marshallerFactory.getMarshaller(xmlObject).marshall(xmlObject); |
195 | 184 | return SerializeSupport.nodeToString(element);
|
196 | 185 | } catch (MarshallingException e) {
|
197 | 186 | throw new Saml2Exception(e);
|
198 | 187 | }
|
199 | 188 | }
|
200 | 189 |
|
| 190 | + String serialize(AuthnRequest authnRequest, List<Saml2X509Credential> signingCredentials) { |
| 191 | + if (hasSigningCredential(signingCredentials) != null) { |
| 192 | + signAuthnRequest(authnRequest, signingCredentials); |
| 193 | + } |
| 194 | + return serialize(authnRequest); |
| 195 | + } |
| 196 | + |
201 | 197 | /**
|
202 | 198 | * Returns query parameter after creating a Query String signature
|
203 | 199 | * All return values are unencoded and will need to be encoded prior to sending
|
@@ -306,15 +302,15 @@ private Credential getSigningCredential(List<Saml2X509Credential> signingCredent
|
306 | 302 | return cred;
|
307 | 303 | }
|
308 | 304 |
|
309 |
| - private void signXmlObject(SignableSAMLObject object, List<Saml2X509Credential> signingCredentials, String entityId) { |
| 305 | + private void signAuthnRequest(AuthnRequest authnRequest, List<Saml2X509Credential> signingCredentials) { |
310 | 306 | SignatureSigningParameters parameters = new SignatureSigningParameters();
|
311 |
| - Credential credential = getSigningCredential(signingCredentials, entityId); |
| 307 | + Credential credential = getSigningCredential(signingCredentials, authnRequest.getIssuer().getValue()); |
312 | 308 | parameters.setSigningCredential(credential);
|
313 | 309 | parameters.setSignatureAlgorithm(SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA256);
|
314 | 310 | parameters.setSignatureReferenceDigestMethod(SignatureConstants.ALGO_ID_DIGEST_SHA256);
|
315 | 311 | parameters.setSignatureCanonicalizationAlgorithm(SignatureConstants.ALGO_ID_C14N_EXCL_OMIT_COMMENTS);
|
316 | 312 | try {
|
317 |
| - SignatureSupport.signObject(object, parameters); |
| 313 | + SignatureSupport.signObject(authnRequest, parameters); |
318 | 314 | } catch (MarshallingException | SignatureException | SecurityException e) {
|
319 | 315 | throw new Saml2Exception(e);
|
320 | 316 | }
|
|
0 commit comments