What is the correct format for SAML 2.0 Assertions? - single-sign-on

We have a customer trying to use ADFS to SSO on to our web application. We are using the ComponentSpace SAML 2.0 library. The assertion being sent to us looks like:
<Assertion ID="_b8a24809-ab6b-4acd-ad6a-8bcb97bb1889" IssueInstant="2012-05-24T13:30:33.917Z" Version="2.0" xmlns="urn:oasis:names:tc:SAML:2.0:assertion">
<Issuer>http://example.com/adfs/services/trust</Issuer>
<Subject>
<NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress">mail#example.com</NameID>
<SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
<SubjectConfirmationData NotOnOrAfter="2012-05-24T13:35:33.920Z" Recipient="https://example.com/default.aspx" />
</SubjectConfirmation>
</Subject>
<Conditions NotBefore="2012-05-24T13:30:33.907Z" NotOnOrAfter="2012-05-24T14:30:33.907Z">
<AudienceRestriction>
<Audience>https://example.com</Audience>
</AudienceRestriction>
</Conditions>
<AttributeStatement>
<Attribute Name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress">
<AttributeValue>mail#example.com</AttributeValue>
</Attribute>
</AttributeStatement>
<AuthnStatement AuthnInstant="2012-05-24T13:30:33.756Z" SessionIndex="_b8a24809-ab6b-4acd-ad6a-8bcb97bb1889">
<AuthnContext>
<AuthnContextClassRef>urn:federation:authentication:windows</AuthnContextClassRef>
</AuthnContext>
</AuthnStatement>
</Assertion>
The ComponentSpace library is pulling the full SamlResponse from the HTTP post but it reports no Assertions (ie samlResponse.GetAssertions().Count == 0). If I use the ComponentSpace examples it works but I notice all of the elements I build with the ComponentSpace library are prefixed with "saml:" (as I believe it should be).
Should the ComponentSpace library be able to find the Assertion without the saml: prefix or is there a way to configure ADFS to send it correctly?

A correct SAML response should contain namespace-qualified elements
<saml2p:Response Destination="https://www.google.com/a/squaresquare.biz/acs" IssueInstant="2010-08-04T17:47:20.956Z" xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol" InResponseTo="djfnhepndikoonjjkeomgplmkjofobhdbdieihpa" Version="2.0" ID="_bd24b4a3514fd93800d2a43cafc98edb">
<saml2:Issuer xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">http://my.ssodemo.url.demo.google.com/idp/shibboleth</saml2: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:CanonicalizationMethod>
<ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"></ds:SignatureMethod>
<ds:Reference URI="#_bd24b4a3514fd93800d2a43cafc98edb">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"></ds:Transform>
<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="dssaml2saml2p"></ec:InclusiveNamespaces>
</ds:Transform>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></ds:DigestMethod>
<ds:DigestValue>m/lUCS3nvfGuSJFKAtIz+ZrfxTU=</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>PLdYgU9u5KirVrMHNSwYvk6fQ401dMbpuiDXpapKf0eOKC6pN3g7tnTEzvfOaXhkDNXVmGN+lXQ6iUDppWpdO2MbvPVZabOBPU1aAO+CWI53ciC0rYsxpFzQLLMC/7x9Wk7VFFmYEecxAJV+lTWvp8ZKXvwqZbhiTO/23EC0xconGhnwSvKjJWQuLnMMaFWSjDFYyzgsp34cR7aX/eqhhJyA/rr2uFdmgEdagAl+/17ppgHgthgK+PJtX16AALtsoXonv6uybRCX/YiDRvM1VsdwusVq5tXh9V+bTMZcgi/3Eh+Em/OZp0En8pqOngvL19U4LfqG0yJZjoDGkpHuhA==</ds:SignatureValue>
<ds:KeyInfo>
<ds:X509Data>
<ds:X509Certificate>MIIDgjCCAmqgAwIBAgIVAKgIqbzZl7+0p2qjxJFVJs3DE/jxMA0GCSqGSIb3DQEBBQUAMDAxLjAsBgNVBAMTJWh0dHA6Ly93cGgtdWJpcTI3LmhvdC5jb3JwLmdvb2dsZS5jb20wHhcNMTAwNzIxMTcxNTA5WhcNMzAwNzIxMTcxNTA5WjAwMS4wLAYDVQQDEyVodHRwOi8vd3BoLXViaXEyNy5ob3QuY29ycC5nb29nbGUuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAioQsJycRmjPjB2xlH0iSGn14lNbO/jIVgiGIlzZwlPkH1s2TTdwoTKKQBSe2s8AnJ4LliXlne/qWun3peYht0+RhejtB20L+Bw/I+iKQBGpHzgIKdkPGZnemWl9KqWQ/ZYKnY2x6qMEBmhUfYZcawzs26em5a+iaYlrTJNVEZ+QwWvg2/EOJvJNyBkSfXyxia5eAHV38Uy7xn0G5Zc9ge4ckCYj6b8a/UxpPJM61KztzY5coDwReQsDBq+DciGALJPbFk4783TW...etc.etc</ds:X509Certificate>
</ds:X509Data>
</ds:KeyInfo>
</ds:Signature>
<saml2p:Status>
<saml2p:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"></saml2p:StatusCode>
</saml2p:Status>
<saml2:Assertion xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" Version="2.0" IssueInstant="2010-08-04T17:47:20.956Z" ID="_73fe28bcbb68e93df954d8e2f25097b1">
<saml2:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">http://my.ssodemo.url.demo.google.com/idp/shibboleth</saml2:Issuer>
<saml2:Subject>
<saml2:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified">my_username</saml2:NameID>
<saml2:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
<saml2:SubjectConfirmationData NotOnOrAfter="2010-08-04T17:52:20.956Z" InResponseTo="djfnhepndikoonjjkeomgplmkjofobhdbdieihpa" Recipient="https://www.google.com/a/squaresquare.biz/acs" Address="172.24.6.38"></saml2:SubjectConfirmationData>
</saml2:SubjectConfirmation>
</saml2:Subject>
<saml2:Conditions NotOnOrAfter="2010-08-04T17:52:20.956Z" NotBefore="2010-08-04T17:47:20.956Z">
<saml2:AudienceRestriction>
<saml2:Audience>google.com</saml2:Audience>
</saml2:AudienceRestriction>
</saml2:Conditions>
<saml2:AuthnStatement SessionIndex="f306dd2bff4e9b3ba9218bd70fbaa87404d38a4c79547ac1edc9436a9f222213" AuthnInstant="2010-08-04T17:47:20.953Z">
<saml2:SubjectLocality Address="172.24.6.38"></saml2:SubjectLocality>
<saml2:AuthnContext>
<saml2:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport</saml2:AuthnContextClassRef>
</saml2:AuthnContext>
</saml2:AuthnStatement>
</saml2:Assertion>
</saml2p:Response>

Namespace qualifications are optional.

