Axis2 WebService Client: The given SOAPAction does not match an operation - soap

I have a test webservice developed with CXF running in my computer and I have been trying to make the client side with the "wsdl2java" function of Apache Axis2. I have already generated the code but I have the following error:
org.apache.axis2.AxisFault: The given SOAPAction http://service.taller1.webservices.spring.com/HolaMundoService/saludaHola does not match an operation.
at org.apache.axis2.util.Utils.getInboundFaultFromMessageContext(Utils.java:531)
at org.apache.axis2.description.OutInAxisOperationClient.handleResponse(OutInAxisOperation.java:375)
at org.apache.axis2.description.OutInAxisOperationClient.send(OutInAxisOperation.java:421)
at org.apache.axis2.description.OutInAxisOperationClient.executeImpl(OutInAxisOperation.java:229)
at org.apache.axis2.client.OperationClient.execute(OperationClient.java:165)
at com.spring.webservices.taller1.service.impl.HolaMundoServiceImplServiceStub.saludaHola(HolaMundoServiceImplServiceStub.java:182)
at mian.Main.main(Main.java:27)
Here the wsdl:
<?xml version='1.0' encoding='UTF-8'?><wsdl:definitions xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="http://impl.service.taller1.webservices.spring.com/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:ns2="http://schemas.xmlsoap.org/soap/http" xmlns:ns1="http://service.taller1.webservices.spring.com/" name="HolaMundoServiceImplService" targetNamespace="http://impl.service.taller1.webservices.spring.com/">
<wsdl:import location="http://localhost:8080/webservice-cfx-spring-0.0.1-SNAPSHOT/HolaMundoService?wsdl=HolaMundoService.wsdl" namespace="http://service.taller1.webservices.spring.com/">
</wsdl:import>
<wsdl:binding name="HolaMundoServiceImplServiceSoapBinding" type="ns1:HolaMundoService">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="saludaHola">
<soap:operation soapAction="" style="document"/>
<wsdl:input name="saludaHola">
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output name="saludaHolaResponse">
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="HolaMundoServiceImplService">
<wsdl:port binding="tns:HolaMundoServiceImplServiceSoapBinding" name="HolaMundoServiceImplPort">
<soap:address location="http://localhost:8080/webservice-cfx-spring-0.0.1-SNAPSHOT/HolaMundoService"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
I would appreciate any help. Thanks in advance for your help!

you're probably using the wrong action or the wrong schema binding.
The following may work for you:
ServiceClient client = new ServiceClient();
OperationClient operationClient = client.createClient(ServiceClient.ANON_OUT_IN_OP);
// creating message context
MessageContext outMsgCtx = new MessageContext();
// assigning message context’s option object into instance variable
Options opts = outMsgCtx.getOptions();
// setting properties into option
opts.setTo(new EndpointReference("http://localhost:8080/webservice-cfx-spring-0.0.1-SNAPSHOT/HolaMundoService"));
opts.setAction(""); //your soap action is null
HttpTransportProperties.Authenticator auth = new HttpTransportProperties.Authenticator();
auth.setUsername("user");
auth.setPassword("pass");
opts.setProperty(org.apache.axis2.transport.http.HTTPConstants.AUTHENTICATE, auth);
//Create the Soap Factory
SOAPFactory fac = OMAbstractFactory.getSOAP11Factory();
//Create the request envelope
SOAPEnvelope envelope = fac.getDefaultEnvelope();
OMNamespace globalNs = fac.createOMNamespace("http://service.taller1.webservices.spring.com/", "ns1");
// creating the payload
OMElement method = fac.createOMElement("saludaHola", globalNs);
method.setText("Hello");
envelope.getBody().addChild(method);
outMsgCtx.setEnvelope(envelope);
operationClient.addMessageContext(outMsgCtx);
operationClient.execute(true);
MessageContext inMsgtCtx = operationClient.getMessageContext("In");
//get the response
SOAPEnvelope response = inMsgtCtx.getEnvelope();
System.out.println(response);

Related

Verifying Signed Xml Generated From Java In NET

