I have C# code to produce a SAML 2.0 AuthnRequest:
String requestXML = "<samlp:AuthnRequest xmlns:samlp=\"urn:oasis:names:tc:SAML:2.0:protocol\" xmlns:saml=\"urn:oasis:names:tc:SAML:2.0:assertion\" ID=\"https://saml.example.com/login\" Version=\"2.0\" IssueInstant=\"" + DateTime.Now.ToString("yyyy-MM-ddTHH:mm:ss") + "\" AssertionConsumerServiceIndex=\"0\"><saml:Issuer>https://saml.example.com/login</saml:Issuer><samlp:NameIDPolicy AllowCreate=\"true\" Format=\"urn:oasis:names:tc:SAML:2.0:nameid-format:transient\"/></samlp:AuthnRequest>";
String convertedRequestXML = System.Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(requestXML));
return Redirect("https://idp.ssocircle.com:443/sso/SSORedirect/metaAlias/ssocircle"+ "?SAMLRequest=" + convertedRequestXML + "&RelayState=" + HttpUtility.UrlEncode("/SamlLogin?ReturnUrl=" + returnurl));
With my actual domain name instead of example.com. I set this up on https://ssocircle.com/ with the SP metadata like this
<md:EntityDescriptor
xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata"
xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
entityID="https://saml.example.com/login">
<md:SPSSODescriptor
protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
<md:AssertionConsumerService index="0"
Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
Location="https://saml.example.com/login" />
</md:SPSSODescriptor>
<md:Organization>
<md:OrganizationName xml:lang="en">
example
</md:OrganizationName>
<md:OrganizationDisplayName xml:lang="en">
example
</md:OrganizationDisplayName>
<md:OrganizationURL xml:lang="en">
http://www.example.com/
</md:OrganizationURL>
</md:Organization>
However, the page returns with:
Error occurred
Reason: The SAML Request is invalid.
And unhelpfully, no other errors. I have also tried setting this up with https://openidp.feide.no but that only returned a blank page with a 500 server error.
My get string comes out as
https://idp.ssocircle.com/sso/SSORedirect/metaAlias/ssocircle?SAMLRequest=PHNhbWxwOkF1dGhuUmVxdWVzdCB4bWxuczpzYW1scD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOnByb3RvY29sIiB4bWxuczpzYW1sPSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6YXNzZXJ0aW9uIiBJRD0iaHR0cHM6Ly9zYW1sLmV4YW1wbGUuY29tL2xvZ2luIiBWZXJzaW9uPSIyLjAiIElzc3VlSW5zdGFudD0iMjAxNC0wOS0xMVQwOTozMTo1NyIgQXNzZXJ0aW9uQ29uc3VtZXJTZXJ2aWNlSW5kZXg9IjAiPjxzYW1sOklzc3Vlcj5odHRwczovL3NhbWwuZXhhbXBsZS5jb20vbG9naW48L3NhbWw6SXNzdWVyPjxzYW1scDpOYW1lSURQb2xpY3kgQWxsb3dDcmVhdGU9InRydWUiIEZvcm1hdD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOm5hbWVpZC1mb3JtYXQ6dHJhbnNpZW50Ii8+PC9zYW1scDpBdXRoblJlcXVlc3Q+&RelayState=%2fSamlLogin%3fReturnUrl%3d31lOpEvtWshJNDa314yOgw%3d%3d
Which https://idp.ssocircle.com/sso/toolbox/samlDecode.jsp is 'unable to decode' and https://rnd.feide.no/simplesaml/module.php/saml2debug/debug.php comes out with
<samlp:AuthnRequest xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" ID="https://saml.example.com/login" Version="2.0" IssueInstant="2014-09-11T09:31:57" AssertionConsumerServiceIndex="0"><saml:Issuer>https://saml.example.com/login</saml:Issuer><samlp:NameIDPolicy AllowCreate="true" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient"/��[[�]]��\]Y\�
I have also tried with similar results
String convertedRequestXML = System.Convert.ToBase64String(System.Text.UTF8Encoding.UTF8.GetBytes(requestXML));
My questions are
1) Is my SAML AuthnRequest actually valid?
2) Is my encoding method correct?
3) Are there any better tools I can use to debug this? These sites do not give out any helpful (or any at all) error messages when something goes wrong
It's not enough to Base64 encode the request, you also need to do something called deflating.
Read the chapter on the HTTP redirect binding.
There is a explanation on how to defalte in C# here
Related
I've confirmed that I have permissions to perform the request.
According to amazon's Cloud Search Dev Troubleshooting Guide the error I'm experiencing is likely due to the .net sdk using the wrong api version. I don't see a way to specify the api version explicitely.
I want to avoid having to manually create the http request.
I want to make the request through the SDK.
I've tried all the available versions of the SDK and all of them give me this error.
I've also tried specifying the request properties in various combinations. Nothing works.
Can anybody give me direction as to how I can resolve this issue?
Expected behavior: return info for all index fields
Actual behavior:
error -
"Result Message:
Amazon.Runtime.AmazonUnmarshallingException : Error unmarshalling response back from AWS. Response Body: {
"message": "Request forbidden by administrative rules",
"__type": "CloudSearchException"
}"
----> System.Xml.XmlException : Data at the root level is invalid. Line 1, position 1.
Code sample:
var _configClient = new AmazonCloudSearchClient(
WebConfigurationManager.AppSettings["CloudSearchAccessKey"],
WebConfigurationManager.AppSettings["CloudSearchSecretKey"],
new AmazonCloudSearchConfig
{
RegionEndpoint = RegionEndpoint.USWest2,
ServiceURL = WebConfigurationManager.AppSettings["CloudSearchUrl"]
});
await _configClient.DescribeIndexFieldsAsync(new DescribeIndexFieldsRequest())
CloudSearch is returning json, which you can see in your response body, and the SDK is trying to unmarshal that into xml. When you make a query directly, you can add &format=xml to get xml results. There should be an analogous option in the SDK.
while i'm using WWW in Unity3D(c#), i found ridiculous result.
www.text has error text not in www.error. so i can't check whether error occured.
if(!string.IsNullOrEmpty (www.error)) {
//handling error
//but www.error is null
}else{
//print www.text
Debug.Log(www.text);
}
[print console]
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>503 Service Temporarily Unavailable</title>
</head><body>
<h1>Service Temporarily Unavailable</h1>
<p>The server is temporarily unable to service your
request due to maintenance downtime or capacity
problems. Please try again later.</p>
<p>Additionally, a 404 Not Found
error was encountered while trying to use an ErrorDocument to handle the request.</p>
</body></html>
does anybody has this experience? please help me..
Your check with IsNullOrEmpty looks fine to me. Never seen any whitespace there, only empty string or null.
Check what HTTP code is returned by the server. Stating in HTML that this is the error code not necessarily mean that the protocol error is the same. Some proxies or broken setups can cause this.
Get cURL and check the error code:
curl -v http://example.com/lipsum
and look for:
< HTTP/1.1 404 Not Found
or simmilar.
well i wanted to make a simple webservice that searches the db and return the data i know i can do it with mysql connector but this is just to learn how to use soaps here is the code for php soap server
require_once ('lib/nusoap.php');
$namespace = "http://localhost/webservice/index.php?wsdl";
$server = new soap_server();
$server->configureWSDL("DBQuery");
$server->wsdl->schemaTargetNamespace = $namespace;
$server->register(
'QueryMsg',
array('name'=>'xsd:string'),
array('return'=>'xsd:string'),
$namespace,
false,
'rpc',
'encoded',
'returns data from database');
function QueryMsg($query)
{
$con=mysqli_connect('localhost','root','','webserivce');
if (mysqli_connect_errno()) {
return "Failed to connect to MySQL: " . mysqli_connect_error();
}
if(!isset($query) or strpos(strtolower($query),'select')<=-1)
{
return "invalid order";
}
else
{
mysqli_real_escape_string($con,$query);
$result = mysqli_query($con,$query);
while($row = mysqli_fetch_array($result)) {
$data[] = $row;}
return json_encode($data);
}
}
// create HTTP listener
$HTTP_RAW_POST_DATA = isset($HTTP_RAW_POST_DATA) ? $HTTP_RAW_POST_DATA : '';
$server->service($HTTP_RAW_POST_DATA);
exit();
?>
it works when i try calling it from a php soap client but when i try adding this http:// localhost /webservice/index.php in visual studio as service refernce to consume it from C# application i get an error here it is
The HTML document does not contain Web service discovery information.
Metadata contains a reference that cannot be resolved: 'http://localhost/webservice/index.php'.
The content type text/xml; charset=ISO-8859-1 of the response message does not match the content type of the binding (application/soap+xml; charset=utf-8). If using a custom encoder, be sure that the IsContentTypeSupported method is implemented properly. The first 700 bytes of the response were: '<?xml version="1.0" encoding="ISO-8859-1"?><SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Body><SOAP-ENV:Fault><faultcode xsi:type="xsd:string">SOAP-ENV:Client</faultcode><faultactor xsi:type="xsd:string"></faultactor><faultstring xsi:type="xsd:string">Operation '' is not defined in the WSDL for this service</faultstring><detail xsi:type="xsd:string"></detail></SOAP-ENV:Fault></SOAP-ENV:Body></SOAP-ENV:Envelope>'.
The remote server returned an error: (500) Internal Server Error.
If the service is defined in the current solution, try building the solution and adding the service reference again.
solved : well it was easy actually there is two ways either use WCF and change encoding to ISO-8859-1
or change encoding of the web service itself by adding this line $server->soap_defencoding = 'UTF-8'; after creating the soap server
I would try adding the service WSDL with a tool like SOAP U.I. and see what kind of errors you get back from that. It's a little more agnostic than adding a web reference with C#, and might disclose more details about why at the client level you can't consume this.
I'm happy to help you troubleshoot this with a little more information. Are you running this service on the same machine where you're running the client from? If it's complaining about being unable to correlate the file http://localhost/webservice/index.php to something I wonder if the discovery process is trying to evaluate a file that can't be found. I.E. an import operation in your source WSDL that points to a URL the client can't resolve.
I have a program that should login to site, it uses POST requests, and all goes fine, until one of the values contain special character('%' for example).
captcha = "ABCDE" //all goes fine and well, server accept captcha
captcha = "ABC&%" //server dont accept captcha and return fail
//here is the bad part:
string request = "password=" + HttpUtility.UrlEncode(encpass, Encoding.UTF8) +
"&username=" + login + "&captcha_text=" + HttpUtility.UrlEncode(captcha, Encoding.UTF8);
Also, i ofcourse googled it, and checked all i could find. I though i need to "warn" server abaut encoding, so i added
request.Headers.TryAddWithoutValidation("Content-Type", #"application/x-www-form-urlencoded; charset=UTF-8");
but it still did not helped me.
Content types and way request should look like i get from Firebug, so if i can find some answers there - please point.
modify0: Also, i compared what my program send to server with browser request(using Firebug) and my request is completley same. Only difference - my request dont get accepted in values it contain special-characters.
modify1: Also, server have no problems handling special-characters when i check it in browser. For example it(browser) sent "K&YF82" as "captcha_text=K%26YF82"(same value in addres propereties and request body) and all worked fine. UrlEncode do same replacement, but in my program it doesnt get accepted by server.
SOLUTION:
{ password:"df464dsj", username:"username", captchaText:"ABC&%", remember_login:"false" }
insteat of
password=f2341f14f&username=username&captha...
Are you dealing with REST application??
If yes then send your post data in request body instead of query string.
Also have a look at the stack post at : Special characters pose problems with REST webservice communication
I'm trying to run GetChanges method (sitedata.asmx) from a Java application. However I can't figure out the correct parameters I must pass. This is for SharePoint 2010.
By checking on the service protocol specification, I saw this are the required parameters:
objectType: The change tracking space
to report about, either
"ContentDatabase" or "SiteCollection".
All other objectType values, as
defined in section 2.2.5.3, MUST NOT
be used. Note that "Site" in the
context of this parameter actually
means site collection.
contentDatabaseId: GUID of the content
database, known in advance or obtained
by GetContent request.
LastChangeId: A token specifying the starting point
for the requested change report.
Normally the protocol client obtains
this value from the response to a
previous GetContent or GetChanges operation.
CurrentChangeId: A token specifying
the endpoint for the requested change
report. If not empty, CurrentChangeId
must be a valid token obtained from
the response to a previous GetChanges
operation. Normally, this element is
empty; empty specifies that the
protocol client requests all changes
starting from the starting point up to
the present time.
Timeout: A value
that determines how many changes
should be fetched in the current
operation. This value MUST be greater
than 0 and the protocol server MUST
only fetch x% of total changes that
are fetched by default, where x is
(Timeout divided by 30000).
The protocol client MUST pass tokens that
correspond to the change tracking
space specified by the objectType and
the target URL of the SOAP request.
The SOAP In message I'm sending is as follows:
<?xml version='1.0' encoding='UTF-8'?>
<soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope">
<soapenv:Body>
<ns1:GetChanges xmlns:ns1="http://schemas.microsoft.com/sharepoint/soap/">
<ns1:objectType>SiteCollection</ns1:objectType>
<ns1:contentDatabaseId>E5C5E20A-5A9F-406C-B9F6-28923750CECD</ns1:contentDatabaseId>
<ns1:startChangeId>1;0;E5C5E20A-5A9F-406C-B9F6-28923750CECD;634438121498470000;46852</ns1:startChangeId>
<ns1:Timeout>0</ns1:Timeout>
</ns1:GetChanges>
</soapenv:Body>
</soapenv:Envelope>
However I get this response:
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<soap:Fault>
<soap:Code>
<soap:Value>soap:Receiver</soap:Value>
</soap:Code>
<soap:Reason>
<soap:Text xml:lang="en">Exception of type 'Microsoft.SharePoint.SoapServer.SoapServerException' was thrown.</soap:Text>
</soap:Reason>
<detail>
<errorstring xmlns="http://schemas.microsoft.com/sharepoint/soap/">Object reference not set to an instance of an object.</errorstring>
</detail>
</soap:Fault>
</soap:Body>
</soap:Envelope>
Checked the logs from SharePoint (located at Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\LOGS) and found the following exception:
SOAP exception: System.NullReferenceException: Object reference not set to an instance of an object.
at Microsoft.SharePoint.SPChangeToken.ParseChangeToken(String strChangeToken)
at Microsoft.SharePoint.SPChangeToken..ctor(String strChangeToken)
at Microsoft.SharePoint.SoapServer.SiteDataImpl.GetChanges(ObjectType objectType, String contentDatabaseId, String& startChangeId, String& endChangeId, Int64 maxChangesToFetch, UInt32 maxSPRequests, Boolean getMetadata, Boolean ignoreSecurityIfInherit, Int32 schemaVersion, Boolean& moreChanges)
at Microsoft.SharePoint.SoapServer.SiteDataImpl.GetChanges(ObjectType objectType, String contentDatabaseId, String& startChangeId, String& endChangeId, Int32 Timeout, Boolean& moreChanges)
at Microsoft.SharePoint.SoapServer.SiteData.GetChanges(ObjectType objectType, String contentDatabaseId, String& LastChangeId, String& CurrentChangeId, Int32 Timeout, Boolean& moreChanges)
However, I'm not able to find any references to that error. I can't even found the method ParseChangeToken from SPChangeToken class (http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.spchangetoken_methods.aspx), so this is confusing.
I already saw this question, however this doesn't solve my issue: Other question
Can anyone help me calling this web service correctly?
EDIT
Tried calling it from a C# application to determine that the issue is not with Java. This is the code:
SiteData.SiteDataSoapClient siteDataService = new SiteData.SiteDataSoapClient();
siteDataService.Endpoint.Address = new System.ServiceModel.EndpointAddress("URL/_vti_bin/sitedata.asmx");
siteDataService.ClientCredentials.Windows.ClientCredential = new System.Net.NetworkCredential("username", "password", "domain");
siteDataService.ClientCredentials.Windows.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation;
String startChangeId = "1;1;69d025ce-96a7-4131-adc0-7da1603e8d24;634439002539570000;46914";
String endChangeId = "";
bool hasMoreChanges = false;
String databaseID = E5C5E20A-5A9F-406C-B9F6-28923750CECD; //Got it by querying SharePoint database. Any idea how to get it programatically?
String result = siteDataService.GetChanges(SiteData.ObjectType.SiteCollection, databaseID, ref startChangeId, ref endChangeId, 0, out hasMoreChanges);
return result;
However, I got 'Microsoft.SharePoint.SoapServer.SoapServerException' and the detail of this exception is null. Used Fiddler to spy on the XML returned by the SharePoint server, and found the same 'Object reference not set to an instance of an object' exception.
So this certainly means there is something wrong with the parameters I'm passing, right?
Thanks!!
Edit
If someone is interested, I made this work too by setting StartChangeId to LastChangeId and EndChangeId to CurrentChangeId in the XML message.
Solved it. By checking on the SharePoint logs, I noticed the following lines:
06/20/2011 08:24:03.80 w3wp.exe (0x1C2C) 0x0CAC SharePoint Foundation General fbs6 Medium <?xml version="1.0" ?><S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"><S:Body><GetChanges xmlns="http://schemas.microsoft.com/sharepoint/soap/"><objectType>SiteCollection</objectType><contentDatabaseId>{E5C5E20X-5A9F-406C-B9F6-28923750CECD}</contentDatabaseId><startChangeId></startChangeId><endChangeId>1;1;69c025ce-96a7-4131-adc0-7da1603e8d24;634439772069030000;47449</endChangeId><Timeout>0</Timeout></GetChanges></S:Body></S:Envelope> bafe1d43-e41c-47e9-bff2-5dc35a15298d
06/20/2011 08:24:03.80 w3wp.exe (0x1C2C) 0x0CAC SharePoint Foundation General 9ka5 Verbose GetChanges: objectType=SiteCollection, contentDbId={E5C5E20X-5A9F-406C-B9F6-28923750CECD}, startChange=, endChange=; MaxChanges=0, MaxSPRequests=50 bafe1d43-e41c-47e9-bff2-3dc35a15298d
Notice on the second line, that the content database Id is enclosed by "{}" characters. Also, see that "contentDbId" is parsed correctly from the incoming XML, while "endChange" is empty. This second observation, is probably what leads to the "Object reference not set to an instance of an object" exception. So, what is wrong with that changeId? No idea, probably there is something wrong with the XML encoding that prevents SharePoint from parsing the changeId correctly.
By further looking on the same log, I found this lines:
06/20/2011 08:42:54.35 w3wp.exe (0x1C2C) 0x2BC4 SharePoint Foundation General fbs6 Medium <?xml version='1.0' encoding='UTF-8'?><soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope"><soapenv:Body><ns1:GetChangesEx xmlns:ns1="http://schemas.microsoft.com/sharepoint/soap/"><ns1:version>1</ns1:version><ns1:xmlInput><GetChanges><ObjectType>1</ObjectType><ContentDatabaseId>{x4284f47-f050-4fe9-b7e9-caf8f4b882b0}</ContentDatabaseId><StartChangeId>1;0;x4284f47-f050-4fe9-b7e9-caf8f4b882b0;634441572386370000;72973</StartChangeId><EndChangeId /><RequestLoad>100</RequestLoad><GetMetadata>False</GetMetadata><IgnoreSecurityIfInherit>True</IgnoreSecurityIfInherit></GetChanges></ns1:xmlInput></ns1:GetChangesEx></soapenv:Body></soapenv:Envelope> fa5ab5a7-2e27-4e78-aa1f-b027ca3b120f
06/20/2011 08:42:54.35 w3wp.exe (0x1C2C) 0x2BC4 SharePoint Foundation General 9ka5 Verbose GetChanges: objectType=ContentDatabase, contentDbId={x4284f47-f050-4fe9-b7e9-caf8f4b882b0}, startChange=1;0;x4284f47-f050-4fe9-b7e9-caf8f4b882b0;634441572386370000;72973, endChange=; MaxChanges=500, MaxSPRequests=50 fa5ab5b7-2e27-4e78-aa1f-b027ca3b120f
Here, the changeId is correctly parsed from the incoming XML. So, I changed from GetChanges() method to GetChangesEx(), passed the exact same parameters I was using on the former call, and it worked correctly!! My guess is that because the parameters are encoded inside an element of the SOAP In request, the Web Service is able to parse them correctly.
Here is the final SOAP In message (formatted):
<?xml version='1.0' encoding='UTF-8'?>
<soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope">
<soapenv:Body>
<ns1:GetChangesEx xmlns:ns1="http://schemas.microsoft.com/sharepoint/soap/">
<ns1:version>1</ns1:version>
<ns1:xmlInput><GetChanges><ObjectType>7</ObjectType><ContentDatabaseId>{X5C5E20A-5A9F-406C-B9F6-28923750CECD}</ContentDatabaseId><StartChangeId>1;1;69f025ce-96a7-4131-adc0-7da1603e8d24;634439727021700000;47404</StartChangeId><EndChangeId>1;1;69d025ce-96a7-4131-adc0-7da1603e8b24;634441802456970000;47472</EndChangeId><RequestLoad>100</RequestLoad><GetMetadata>False</GetMetadata><IgnoreSecurityIfInherit>True</IgnoreSecurityIfInherit></GetChanges></ns1:xmlInput>
</ns1:GetChangesEx>
</soapenv:Body>
</soapenv:Envelope>
Edit
C# code example:
SiteData.SiteDataSoapClient siteDataService = new SiteData.SiteDataSoapClient();
siteDataService.Endpoint.Address = new System.ServiceModel.EndpointAddress("URL/_vti_bin/sitedata.asmx");
siteDataService.ClientCredentials.Windows.ClientCredential = new System.Net.NetworkCredential("username", "password", "domain");
siteDataService.ClientCredentials.Windows.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation;
String xmlInput = "<GetChanges>" +
"<ObjectType>7</ObjectType>" +
"<ContentDatabaseId>{X5C5E20A-5A9F-406C-B9F6-28923750CECD}</ContentDatabaseId>" +
"<StartChangeId>1;1;69b025ce-96a7-4131-adc0-7da1603e8d24;634439727021700000;47404</StartChangeId>" +
"<EndChangeId>1;1;69b025ce-96a7-4131-adc0-7da1603e8d24;634441802456970000;47472</EndChangeId>" +
"<RequestLoad>100</RequestLoad>" +
"<GetMetadata>False</GetMetadata>" +
"<IgnoreSecurityIfInherit>True</IgnoreSecurityIfInherit>" +
"</GetChanges>";
String result = siteDataService.GetChangesEx(1, xmlInput);