invalid request on wstlogin.srf (WS-Trust)

Hello,

Each time I try to authenticate with Windows Live Date using RPS I get an "invalid request" error response.

<?xml version='1.0' encoding='UTF-8'?><S:Envelope xmlnsTongue Tied="http://www.w3.org/2003/05/soap-envelope" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlnsStick out tonguesf="http://schemas.microsoft.com/Passport/SoapServices/SOAPFault">
<S:Body><S:Fault><S:Code><S:Value>STongue Tiedender</S:Value></S:Code><S:Reason><S:Text xml:lang="en-US">Invalid Request</S:Text></S:Reason></S:Fault></S:Body></S:Envelope>

I follow the directives from http://msdn2.microsoft.com/en-us/library/bb447721.aspx replacing username and password values but I always got the same error.

Any help ?

[1195 byte] By [demo4] at [2008-2-23]
# 1

Could you please post the code you are using to make the request. Please replace the real Windows Live ID and password with some dummy values when posting on the forum.

PermitMe at 2007-10-11 > top of Msdn Tech,Windows Live Developer Forums,Windows Live Data Development...
# 2
The documentation is possibly out of date, I will post the correct SOAP envelope once I get more information. Thanks for your patience.
PermitMe at 2007-10-11 > top of Msdn Tech,Windows Live Developer Forums,Windows Live Data Development...
# 3
Just before we shipped Cumulus there was a last minute change in the syntax for the WS-Trust requests. We have the new syntax and we need to update our docs. Hopefully that should happen early next week. Sorry for the confusion.
Yaron
YaronY.Goland at 2007-10-11 > top of Msdn Tech,Windows Live Developer Forums,Windows Live Data Development...
# 4

You can use the following code to acquire RPS tickets.

Code Snippet

using System;

using System.Net;

using System.Xml;

using System.Xml.XPath;

class Program

{

static void Main(string[] args)

{

TicketAcquirer t = new TicketAcquirer();

string s = t.GetTicket();

Console.WriteLine(s);

}

}

public class TicketAcquirer

