I'm trying to consume Windows Azure Active Directory as an IdP in a web application. My code works fine on other SAML IdPs but gives the following message in the Windows Azure AD only !!
Sign in
Sorry, but we're having trouble signing you in.
We received a bad request.
Additional technical information:
Trace ID:8377e605-6b9f-47be-8547-5fce7f4285af
Timestamp: 2014-08-04 13:31:27Z
ACS75005:
The request is not a valid SAML2 protocol message.
I replaced my code and used the SAML request that Microsoft published here and replaced only some values but still getting the same error message !!
What is wrong with my request? And how can I get more details about the message !
Knowing that my application is defined in the Windows Azure AD applications.
<samlp:AuthnRequest xmlns="urn:oasis:names:tc:SAML:2.0:metadata" ID="_56dbfeac-107a-46d2-b989-651f90107312" Version="2.0" IssueInstant="2014-08-04T13:28:05Z" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol">
<Issuer xmlns="urn:oasis:names:tc:SAML:2.0:assertion">SOMETHING</Issuer>
</samlp:AuthnRequest>
Edit 001
After editing the assertion to be as Dushyant suggested, it becomes:
<samlp:AuthnRequest xmlns="urn:oasis:names:tc:SAML:2.0:assertion"
ID="_efcebb45-5ee6-42df-ace4-a343f28f5a46"
Version="2.0" IssueInstant="2014-08-07T06:29:09Z"
xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol">
<Issuer xmlns="urn:oasis:names:tc:SAML:2.0:assertion">SOMETHING</Issuer>
</samlp:AuthnRequest>
But still the same error is showing!
Also please find the test project I'm using here. Only replace the values in the AppSettings in the webconfig for your SAML settings.
Use
xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
instead of xmlns="urn:oasis:names:tc:SAML:2.0:metadata"
I believe you followed what we've document here: http://msdn.microsoft.com/en-us/library/azure/dn195589.aspx. If so, you've found a bug in that article - sorry about that.
Hope this helps.
Homam, I reviewed your code. The problem was with the way the AuthnRequest was being encoded. I changed it to standard deflate encoding and it worked.
public string GetAzureRequest(AuthRequestFormat format)
{
string xml = @"<samlp:AuthnRequest xmlns=""urn:oasis:names:tc:SAML:2.0:assertion"" ID=""#ID""
Version=""2.0"" IssueInstant=""#DATE""
xmlns:samlp=""urn:oasis:names:tc:SAML:2.0:protocol"">
<Issuer xmlns=""urn:oasis:names:tc:SAML:2.0:assertion"">#ISSUER</Issuer>
</samlp:AuthnRequest>";
xml = xml.Replace("#DATE", issue_instant);
xml = xml.Replace("#ID", id);
xml = xml.Replace("#ISSUER", appSettings.Issuer);
xml = xml.Replace("\r\n", "");
if (format == AuthRequestFormat.Base64)
{
/*COMMENTED THIS OUT*/
//byte[] toEncodeAsBytes = System.Text.ASCIIEncoding.ASCII.GetBytes(requestDocument.OuterXml);
//string result = System.Convert.ToBase64String(toEncodeAsBytes);
//return result;
/*ADDED THIS*/
MemoryStream memoryStream = new MemoryStream();
StreamWriter writer = new StreamWriter(new DeflateStream(memoryStream, CompressionMode.Compress, true), new UTF8Encoding(false));
writer.Write(xml);
writer.Close();
string result = Convert.ToBase64String(memoryStream.GetBuffer(), 0, (int)memoryStream.Length, Base64FormattingOptions.None);
return result;
}
return null;
}
You need to UrlEncode (e.g. HttpUtility.UrlEncode(result)) the 'result' before using it in a Get request.
I believe there is a mismatch in namespaces here...The SAMLRequest should look like this.
<samlp:AuthnRequest
ID="_efcebb45-5ee6-42df-ace4-a343f28f5a46"
Version="2.0" IssueInstant="2014-08-07T06:29:09Z"
xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol">
<Issuer xmlns="urn:oasis:names:tc:SAML:2.0:assertion">SOMETHING</Issuer>
</samlp:AuthnRequest>
The Issuer element must be in the namespace of 'urn:oasis:names:tc:SAML:2.0:assertion' and the AuthnRequest element within the namespace of 'urn:oasis:names:tc:SAML:2.0:protocol'
Of course this needs to be deflated + base64 encoded. If using HttpRedirect binding then also urlencode this before embedding within the URL