TL;DR: Can anyone find an authority on which signature algorithms are supported by Saml2SecurityTokenHandler during validation?
I'm using a Saml2SecurityTokenHandler to verify SAML assertions from my IdP.
For reference, I am using a sample assertion signed with SHA256 found here
<Assertion ID="_de9f29bd-52ca-4237-95c1-eb53f70fe8e5" IssueInstant="2012-11-06T00:45:30.593Z" Version="2.0" xmlns="urn:oasis:names:tc:SAML:2.0:assertion">
<Issuer>ADatum</Issuer>
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:SignedInfo>
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
<ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256" />
<ds:Reference URI="#_de9f29bd-52ca-4237-95c1-eb53f70fe8e5">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" />
<ds:DigestValue>+6OWUn1dFIUJQ6FQ25zgmZvg8zPzfcjnj4ujUvgfmEQ=</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>O85ytS9fcAhOk/0K25SndyBUbNLrx6J+tv+Uht+HZZ4CzsqjVBU1FpkXjDG03HqZ7xEu3+rMnsyxefDq6Xftw1E926QsG/oPM/afWfbR5dLucjsVaNzXCXzZu+jBmp5KkAv/vv1Es67KnPMr/RDeCVFy9eyxJka6dd8h8RTlatg=</ds:SignatureValue>
<KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
<X509Data>
<X509Certificate>MIICGjCCAYOgAwIBAgIQeJe5qR+4T6VJNZYtWjhErzANBgkqhkiG9w0BAQQFADAgMR4wHAYDVQQDExVBQ1MyQ2xpZW50Q2VydGlmaWNhdGUwHhcNMTExMDEwMDcwMDAwWhcNNDExMjMxMDcwMDAwWjAgMR4wHAYDVQQDExVBQ1MyQ2xpZW50Q2VydGlmaWNhdGUwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAKjtrnJ+bduREosQ9+SH1ocI13wlxStLi8y5heGPo5UBcuf0hYRq4PvjwEY2twebP6iwxjwGqhu224UDUfPWMhQBOh+NFnv9GHAh+W4jFJxvTCcyXTkZRFqgAYRjMvyxzNeHVqn4AJ/ddKGf1fMVCuKhPYteHy2yNacXujucPP6/AgMBAAGjVTBTMFEGA1UdAQRKMEiAEFD3/7uhGcI2nSHZqB0bN66hIjAgMR4wHAYDVQQDExVBQ1MyQ2xpZW50Q2VydGlmaWNhdGWCEHiXuakfuE+lSTWWLVo4RK8wDQYJKoZIhvcNAQEEBQADgYEAkgxktVU5e8TVoigsDRm4qyw6gM/kie3e6dFM0T1BFoQV0PW9W9yKPiP72eTi+331tLFnwDxz5RJLABctAO71plwtREd0k3E0Jsju+Web+u8YcCD43aViQXgXRrY5ghDGwpFRcaNa1PnYY5nk3DYfyZZdz1L+fb30VDiugdf7dBI=</X509Certificate>
</X509Data>
</KeyInfo>
</ds:Signature>
<Subject>
<NameID>ADatum</NameID>
<SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer" />
</Subject>
<Conditions NotBefore="2012-11-06T00:45:31.905Z" NotOnOrAfter="9999-12-31T23:59:59.999Z">
<AudienceRestriction>
<Audience>https://accesscontrol.adatum.com</Audience>
</AudienceRestriction>
</Conditions>
<AttributeStatement>
<Attribute Name="http://schemas.microsoft.com/spf/2012/03/claims/tenantname">
<AttributeValue>Fabrikam</AttributeValue>
</Attribute>
</AttributeStatement>
<AttributeStatement>
<Attribute Name="http://schemas.microsoft.com/ws/2008/06/identity/claims/role">
<AttributeValue>SSU</AttributeValue>
</Attribute>
</AttributeStatement>
<AttributeStatement>
<Attribute Name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn">
<AttributeValue>accesscontrol#adaum.com</AttributeValue>
</Attribute>
</AttributeStatement>
I have the following code attempting to verify this signature
//All that matters now is to validate the token and get the claims
var validationParameters = new TokenValidationParameters();
validationParameters.ValidIssuer = options.Issuer;
validationParameters.ValidAudience = options.Audience;
validationParameters.IssuerSigningToken = new X509SecurityToken(options.SigningCertificate);
validationParameters.ValidateLifetime = validateLifetime;
validationParameters.TokenReplayCache = options.ReplayRepository;
EnsureCanonicalForm(response, assertion);
SecurityTokenHandlerCollection coll = SecurityTokenHandlerCollectionExtensions.GetDefaultHandlers();
SecurityToken tokenOut;
var retVal = coll.ValidateToken(assertion.OuterXml, validationParameters, out tokenOut);
options.SigningCertificate is the certificate you can see in the XML starting with MII.... assertion.OuterXml is the entire contents of the XML above.
I was expecting the SAML2SecurityTokenHandler to handle SHA256, but this code fails on ValidateToken() with the error
The signature verification failed.
I know the code works for SHA1 using the same code with a different assertion sample.
I wasn't able to find any mention of signing algorithms in the documentation around either the handler or the token itself, but at least one of the specs for XML signature hashing does call-out SHA256.
Can anyone find an authoritative source on which signature algorithms are supported by this class?
The Saml2SecurityTokenHandler doesn't handle white spaces correctly when validating the signature. In most cases it doesn't matter as assertions are rarely pretty printed. But this one is. So I guess that's the problem.
For the SAML library I've created we completely skip the signature validation in the handler and do our own based on SignedXml instead, which is more reliable (although you need to remember to check the references yourself).
Related
I need some help to consume a web service using SOAP.
My application use .NET 4.0.
The SOAP request have to follow the following requirments :
Transport protocol : HTTPS
Encryption and authentication is carried out via SSL v3/TLS v1.0
The message need to be signed. (WS-Security 1.1, http://www.w3.org/TR/2002/REC-xml-exc-c14n-20020718, PKCS#1 v1.5, RSA-SHA256)
I have to use two differents certificats for encryption and signing.
The WCF configuration should be configurable (the signature can be desactivated). So the bindings have to be created in c# code and not in app.config.
Sample of request expected by the server :
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope">
<s:Header>
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#" Id="SIG-C6D119F21B41F79DBF154885449980234">
<ds:SignedInfo>
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
<ec:InclusiveNamespaces xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#" PrefixList="s" />
</ds:CanonicalizationMethod>
<ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256" />
<ds:Reference URI="#id-5">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
<ec:InclusiveNamespaces xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#" PrefixList="" />
</ds:Transform>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" />
<ds:DigestValue>...</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>...</ds:SignatureValue>
<ds:KeyInfo Id="KI-C6D119F21B41F79DBF154885449979232">
<wsse:SecurityTokenReference wsu:Id="STR-C6D119F21B41F79DBF154885449979233">
<ds:X509Data>
<ds:X509IssuerSerial>
<ds:X509IssuerName>CN=..,O=...,C=..</ds:X509IssuerName>
<ds:X509SerialNumber>...</ds:X509SerialNumber>
</ds:X509IssuerSerial>
</ds:X509Data>
</wsse:SecurityTokenReference>
</ds:KeyInfo>
</ds:Signature>
</wsse:Security>
</s:Header>
<s:Body xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="id-5">
...
</s:Body>
</s:Envelope>
My first attempt was to generate and send the request using WCF but I didn't find out how to generate something following the requirement.
Then I try to generate the signature manually and use an IClientMessageFormatter and a IEndpointBehavior to create the header manualy.
This solution didn't work because WCF applies treatments (switching xml attributes and namespaces...) that invalidates the signature.
My last attempt was to completly remove WCF and send the request manualy but HttpClient is not available in .NET 4.0 and I didn't find out how to send TLS request without it.
Can anyone tell me how to configure WCF to generate the right SOAP request ?
If the request can't be created with WCF, how can I send TLS request (and handle a responce) with .NET 4.0?
Thanks.
As far as I know, header could be configured in web.config or app.config.
<endpoint address="http://ws-wuxipc-5077:4000/calculator" binding="basicHttpBinding"
contract="ServiceInterface.ICalculatorService" name="cal">
<headers>
<Security xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<wsse:UsernameToken xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<wsse:Username>
</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest">monMonDePasse</wsse:Password>
<wsse:Nonce>sdsdsdlojhfdsdM5Nw==</wsse:Nonce>
<wsu:Created>2019-01-21T6:17:34Z</wsu:Created>
</wsse:UsernameToken>
</Security>
</headers>
</endpoint>
You could also add header in your code through xml.
using (ChannelFactory<ICalculatorService> ChannelFactory = new ChannelFactory<ICalculatorService>("cal"))
{
// ChannelFactory.Endpoint.EndpointBehaviors.Add(new MyEndpointBehavior());
ICalculatorService employeeService = ChannelFactory.CreateChannel();
using (OperationContextScope scope = new OperationContextScope((IContextChannel)employeeService))
{
System.Xml.XmlDocument document = new XmlDocument();
XmlElement element = document.CreateElement("wsse", "UsernameToken", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");
XmlElement newChild = null;
newChild = document.CreateElement("wsse", "Username", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");
newChild.InnerText = "finance";
element.AppendChild(newChild);
newChild = document.CreateElement("wsse", "password", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");
newChild.SetAttribute("Type", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest");
newChild.InnerText = "387";
element.AppendChild(newChild);
MessageHeader messageHeader = MessageHeader.CreateHeader("security", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd", element, false);
OperationContext.Current.OutgoingMessageHeaders.Add(messageHeader);
employeeService.Add(5, 6);
}
// List<Employee> list= employeeService.GetList();
Console.Read();
}
I have to use a webservice that requires me to sign the SOAP Header, the resulting XML must look like this:
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header>
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" SOAP-ENV:mustUnderstand="1">
<wsse:BinarySecurityToken xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" wsu:Id="CertId-869FA65AC981B550EF133970680723210" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">MIID0jCCArqgAwIBAgIBBDANBgkqhkiG9w0B...(long Base64 string here)...4a7AXPA==</wsse:BinarySecurityToken>
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#" Id="Signature-7">
<ds:SignedInfo>
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
<ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
<ds:Reference URI="#id-8">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<ds:DigestValue>i6nAseheCMiozKeQRwlJsUDlV8A=</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>
i9v0zDtvxu9mH+iPfYoiLL30vMrfgHlcIr9UOtIX1+QcM+nBL0jI+JFcYlNUVgzIFddn/RYxSiGK
4/amTXHIKxeyI2E/UnX/ajX70t1Pv0boM/i6klZScxmsncgX05ZOQ1AIMLtkSSclK6/vzCFReOmJ
R6WQs+axGAjF39AqdCQ=
</ds:SignatureValue>
<ds:KeyInfo Id="KeyId-869FA65AC981B550EF133970680723311">
<wsse:SecurityTokenReference xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="STRId-869FA65AC981B550EF133970680723312" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<wsse:Reference URI="#CertId-869FA65AC981B550EF133970680723210" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"/>
</wsse:SecurityTokenReference>
</ds:KeyInfo>
</ds:Signature>
</wsse:Security>
</SOAP-ENV:Header>
<SOAP-ENV:Body xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="id-8">
<XmlContent>Some content here</XmlContent>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Of course, I must sign it following the OASIS specification (http://docs.oasisopen.
org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0.pdf).
But I have no idea of where I should start. I'm already able to sign a XML tag, but I never had to sign the SOAP message header following the OASIS specification.
All I need to worry is about creating the SOAP XML message and sign its header, the process of actually sending the SOAP message to the webservice is another thing. We can't consume the webservice directly in Visual Studio, that's why I'm not asking how to actually send it, I just have to create the SOAP message.
Yes, I already have the client's certificate and password, which I can instantiate like this:
X509Certificate2 certificate = new X509Certificate2(this.PfxLocation, this.PfxPassword);
I suppose I must create the header string manually, including the wsse:security and all the strings. But as I already said before, I have no idea where to start, where do I get the BinarySecurityToken, how do I add the ds namespace in the signature, among other things.
So, where could I start to resolve this problem? Is there already a solution in C# that I can use?
I am working on sending an XML message to a government agency (using that government agency's specifications, so I have no control over what the resulting XML needs to look like), and I am using C# for my development (company policy).
Two people that are far better than myself with C# and internet technologies reviewed the XML before I did, and informed me that WCF would not support the methods that were required to generate the signature on the XML document (this was a bit of a relief, since I haven't developed any WCF projects, and frightening, since I understand WCF be a mature web technology).
So, I ended up using a combination of LINQ to XML and System.Xml to generate the message, and attempt to sign it.
Here's a bit of a trimmed down sample of the XML:
<soapenv:Envelope
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:soap-sec="http://schemas.xmlsoap.org/security/2000-12"
xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy"
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"
xmlns:cns="http://customNamespace1.com"
xmlns:cnt="http://customNamespace2.com"
>
<soapenv:Header>
<ns2:Element1 xmlns:ns2="http://namespace2.element1.com" wsu:Id="id-1">
...
</ns2:Element1>
<ns2:Element2 xmlns:ns2="http://namespace2.element2.com/" wsu:Id="id-2">
...
</ns2:Element2>
<wsse:Security SOAP-ENV:mustUnderstand="1" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<wsu:Timestamp wsu:Id="id-3">
...
</wsu:Timestamp>
<wsse:UsernameToken wsu:Id="id-4">
...
</wsse:UsernameToken>
<wsse:BinarySecurityToken ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="SecurityToken-5bf699c7-5336-4695-b395-88d2b984fe54" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
...
</wsse:BinarySecurityToken>
<ds:Signature Id="SIG-6" xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:SignedInfo>
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
<ec:InclusiveNamespaces PrefixList="SOAP-ENV cnt soap-sec soapenv sp cns wsdl wsp wsse wsu xs xsi" xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#" />
</ds:CanonicalizationMethod>
<ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
<ds:Reference URI="#id-1">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
<ec:InclusiveNamespaces PrefixList="SOAP-ENV cnt soap-sec soapenv sp cns wsdl wsp wsse wsu xs xsi" xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#" />
</ds:Transform>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" />
<ds:DigestValue>...</ds:DigestValue>
</ds:Reference>
<ds:Reference URI="#id-2">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
<ec:InclusiveNamespaces PrefixList="SOAP-ENV cnt soap-sec soapenv sp cns wsdl wsp wsse wsu xs xsi" xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#" />
</ds:Transform>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" />
<ds:DigestValue>...</ds:DigestValue>
</ds:Reference>
<ds:Reference URI="#id-3">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
<ec:InclusiveNamespaces PrefixList="SOAP-ENV cnt soap-sec soapenv sp cns wsdl wsp wsse xs xsi" xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#" />
</ds:Transform>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" />
<ds:DigestValue>...</ds:DigestValue>
</ds:Reference>
<ds:Reference URI="#id-4">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
<ec:InclusiveNamespaces PrefixList="SOAP-ENV cnt soap-sec soapenv sp cns wsdl wsp wsu xs xsi" xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#" />
</ds:Transform>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" />
<ds:DigestValue>...</ds:DigestValue>
</ds:Reference>
<ds:Reference URI="#id-5">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
<ec:InclusiveNamespaces PrefixList="SOAP-ENV cnt soap-sec sp cns wsdl wsp wsse wsu xs xsi" xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#" />
</ds:Transform>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" />
<ds:DigestValue>...</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>
...
</ds:SignatureValue>
<ds:KeyInfo Id="KI-ABDCFEC7595B7819C213402151542862">
<wsse:SecurityTokenReference wsu:Id="STR-ABDCFEC7595B7819C213402151542863">
<wsse:Reference URI="#SecurityToken-5bf699c7-5336-4695-b395-88d2b984fe54" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" />
</wsse:SecurityTokenReference>
</ds:KeyInfo>
</ds:Signature>
</wsse:Security>
</soapenv:Header>
<soapenv:Body wsu:Id="id-5">
<ns5:bodyelement xmlns:ns4="http://namespace4.com/" xmlns:ns3="http://namespace3.com/" xmlns:ns2="http://bodynamespace2.com/" xmlns:ns5="http://namespace5.com/">
...
</ns5:bodyelement>
</soapenv:Body>
</soapenv:Envelope>
Here is some of the code that I have been trying (3 different methods for trying to get the uri fragment to work). I am only posting a portion of the code here, since it took over 200 lines of code to generate the appropriate XML, which I am now attempting to sign:
RSACryptoServiceProvider rsacsp = (RSACryptoServiceProvider)Key;
SignedXml xmlWSig = new SignedXml(myDoc);
xmlWSig.SigningKey = Key;
xmlWSig.SignedInfo.CanonicalizationMethod = SignedXml.XmlDsigExcC14NTransformUrl;
XmlDsigExcC14NTransform canMethod = (XmlDsigExcC14NTransform)xmlWSig.SignedInfo.CanonicalizationMethodObject;
canMethod.InclusiveNamespacesPrefixList = "SOAP-ENV cns soap-sec soapenv sp cnt wsdl wsp wsse wsu xs xsi";
Uri uri = new Uri("#id-1");
Reference ref1 = new Reference(uri.ToString());
XmlDsigExcC14NTransform transform1 = new XmlDsigExcC14NTransform("SOAP-ENV cns soap-sec soapenv sp cnt wsdl wsp wsse wsu xs xsi");
ref1.AddTransform(transform1);
ref1.DigestMethod = "http://www.w3.org/2001/04/xmlenc#sha256";
xmlWSig.AddReference(ref1);
Reference ref2 = new Reference("#id-2");
XmlDsigExcC14NTransform transform2 = new XmlDsigExcC14NTransform("SOAP-ENV cns soap-sec soapenv sp cnt wsdl wsp wsse wsu xs xsi");
ref2.AddTransform(transform2);
ref2.DigestMethod = "http://www.w3.org/2001/04/xmlenc#sha256";
xmlWSig.AddReference(ref2);
Reference ref3 = new Reference("");
ref3.Uri = "#id-3";
XmlDsigExcC14NTransform transform3 = new XmlDsigExcC14NTransform("SOAP-ENV cns soap-sec soapenv sp cnt wsdl wsp wsse xs xsi");
ref3.AddTransform(transform3);
ref3.DigestMethod = "http://www.w3.org/2001/04/xmlenc#sha256";
xmlWSig.AddReference(ref3);
//repeat things for id-4, and id-5
KeyInfo myKeyInfo = new KeyInfo();
myKeyInfo.AddClause(new RSAKeyValue((RSA)Key));
xmlWSig.KeyInfo = myKeyInfo;
xmlWSig.ComputeSignature();
XmlElement signedXmlElement = xmlWSig.GetXml();
Key is the private key grabbed from the X509 Certificate (and is what should be used as the key to sign the document). myDoc is the System.Xml XmlDocument that I have generated that I need to insert the signature into.
Method #1 Gives me a System.UriFormatException: Invalid URI: The Format of the URI could not be determined.
Method #2 Gives me a System.Security.Cryptography.CryptograpicException: Malformed reference element (if I drop the # from the Uri, it gives me a System.UriFormatException: Invalid URI: The URI is empty).
Method #3 Gives me the same errors as Method #2.
From all of the documentation on using Uris for signatures, using just a Uri Fragment is allowed (assuming that the element being referenced is inside the same document), but the Uri class in C# doesn't seem to accept Fragments as an acceptable Uri.
The Reference class also seems to be requiring the full Uri, and not just a Fragment.
I'm open to any suggestions for how I can properly generate the signature in this XML using the specifications.
UPDATE: While the SignedXml + Reference + Transform seems like the best solution, I'm now beginning to believe that .NET has a major gap in these libraries, and dropping down to some lower-level libraries in order to generate the signature might be necessary.
Unfortunately, I'm still struggling with trying to tell what libraries would be needed and the algorithm for finding what needs to be signed. My understanding of the Exclusive Canonicalization was that you were only signing the elements specified by the prefixes listed in the InclusiveNamespaces PrefixList, but the URI in the Reference specifies the sub-document that the signature should be over, but the elements inside the specified elements don't use most of the included namespaces. Am I understanding the way that these References are supposed to work?
Looks like I may have to duplicate the algorithm of doing the URI + the Inclusive Namespaces for myself (still need to figure out how that will work), and convert those elements into byte arrays. Then use lower-level libraries for signatures.
Something like this:
RSACryptoServiceProvider rsa = (RSACryptoServiceProvider)cert.PrivateKey;
signedMessage = rsa.SignData(originalMessage, CryptoConfig.MapNameToOID("SHA1"));
Then, signedMessage can be converted into a Base64 string, and inserted into each of the appropriate Digest Values.
A lot more work than I had hoped for, but if .NET doesn't support URI Fragments, I guess I have to do what I have to do.
Due to the complexity of this solution, I'm definitely open to alternatives if anybody has something smoother.
EDIT: After several hours of pouring over the canonicalization documentation, it looks like the exclusive canonicalization is more about what namespaces you insert into the XML when ripping it out to sign it. If the namespace isn't directly used, and isn't included in the inclusive namespace prefix list, you don't add that namespace to the elements that you are signing prior to signing them. This still seems odd to me, since you don't necessarily want that namespace in the element inside the fuller context of the XML, and signing it means that it can't change, but you're not including it.
UPDATE: after many hours of testing, I did finally get this to work. But it had lots, and lots of very hideous code. Essentially, I had to pull each element that we were signing out into a copy, and manually update the namespaces that were included in that element, and then generate the hash from that (including performing the more complete transform at this time). But it did work.
Turns out that the reason .NET wasn't accepting it was because of the wsu namespace prefix.
flipping the wsu:Id= to be just id= was able to generate the signature at least.
Then, I came across this:
'Malformed Reference Element' when adding a reference based on an Id attribute with SignedXml class
This used drastically less code than my previous answer to develop, and is much easier to read/maintain.
I was assigned to create a client for a web service. I have no previous experience with web services and I have been trying with no success.
The web service is hosted at https://ws.conf.ebs.health.gov.on.ca:1441/EDTService/EDTService
I was able to create the proxy classes with Visual Studio 2012 and create a basic client that was rejected by the service since it did not include any of the security specifications that the services require.
The following are extract from the documentation, that is available at http://www.health.gov.on.ca/en/pro/publications/ohip/default.aspx
The WS-Security section includes:
Technical specifications of the WSS 1.1
• Identity requirements;
• Signing requirements ;
• Encryption requirements; and
• Time stamps
IDP
To ensure confidentiality and integrity of sensitive information within the message, sender software must use public key technology to sign the SOAP headers and body.
The signing certificate can be any available certificate and can be self signed.
If any response data is specified to be encrypted, by the specific web service technical specification, the data will be encrypted using, at least, the AES128-CBC symmetric encryption algorithm with the public key belonging to the signer of the initial SOAP request. The encryption algorithm may be increased based on the specific web service technical specification.
My goal is to create a wcf client that can access this service. So far this is what I have done and it does not work:
This example tries to upload a file to the server:
EndpointAddress address = new EndpointAddress("https://ws.conf.ebs.health.gov.on.ca:1441/EDTService/EDTService");
//MCEDT userID and password
string userId = "abcdefg";
string password = "password";
//MOH Id
string mohId = "123456";
//Vendor Conformance Key
string key = "1234abcd-eeee-aaaa-ffff-abcdef123456";
public void upload()
{
Console.WriteLine("Uploading....");
//Specify the binding to be used for the client.
WSHttpBinding binding = new WSHttpBinding(SecurityMode.TransportWithMessageCredential);
binding.SendTimeout = new TimeSpan(0, 10, 0);
UsernameToken ut = new UsernameToken(userId, password, PasswordOption.SendHashed);
EDTDelegateClient client = new EDTDelegateClient(binding,address);
//Capture before send and after receive events
client.Endpoint.Behaviors.Add(new InspectorBehavior());
ebs_header EBS = new ebs_header();
EBS.AuditId = "123456789";
EBS.SoftwareConformanceKey = confomanceKey;
//The MCEDT service will only support the IDP security model in its first release.
idp_header IDP = new idp_header();
IDP.ServiceUserMUID = mohId;
msa_header MSA = new msa_header();
MSA.UserID = userId;
//data to upload
//sample claim provided by OHIP
uploadData data = new uploadData();
data.description = claim_file;
data.content = File.ReadAllBytes(#"..\..\" + claim_file);
uploadRequest ur = new uploadRequest();
ur.upload = new uploadData[1];
ur.upload[0] = data;
try
{
resourceResult result = client.upload(EBS, MSA, IDP, ur.upload);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
}
I I believe that what I have done so far is in line with the technical requirements:
" The electronic system constructs a SOAP message using appropriate values and inserts the EBS and IDP headers into the SOAP message header with the user name and password (for the IDP in a WS-Security Username token). The SOAP headers and body are then digitally signed to guarantee message integrity and source. If any request data is specified to be encrypted, by the specific web service technical specification, it will use the public key of the EBS system."
but I don't know how to sign the headers and body and how to encrypt the data.
The certificates are provided with all the technical specifications and we have the proper information for user and password. It is only my lack of knowledge what is stopping to finish this project.
Thanks in advance to the community for the help.
Edit #1: Sample Message from Docs:
<soapenv:Envelope
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:msa="http://msa.ebs.health.ontario.ca/"
xmlns:idp="http://idp.ebs.health.ontario.ca/"
xmlns:edt="http://edt.health.ontario.ca/"
xmlns:ebs="http://ebs.health.ontario.ca/">
<soapenv:Header>
<ebs:EBS wsu:Id="id-4"
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<SoftwareConformanceKey>444361ee-277f-7732-c684-7a9923jfgh1b</SoftwareConformanceKey>
<AuditId>124355467675</AuditId>
</ebs:EBS>
<idp:IDP wsu:Id="id-3"
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<ServiceUserMUID>1111222</ServiceUserMUID>
</idp:IDP>
<wsse:Security soapenv:mustUnderstand="1"
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<wsse:BinarySecurityToken
EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary"
ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3"
wsu:Id="X509-04FD51796CB607011413612828891871">MIIF0zCCBLugAwIBAgIBAjANBgkqhkiG9w0BAQUFADCBzzELMAkGA1UEBhMCQ0ExCzAJBgNVBAgTAm9uMREwDwYDVQQHEwhraW5nc3RvbjEpMCcGA1UEChMgSGVhbHRoIFNvbHV0aW9ucyBEZWxpdmVyeSBCcmFuY2gxJTAjBgNVBAsTHEVsZWN0cm9uaWMgQnVzaW5lc3MgU2VydmljZXMxJzAlBgNVBAMTHkVCUyBUZXN0IENlcnRpZmljYXRlIEF1dGhvcml0eTElMCMGCSqGSIb3DQEJARYWc2Vhbi5jYXJzb25Ab250YXJpby5jYTAeFw0xMjA0MjkxNjAyMjNaFw0xNDA0MzAxNjAyMjNaMIGUMQswCQYDVQQGEwJDQTELMAkGA1UECBMCb24xETAPBgNVBAcTCGtpbmdzdG9uMSkwJwYDVQQKEyBIZWFsdGggU29sdXRpb25zIERlbGl2ZXJ5IEJyYW5jaDElMCMGA1UECxMcRWxlY3Ryb25pYyBCdXNpbmVzcyBTZXJ2aWNlczETMBEGA1UEAxQKRUJTX0NsaWVudDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMEEvvZ96t117651bJXIa8AaE69N1klliJvhrXFxtV2JcKoJHZG19Em6nFtxznvrfjHjQCOJXgREq0YLJmIHgIaIggug9g4oZhZoSXm11b0k+l9sI0uV1UQxSPvKZbptLw3JuY3E8iHoBTBY4TZDg0yfuuk5kpwT0JCqn8Pcoi2Oq2rQtEdnQ0TG5/lofJAMDRzBpK1ETnNOjzCeAkR3wHPec++q2nTuY9QFYntpOyk5JksRVuuIsR5OCW6rjFXTF7CJ84qxWloXmWl4M3yKDTi3ouD36Gplgo8fi2HLpNqVBDLCm7Acv8klkc0EyiFOpBzhEYWAVIIwC9ovybXRjg0CAwEAAaOCAfEwggHtMAkGA1UdEwQCMAAwEQYJYIZIAYb4QgEBBAQDAgSwMEsGCWCGSAGG+EIBDQQ+FjxTU0wgQ2xpZW50IGNlcnRpZmljYXRlIHZhbGlkIG9ubHkgZm9yIE1PSExUQy9IU0MgRUJTIFRlc3RpbmcwHQYDVR0OBBYEFKV6tGi2SztsTcIPYFkZcKr4yLJMMIIBBAYDVR0jBIH8MIH5gBT/qI53Ggvfsdz34whLQ2gDg+PhW6GB1aSB0jCBzzELMAkGA1UEBhMCQ0ExCzAJBgNVBAgTAm9uMREwDwYDVQQHEwhraW5nc3RvbjEpMCcGA1UEChMgSGVhbHRoIFNvbHV0aW9ucyBEZWxpdmVyeSBCcmFuY2gxJTAjBgNVBAsTHEVsZWN0cm9uaWMgQnVzaW5lc3MgU2VydmljZXMxJzAlBgNVBAMTHkVCUyBUZXN0IENlcnRpZmljYXRlIEF1dGhvcml0eTElMCMGCSqGSIb3DQEJARYWc2Vhbi5jYXJzb25Ab250YXJpby5jYYIJAOnNHCT34+b/MCEGA1UdEgQaMBiBFnNlYW4uY2Fyc29uQG9udGFyaW8uY2EwJgYDVR0RBB8wHYEbZGVyZXlrLmZlcm5hbmRlc0BvbnRhcmlvLmNhMA4GA1UdDwEB/wQEAwIFoDANBgkqhkiG9w0BAQUFAAOCAQEAJqCht181F8rUUNQ8jHa42kdKH+FDF0ISuklbg5MARHo+wt1laltaMeaXdESnLJBNGvcgxPZ4StYMdCH8mOEWYftCy5nkyGQCuOd2GpaJ3Hj50bjZ9vZUYyUBPUmwIEP2v75QQe62fHTqza/VjA0I5eMGMKa3URHsTdfNdnEJjtmHdxWRjAjjrHpHQWE0e1QtG+ZV1ved0f5OzDvdylbvrm4S0mgCifk8qEvZtNSoDp37MmSFr5fFmo91BqT23xAgzUKra428dw4T1EKJYEd6pNssNS4XCQ6bTx0Au3mW5iINtiaYQP8rlSykwaJ+dFAtBG00kdGpebf1prvq4H91eA==</wsse:BinarySecurityToken>
<ds:Signature Id="SIG-6" xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:SignedInfo>
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
<ec:InclusiveNamespaces PrefixList="ebs edt idp msa soapenv"
xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</ds:CanonicalizationMethod>
<ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
<ds:Reference URI="#UsernameToken-2">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
<ec:InclusiveNamespaces PrefixList="ebs edt idp msa soapenv"
xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</ds:Transform>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" />
<ds:DigestValue>peTHpiEd5ujPqxNuKGN0k4p7up8c0dFPuRXbpQ+eMwI=</ds:DigestValue>
</ds:Reference>
<ds:Reference URI="#TS-1">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
<ec:InclusiveNamespaces PrefixList="wsse ebs edt idp msa soapenv"
xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</ds:Transform>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" />
<ds:DigestValue>DqLqNQVHwzHRx7amwoYxEMwxN2g0/rND2I13WPP1Vhw=</ds:DigestValue>
</ds:Reference>
<ds:Reference URI="#id-3">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
<ec:InclusiveNamespaces PrefixList="ebs edt msa soapenv"
xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</ds:Transform>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" />
<ds:DigestValue>K4IrndAA4zBmkumIfgKcluiKA8dmzwgGdKo5aq45LHg=</ds:DigestValue>
</ds:Reference>
<ds:Reference URI="#id-4">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
<ec:InclusiveNamespaces PrefixList="edt idp msa soapenv"
xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</ds:Transform>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" />
<ds:DigestValue>o92xRJQNwGz0Hv7DX87vSYUScX0qHL/bFGE3GmtUzQg=</ds:DigestValue>
</ds:Reference>
<ds:Reference URI="#id-5">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
<ec:InclusiveNamespaces PrefixList="ebs edt idp msa"
xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</ds:Transform>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" />
<ds:DigestValue>svNyvvP+MrjIYlZFsg+bgw//8IPNVvIO9px3vYUfW3I=</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>
qDSZlgY/aTFOzzo1C4tx+1E8ertrbmBySRxEK6sJ1JCt/77TLV5PBGnAme9Ttdmzf6h7/qb4rBGL 76LM0PaCQ9xm3DTsSQOz/So82G+/kX8M9TPY9D44+dvlB+cXm9rPn2BLMSVwtJf0kwI22SmRzMTR 6a6jfNYkGga6ZwZC9NLfG5/KTvsyZ39vOdO3T5GYc15RSjHKVBggoWmKm7x5PHrhU+3gClEbtHP8+Fgmmd9PJOtl9WunzR7NpY79xRNGxmDmL8hLvE4+uIc//b6TvrbGB2t8IWb5e5Wdz+ssHgMm0802 wFwGXlVxvSHpEJroHz5OvRgh7PKGlUSZP9fWkg==
</ds:SignatureValue>
<ds:KeyInfo Id="KI-04FD51796CB607011413612828892812">
<wsse:SecurityTokenReference wsu:Id="STR-04FD51796CB607011413612828892813">
<wsse:Reference
URI="#X509-04FD51796CB607011413612828891871"
ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" />
</wsse:SecurityTokenReference>
</ds:KeyInfo>
</ds:Signature>
<wsse:UsernameToken wsu:Id="UsernameToken-2">
<wsse:Username>johndoe#examplemail.com</wsse:Username>
<wsse:Password
Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">****</wsse:Password>
</wsse:UsernameToken>
<wsu:Timestamp wsu:Id="TS-1">
<wsu:Created>2013-02-19T14:08:08Z</wsu:Created>
<wsu:Expires>2013-02-19T14:08:38Z</wsu:Expires>
</wsu:Timestamp>
</wsse:Security>
</soapenv:Header>
<soapenv:Body wsu:Id="id-5"
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<edt:upload>
<upload>
<content>
<inc:Include href="cid:2341682853256" xmlns:inc="http://www.w3.org/2004/08/xop/include" />
</content>
<description>00123</description>
<resourceType>CL</resourceType>
</upload>
</edt:upload>
</soapenv:Body>
</soapenv:Envelope>
EDIT: See here a detailed solution to consume this EBS-EDT service
Since you have both username auth and x.509 signature you need to create the binding from code:
var sec = (AsymmetricSecurityBindingElement)SecurityBindingElement.CreateMutualCertificateBindingElement(MessageSecurityVersion.WSSecurity10WSTrust13WSSecureConversation13WSSecurityPolicy12BasicSecurityProfile10);
sec.EndpointSupportingTokenParameters.Signed.Add(new UserNameSecurityTokenParameters());
sec.MessageSecurityVersion =
MessageSecurityVersion.
WSSecurity10WSTrust13WSSecureConversation13WSSecurityPolicy12BasicSecurityProfile10;
sec.IncludeTimestamp = false;
sec.MessageProtectionOrder = System.ServiceModel.Security.MessageProtectionOrder.EncryptBeforeSign;
b.Elements.Add(sec);
b.Elements.Add(new TextMessageEncodingBindingElement(MessageVersion.Soap11, Encoding.UTF8));
b.Elements.Add(new HttpsTransportBindingElement());
Then you need to sign the headers. Assuming you use a message contract (not a data contract) where headers are explicitly tagged with a MessageHeader attribute then add to it a property "ProtectionMode=ProtectionMode.Sign".
I'm trying to implement an SSO for microsoft dynamics 2011 as described in this (very poorly written) walkthrough.
I've configured my ASP.NET website as a relying party in ADFS manager, and followed the instructions to add an STS reference.
I've defined an issuance transform rule for the UPN field in ADFS.
In my ASP.NET application, when doing this-
IClaimsIdentity claimsIdentity = ((IClaimsPrincipal)(Thread.CurrentPrincipal)).Identities[0]; I do get an instance of Microsoft.IdentityModel.Claims.ClaimsIdentity, however, its Claims collection is empty.
I've noticed, however, that the FederationMetadata.xml generated by the 'add sts' wizard only contains 2 <auth:ClaimType> elements- for name and role, both optional=true.
However, if I try to manually edit and update my relying party's FederationMetadata.xml to add upn as a claim type, or to make one of the existing claim types non-optional, I encounter the following error- ID6018 Digest verification failed....
If I revert back to 'optional=true' for both, the error doesn't occur.
Can anyone provide any insight as to how to get the UPN field to my ASP.NET app?
Also, better how-to's / walkthroughs than the one I've mentioned would be greatly appreciated.
I'm not really sure what further information to supply here, so i'll just post my application's FederationMetadata.xml:
<?xml version="1.0" encoding="utf-8"?>
<EntityDescriptor ID="_bad84517-5281-47e8-be9d-2e1a78eae772" entityID="https://MyAspnetSite.com:4455/"
xmlns="urn:oasis:names:tc:SAML:2.0:metadata">
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:SignedInfo>
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
<ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256" />
<ds:Reference URI="#_bad84517-5281-47e8-be9d-2e1a78eae772">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" />
<ds:DigestValue>
eWoZYLA/oMNMWd+S9m0TlbIg2rUSuumAckA0BTdAqbg=
</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>
yMubsY42ZblFDP4ZFEO06uT317c/xdMUF7PrOhPpShkDtbigg1TWq3tGYEa35+xpfjqQCseHJH07ftkxOH6t0u6ngqbGCmZ4yaOBTA3bdbGMGull6WwLSQIxNn2eR1mRzyF2mIM3t4Jfl6EoOZ0msnsyUTVI9Oq03eFweDN2zoI=
</ds:SignatureValue>
<KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
<X509Data>
<X509Certificate>
certificate data
</X509Certificate>
</X509Data>
</KeyInfo>
</ds:Signature>
<RoleDescriptor xsi:type="fed:ApplicationServiceType"
protocolSupportEnumeration="http://schemas.xmlsoap.org/ws/2005/02/trust http://docs.oasis-open.org/ws-sx/ws-trust/200512"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:fed="http://docs.oasis-open.org/wsfed/federation/200706">
<KeyDescriptor use="encryption">
<KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
<X509Data>
<X509Certificate>
certificate data
</X509Certificate>
</X509Data>
</KeyInfo>
</KeyDescriptor>
<fed:ClaimTypesRequested>
<auth:ClaimType Uri="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name" Optional="false"
xmlns:auth="http://docs.oasis-open.org/wsfed/authorization/200706" />
<auth:ClaimType Uri="http://schemas.microsoft.com/ws/2008/06/identity/claims/role" Optional="false"
xmlns:auth="http://docs.oasis-open.org/wsfed/authorization/200706" />
<auth:ClaimType Uri="http://schemas.microsoft.com/ws/2005/05/identity/claims/upn" Optional="false"
xmlns:auth="http://docs.oasis-open.org/wsfed/authorization/200706" />
</fed:ClaimTypesRequested>
<fed:TargetScopes>
<EndpointReference xmlns="http://www.w3.org/2005/08/addressing">
<Address>
https://MyAspnetSite.com:4455/
</Address>
</EndpointReference>
</fed:TargetScopes>
<fed:ApplicationServiceEndpoint>
<EndpointReference xmlns="http://www.w3.org/2005/08/addressing">
<Address>
https://MyAspnetSite.com:4455/
</Address>
</EndpointReference>
</fed:ApplicationServiceEndpoint>
</RoleDescriptor>
</EntityDescriptor>
You can't modify the FederationMetadata document directly because it is digitally signed. If you do, it will be rejected by ADFS, as it believes it has been tampered with.
Anyway, the metadata doc doesn't control what claims are being issued in ADFS. In addition to adding the RP, you need to create rules in ADFS that define what claims will be issued for this RP.
This other doc for CRM explains how to do it.
Well, for the benefit of the poor souls that may encounter this in the future, I'll document what the problem was for me:
The 'Add STS reference' wizard has altered my web.config in a wrong way.
I don't know why that is, perhaps it's because I had a pre-existing <system.serviceModel> section, but the wizard added the <claimTypeRequirements> section and all sorts of other stuff under <system.serviceModel> \ <bindings> \ <ws2007FederationHttpBinding> which didn't really seem to do anything.
I ended up deleting it and manually adding the appropriate <microsoft.identityModel>
section.
That seemed to have done the trick.