It turns out that the above XML is valid (ADFS adds the namespace to the overall XML but not each element). The problem was that the ComponentSpace library has different methods for getting Signed or Encrypted Assertions and I was just calling the generic GetAssertions. ADFS was generating signed assertions and I needed to call the other function.
Here is the code we ended up with:
IList<EncryptedAssertion> encryptedAssertions = samlResponse.GetEncryptedAssertions();
if (encryptedAssertions.Count > 0 && x509Certificate != null) {
// Decrypt the assertion
EncryptedAssertion encryptedAssertion = encryptedAssertions[0];
XmlElement decryptedElement = encryptedAssertion.DecryptToXml(x509Certificate, null);
LogMessage("Decrypted assertion: " + decryptedElement.OuterXml);
// Then verify the signature.
VerifySignature(x509Certificate, decryptedElement);
samlAssertion = new SAMLAssertion(decryptedElement);
} else {
if (samlResponse.GetSignedAssertions().Count > 0) {
// Get the signed assertion and verify the signature.
XmlElement signedAssertionElement = samlResponse.GetSignedAssertions()[0];
LogMessage("Signed assertion: " + signedAssertionElement.OuterXml);
VerifySignature(x509Certificate, signedAssertionElement);
samlAssertion = new SAMLAssertion(signedAssertionElement);
} else {
// Assertion is not encrypted or signed.
if (samlResponse.GetAssertions().Count > 0) {
samlAssertion = samlResponse.GetAssertions()[0];
LogMessage("Assertion: " + samlAssertion.ToXml().OuterXml);
} else {
LogFatalError("No assertions in response");
}
}
}

Related

Soap request signing

