WS-Trust-Client-API
Die WS-Trust-Client-API (Anwendungsprogrammierschnittstelle) umfasst die Klasse WSSTrustClient, die Klasse WSSTrustClientValidateResult und andere Konfigurationsdienstprogrammklassen. Die Klasse WSSTrustClient stellt Helper-Funktionen bereit, die SOAP-Anforderungen an den angegebenen externen Sicherheitstokenservice (STS) sendet, damit der STS eine oder mehrere SAML-Zusicherungen oder andere Arten von Sicherheitstoken ausgeben oder validieren kann.
Übersicht
WebSphere Application Server umfasst die WS-Trust-Clientfunktion, die mit der Klasse WSSTrustClient implementiert wird. Diese Klasse sendet WS-Trust-SOAP-Anforderungen an einen angegebenen Sicherheitstokenservice (STS). Mit den Trust-Anforderungen kann der der STS eine oder mehrere SAML-Zusicherungen oder andere Arten von Sicherheitstoken ausgeben. Die Klasse WSSTrustClient unterstützt die Spezifikation OASIS WS-Trust Version 1.3 sowie die Spezifikation WS-Trust Version 1.2. Außerdem unterstützt die Funktion die Spezifikationen SOAP Version 1.1 und SOAP Version 1.2.
Der weiter unten dargestellte Beispielcode zeigt, wie ein Web-Service-Client die API WSSTrustClient zum Anfordern eines SAML-Bearer-Tokens verwendet. In der dem Beispielcode vorausgehenden Erläuterung wird der Begriff SAML-Token synonym mit dem Begriff SAML-Zusicherung verwendet.
Die Klasse WSSTrustClient
Sie können den Beispielcode in die Anwendung eines Assembliertools wie Rational Application Developer kopieren und den Code nach Ausführung der Konfigurationsschritt starten. Verwenden Sie die Klasse WSSTrustClient zusammen mit anderen SAML APIs, um nützliche SAML-Funktionen zu erstellen. Weitere Informationen hierzu finden Sie in der Java-Dokumentation zur SAML API.
Die Klasse WSSTrustClient ist eine abstrakte Klasse und verfügt über zwei konkrete Implementierungen: die Implementierung von WS-Trust Version 1.3 und die Implementierung von a WS-Trust v1.2. In Zeile 50 des Beispielcodes ruft der Web-Service-Clientcode SAMLWSTrustClientExample die Methode WSSTrustClient.getInstance(ProviderConfig) auf, um die Implementierung WS-Trust v1.3 abzurufen. Die Methode getInstance() verwendet ein einzelnes ProviderConfig-Objekt, das die Konfigurationsdaten angibt, die für den Aussteller des SAML-Tokens relevant sind. Ein ProviderConfig-Objekt wird außerdem in Zeile 32 des Beispielcodes instanziiert. Der Clientcode sendet Anforderungsnachrichten der WS-Trust Version 1.3 an einen STS-Zielendpunkt. In dem Beispiel ist https://MyCompany/Trust/13/UsernameMixed der Endpunkt. Wenn Sie den Beispielcode verwenden, ersetzen Sie diesen STS-Beispielendpunkt durch den speziellen STS-Endpunkt, den Sie verwenden möchten.
Die SAML-Unterstützung der WSS-API ergänzt die Schnittstellen com.ibm.websphere.wssecurity.wssapi.token.SAMLTokenFactory und com.ibm.websphere.wssecurity.wssapi.trust.WSSTrustClient. SAMLToken, die mit der Methode com.ibm.websphere.wssecurity.wssapi.WSSFactory newSecurityToken() generiert werden, können von den Programmierschnittstellen SAMLTokenFactory und WSSTrustClient verarbeitet werden. SAMLToken, die von SAMLTokenFactory generiert oder von WSSTrustClient zurückgegeben werden, können in WSS API verwendet werden. Die Entscheidung, welche API Sie in Ihrer Anwendung verwenden, richtet sich nach den jeweiligen Anforderungen. Die SAML-Unterstützung von WSS API ist insofern eigenständig, dass sie in Bezug auf Web-Service-Clientanwendungen Funktionen bereitstellt, die denen der Schnittstellen SAMLTokenFactory und WSSTrustClient entsprechen. Die Schnittstelle SAMLTokenFactory enthält weitere Funktionen für die Validierung von SAMLToken und für die Erstellung des JAAS-Subject-Objekts, das authentifizierte SAMLToken darstellt. Diese Validierung ist hilfreich für die Web-Service-Providerseite. Wenn Sie Anwendungen entwickeln, die SAMLToken konsumieren, ist die Programmierschnittstelle SAMLTokenFactory besser für Sie geeignet.
Beispiel: Web-Service-Clientcde mit Verwendung der Klasse WSSTrustClient
1. package sample;
2.
3. import com.ibm.websphere.wssecurity.wssapi.WSSException;
4. import com.ibm.websphere.wssecurity.wssapi.token.SecurityToken;
5. import com.ibm.websphere.wssecurity.wssapi.trust.WSSTrustClient;
6. import com.ibm.websphere.wssecurity.wssapi.token.SAMLToken;
7. import com.ibm.websphere.wssecurity.wssapi.XMLStructure;
8.
9.
10. import com.ibm.wsspi.wssecurity.core.token.config.RequesterConfiguration;
11. import com.ibm.wsspi.wssecurity.core.token.config.WSSConstants.Namespace;
12. import com.ibm.wsspi.wssecurity.core.token.config.WSSConstants.TokenType;
13. import com.ibm.wsspi.wssecurity.core.token.config.WSSConstants.WST13;
14. import com.ibm.wsspi.wssecurity.trust.config.ProviderConfig;
15. import com.ibm.wsspi.wssecurity.trust.config.RequesterConfig;
16. import com.ibm.wsspi.wssecurity.wssapi.OMStructure;
17.
18. import org.apache.axiom.om.OMElement;
19. import org.apache.axis2.util.XMLPrettyPrinter;
20.
21. import java.util.List;
22. import java.io.ByteArrayOutputStream;
23. import java.io.InputStream;
24. import java.io.BufferedReader;
25. import java.io.InputStreamReader;
26. import java.io.IOException;
27.
28. public class WSSTrustClientExample {
29.
30. public static void main(String[] args) {
31. try {
32. ProviderConfig providerConfig = WSSTrustClient.newProviderConfig(Namespace.WST13, https://MyCompany.com/Trust/13/UsernameMixed );
33. 34. showProviderConfigDefaultValue(providerConfig);
35. 36. providerConfig.setPolicySetName("Username WSHTTPS default");
37. providerConfig.setBindingName("SamlTCSample");
38. providerConfig.setBindingScope("domain");
39.
40.
41. RequesterConfig requesterConfig = WSSTrustClient.newRequesterConfig(Namespace.WST13);
42. 43. showRequestConfigDefaultValue(requesterConfig);
44. 45. requesterConfig.put(RequesterConfiguration.RSTT.APPLIESTO_ADDRESS, "https://user.MyCompany:9443/WSSampleSei/EchoService12");
46. requesterConfig.put(RequesterConfiguration.RSTT.TOKENTYPE, TokenType.SAML11);
47. requesterConfig.put(RequesterConfiguration.RSTT.KEYTYPE, WST13.KEYTYPE_BEARER);
48. requesterConfig.setSOAPNamespace(Namespace.SOAP12);
49. 50. WSSTrustClient client = WSSTrustClient.getInstance(providerConfig);
51. List<SecurityToken> securityTokens = client.issue(providerConfig, requesterConfig);
52. 53. // SAML-Token verarbeiten
54. if (securityTokens != null && !securityTokens.isEmpty()) {
55. System.out.println("Number of tokens returned = " + securityTokens.size());
56. SecurityToken token = securityTokens.get(0);
57. if (token instanceof SAMLToken) {
58. showSAMLToken((SAMLToken)token);
59. } else {
60. System.out.println("Returned token is not an SAMLToken");
61. }
62. } else {
63. System.out.println("No securityToken obtained.");
64. }
65. 66. } catch (SoapSecurityException ex) {
67. System.out.println("Caught exception: " + ex.getMessage());
68. ex.printStackTrace();
69. }
70. }
71.
72. private static void showProviderConfigDefaultValue(ProviderConfig providerConfig) {
73. System.out.println("providerConfig.getApplicationName() = " + providerConfig.getApplicationName());
74. System.out.println("providerConfig.getBindingName() = " + providerConfig.getBindingName());
75. System.out.println("ProviderConfig.getBindingScope() = " + providerConfig.getBindingScope());
76. System.out.println("providerConfig.getIssuerURI() = " + providerConfig.getIssuerURI());
77.
78. System.out.println("providerConfig.getPolicySetName() = " + providerConfig.getPolicySetName());
79. System.out.println("ProviderConfig.getPortName() = " + providerConfig.getPortName());
80. System.out.println("providerConfig.getProvider() = " + providerConfig.getProvider());
81. System.out.println("ProviderConfig.getServiceName() = " + providerConfig.getServiceName());
82. System.out.println("providerConfig.getWSTrustNamespace() = " + providerConfig.getWSTrustNamespace());
83. System.out.println("ProviderConfig.toString() = " + providerConfig.toString());
84. }
85. 86. private static void showRequestConfigDefaultValue(RequesterConfig requesterConfig) {
87. System.out.println("requesterConfig.getRSTTProperties() = " + requesterConfig.getRSTTProperties());
88. System.out.println("requesterConfig.getSecondaryParameters() = " + requesterConfig.getSecondaryParameters());
89. System.out.println("requesterConfig.getSOAPNamespace() = " + requesterConfig.getSOAPNamespace());
90. System.out.println("requesterConfig.getWSAddressingNamespace() = " + requesterConfig.getWSAddressingNamespace());
91. 92. System.out.println("requesterConfig.getMessageID() = " + requesterConfig.getMessageID());
93. System.out.println("requesterConfig.toString() = " + requesterConfig.toString());
94. }
95. 96. private static void showSAMLToken(SAMLToken samlToken){
97. System.out.println("samlToken.getAssertionQName() = " + samlToken.getAssertionQName());
98. System.out.println("samlToken.getAudienceRestriction() = " + samlToken.getAudienceRestriction());
99. System.out.println("samlToken.getAuthenticationMethod() = " + samlToken.getAuthenticationMethod());
100. System.out.println("samlToken.getConfirmationMethod() = " + samlToken.getConfirmationMethod());
101. System.out.println("samlToken.getId() = " + samlToken.getId());
102. System.out.println("samlToken.getKeyIdentifier() = " + samlToken.getKeyIdentifier());
103. System.out.println("samlToken.getKeyIdentifierEncodingType() = " + samlToken.getKeyIdentifierEncodingType());
104. System.out.println("samlToken.getKeyIdentifierValueType() = " + samlToken.getKeyIdentifierValueType());
105. System.out.println("samlToken.getKeyName() = " + samlToken.getKeyName());
106. System.out.println("samlToken.getPrincipal() = " + samlToken.getPrincipal());
107. System.out.println("samlToken.getProperties() = " + samlToken.getProperties());
108. System.out.println("samlToken.getReferenceURI() = " + samlToken.getReferenceURI());
109. System.out.println("samlToken.getSAMLAttributes() = " + samlToken.getSAMLAttributes());
110. System.out.println("samlToken.getSamlCreated() = " + samlToken.getSamlCreated());
111. System.out.println("samlToken.getSamlExpires() = " + samlToken.getSamlExpires());
112. System.out.println("samlToken.getSamlID() = " + samlToken.getSamlID());
113. System.out.println("samlToken.getSAMLIssuerName() = " + samlToken.getSAMLIssuerName());
114. System.out.println("samlToken.getSAMLNameID() = " + samlToken.getSAMLNameID());
115. System.out.println("samlToken.getStringAttributes() = " + samlToken.getStringAttributes());
116. System.out.println("samlToken.getSubjectDNS() = " + samlToken.getSubjectDNS());
117. System.out.println("samlToken.getSubjectIPAddress() = " + samlToken.getSubjectIPAddress());
118. System.out.println("samlToken.getThumbprint() = " + samlToken.getThumbprint());
119. System.out.println("samlToken.getThumbprintEncodingType() = " + samlToken.getThumbprintEncodingType());
120. System.out.println("samlToken.getThumbprintValueType() = " + samlToken.getThumbprintValueType());
121. System.out.println("samlToken.getTokenQname() = " + samlToken.getTokenQname());
122. System.out.println("samlToken.getValueType() = " + samlToken.getValueType());
123. 124. XMLStructure samlXmlStructure = samlToken.getXML();
125. if (samlXmlStructure != null && samlXmlStructure instanceof OMStructure) {
126. OMStructure samlOMStructure = (OMStructure) samlXmlStructure;
127. System.out.println("((OMStructure)samlToken.getXML()).getNode()formatted = " + formatXML(samlOMStructure.getNode()));
128. }
129. 130. try {
131. InputStream is = samlToken.getXMLInputStream();
132. if (is != null) {
133. try {
134. BufferedReader reader = new BufferedReader(new InputStreamReader(is));
135. StringBuilder sb = new StringBuilder();
136. String line = null;
137. while ((line = reader.readLine()) != null) {
138. sb.append(line + "\n");
139. }
140. System.out.println(sb.toString());
141. } catch (Exception ex) {
142. System.out.println("Caught exception reading from InputStream: " + ex.getMessage());
143. ex.printStackTrace();
144. } finally {
145. try {
146. is.close();
147. } catch (IOException e) {
148. e.printStackTrace();
149. }
150. }
151. }
152. } catch (WSSException wex) {
153. System.out.println("Caught exception getXMLInputStream(): " + wex.getMessage());
154. wex.printStackTrace();
155. }
156. }
157. 158. private static String formatXML(OMElement omInput) {
159. ByteArrayOutputStream out = new ByteArrayOutputStream ();
160. String output = "";
161. 162. try {
163. XMLPrettyPrinter.prettify(omInput, out);
164. output = out.toString();
165. } catch (Throwable e) {
166. try {
167. output = omInput.toString();
168. } catch (Throwable e2) {
169. System.out.println("Caught exception: " + e2.getMessage());
170. e2.printStackTrace();
171. }
172. }
173. return output;
174. }
175. 176. }
Unterstützung der Klasse WSSTrustClient für Richtliniensätze und Bindungen
Die WS-Trust-Clientfunktion unterstützt sowohl anwendungsspezifische Bindungen als auch allgemeine Bindungen für Trust-Client-Richtliniensätze und Bindungsdokumente. Darüber hinaus werden allgemeine Bindungen und Standardbindungen unterstützt, wenn die Anwendung in einer Anwendungsserverumgebung ausgeführt wird. Allgemeine Bindungen werden in der Thin-Client-Umgebung nicht unterstützt, Standardclientbindungen hingegen werden unterstützt.
Die Verwaltung des Richtliniensatzes und der Bindungen für die WS-Trust-Client-API erfolgt ähnlich wie die Verwaltung eines Richtliniensatzes und der Bindungen für einen Web-Service-Client. Allerdings gibt es Abweichungen, die nur für den WS-Trust-Client gelten. Eine Abweichung besteht darin, dass der WS-Trust-Client keine Richtliniensatzzuordnungen verwendet. Statt dessen werden der Richtliniensatzname und der Bindungsname wie in Zeile 36 und 37 des Beispielcodes gezeigt in einem ProviderConfig-Objekt angegeben.
Wenn der WS-Trust-Client nach Bindungen sucht, verwaltet der Client den Suchbereich auf andere Art und Weise als der Web-Service-Client. Wenn Sie die Eigenschaft wstrustClientBindingScope für die Trust-Clientbindung nicht angeben, sucht das System zuerst in der Anwendung nach der anwendungsspezifischen Bindung mit dem angegebenen Bindungsnamen. Wird eine Bindung gefunden, wird sie für die Trust-Clientanforderung verwendet. Wird keine anwendungsspezifische Bindung gefunden, durchsucht das System die verfügbaren allgemeinen Bindungen nach einer Bindung mit dem angegebenen Namen. Wird eine allgemeine Bindung gefunden, wird sie für die Trust-Clientanforderung verwendet. Wird für den angegebenen Namen keine Bindung gefunden, werden in einer Serverumgebung Standardbindungen verwendet. Standardbindungen werden nur in einer Serverumgebung verwendet. Wenn der Bindungsbereich angegeben ist, wird nur dieser Bereich für die Bindungssuche verwendet.
Zeile 38 des Beispielcodes, providerConfig.setBindingScope("domain"), zeigt, dass im Beispiel allgemeine Bindungen verwendet werden. Sie können als Bindungsbereich auch application angeben, um festzulegen, dass der Beispielcode anwendungsspezifische Bindungen verwendet. Das Beispiel verwendet die allgemeine Bindung mit dem Namen SamlTCSample. Sowohl anwendungsspezifische Bindungen als auch allgemeine Bindungen werden im Anwendungsserver und in der Thin-Client-Umgebung unterstützt. Weitere Informationen zur Konfiguration der SamlTCSample-Bindungen, wenn die Anwendung im Anwendungsserver installiert ist, finden Sie in den Artikeln, die sich mit der Konfiguration von Richtliniensätzen und Bindungen für die Kommunikation mit dem STS befassen.
Der Code showProviderConfigDefaultValue(providerConfig) in Zeile 34 des Beispielcodes zeigt die Standardeinstellungen. Der Beispielcode enthält eine Dienstprogrammmethode, die den Inhalt von providerConfig wiedergibt.
Zeile 51 des Beispielcodes, List<SecurityToken> securityTokens = client.issue(providerConfig, requesterConfig), sendet eine WS-Trust-issue-Anforderung. Der zweite Parameter in dieser Zeile gibt das RequesterConfig-Objekt an, und dieser Parameter legt den Inhalt der "issue"-Anforderung fest. Der Code in Zeile 41, RequesterConfig requesterConfig = WSSTrustClient.newRequesterConfig(Namespace.WST13), erstellt eine Instanz des RequesterConfig-Objekts, die verwendet wird, um die Trust-Anforderung mit dem Namespace der WS-Trust Version 1.3 zu erstellen. Eine Dienstprogrammfunktion wird in Zeile 43 gezeigt: showRequestConfigDefaultValue(requesterConfig). Diese Funktion zeigt die Standardeinstellungen für das RequesterConfig-Objekt an. Der Code zwischen den Zeilen 45 und 48 initialisiert das RequesterConfig-Objekt, damit dieses das SAML-Bearer-Token der Version 1.1 anfordert. Dieses Token wird für den Zugriff auf den Serviceendpunkt über den SOAP-1.2-Namespace verwendet. Im Beispiel ist https://user.MyCompany.com:9443/WSSampleSei/EchoService12 der Serviceendpunkt.
Unterstützung von JVM-Argumenten
Vor Ausführung des Beispielcodes müssen Sie mehrere JVM-Argumente definieren (JVM = Java™ Virtual Machine). Der Beispielcode implementiert den Richtliniensatz "Username WSHTTPS default", für den zwei Anforderungen festgelegt sind: 1) ein Benutzernamenstoken wird an den STS gesendet; 2) Nachrichten werden mit Secure Sockets Layer (SSL) gesichert. Um die Umgebung so zu konfigurieren, dass diese Anforderungen erfüllt werden, müssen Sie zunächst mit der Datei ssl.client.props einen Truststore definieren. Schritt-für-Schritt-Anleitungen finden Sie in der Beschreibung der Ausführung nicht verwalteter JAX-WS-Web-Service-Clients.
Um die zweite Anforderung bezüglich des SSL-Nachrichtenschutzes zu erfüllen, erwerben Sie eine Kopie des STS-Zertifikats SSL X.509, und fügen Sie diese in den Truststore ein. Befolgen Sie dabei die Schritte im Artikel über die Verwendung des Befehls "retrieveSigners", um eine Trust-Beziehung zwischen den Servern herzustellen. Alternativ dazu können Sie das STS-Zertifikat akzeptieren, wenn sie die erste Trust-Anforderung an den STS senden, falls die Eigenschaft com.ibm.ssl.enableSignerExchangePrompt in der Datei profile_home/properties/ssl.client.props auf true gesetzt ist. Weitere Informationen zu dieser Option finden Sie im Artikel über die Änderung der Eingabeaufforderung für automatischen Unterzeichneraustausch im Client.
Zusätzlich müssen Sie die Client-JAAS-Konfigurationsdatei angeben, damit die Laufzeitumgebung des Clients die LoginModule-JAAS-Anmeldekonfiguration für das Benutzernamenstoken lokalisieren kann. Geben Sie den Parameter mit diesem Code an: -Djava.security.auth.login.config="%WAS_HOME%\properties\wsjaas_client.conf. Außerdem müssen Sie die Thin-Client-Jar-Datei in den Klassenpfad aufnehmen, z. B. com.ibm.jaxws.thinclient_9.0.jar. Weitere Informationen finden Sie in der Beschreibung der Ausführung nicht verwalteter JAX-WS-Web-Service-Clientanwendungen.
Ausführung des Beispielcodes
Voraussetzung für die Ausführung des Beispielcodes ist die Definition eines externen STS-Endpunkts zum Ausstellen eines SAML-1.1-Bearer-Tokens für die angegebenen Web-Services gemäß der Festlegung in der Eigenschaft RequesterConfiguration.RSTT.APPLIESTO_ADDRESS.
177. <?xml version="1.0" encoding="UTF-8"?><soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope">
178. <soapenv:Header>
179. <wsa:To xmlns:wsa="http://www.w3.org/2005/08/addressing">https://user.MyCompany.com/Trust/13/UsernameMixed</wsa:To>
180. <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">urn:uuid:4951B6775950CAC92A1252458259166</wsa:MessageID>
181. <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://docs.oasis-open.org/ws-sx/ws-trust/200512/RST/Issue</wsa:Action>
182. </soapenv:Header>
183. <soapenv:Body>
184. <wst:RequestSecurityToken xmlns:wst="http://docs.oasis-open.org/ws-sx/ws-trust/200512">
185. <wst:TokenType>http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV1.1</wst:TokenType>
186. <wst:RequestType>http://docs.oasis-open.org/ws-sx/ws-trust/200512/Issue</wst:RequestType>
187. <wst:KeyType>http://docs.oasis-open.org/ws-sx/ws-trust/200512/Bearer</wst:KeyType>
188. <wsp:AppliesTo xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy">
189. <wsa:EndpointReference xmlns:wsa="http://www.w3.org/2005/08/addressing">
190. <wsa:Address>https://user.MyCompany.com:9443/WSSampleSei/EchoService12</wsa:Address>
191. </wsa:EndpointReference>
192. </wsp:AppliesTo>
193. </wst:RequestSecurityToken>
194. </soapenv:Body>
195. </soapenv:Envelope>
- -DtraceSettingsFile=MyTraceSettings.properties
- -Djava.util.logging.manager=com.ibm.ws.bootstrap.WsLogManager
- -Djava.util.logging.configureByServer=true
SAML-Tokenrückgabe
196. <?xml version="1.0" encoding="UTF-8"?>
197. <saml:Assertion xmlns:saml="urn:oasis:names:tc:SAML:1.0:assertion" MajorVersion="1" MinorVersion="1"
198. AssertionID="_f7f65d28-fbb1-4e10-8ddf-f4b6ed0c8277" Issuer="http://MyCompany.com/Trust"
199. IssueInstant="2009-09-09T01:04:41.144Z">
200. <saml:Conditions NotBefore="2009-09-09T01:04:41.141Z" NotOnOrAfter="2009-09-09T11:04:41.141Z">
201. <saml:AudienceRestrictionCondition>
202. <saml:Audience>https://user.MyCompany.com:9443/WSSampleSei/EchoService12</saml:Audience>
203. </saml:AudienceRestrictionCondition>
204. </saml:Conditions>
205. <saml:AuthenticationStatement AuthenticationMethod="urn:oasis:names:tc:SAML:1.0:am:password"
206. AuthenticationInstant="2009-09-09T01:04:41.131Z">
207. <saml:Subject>
208. <saml:SubjectConfirmation>
209. <saml:ConfirmationMethod>urn:oasis:names:tc:SAML:1.0:cm:bearer</saml:ConfirmationMethod>
210. </saml:SubjectConfirmation> 211. </saml:Subject>
212. </saml:AuthenticationStatement>
213. <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
214. <ds:SignedInfo>
215. <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
216. <ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
217. <ds:Reference URI="#_f7f65d28-fbb1-4e10-8ddf-f4b6ed0c8277">
218. <ds:Transforms>
219. <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
220. <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
221. </ds:Transforms>
222. <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
223. <ds:DigestValue>AQ6e7YQqKgcg/B/ebBj8/DF+uWg=</ds:DigestValue>
224. </ds:Reference>
225. </ds:SignedInfo>
226. <ds:SignatureValue>SuccIOniR . . . . yjTh9iQs=</ds:SignatureValue>
227. <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
228. <X509Data>
229. <X509Certificate>MIIB3zCCAUi . . . . itzymqg3</X509Certificate>
230. </X509Data>
231. </KeyInfo>
232. </ds:Signature>
233. </saml:Assertion>