{

private const string userName = "yourWindowsLiveID@hotmail.com";

private const string password = "yourPassword";

private const string applicationId = "10"; // An arbitrary value that will be defined in the next non-alpha release

private const string soapEnvelope = @"<s:Envelope

xmlns:s = ""http://www.w3.org/2003/05/soap-envelope""

xmlns:wsse = ""http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd""

xmlns:saml = ""urn:oasis:names:tc:SAML:1.0:assertion""

xmlns:wsp = ""http://schemas.xmlsoap.org/ws/2004/09/policy""

xmlns:wsu = ""http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd""

xmlns:wsa = ""http://www.w3.org/2005/08/addressing""

xmlns:wssc = ""http://schemas.xmlsoap.org/ws/2005/02/sc""

xmlns:wst = ""http://schemas.xmlsoap.org/ws/2005/02/trust"">

<s:Header>

<wlid:ClientInfo xmlns:wlid = ""http://schemas.microsoft.com/wlid"">

<wlid:ApplicationID>" + applicationId + @"</wlid:ApplicationID>

</wlid:ClientInfo>

<wsa:Action s:mustUnderstand = ""1"">http://schemas.xmlsoap.org/ws/2005/02/trust/RST/Issue</wsa:Action>

<wsa:To s:mustUnderstand = ""1"">https://dev.login.live.com/wstlogin.srf</wsa:To>

<wsse:Security>

<wsse:UsernameToken wsu:Id = ""user"">

<wsse:Username>" + userName + @"</wsse:Username>

<wsse:Password>" + password + @"</wsse:Password>

</wsse:UsernameToken>

</wsse:Security>

</s:Header>

<s:Body>

<wst:RequestSecurityToken Id = ""RST0"">

<wst:RequestType>http://schemas.xmlsoap.org/ws/2005/02/trust/Issue</wst:RequestType>

<wsp:AppliesTo>

<wsa:EndpointReference>

<wsa:Address>http://live.com</wsa:Address>

</wsa:EndpointReference>

</wsp:AppliesTo>

<wsp:PolicyReference URI = ""MBI""></wsp:PolicyReference>

</wst:RequestSecurityToken>

</s:Body>

</s:Envelope>

";

/* methods */

public string GetTicket()

{

const string url = @"https://dev.login.live.com/wstlogin.srf";

WebRequest request = WebRequest.Create(url);

request.Method = "POST";

request.ContentType = "application/soap+xml; charset=UTF-8";

request.Timeout = 10 * 1000; // Wait for at most 10 seconds

byte[] bytes = System.Text.Encoding.UTF8.GetBytes(soapEnvelope);

request.GetRequestStream().Write(bytes, 0, bytes.Length);

request.GetRequestStream().Close();

WebResponse response;

response = request.GetResponse();

string xml;

using (System.IO.StreamReader reader = new System.IO.StreamReader(response.GetResponseStream()))

xml = reader.ReadToEnd();

response.Close();

XmlDocument document = new XmlDocument();

document.LoadXml(xml);

XmlNamespaceManager nsManager = new XmlNamespaceManager(document.NameTable);

nsManager.AddNamespace("wsse", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");

XmlNode node = document.SelectSingleNode(@"//wsse:BinarySecurityToken/text()", nsManager);

if (node == null)

return null; // The wsse:BinarySecurityToken element is missing. Examine the xml for error information

else

return node.Value;

}

}

PermitMe at 2007-10-11 > top of Msdn Tech,Windows Live Developer Forums,Windows Live Data Development...
# 5

Here is an example of a success response:

Code Snippet

<?xml version="1.0" encoding="utf-8" ?>
<S:Envelope xmlns:S = "http://www.w3.org/2003/05/soap-envelope">
<S:Header></S:Header>
<S:Body>
<wst:RequestSecurityTokenResponse
xmlns:S = "http://www.w3.org/2003/05/soap-envelope"
xmlns:psf = "http://schemas.microsoft.com/Passport/SoapServices/SOAPFault"
xmlns:wsse = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
xmlns:saml = "urn:oasis:names:tc:SAML:1.0:assertion"
xmlns:wst = "http://schemas.xmlsoap.org/ws/2005/02/trust"
xmlns:wsp = "http://schemas.xmlsoap.org/ws/2004/09/policy"
xmlns:wsu = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<wst:TokenType>urn:passport:compact</wst:TokenType>
<wsp:AppliesTo xmlns:wsa = "http://www.w3.org/2005/08/addressing">
<wsa:EndpointReference>
<wsa:Address>http://live.com</wsa:Address>
</wsa:EndpointReference>
</wsp:AppliesTo>
<wst:Lifetime>
<wsu:Created>2007-06-07T18:49:18Z</wsu:Created>
<wsu:Expires>2007-06-08T02:49:18Z</wsu:Expires>
</wst:Lifetime>
<wst:RequestedSecurityToken>
<wsse:BinarySecurityToken Id = "Compact0">t=EwDQARAnAAAURATre1Nkcu71L953y0QRAvwyKdOAAOvPFywnEgZhxfuteZvux+A1CLkGwMCfwYlgzbRgp4fSlR1uB0MNhh7navf0P0Pj8SFzF4quFfao4hhOdu8KI0A4ZnkK4Tnv45bUThaJZDS87I2FOZyvbe6h9upyej/nDdZTv4L3m6VurwVwNbaRdOjjPCmcz0NB9NBHz/bZwn4LA2YAAAgclX6u5SBpQCABpEvjTYKLQwGktsCM8MapkzNRvEr2OhXJGAhqflDzP7TlQqeoU6EeNuWmntZFFN/RX5DFxkyx2QbLi5Zat7/z9qDBZPcRrx6wm/LbllVS7Bhpk7J0nS8rGyhRMXpCxf1xb9DazXGVBip5o4LGM3f5ZPLbOsLuypO4fTIcZ49FxjdhoyABJcfwFvR8POYDbV+6KpBf8J7XHL5JkUTcAfS7uquZem5nzq+jClxl7EoGzgBktmznQKVhGrkbR69zR82zsD0fuZqFJ/AkQ+1zDL1IDNTcCOT/8st0hhHakrDfbWZfZ6+KxUh7ucx/1z8VZA9jxAyS7RmDtC1cxEjgDooHip227l5zm3WiLPjIrhty9wmjIPP3zw4sxbuh8/UV9yfdQAE=&amp;p=</wsse:BinarySecurityToken>
</wst:RequestedSecurityToken>
<wst:RequestedAttachedReference>
<wsse:SecurityTokenReference>
<wsse:Reference URI = "REXF1JXpv5fuoOdA0CfdEb3d4OQ="></wsse:Reference>
</wsse:SecurityTokenReference>
</wst:RequestedAttachedReference>
<wst:RequestedUnattachedReference>
<wsse:SecurityTokenReference>
<wsse:Reference URI = "REXF1JXpv5fuoOdA0CfdEb3d4OQ="></wsse:Reference>
</wsse:SecurityTokenReference>
</wst:RequestedUnattachedReference>
</wst:RequestSecurityTokenResponse>
</S:Body>
</S:Envelope>

PermitMe at 2007-10-11 > top of Msdn Tech,Windows Live Developer Forums,Windows Live Data Development...
# 6

Here is an example of a failure response:

Code Snippet

<?xml version='1.0' encoding='UTF-8'?>
<S:Envelope
xmlns:S = "http://www.w3.org/2003/05/soap-envelope"
xmlns:wsse = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
xmlns:psf = "http://schemas.microsoft.com/Passport/SoapServices/SOAPFault">
<S:Body>
<S:Fault>
<S:Code>
<S:Value>wsse:FailedAuthentication</S:Value>
</S:Code>
<S:Reason>
<S:Text xml:lang = "en-US">Authentication Failure</S:Text>
</S:Reason>
</S:Fault>
</S:Body>
</S:Envelope>

PermitMe at 2007-10-11 > top of Msdn Tech,Windows Live Developer Forums,Windows Live Data Development...
# 7

Has anyone gotten this to work with .NET CF? Here are a few things I have picked up:

- The HttpWebRequest must allow write stream buffering:

Code Snippet
request.AllowWriteStreamBuffering =
true;

- The TicketAcquirer class should implement the ICertificatePolicy interface, and always return true in CheckValidationResult():

Code Snippet

#region ICertificatePolicy Members

publicbool CheckValidationResult(ServicePoint srvPoint, X509Certificate certificate, WebRequest request, int certificateProblem)

{

returntrue;

}

#endregion

The first line of GetTicket() then becomes:

Code Snippet

System.Net.ServicePointManager.CertificatePolicy = this;

Even after all of these "fixes" I still get an Invalid Request SOAP fault in the response. I am currently stuck here:

Code Snippet

<?xml version='1.0' encoding='UTF-8'?>

<S:Envelope xmlns:S="http://www.w3.org/2003/05/soap-envelope" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:psf="http://schemas.microsoft.com/Passport/SoapServices/SOAPFault">

<S:Body>

<S:Fault>

<S:Code>

<S:Value>S:Sender</S:Value>

</S:Code>

<S:Reason>

<S:Text xml:lang="en-US">Invalid Request</S:Text>

</S:Reason>

</S:Fault>

</S:Body>

</S:Envelope>

marsboee at 2007-10-11 > top of Msdn Tech,Windows Live Developer Forums,Windows Live Data Development...
# 8
Hi, marsboee, sorry for the delay of response. I cannot get the code snippet running right now since PocketPC simulator just cannot successfully connect to the network. I will try it again back home using my own cellphone and let you know if I get anything out of it.
YuanYuanYu-MSFT at 2007-10-11 > top of Msdn Tech,Windows Live Developer Forums,Windows Live Data Development...
# 9

Hi. Thanks for the effort. I also had the problem where my simulator couldn't connect. The behavior I am describing was seen on my WM5 device in debug mode.

I look forward to the results of your attempt.

marsboee at 2007-10-11 > top of Msdn Tech,Windows Live Developer Forums,Windows Live Data Development...
# 10

Is JavaScript imlementation available for the C# code anywhere, as an alternative?

As it would be great to use this RPS method of requestion a token straigh from JavaScript.

I am developing a gadget which connects to Windows Live account to get contact details

from an address book, and would like to retrieve the auth.token with the help of JavaScript, not C# code. Is it possible?
SergeiGolubev at 2007-10-11 > top of Msdn Tech,Windows Live Developer Forums,Windows Live Data Development...
# 11

Sergei:
I'm not aware of a JavaScript implementation and I'm not very familiar with gadgets, but I believe can use RPS with JavaScript and the Web Gadgets framework.

Also consider using the Contacts Control as an alternative. I just asked Koji Kato, the Program Manager for the Contacts Control and he said you can embedd the control on a Web Gadget.

Let me know how it goes!

FedericoRaggi-MSFT at 2007-10-11 > top of Msdn Tech,Windows Live Developer Forums,Windows Live Data Development...
# 12

Thanks for your help, Federico.

I already had a look at the Contacts Control before, however in doubt if I can customise it enough. What I would like my gadget to display is the list of contacts as a simple list of links, when you click on a name the flyout opens with the specific information on this contact. At the moment to authenticate to the address book of Windows Live I'm using C# code to get auth.token via RPS and then with AJAX I am sending it to the server to get XML data back. Thus, I am not sure that Contacts Control will allow me to do this?

SergeiGolubev at 2007-10-11 > top of Msdn Tech,Windows Live Developer Forums,Windows Live Data Development...
# 13
OK, more on making this work with the .NET CF. Apparently, the request *HAS* to have it's ContentLength property set. By doing this, I can get the ticket successfully (finally).

Here's some code:

Code Snippet

HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
request.Method = "POST";
request.ContentType = "application/soap+xml; charset=UTF-8";
request.Timeout = 60 * 1000; // Wait for at most 60 seconds

byte[] bytes = System.Text.Encoding.UTF8.GetBytes(soapEnvelope);

request.AllowWriteStreamBuffering = true;
request.ContentLength = bytes.Length;

Stream stream = request.GetRequestStream();
stream.Write(bytes, 0, (int)request.ContentLength);
stream.Close();

HttpWebResponse response = null;
response = request.GetResponse() as HttpWebResponse;


The only issue I see now is I see a "System.IO.IOException" first-chance exception and a "System.UriFormatException" first-chance exception roll by as the GetRequestStream() function is called. I'm not sure what's going on here, or if I need to worry about it?

Let me know, community, what you think.

-Aaron

marsboee at 2007-10-11 > top of Msdn Tech,Windows Live Developer Forums,Windows Live Data Development...
# 14

Hi, Aaron:

Very nice work. Please let us know what kind of cool app you have come up with for mobile platforms. We will have more exciting new feature in this upcoming beta release (hint: much more interesting than dumb addresses/telephones/last names). Please stay tuned.

As for the exceptions, I am not sure about the IOException, but the UriFormatException is a bit weird. What is the Uri you are using?

YuanYuanYu-MSFT at 2007-10-11 > top of Msdn Tech,Windows Live Developer Forums,Windows Live Data Development...

Windows Live Developer Forums

Site Classified