Hello fellow developers,
I have no experience working on soap, saml and xml signing,
I am trying to generate this structure and then add 2 signature tags to it.
<env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope">
<env:Header xmlns:a="http://www.w3.org/2005/08/addressing">
<a:MessageID></a:MessageID>
<a:To env:mustUnderstand="true"></a:To>
<a:Action env:mustUnderstand="true">urn:hl7-org:v3:PRPA_IN201305UV02:CrossGatewayPatientDiscovery</a:Action>
<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">
<wsu:Timestamp wsu:Id="timestamp_ID">
<wsu:Created>2022-10-13T18:18:17.763Z</wsu:Created>
<wsu:Expires>2023-10-13T18:23:17.763Z</wsu:Expires>
</wsu:Timestamp>
<saml2:Assertion xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ID="assertion_ID" IssueInstant="2022-10-13T18:18:17.763Z" Version="2.0">
<saml2:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:X509SubjectName"></saml2:Issuer>
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
<SignedInfo>
<CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
<SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
<Reference URI="#assertion_ID">
<Transforms>
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
<Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<DigestValue></DigestValue>
</Reference>
</SignedInfo>
<SignatureValue></SignatureValue>
<KeyInfo>
<X509Data>
<X509Certificate></X509Certificate>
</X509Data>
</KeyInfo>
</Signature>
<saml2:Subject>
<saml2:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:X509SubjectName"></saml2:NameID>
<saml2:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:holder-of-key">
<saml2:SubjectConfirmationData>
<KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
<KeyValue>
<RSAKeyValue>
<Modulus></Modulus>
<Exponent>AQAB</Exponent>
</RSAKeyValue>
</KeyValue>
</KeyInfo>
</saml2:SubjectConfirmationData>
</saml2:SubjectConfirmation>
</saml2:Subject>
<saml2:Conditions NotBefore="2022-10-13T18:15:17.763Z" NotOnOrAfter="2022-10-13T18:23:17.763Z">
<saml2:AudienceRestriction>
<saml2:Audience></saml2:Audience>
</saml2:AudienceRestriction>
</saml2:Conditions>
<saml2:AuthnStatement AuthnInstant="2022-10-13T17:55:17.743Z" SessionIndex="1234567890">
<saml2:SubjectLocality Address="10.1.1.144" DNSName="localhost"/>
<saml2:AuthnContext>
<saml2:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport</saml2:AuthnContextClassRef>
</saml2:AuthnContext>
</saml2:AuthnStatement>
<saml2:AttributeStatement>
<saml2:Attribute Name="urn:oasis:names:tc:xspa:1.0:subject:subject-id">
<saml2:AttributeValue>John Doe</saml2:AttributeValue>
</saml2:Attribute>
<saml2:Attribute Name="urn:oasis:names:tc:xspa:1.0:subject:organization">
<saml2:AttributeValue>Dr. John M Doe, MD Practice</saml2:AttributeValue>
</saml2:Attribute>
<saml2:Attribute Name="urn:oasis:names:tc:xspa:1.0:subject:organization-id">
<saml2:AttributeValue></saml2:AttributeValue>
</saml2:Attribute>
<saml2:Attribute Name="urn:nhin:names:saml:homeCommunityId">
<saml2:AttributeValue></saml2:AttributeValue>
</saml2:Attribute>
<saml2:Attribute Name="urn:oasis:names:tc:xacml:2.0:subject:role">
<saml2:AttributeValue>
<Role xmlns="urn:hl7-org:v3" code="112247003" codeSystem="2.16.840.1.113883.6.96" codeSystemName="SNOMED CT" displayName="Medical doctor" xsi:type="CE"/>
</saml2:AttributeValue>
</saml2:Attribute>
<saml2:Attribute Name="urn:oasis:names:tc:xspa:1.0:subject:purposeofuse">
<saml2:AttributeValue>
<PurposeOfUse xmlns="urn:hl7-org:v3" code="TREATMENT" codeSystem="2.16.840.1.113883.3.18.7.1" codeSystemName="nhin-purpose" displayName="Treatment" xsi:type="CE"/>
</saml2:AttributeValue>
</saml2:Attribute>
<saml2:Attribute Name="urn:oasis:names:tc:xacml:2.0:resource:resource-id">
<saml2:AttributeValue></saml2:AttributeValue>
</saml2:Attribute>
</saml2:AttributeStatement>
</saml2:Assertion>
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
<SignedInfo>
<CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
<SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
<Reference URI="#timestamp_ID">
<Transforms>
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
<Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<DigestValue></DigestValue>
</Reference>
</SignedInfo>
<SignatureValue></SignatureValue>
<KeyInfo>
<wsse:SecurityTokenReference xmlns:wsse11="http://docs.oasis-open.org/wss/oasis-wss-wssecurity-secext-1.1.xsd" wsse11:TokenType="http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV2.0">
<wsse:KeyIdentifier ValueType="http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLID">assertion_ID</wsse:KeyIdentifier>
</wsse:SecurityTokenReference>
</KeyInfo>
</Signature>
</wsse:Security>
</env:Header>
<env:Body>
<PRPA_IN201305UV02 xmlns="urn:hl7-org:v3" ITSVersion="XML_1.0">
<id extension="126627497759" root="1.3.6.1.4.1.52618.1.3"/>
<creationTime value="20221013181817"/>
<interactionId extension="PRPA_IN201305UV02" root="2.16.840.1.113883.1.6"/>
<processingCode code="P"/>
<processingModeCode code="T"/>
<acceptAckCode code="AL"/>
<receiver typeCode="RCV">
<device classCode="DEV" determinerCode="INSTANCE">
<id root="0.0.0"/>
<telecom value="https://RH-Windows-TMP-b994dba9f85ba908.elb.us-east-1.amazonaws.com:4437/"/>
<asAgent classCode="AGNT">
<representedOrganization classCode="ORG" determinerCode="INSTANCE">
<id root=""/>
</representedOrganization>
</asAgent>
</device>
</receiver>
<sender typeCode="SND">
<device classCode="DEV" determinerCode="INSTANCE">
<id root="1.3.6.1.4.1.52618.1.2"/>
<asAgent classCode="AGNT">
<representedOrganization classCode="ORG" determinerCode="INSTANCE">
<id root="1.3.6.1.4.1.52618.1"/>
</representedOrganization>
</asAgent>
</device>
</sender>
<controlActProcess classCode="CACT" moodCode="EVN">
<code code="PRPA_TE201305UV02" codeSystem="2.16.840.1.113883.1.6"/>
<authorOrPerformer typeCode="AUT">
<assignedDevice classCode="ASSIGNED">
<id root="1.3.6.1.4.1.52618.1.1"/>
</assignedDevice>
</authorOrPerformer>
<queryByParameter>
<queryId extension="126627497760" root="1.3.6.1.4.1.52618.1.3.1"/>
<statusCode code="new"/>
<responseModalityCode code="R"/>
<responsePriorityCode code="I"/>
<parameterList>
<livingSubjectAdministrativeGender>
<value code="M"/>
<semanticsText>LivingSubject.administrativeGender</semanticsText>
</livingSubjectAdministrativeGender>
<livingSubjectBirthTime>
<value value=""/>
<semanticsText>LivingSubject.birthTime</semanticsText>
</livingSubjectBirthTime>
<livingSubjectId>
<value extension="" root="1.3.6.1.4.1.52618.1.1"/>
<semanticsText>LivingSubject.id</semanticsText>
</livingSubjectId>
<livingSubjectName>
<value>
<given></given>
<family>TEST</family>
</value>
<semanticsText>LivingSubject.name</semanticsText>
</livingSubjectName>
<patientAddress>
<value>
<streetAddressLine>Home Dr</streetAddressLine>
<city>Charlotte</city>
<state>NC</state>
<postalCode></postalCode>
<country>US</country>
</value>
<semanticsText>Patient.addr</semanticsText>
</patientAddress>
</parameterList>
</queryByParameter>
</controlActProcess>
</PRPA_IN201305UV02>
</env:Body>
</env:Envelope>
I am using rhino javascript and below is the code
//////////////////////////////////////////////////////////////////////////////////
// Generate our dynamic message values
//
var timestampId = UUIDGenerator.getUUID();
var assertionId = UUIDGenerator.getUUID();
var createdTimestamp = new Date().toISOString();
var expiresTimestamp = new Date((new Date()).getTime() + 10000*10).toISOString();
var samlenvelope="<env:Envelope xmlns:env=\"http://www.w3.org/2003/05/soap-envelope\">"+
"<env:Header xmlns:a=\"http://www.w3.org/2005/08/addressing\">"+
"<a:MessageID>urn:uuid:32886a29-98ad-4284-b00e-3fe4ded10d16</a:MessageID>"+
"<a:To env:mustUnderstand=\"true\"></a:To>"+
"<a:Action env:mustUnderstand=\"true\">urn:hl7-org:v3:PRPA_IN201305UV02:CrossGatewayPatientDiscovery</a:Action>"+
"<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\">"+
"<wsu:Timestamp wsu:Id=\"timestamp_ID\">"+
"<wsu:Created>2022-10-13T18:18:17.763Z</wsu:Created>"+
"<wsu:Expires>2023-10-13T18:23:17.763Z</wsu:Expires>"+
"</wsu:Timestamp>"+
"<saml2:Assertion xmlns:saml2=\"urn:oasis:names:tc:SAML:2.0:assertion\" xmlns:ds=\"http://www.w3.org/2000/09/xmldsig#\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" ID=\"assertion_ID\" IssueInstant=\"2022-10-13T18:18:17.763Z\" Version=\"2.0\">"+
"<saml2:Issuer Format=\"urn:oasis:names:tc:SAML:2.0:nameid-format:X509SubjectName\"></saml2:Issuer>"+
"<saml2:Subject>"+
"<saml2:NameID Format=\"urn:oasis:names:tc:SAML:1.1:nameid-format:X509SubjectName\"></saml2:NameID>"+
"<saml2:SubjectConfirmation Method=\"urn:oasis:names:tc:SAML:2.0:cm:holder-of-key\">"+
"<saml2:SubjectConfirmationData>"+
"<KeyInfo xmlns=\"http://www.w3.org/2000/09/xmldsig#\">"+
"<KeyValue>"+
"<RSAKeyValue>"+
"<Modulus></Modulus>"+
"<Exponent>AQAB</Exponent>"+
"</RSAKeyValue>"+
"</KeyValue>"+
"</KeyInfo>"+
"</saml2:SubjectConfirmationData>"+
"</saml2:SubjectConfirmation>"+
"</saml2:Subject>"+
"<saml2:Conditions NotBefore=\"2022-10-13T18:15:17.763Z\" NotOnOrAfter=\"2022-10-13T18:23:17.763Z\">"+
"</saml2:Conditions>"+
"<saml2:AuthnStatement AuthnInstant=\"2022-10-13T17:55:17.743Z\" SessionIndex=\"1234567890\">"+
"<saml2:SubjectLocality Address=\"10.1.1.144\" DNSName=\"localhost\"/>"+
"<saml2:AuthnContext>"+
"<saml2:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport</saml2:AuthnContextClassRef>"+
"</saml2:AuthnContext>"+
"</saml2:AuthnStatement>"+
"<saml2:AttributeStatement>"+
"<saml2:Attribute Name=\"urn:oasis:names:tc:xspa:1.0:subject:subject-id\">"+
"<saml2:AttributeValue>John Doe</saml2:AttributeValue>"+
"</saml2:Attribute>"+
"<saml2:Attribute Name=\"urn:oasis:names:tc:xspa:1.0:subject:organization\">"+
"<saml2:AttributeValue>Dr. John M Doe, MD Practice</saml2:AttributeValue>"+
"</saml2:Attribute>"+
"<saml2:Attribute Name=\"urn:oasis:names:tc:xspa:1.0:subject:organization-id\">"+
"<saml2:AttributeValue></saml2:AttributeValue>"+
"</saml2:Attribute>"+
"<saml2:Attribute Name=\"urn:nhin:names:saml:homeCommunityId\">"+
"<saml2:AttributeValue></saml2:AttributeValue>"+
"</saml2:Attribute>"+
"<saml2:Attribute Name=\"urn:oasis:names:tc:xacml:2.0:subject:role\">"+
"<saml2:AttributeValue>"+
"<Role xmlns=\"urn:hl7-org:v3\" code=\"112247003\" codeSystem=\"2.16.840.1.113883.6.96\" codeSystemName=\"SNOMED CT\" displayName=\"Medical doctor\" xsi:type=\"CE\"/>"+
"</saml2:AttributeValue>"+
"</saml2:Attribute>"+
"<saml2:Attribute Name=\"urn:oasis:names:tc:xspa:1.0:subject:purposeofuse\">"+
"<saml2:AttributeValue>"+
"<PurposeOfUse xmlns=\"urn:hl7-org:v3\" code=\"TREATMENT\" codeSystem=\"2.16.840.1.113883.3.18.7.1\" codeSystemName=\"nhin-purpose\" displayName=\"Treatment\" xsi:type=\"CE\"/>"+
"</saml2:AttributeValue>"+
"</saml2:Attribute>"+
"<saml2:Attribute Name=\"urn:oasis:names:tc:xacml:2.0:resource:resource-id\">"+
"<saml2:AttributeValue></saml2:AttributeValue>"+
"</saml2:Attribute>"+
"</saml2:AttributeStatement>"+
"</saml2:Assertion>"+
"</wsse:Security>"+
"</env:Header>"+
"<env:Body>"+
"<PRPA_IN201305UV02 xmlns=\"urn:hl7-org:v3\" ITSVersion=\"XML_1.0\">"+
"<id extension=\"126627497759\" root=\"1.3.6.1.4.1.52618.1.3\"/>"+
"<creationTime value=\"20221013181817\"/>"+
"<interactionId extension=\"PRPA_IN201305UV02\" root=\"2.16.840.1.113883.1.6\"/>"+
"<processingCode code=\"P\"/>"+
"<processingModeCode code=\"T\"/>"+
"<acceptAckCode code=\"AL\"/>"+
"<receiver typeCode=\"RCV\">"+
"<device classCode=\"DEV\" determinerCode=\"INSTANCE\">"+
"<id root=\"0.0.0\"/>"+
"<telecom value=\"https://RH-Windows-TMP-b994dba9f85ba908.elb.us-east-1.amazonaws.com:4437/\"/>"+
"<asAgent classCode=\"AGNT\">"+
"<representedOrganization classCode=\"ORG\" determinerCode=\"INSTANCE\">"+
"<id root=\"\"/>"+
"</representedOrganization>"+
"</asAgent>"+
"</device>"+
"</receiver>"+
"<sender typeCode=\"SND\">"+
"<device classCode=\"DEV\" determinerCode=\"INSTANCE\">"+
"<id root=\"1.3.6.1.4.1.52618.1.2\"/>"+
"<asAgent classCode=\"AGNT\">"+
"<representedOrganization classCode=\"ORG\" determinerCode=\"INSTANCE\">"+
"<id root=\"1.3.6.1.4.1.52618.1\"/>"+
"</representedOrganization>"+
"</asAgent>"+
"</device>"+
"</sender>"+
"<controlActProcess classCode=\"CACT\" moodCode=\"EVN\">"+
"<code code=\"PRPA_TE201305UV02\" codeSystem=\"2.16.840.1.113883.1.6\"/>"+
"<authorOrPerformer typeCode=\"AUT\">"+
"<assignedDevice classCode=\"ASSIGNED\">"+
"<id root=\"1.3.6.1.4.1.52618.1.1\"/>"+
"</assignedDevice>"+
"</authorOrPerformer>"+
"<queryByParameter>"+
"<queryId extension=\"\" root=\"1.3.6.1.4.1.52618.1.3.1\"/>"+
"<statusCode code=\"new\"/>"+
"<responseModalityCode code=\"R\"/>"+
"<responsePriorityCode code=\"I\"/>"+
"<parameterList>"+
"<livingSubjectAdministrativeGender>"+
"<value code=\"M\"/>"+
"<semanticsText>LivingSubject.administrativeGender</semanticsText>"+
"</livingSubjectAdministrativeGender>"+
"<livingSubjectBirthTime>"+
"<value value=\"\"/>"+
"<semanticsText>LivingSubject.birthTime</semanticsText>"+
"</livingSubjectBirthTime>"+
"<livingSubjectId>"+
"<value extension=\"\" root=\"1.3.6.1.4.1.52618.1.1\"/>"+
"<semanticsText>LivingSubject.id</semanticsText>"+
"</livingSubjectId>"+
"<livingSubjectName>"+
"<value>"+
"<given></given>"+
"<family>TEST</family>"+
"</value>"+
"<semanticsText>LivingSubject.name</semanticsText>"+
"</livingSubjectName>"+
"<patientAddress>"+
"<value>"+
"<streetAddressLine>Home Dr</streetAddressLine>"+
"<city>Charlotte</city>"+
"<state>NC</state>"+
"<postalCode></postalCode>"+
"<country>US</country>"+
"</value>"+
"<semanticsText>Patient.addr</semanticsText>"+
"</patientAddress>"+
"</parameterList>"+
"</queryByParameter>"+
"</controlActProcess>"+
"</PRPA_IN201305UV02>"+
"</env:Body>"+
"</env:Envelope>"+;
var samlString = new java.lang.String(samlenvelope);
////////////////////////////////////////////////////////////////////////////////////
// Build our XML DOM for signature
//
var documentBuilderFactory = javax.xml.parsers.DocumentBuilderFactory.newInstance();
documentBuilderFactory.setNamespaceAware(true);
var document = documentBuilderFactory.newDocumentBuilder().parse(new java.io.ByteArrayInputStream(samlString.getBytes("utf-8")));
////////////////////////////////////////////////////////////////////////////////////
// Configure Digital Signature utilities for required crypto operations
//
var xmlDsigFactory = javax.xml.crypto.dsig.XMLSignatureFactory.getInstance("DOM");
var parameterSpec = new javax.xml.crypto.dsig.spec.ExcC14NParameterSpec();
var reference = xmlDsigFactory.newReference
(
"#assertion_ID",
xmlDsigFactory.newDigestMethod(javax.xml.crypto.dsig.DigestMethod.SHA1, null),
java.util.Collections.singletonList(xmlDsigFactory.newTransform("http://www.w3.org/2001/10/xml-exc-c14n#", parameterSpec)),
null, //type
null //id
)
var signedInfo = xmlDsigFactory.newSignedInfo
(
xmlDsigFactory.newCanonicalizationMethod
(
javax.xml.crypto.dsig.CanonicalizationMethod.EXCLUSIVE,
parameterSpec
),
xmlDsigFactory.newSignatureMethod(javax.xml.crypto.dsig.SignatureMethod.RSA_SHA1, null),
java.util.Collections.singletonList(reference)
)
var reference1 = xmlDsigFactory.newReference
(
"#timestamp_ID",
xmlDsigFactory.newDigestMethod(javax.xml.crypto.dsig.DigestMethod.SHA1, null),
java.util.Collections.singletonList(xmlDsigFactory.newTransform("http://www.w3.org/2001/10/xml-exc-c14n#", parameterSpec)),
null, //type
null //id
)
var signedInfo1 = xmlDsigFactory.newSignedInfo
(
xmlDsigFactory.newCanonicalizationMethod
(
javax.xml.crypto.dsig.CanonicalizationMethod.EXCLUSIVE,
parameterSpec
),
xmlDsigFactory.newSignatureMethod(javax.xml.crypto.dsig.SignatureMethod.RSA_SHA1, null),
java.util.Collections.singletonList(reference1)
)
//////////////////////////////////////////////////////
// Fetch our certificate and key
//
var certificate;
try
{
var inputStream = new java.io.FileInputStream("test.crt");
var certificateFactory = java.security.cert.CertificateFactory.getInstance("X.509");
certificate = certificateFactory.generateCertificate(inputStream);
}
finally
{
if (inputStream != null)
inputStream.close();
}
var privateKey;
var keyFactory = java.security.KeyFactory.getInstance("RSA");
var keySpec = new java.security.spec.PKCS8EncodedKeySpec(java.nio.file.Files.readAllBytes(new java.io.File("private_key.der").toPath()));
privateKey = keyFactory.generatePrivate(keySpec);
////////////////////////////////////////////////////////
// Generate the KeyInfo for our signature
//
var keyInfoFactory = xmlDsigFactory.getKeyInfoFactory();
var x509Content = new java.util.ArrayList();
x509Content.add(certificate);
var x509Data = keyInfoFactory.newX509Data(x509Content);
var keyInfo = keyInfoFactory.newKeyInfo(java.util.Collections.singletonList(x509Data));
var signature = xmlDsigFactory.newXMLSignature(signedInfo, keyInfo);
var dsc = new javax.xml.crypto.dsig.dom.DOMSignContext(privateKey, document.getDocumentElement());
var rootEl = document.getDocumentElement();
rootEl.setIdAttribute("ID",true);
signature.sign(dsc);
var signature1 = xmlDsigFactory.newXMLSignature(signedInfo1, keyInfo1);
var dsc = new javax.xml.crypto.dsig.dom.DOMSignContext(privateKey, document.getDocumentElement());
signature1.sign(dsc);
/*
var newEle=document.createElement("Transform");
newEle.setAttribute('Algorithm', 'http://www.w3.org/2000/09/xmldsig#enveloped-signature');
document.getElementsByTagName("Transforms").item(0).appendChild(newEle);*/
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Define any formatting preferences get the signed document as a string
//
var transformerFactory = javax.xml.transform.TransformerFactory.newInstance();
var transformer = transformerFactory.newTransformer();
transformer.setOutputProperty(javax.xml.transform.OutputKeys.OMIT_XML_DECLARATION, "yes");
var stringWriter = new java.io.StringWriter();
transformer.transform(new javax.xml.transform.dom.DOMSource(document), new javax.xml.transform.stream.StreamResult(stringWriter));
channelMap.put("soapMessage", stringWriter.toString());
when I run the code I get this error
Wrapped org.w3c.dom.DOMException: NOT_FOUND_ERR: An attempt is made to
reference a node in a context where it does not exist.
Will appreciate your help