I have the below XML,
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<Response xmlns="http://www.site.ae/g">
<Message xml:id="message">
<Header>
<Service>Read</Service>
<Action>SomeAction</Action>
</Header>
<Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="SomeDataType">
<Status>Success</Status>
<Data>
<Id>123</Id>
</Data>
</Body>
</Message>
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
<SignedInfo>
<CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments"/>
<SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
<Reference URI="#message">
<Transforms>
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
<DigestValue>SomeValue</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>
SomeValue
</SignatureValue>
<KeyInfo>
<X509Data>
<X509Certificate>
SomeValue
</X509Certificate>
</X509Data>
</KeyInfo>
</Signature>
</Response>
The above XML genereted from a java application. The java application team provided us 3 certificate to verify the above xml. I have created 3 objects in C#,
var clientCert = new X509Certificate2("clientCert.cer");
var intermediateCert = new X509Certificate2("intermediateCert.cer");
var rootCert = new X509Certificate2("rootCert.cer");
One is root, second one is intermediate and third one is certificate. I have created the below code,
var xmlDoc = new XmlDocument();
xmlDoc.PreserveWhitespace = true;
xmlDoc.Load("above.xml");
bool result = VerifyXml(xmlDoc, clientCert);
private static Boolean VerifyXml(XmlDocument Doc, X509Certificate2 Key)
{
// Create a new SignedXml object and pass it
// the XML document class.
var signedXml = new System.Security.Cryptography.Xml.SignedXml(Doc);
// Find the "Signature" node and create a new XmlNodeList object.
XmlNodeList nodeList = Doc.GetElementsByTagName("Signature");
// Throw an exception if no signature was found.
if (nodeList.Count <= 0)
{
throw new CryptographicException("Verification failed: No Signature was found in the document.");
}
// Though it is possible to have multiple signatures on
// an XML document, this app only supports one signature for
// the entire XML document. Throw an exception
// if more than one signature was found.
if (nodeList.Count >= 2)
{
throw new CryptographicException("Verification failed: More that one signature was found for the document.");
}
// Load the first <signature> node.
signedXml.LoadXml((XmlElement)nodeList[0]);
// Check the signature and return the result.
return signedXml.CheckSignature(Key, true);
}
But the above code result is always return false. Is there is something I am missing? Is .NET support verifying the xml generated from java?
Got Answer from
Verify SignatureValue And DigestValue Using Sha256 RSA

How to remove Mule Headers from SOAP response

I have a requirement where I need to expose a SOAP webservice .. So I have the following Mule flow :-
<jms:activemq-connector name="Active_MQ" brokerURL="tcp://localhost:61616" validateConnections="true" doc:name="Active MQ"/>
<flow name="Flow1" doc:name="Flow1" >
<http:inbound-endpoint exchange-pattern="request-response" host="localhost" port="8082" path="mainData" doc:name="HTTP"/>
<cxf:jaxws-service serviceClass="com.test.services.schema.maindata.v1.MainData" doc:name="SOAP"/>
<mulexml:object-to-xml-transformer doc:name="Object to XML"/>
<jms:outbound-endpoint queue="NewQueue" connector-ref="Active_MQ" doc:name="JMS" exchange-pattern="request-response"/>
<logger message="Response2 :- #[message.payload]" level="INFO" doc:name="Logger"/>
<mulexml:xml-to-object-transformer doc:name="XML to Object"/>
</flow>
<flow name="flow2" doc:name="flow2" >
<jms:inbound-endpoint connector-ref="Active_MQ" address="jms://tcp:NewQueue" doc:name="JMS" exchange-pattern="request-response" disableTemporaryReplyToDestinations="true" responseTimeout="90000"/>
<set-variable variableName="SOAPRequest" value="#[message.payload]" doc:name="Variable"/>
<mulexml:xml-to-object-transformer doc:name="XML to Object"/>
<component class="com.test.services.schema.maindata.v1.Impl.MainDataImpl" doc:name="JavaMain_ServiceImpl">
<method-entry-point-resolver>
<include-entry-point method="retrieveDataOperation"/>
<include-entry-point method="insertDataOperation"/>
<include-entry-point method="updateDataOperation"/>
<include-entry-point method="deleteDataOperation"/>
</method-entry-point-resolver>
</component>
<mulexml:object-to-xml-transformer doc:name="Object to XML"/>
</flow>
Here you can see the request is getting into JMS queue from the first flow and the second flow use JMS inbound takes it from the JMS queue and the webservice implemented class proccess it .. Now the service works fine without any issue .. the only issue is it get Mule Header in the SOAP in the response like the following :-
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
<mule:header xmlns:mule="http://www.muleumo.org/providers/soap/1.0">
<mule:MULE_CORRELATION_ID>ID:ANIRBAN-PC-49483-1408719168461-1:1:10:1:1</mule:MULE_CORRELATION_ID>
<mule:MULE_CORRELATION_GROUP_SIZE>-1</mule:MULE_CORRELATION_GROUP_SIZE>
<mule:MULE_CORRELATION_SEQUENCE>-1</mule:MULE_CORRELATION_SEQUENCE>
</mule:header>
</soap:Header>
<soap:Body>
<deleteDataResponse xmlns="http://services.test.com/schema/MainData/V1">
<Response>Data not exists !!! Please provide correct ID</Response>
<Id>0</Id>
<Age>0</Age>
</deleteDataResponse>
</soap:Body>
</soap:Envelope>
Now please help me to remove the Mule headers from the SOAP response .. I tried with the following :- <cxf:jaxws-service serviceClass="com.test.services.schema.maindata.v1.MainData" enableMuleSoapHeaders="false" doc:name="SOAP"/> but no use .. it's still showing the Mule headers .. Please help ..
You can potentially get away with a temporary workaround until the enableMuleSoapHeaders="false" issue gets solved, by either:
Adding a between the HTTP inbound endpoint and the CXF service ; in order to remove the undue SOAP headers but XSL-Transformation
Using delete-message-property to remove the MULE_* props at the end of Flow1, right after the mulexml:xml-to-object-transformer
I also found an alternate solution off adding it to cxf:outInterceptors
<cxf:jaxws-service serviceClass="com.test.services.schema.maindata.v1.MainData" doc:name="SOAP">
<cxf:outInterceptors >
<spring:bean id="outfault" class="com.test.services.schema.SOAPOptionalData.SOAPInterceptorOutboundHeaderRemover"/>
</cxf:outInterceptors>
</cxf:jaxws-service>
And in the Java class :-
public class SOAPInterceptorOutboundHeaderRemover extends AbstractSoapInterceptor {
public SOAPInterceptorOutboundHeaderRemover() {
super(Phase.PRE_PROTOCOL);
}
#Override
public void handleMessage(SoapMessage arg0) throws Fault {
List<Header> headerList = arg0.getHeaders();
Header muleHeader = null;
boolean isMuleHeader = false;
for (Header header : headerList) {
ElementNSImpl element = (ElementNSImpl) header.getObject();
if ("mule:header".equals(element.getNodeName())) {
isMuleHeader = true;
muleHeader = header;
}
}
if (isMuleHeader) {
arg0.getHeaders().remove(muleHeader);
}
}
}
And this is also working fine