SAML reponse difference between SP initiated SSO and IDP initiated SSO

How to tell from a SAML response if it's a SP initiated SSO or an IDP initiated SSO? Is there an attribute which tells me who initiated the SSO?
For example in this StackOverflow Question: Differences between SP initiated SSO and IDP initiated SSO they discuss the differences but they don't talk about the XML level itself...
The SAML response looks like this:
<samlp:Response xmlns:samlp ="urn:oasis:names:tc:SAML:2 .0 :protocol" Destination ="http: //my - sp . com /sso /saml" ID ="_45307c23795120" IssueInstant ="2014 -03 -07 T08:30:00Z" Version ="2.0">
<saml:Issuer xmlns:saml ="urn:oasis:names:tc:SAML:2 .0 :assertion">http: //my - idp . com </saml:Issuer>
<samlp:Status>
<samlp:StatusCode Value ="urn:oasis:names:tc:SAML:2.0:status:Success"/>
</samlp:Status>
<saml:Assertion ID ="ebe015e8be2a" IssueInstant="2014-03-07T08:30:00Z" Version ="2.0">
<saml:Issuer> http: //my - idp . com </saml: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 /2000/09/ xmldsig # rsa - sha1"/>
<ds:Reference URI ="# ebe015e8be2a">
<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 /2000/09/ xmldsig # sha1"/>
<ds:DigestValue> ... </ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue> ... </ds:SignatureValue>
<ds:KeyInfo>
<ds:X509Data>
<ds:X509Certificate> ... </ds:X509Certificate>
</ds:X509Data>
</ds:KeyInfo>
</ds:Signature>
<saml:Subject>
<saml:NameID Format ="urn:oasis:names:tc:SAML:2 .0 :nameid - format:persistent" NameQualifier ="http: //my - idp . com" SPNameQualifier ="http: //my - sp . com /sso /saml"> NDSUser </saml:NameID>
<saml:SubjectConfirmation Method ="urn:oasis:names:tc:SAML:2.0:cm:bearer">
<saml:SubjectConfirmationData NotOnOrAfter ="2014 -03 -07 T10:45:00Z" Recipient ="http: //my - sp . com /sso /saml"/>
</saml:SubjectConfirmation>
</saml:Subject>
<saml:Conditions NotBefore ="2014 -03 -07 T08:29:00Z" NotOnOrAfter="2014 -03 -07 T10:46:00Z">
<saml:AudienceRestriction>
<saml:Audience> http: //my - sp . com /sso /saml </saml:Audience>
</saml:AudienceRestriction>
</saml:Conditions>
<saml:AuthnStatement AuthnInstant="2014 -03 -07 T08:25:56Z" SessionIndex="f7810a8c86a6">
<saml:AuthnContext>
<saml:AuthnContextClassRef> urn:oasis:names:tc:SAML:2 .0:ac:classes:PasswordProtectedTransport </saml:AuthnContextClassRef>
</saml:AuthnContext>
</saml:AuthnStatement>
<saml:AttributeStatement>
<saml:Attribute Name ="FEDERATION_ID">
<saml:AttributeValue xmlns:xs ="http: //www . w3 . org /2001/XMLSchema" xmlns:xsi ="http: //www . w3 . org /2001/XMLSchema - instance" xsi:type ="xs:string"> NDS </saml:AttributeValue>
</saml:Attribute>
</saml:AttributeStatement>
</saml:Assertion>
</samlp:Response>
SAML response from SP-initiated SSO flow has 'InResponseTo' attribute.