Error: ContractFilter mismatch at the EndpointDispatcher

I am developing an iPhone app that is using the WCF to return data in json format. But when I am making call to the wcf service then I am getting the Error:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"><s:Body><s:Fault><faultcode xmlns:a="http://schemas.microsoft.com/ws/2005/05/addressing/none">a:ActionNotSupported</faultcode><faultstring xml:lang="en-US">The message with Action 'IPhoneDevService/GetConferenceIdByEventUrlName' cannot be processed at the receiver, due to a ContractFilter mismatch at the EndpointDispatcher. This may be because of either a contract mismatch (mismatched Actions between sender and receiver) or a binding/security mismatch between the sender and the receiver. Check that sender and receiver have the same contract and the same binding (including security requirements, e.g. Message, Transport, None).</faultstring></s:Fault></s:Body></s:Envelope>
Service name : IPhoneDevService.svc there is no interface created for this.Same issue is comin g if I am using the Interface
Function :
[ServiceContract(Namespace = "")]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
[ServiceBehaviorAttribute(IncludeExceptionDetailInFaults = true)]
[DataContractFormat(Style = OperationFormatStyle.Document)]
// NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "IPhoneDevService" in code, svc and config file together.
public class IPhoneDevService
{
[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.WrappedRequest, RequestFormat = WebMessageFormat.Xml, ResponseFormat = WebMessageFormat.Json)]
[OperationContract]
public string GetOneUserAuthentication(long confrenceid, string email, string password)
{
StringBuilder sbJson = new StringBuilder();
try
{
User[] objuserdetails = new User[1];
System.Nullable<short> strRet = 0;
string strRetMsg = string.Empty;
using (LINQTODBDataContext objDB = new LINQTODBDataContext())
{
objuserdetails = objDB.s_t_UserLoginVerifyClient(email, password, ref strRet, ref strRetMsg).Select(res => new User
{
UserID = res.UserId,
Message = ExceptionMsg.GetMessage(Convert.ToInt32(strRet), strRetMsg)
}).ToArray();
if (strRet == 2)
{
new JavaScriptSerializer().Serialize(objuserdetails, sbJson);
}
else
{
new JavaScriptSerializer().Serialize(ExceptionMsg.GetMessage(Convert.ToInt32(strRet), strRetMsg), sbJson);
}
}
}
catch (Exception ex)
{
return "";
}
return sbJson.ToString();
}
}
xcode consumption is:
NSString *soapMessage = [NSString stringWithFormat:#"<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\ <http://schemas.xmlsoap.org/soap/envelope/%5C>"><SOAP-ENV:Body><GetOneUserAuthentication><confrenceid>123</confrenceid><email>demo#abc.com <mailto:demo#abc.com></email><password>abc</password></GetOneUserAuthentication></SOAP-ENV:Body></SOAP-ENV:Envelope>"];
NSURL *url = [NSURL URLWithString:#"http://mydomain.com/IPhoneDevService.svc/basic"];
NSMutableURLRequest *theRequest = [NSMutableURLRequest requestWithURL:url];
NSString *msgLength = [NSString stringWithFormat:#&quot;%d&quot;, [soapMessage length]];
[theRequest addValue: #&quot;text/xml; charset=utf-8&quot; forHTTPHeaderField:#&quot;Content-Type&quot;];
[theRequest addValue:#&quot;IPhoneDevService/GetOneUserAuthentication&quot; forHTTPHeaderField:#&quot;SOAPAction&quot;];
[theRequest addValue: msgLength forHTTPHeaderField:#&quot;Content-Length&quot;];
[theRequest setHTTPMethod:#&quot;POST&quot;];
[theRequest setHTTPBody: [soapMessage dataUsingEncoding:NSUTF8StringEncoding]];
NSURLConnection *theConnection = [[NSURLConnection alloc] initWithRequest:theRequest delegate:self];
Service Model of WCF webconfig is:
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
<bindings>
<basicHttpBinding>
<binding name="bhbinding" allowCookies="false">
<readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
<security mode="None" />
</binding>
</basicHttpBinding>
</bindings>
<behaviors>
<endpointBehaviors>
<behavior name="web">
<webHttp />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="ServiceBehaviour">
<!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
<serviceMetadata httpGetEnabled="true" />
<!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
<behavior>
<!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
<serviceMetadata httpGetEnabled="true" />
<!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="false" />
<serviceThrottling maxConcurrentCalls="400" maxConcurrentInstances="400" maxConcurrentSessions="400" />
</behavior>
<behavior name="IphoneServiceBehaviour">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
<useRequestHeadersForMetadataAddress>
<defaultPorts>
<add scheme="http" port="8081" />
<add scheme="https" port="444" />
</defaultPorts>
</useRequestHeadersForMetadataAddress>
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service name="Configurator_Service.IPhoneDevService" behaviorConfiguration="IphoneServiceBehaviour">
<endpoint address="basic" binding="basicHttpBinding" bindingConfiguration="bhbinding" contract="Configurator_Service.IPhoneDevService" />
</service>
</services>
</system.serviceModel>
It looks like you've configured your endpoint wrong.
In your WCF configuration you have:
<endpoint address="basic"
but in your XCode you specify
http://.../IPhoneDevService.svc
The endpoint address you specified in your configuration is going to look like:
http://.../IPhoneDevService.svc/basic
Typically, you just leave the endpoint address blank unless you need to have more than one (e.g. if you want to expose an MEX endpoint).

%XML.DataSet creating invalid xml

Class Services.TestClass Extends (%RegisteredObject, %XML.Adaptor)
{
Property DS As %XML.DataSet;
}
and the following web method inside my web service class:
Method HelloWorld(name As %String) As Services.TestClass [ WebMethod ]
{
Quit ##class(Services.TestClass).%New()
}
This produces the following XML:
<s:complexType name="TestClass">
<s:sequence>
<s:element minOccurs="0" name="DS" type="s0:DataSet"/>
</s:sequence>
</s:complexType>
<s:complexType name="s_DataSet">
<s:sequence>
<s:element ref="s:schema"/>
<s:any/>
</s:sequence>
</s:complexType>
</s:schema>
I believe s_DataSet name should actually be just DataSet, because s0:DataSet points to DataSet, not s_DataSet
When I use a client that consumes the service I get the following error: Error: type 'DataSet#http://tempuri.org' not found.
(from SoapUI)
When I take the DataSet property out of the TestClass and return it directly everything is fine. What is going on?
What you are showing us is (part of) the WSDL of the WebService (class).
s_Dataset is just a name, the schema part refers to the schema element.
Calling the webService :
... Serivices.Client.cls?soap_method=HelloWorld&name=zzz
Just produces:
<SOAP-ENV:Envelope>
<SOAP-ENV:Body>
<HelloWorldResponse>
<HelloWorldResult/>
</HelloWorldResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
No errors

What is the correct format for SAML 2.0 Assertions?

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");
}
}
}