CAS Delegated Authentication and AttributeReleasePolicies

We were able to integrate CAS 5.2.6 using delegated authentication with Azure AD (Saml Idp)
The integrated is working fine when the client webapp is deployed on Tomcat-9
The same client WAR fails in JBoss-EAP or Wildfly because of SaxParing exception
This is because Jboss is using xercesImpl for parsing Xml which fails when the xml element is numeric.
So, a standard solution will be to use AttributeResolver configuration on CAS server side to ensure that we map the attribute to standard names (vs numeric names)
Attached herewith the SAML response and CAS Client Response
<samlp:Response
Destination="https://somedomain.cloudapp.azure.com:8443/cas/login?client_name=MY_SAML"
ID="_6a00b756-53f4-4702-b329-7a6af0145fa0" InResponseTo="_d5nkosrzkcj29rlldngsuozq3uwtb5znanfm616"
IssueInstant="2018-10-04T13:22:05.275Z" Version="2.0"
xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol">
<Issuer xmlns="urn:oasis:names:tc:SAML:2.0:assertion">https://sts.windows.net/522b3803-a001-4675-b3b5-1d727d43585a/</Issuer>
<samlp:Status><samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/></samlp:Status>
<Assertion ID="_337eded3-a927-4674-b78a-77259cfbf784" IssueInstant="2018-10-04T13:22:05.275Z"
Version="2.0" xmlns="urn:oasis:names:tc:SAML:2.0:assertion">
<Issuer>https://sts.windows.net/522b3803-a001-4675-b3b5-1d727d43585a/</Issuer>
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
<SignedInfo><CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/><SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
<Reference URI="#_337eded3-a927-4674-b78a-77259cfbf784">
<Transforms><Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/><Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/></Transforms><DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
<DigestValue>BkenglDOQwAFlKJ3hLrZ4vUzAg9gOD9EFUjGKH9hsI4=</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>...</SignatureValue>
<KeyInfo>
<X509Data>
<X509Certificate>...</X509Certificate>
</X509Data>
</KeyInfo>
</Signature>
<Subject>
<NameID Format="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent">nX16LJA-9igFhluTHQGlDUOK0CNPy_XfliMDJ3iud88</NameID>
<SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer"><SubjectConfirmationData InResponseTo="_d5nkosrzkcj29rlldngsuozq3uwtb5znanfm616"
NotOnOrAfter="2018-10-04T13:27:05.275Z"
Recipient="https://somedomain.cloudapp.azure.com:8443/cas/login?client_name=MY_SAML"/></SubjectConfirmation>
</Subject>
<Conditions NotBefore="2018-10-04T13:17:05.275Z" NotOnOrAfter="2018-10-04T14:17:05.275Z">
<AudienceRestriction>
<Audience>spn:8b4fcc4d-6781-4da0-acc9-0c28a3317695</Audience>
</AudienceRestriction>
</Conditions>
<AttributeStatement>
<Attribute Name="http://schemas.microsoft.com/identity/claims/tenantid">
<AttributeValue>522b3803-a001-4675-b3b5-1d727d43585a</AttributeValue>
</Attribute>
<Attribute Name="http://schemas.microsoft.com/identity/claims/objectidentifier">
<AttributeValue>8fa1e8a3-41b8-440e-91cf-fafa246ab571</AttributeValue>
</Attribute>
<Attribute Name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name">
<AttributeValue>xxxxx#AAAA.onmicrosoft.com</AttributeValue>
</Attribute>
<Attribute Name="http://schemas.microsoft.com/identity/claims/displayname">
<AttributeValue>Firstname Lastname</AttributeValue>
</Attribute>
<Attribute Name="http://schemas.microsoft.com/identity/claims/identityprovider">
<AttributeValue>https://sts.windows.net/522b3803-a001-4675-b3b5-1d727d43585a/</AttributeValue>
</Attribute>
<Attribute Name="http://schemas.microsoft.com/claims/authnmethodsreferences">
<AttributeValue>http://schemas.microsoft.com/ws/2008/06/identity/authenticationmethod/password</AttributeValue>
<AttributeValue>http://schemas.microsoft.com/claims/multipleauthn</AttributeValue>
</Attribute>
</AttributeStatement>
<AuthnStatement AuthnInstant="2018-10-04T09:50:06.611Z"
SessionIndex="_337eded3-a927-4674-b78a-77259cfbf784">
<AuthnContext>
<AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:Password</AuthnContextClassRef>
</AuthnContext>
</AuthnStatement>
</Assertion>
CAS Client Response
<cas:serviceResponse xmlns:cas='http://www.yale.edu/tp/cas'>
<cas:authenticationSuccess>
<cas:user>nX16LJA-9igFhluTHQGlDUOK0CNPy_XfliMDJ3iud88</cas:user>
<cas:attributes>
<cas:isFromNewLogin>true</cas:isFromNewLogin>
<cas:687474703a2f2f736368656d61732e6d6963726f736f66742e636f6d2f6964656e746974792f636c61696d732f6f626a6563746964656e746966696572>8fa1e8a3-41b8-440e-91cf-fafa246ab571</cas:687474703a2f2f736368656d61732e6d6963726f736f66742e636f6d2f6964656e746974792f636c61696d732f6f626a6563746964656e746966696572>
<cas:authenticationDate>2018-10-04T13:22:05.643Z[Etc/UTC]</cas:authenticationDate>
<cas:clientName>MY_SAML</cas:clientName>
<cas:successfulAuthenticationHandlers>ClientAuthenticationHandler</cas:successfulAuthenticationHandlers>
<cas:687474703a2f2f736368656d61732e6d6963726f736f66742e636f6d2f6964656e746974792f636c61696d732f646973706c61796e616d65>Firstname Lastname</cas:687474703a2f2f736368656d61732e6d6963726f736f66742e636f6d2f6964656e746974792f636c61696d732f646973706c61796e616d65>
<cas:notBefore>2018-10-04T13:17:05.275Z</cas:notBefore>
<cas:credentialType>ClientCredential</cas:credentialType>
<cas:687474703a2f2f736368656d61732e6d6963726f736f66742e636f6d2f636c61696d732f617574686e6d6574686f64737265666572656e636573>http://schemas.microsoft.com/ws/2008/06/identity/authenticationmethod/password</cas:687474703a2f2f736368656d61732e6d6963726f736f66742e636f6d2f636c61696d732f617574686e6d6574686f64737265666572656e636573>
<cas:687474703a2f2f736368656d61732e6d6963726f736f66742e636f6d2f636c61696d732f617574686e6d6574686f64737265666572656e636573>http://schemas.microsoft.com/claims/multipleauthn</cas:687474703a2f2f736368656d61732e6d6963726f736f66742e636f6d2f636c61696d732f617574686e6d6574686f64737265666572656e636573>
<cas:687474703a2f2f736368656d61732e6d6963726f736f66742e636f6d2f6964656e746974792f636c61696d732f74656e616e746964>522b3803-a001-4675-b3b5-1d727d43585a</cas:687474703a2f2f736368656d61732e6d6963726f736f66742e636f6d2f6964656e746974792f636c61696d732f74656e616e746964>
<cas:687474703a2f2f736368656d61732e786d6c736f61702e6f72672f77732f323030352f30352f6964656e746974792f636c61696d732f6e616d65>myuserID#MYDOMAIN.onmicrosoft.com</cas:687474703a2f2f736368656d61732e786d6c736f61702e6f72672f77732f323030352f30352f6964656e746974792f636c61696d732f6e616d65>
<cas:authenticationMethod>ClientAuthenticationHandler</cas:authenticationMethod>
<cas:687474703a2f2f736368656d61732e6d6963726f736f66742e636f6d2f6964656e746974792f636c61696d732f6964656e7469747970726f7669646572>https://sts.windows.net/522b3803-a001-4675-b3b5-1d727d43585a/</cas:687474703a2f2f736368656d61732e6d6963726f736f66742e636f6d2f6964656e746974792f636c61696d732f6964656e7469747970726f7669646572>
<cas:notOnOrAfter>2018-10-04T14:17:05.275Z</cas:notOnOrAfter>
<cas:longTermAuthenticationRequestTokenUsed>false</cas:longTermAuthenticationRequestTokenUsed>
<cas:sessionindex>_337eded3-a927-4674-b78a-77259cfbf784</cas:sessionindex>
</cas:attributes>
</cas:authenticationSuccess>
So, we need to map this attribute - 687474703a2f2f736368656d61732e786d6c736f61702e6f72672f77732f323030352f30352f6964656e746974792f636c61696d732f6e616d65 to a standard attribute name via AttributeResolver
We have tried the following configuration but its not working out
"attributeReleasePolicy" : {
"#class" : "org.apereo.cas.services.ReturnMappedAttributeReleasePolicy",
"allowedAttributes" : {
"#class" : "java.util.TreeMap",
"name" : "username",
"displayname" : "userdisplayname",
"someattrname" : "groovy { return attributes['name']}"
}
}
So, anyone who was able to map the attributeNames via AttributeReleasePolicies ?
Any help related to this configuration will be really helpful
This issue is resolved. We had to give the complete path of the attribute and not just part of the name
{
"#class" : "org.apereo.cas.services.RegexRegisteredService",
"serviceId" : "^(https|imaps)://.*"
"name" : "SOME-NAME",
"id" : 200,
"description" : "This configuration is for app",
"evaluationOrder" : 10000
"logoutType" : "BACK_CHANNEL",
"logoutUrl" : "https://login.microsoftonline.com/522b3803-a001-4675-b3b5-1d727d43585a/saml2"
"attributeReleasePolicy" : {
"#class" : "org.apereo.cas.services.ReturnMappedAttributeReleasePolicy",
"allowedAttributes" : {
"#class" : "java.util.TreeMap",
"userid" : "groovy { return attributes['http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name']}"
"displayname" : "groovy { return attributes['http://schemas.xmlsoap.org/ws/2005/05/identity/claims/displayname']}"
}
}
}
So, post this configuration change, now the SAML Response is returning meaningful names
<cas:serviceResponse xmlns:cas='http://www.yale.edu/tp/cas'>
<cas:authenticationSuccess>
<cas:user>Elsbhy4pa-ZLcZ7OWNZ-0vKWjqzV4F7UfVYjRJTCjDY</cas:user>
<cas:attributes>
<cas:credentialType>ClientCredential</cas:credentialType>
<cas:isFromNewLogin>false</cas:isFromNewLogin>
<cas:authenticationDate>2018-10-05T09:20:07.216Z[Etc/UTC]</cas:authenticationDate>
<cas:authenticationMethod>ClientAuthenticationHandler</cas:authenticationMethod>
<cas:clientName>SOME_CLIENT</cas:clientName>
<cas:displayname>FirstName Lastname</cas:displayname>
<cas:successfulAuthenticationHandlers>ClientAuthenticationHandler</cas:successfulAuthenticationHandlers>
<cas:longTermAuthenticationRequestTokenUsed>false</cas:longTermAuthenticationRequestTokenUsed>
<cas:userid>myusername#MYDOMAIN.onmicrosoft.com</cas:userid>
</cas:attributes>
</cas:authenticationSuccess>
</cas:serviceResponse>

SSRS 2008 Execution Service LoadReport Error

I'm using SSRS 2008 (NOT R2)
I have a report deployed to a dev server, I'm trying to render the report as a pdf by calling the execution service.
The error I am getting is
This operation is not supported on a report server that runs in native mode. ---> Microsoft.ReportingServices.Diagnostics.Utilities.OperationNotSupportedNativeModeException: This operation is not supported on a report server that runs in native mode.
Two things I notice: one is that web service wsdl shows LoadReport having two parameters - report path and history id, but when I generate a service reference for the ReportExecution2005.asmx, the LoadReport method has 5 parameters: trusteduserheader, reportPath, historyid, serviceinfoheader, and executionheader
I have tried adding the service reference with and without ?wsdl at the end of the url but the result is the same
Here's the code I'm using:
ReportExecutionServiceSoapClient rs = new ReportExecutionServiceSoapClient("ReportExecutionServiceSoap", "http://xxx:80/ReportServer/ReportExecution2005.asmx");
rs.ClientCredentials.Windows.ClientCredential = new NetworkCredential("aaa", "aaa", "aaa");
rs.ClientCredentials.Windows.AllowedImpersonationLevel = TokenImpersonationLevel.Impersonation;
// Render arguments
byte[] result = null;
string reportPath = "/Invoices/InvoiceStandard";
string format = "PDF";
string historyID = null;
string devInfo = "";
// Prepare report parameter.
ParameterValue[] parameters = new ParameterValue[3];
parameters[0] = new ParameterValue();
parameters[0].Name = "PartyID";
parameters[0].Value = "19758";
parameters[1] = new ParameterValue();
parameters[1].Name = "Contract";
parameters[1].Value = "17703"; // June
parameters[2] = new ParameterValue();
parameters[2].Name = "FinancialPeriod";
parameters[2].Value = "MAR-2012";
string encoding="";
string mimeType="";
string extension="";
Warning[] warnings = null;
string[] streamIDs = null;
ExecutionInfo execInfo = new ExecutionInfo();
TrustedUserHeader trusteduserHeader = new TrustedUserHeader();
ExecutionHeader execHeader = new ExecutionHeader();
ServerInfoHeader serviceInfo = new ServerInfoHeader();
execHeader = rs.LoadReport(trusteduserHeader, reportPath, historyID, out serviceInfo, out execInfo);
rs.SetExecutionParameters(execHeader, trusteduserHeader, parameters, "en-us", out execInfo);
try
{
rs.Render(execHeader,
trusteduserHeader,
format,
devInfo,
out result,
out extension,
out encoding,
out mimeType,
out warnings,
out streamIDs);
}
Here's my web.config
<?xml version="1.0"?>
<configuration>
<connectionStrings>
<add name="ApplicationServices"
connectionString="data source=.\SQLEXPRESS;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|\aspnetdb.mdf;User Instance=true"
providerName="System.Data.SqlClient" />
</connectionStrings>
<system.web>
<compilation debug="true" targetFramework="4.0" />
<authentication mode="Forms">
<forms loginUrl="~/Account/Login.aspx" timeout="2880" />
</authentication>
<membership>
<providers>
<clear/>
<add name="AspNetSqlMembershipProvider" type="System.Web.Security.SqlMembershipProvider" connectionStringName="ApplicationServices"
enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="false"
maxInvalidPasswordAttempts="5" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10"
applicationName="/" />
</providers>
</membership>
<profile>
<providers>
<clear/>
<add name="AspNetSqlProfileProvider" type="System.Web.Profile.SqlProfileProvider" connectionStringName="ApplicationServices" applicationName="/"/>
</providers>
</profile>
<roleManager enabled="false">
<providers>
<clear/>
<add name="AspNetSqlRoleProvider" type="System.Web.Security.SqlRoleProvider" connectionStringName="ApplicationServices" applicationName="/" />
<add name="AspNetWindowsTokenRoleProvider" type="System.Web.Security.WindowsTokenRoleProvider" applicationName="/" />
</providers>
</roleManager>
</system.web>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="ReportExecutionServiceSoap" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
useDefaultWebProxy="true">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Windows"/>
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://xxx:80/ReportServer/ReportExecution2005.asmx"
binding="basicHttpBinding" bindingConfiguration="ReportExecutionServiceSoap"
contract="SSRS.ReportExecutionServiceSoap" name="ReportExecutionServiceSoap" />
</client>
</system.serviceModel>
</configuration>
I had the same problem with SSRS 2008 R2, but I did not want to resort to calling the report viewer control.
Above, Rick Hodder was using the following statement:
TrustedUserHeader trusteduserHeader = new TrustedUserHeader();
This statement will cause the OperationNotSupportedNativeModeException error he encountered if the SSRS installation is not configured with a certificate for SSL connections. Check the SSRS Logs for an error entry that contains:
ERROR: TrustedHeader Not Supported in Native Mode.
If this is the case, you need to either configure the server to work with SSL, or use null for the trusted header.
TrustedUserHeader trusteduserHeader = null;
Is this report loaded from some front end or is it loaded from DLL? To me it looks like you are using ASP.net Application. In this case you could use reportViewer object to pull the report for you all the heavy lifting can be done by the ReportViewer and you can then just save the file as PDF
using something like this
reportViewer.ServerReport.ReportServerUrl = new Uri(Config.ReportServerURL);
reportViewer.ServerReport.ReportPath = String.Format("{0}/{1}", Config.ReportServerEnvironment, reportName);
reportViewer.ServerReport.ReportServerCredentials = new ReportsCredentials(Config.ReportServerUser, Config.ReportServerPassword, Config.ReportServerDomain);
reportViewer.GetDocumentStream(SSRSFormatType.Pdf, documentName);
Here reportViewer is the reference to ReportViewer object on the screen.

How do I validate a SAML assertion in Perl?

I need to validate a SAML assertion of this kind:
<saml:Assertion xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ID="Assertion-uuide824d44-0134-14b1-8e70-f85c710cb043" IssueInstant="2011-12-05T13:55:47Z" Version="2.0">
<saml:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">MPS</saml:Issuer>
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#" Id="uuide824d48-0134-18fe-b37b-f85c710cb043">
<ds:SignedInfo>
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"></ds:CanonicalizationMethod>
<ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"></ds:SignatureMethod>
<ds:Reference URI="#Assertion-uuide824d44-0134-14b1-8e70-f85c710cb043">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"></ds:Transform>
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
<xc14n:InclusiveNamespaces xmlns:xc14n="http://www.w3.org/2001/10/xml-exc-c14n#" PrefixList="xs saml xsi"></xc14n:InclusiveNamespaces>
</ds:Transform>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></ds:DigestMethod>
<ds:DigestValue>p02xKMDUYCR5xpppYUOQgsGBR5c=</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>R9YHo8TK/wYkGkTP3QrnnM8U6TKf9vu+ElpRjDPgpg4O88oARZSb9OhlVn2sXJGEaQ5i0ORrofbKwOI+D/jFgz3Hz/g/h4yt2aqIFxLpOTFb448bDvFsHHWAoWc0DUPYf1AjW7Peu1ICSCdR3EaVLqtgdsUsVWoA7oXbWyAyVLM=</ds:SignatureValue>
<ds:KeyInfo>
<ds:KeyValue>
<ds:RSAKeyValue>
<ds:Modulus>iZ0D1X6rk8+ZwNBTVZt7C85m421a8A52Ksjw40t+jNvbLYDp/W66AMMYD7rB5qgniZ5K1p9W8ivM9WbPxc2u/60tFPg0e/Q/r/fxegW1K1umnay+5MaUvN3p4XUCRrfg79OvurvXQ7GZa1/wOp5vBIdXzg6i9CVAqL29JGi6GYU=</ds:Modulus>
<ds:Exponent>AQAB</ds:Exponent>
</ds:RSAKeyValue>
</ds:KeyValue>
</ds:KeyInfo>
</ds:Signature>
<saml:Subject>
<saml:NameID Format="urn:ibm:names:ITFIM:5.1:accessmanager">J006068</saml:NameID>
<saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer"></saml:SubjectConfirmation>
</saml:Subject>
<saml:Conditions NotBefore="2011-12-05T13:45:47Z" NotOnOrAfter="2011-12-05T14:05:47Z">
<saml:AudienceRestriction>
<saml:AttributeValue xsi:type="xs:string">1030</saml>
I did not find a library on CPAN that can take the SAML as argument and can validate it.
Someone can help me with how to reach my goal?
Ok, better late than never... how to use it...
When you say 'validate' I'm not sure if you mean 'check the assertion', or 'verify the signature'.
my $assertion = Net::SAML2::Protocol::Assertion->new_from_xml(
xml => decode_base64($saml_response)
);
then you just check the validity of the Assertion object created via the accessors. I'm assuming you understand SAML semantics.
To verify the signature, you need access to the private key:
my $sig = Net::SAML2::XML::Sig->new( { key =>'/private.key' } );
$sig->verify( $xml );
See the XML::Sig perldoc for variations on the source of the key (x509, certs).
Note that Net::SAML2 doesn't cover encrypted SAML assertions () but you didn't ask about that.
The Net::SAML2 CPAN module would help you out here
http://metacpan.org/pod/Net::SAML2