无法通过 HTTP post 接收 SAML 响应
Failed to receive SAML response by HTTP post
在 SSO 实施中,验证用户后,我创建了一个 SAMLResponse 对象并使用 IdentityProvider.SendSAMLResponseByHTTPPost() 方法将其发布到默认登陆 URL。
IdentityProvider.SendSAMLResponseByHTTPPost(Response,
strAssertionConsumerServiceURL, samlResponseXml, relayState);
samlResponseXml - 包含 SAML 请求 XML
在 ServiceProvider.ReceiveSAMLResponseByHTTPPost() 方法上,我得到以下捕获异常。
Failed to receive SAML response by HTTP post
身份提供者和服务提供者都在同一个网络域中。
附上 ComponentSpace.SAML2 的日志
ComponentSpace.SAML2 Verbose: 0 : 9:19:44 PM: Missing form variable SAMLResponse
ComponentSpace.SAML2 Verbose: 0 : 9:19:44 PM: Exception: ComponentSpace.SAML2.SAMLBindingException: The form is missing the variable SAMLResponse
ComponentSpace.SAML2 Verbose: 0 : 9:19:44 PM: Exception: ComponentSpace.SAML2.SAMLBindingException: Failed to receive response over HTTP POST. ---> ComponentSpace.SAML2.SAMLBindingException: The form is missing the variable SAMLResponse
at ComponentSpace.SAML2.Bindings.HTTPPostBinding.GetFormVariables(HttpRequest httpRequest, String messageFormVariableName, XmlElement& samlMessage, String& relayState)
at ComponentSpace.SAML2.Bindings.HTTPPostBinding.ReceiveResponse(HttpRequest httpRequest, XmlElement& samlMessage, String& relayState)
--- End of inner exception stack trace ---
问题:
(1) 无法通过 HTTP post
接收 SAML 响应
(2)
ComponentSpace.SAML2 Verbose: 0 : 9:19:44 PM: Missing form variable SAMLResponse
ComponentSpace.SAML2 Verbose: 0 : 9:19:44 PM: Exception: ComponentSpace.SAML2.SAMLBindingException: The form is missing the variable SAMLResponse
分辨率:
SAML 异常日志指出 SAML 响应的 form/format 不正确。
Creating SAML Response for SSO提供以下示例代码来演示如何使用 ComponentSpace 库生成 SAML 响应。
// Create a SAML response with the user's local identity.
private SAMLResponse CreateSAMLResponse()
{
//Trace.Write("IdPreating SAML response");
SAMLResponse samlResponse = new SAMLResponse();
samlResponse.Destination = strAssertionConsumerServiceURL;
Issuer issuer = new Issuer(CreateAbsoluteURL("~/"));
samlResponse.Issuer = issuer;
samlResponse.Status = new Status(SAMLIdentifiers.PrimaryStatusCodes.Success, null);
SAMLAssertion samlAssertion = new SAMLAssertion();
samlAssertion.Issuer = issuer;
//Subject subject = new Subject(new NameID(User.Identity.Name));
Subject subject = new Subject(new NameID());
SubjectConfirmation subjectConfirmation = new SubjectConfirmation(SAMLIdentifiers.SubjectConfirmationMethods.Bearer);
SubjectConfirmationData subjectConfirmationData = new SubjectConfirmationData();
subjectConfirmationData.Recipient = strAssertionConsumerServiceURL;
subjectConfirmation.SubjectConfirmationData = subjectConfirmationData;
subject.SubjectConfirmations.Add(subjectConfirmation);
samlAssertion.Subject = subject;
samlAssertion.SetAttributeValue("MemberId", this.txtMemberId.Text);
samlAssertion.SetAttributeValue("Name", this.txtName.Text);
samlAssertion.SetAttributeValue("Phone", this.txtPhone.Text);
AuthnStatement authnStatement = new AuthnStatement();
authnStatement.AuthnContext = new AuthnContext();
authnStatement.AuthnContext.AuthnContextClassRef = new AuthnContextClassRef(SAMLIdentifiers.AuthnContextClasses.Password);
samlAssertion.Statements.Add(authnStatement);
samlResponse.Assertions.Add(samlAssertion);
return samlResponse;
}
// Send the SAML response to the SP.
private void SendSAMLResponse(SAMLResponse samlResponse, string relayState)
{
// Serialize the SAML response for transmission.
XmlElement samlResponseXml = samlResponse.ToXml();
// Sign the SAML response.
X509Certificate2 x509Certificate = (X509Certificate2)Application["IdPX509Certificate"];
SAMLMessageSignature.Generate(samlResponseXml, x509Certificate.PrivateKey, x509Certificate);
IdentityProvider.SendSAMLResponseByHTTPPost(Response, strAssertionConsumerServiceURL, samlResponseXml, relayState);
}
在使用 Firebug 控制台和 Fiddler2 进行多次尝试后,已确定当我尝试将数据发布到 AssertionConsumerServiceURL
页面时调用了 Http GET,尽管使用了 SendSAMLResponseByHTTPPost() 和 ReceiveSAMLResponseByHTTPPost()。
string strAssertionConsumerServiceURL = "http://localhost:58986/AssertionInternal.aspx";
上面的 AssertionConsumer 服务 url 被修改为如下,
string strAssertionConsumerServiceURL = "http://localhost:58986/AssertionInternal";
有了这个 URL,SAML POST 数据已成功接收。
指定 URL 扩展名为 .aspx 在我的应用程序中调用 GET Verb
而不是 POST 动词
在 SSO 实施中,验证用户后,我创建了一个 SAMLResponse 对象并使用 IdentityProvider.SendSAMLResponseByHTTPPost() 方法将其发布到默认登陆 URL。
IdentityProvider.SendSAMLResponseByHTTPPost(Response, strAssertionConsumerServiceURL, samlResponseXml, relayState);
samlResponseXml - 包含 SAML 请求 XML
在 ServiceProvider.ReceiveSAMLResponseByHTTPPost() 方法上,我得到以下捕获异常。
Failed to receive SAML response by HTTP post
身份提供者和服务提供者都在同一个网络域中。
附上 ComponentSpace.SAML2 的日志
ComponentSpace.SAML2 Verbose: 0 : 9:19:44 PM: Missing form variable SAMLResponse
ComponentSpace.SAML2 Verbose: 0 : 9:19:44 PM: Exception: ComponentSpace.SAML2.SAMLBindingException: The form is missing the variable SAMLResponse
ComponentSpace.SAML2 Verbose: 0 : 9:19:44 PM: Exception: ComponentSpace.SAML2.SAMLBindingException: Failed to receive response over HTTP POST. ---> ComponentSpace.SAML2.SAMLBindingException: The form is missing the variable SAMLResponse
at ComponentSpace.SAML2.Bindings.HTTPPostBinding.GetFormVariables(HttpRequest httpRequest, String messageFormVariableName, XmlElement& samlMessage, String& relayState)
at ComponentSpace.SAML2.Bindings.HTTPPostBinding.ReceiveResponse(HttpRequest httpRequest, XmlElement& samlMessage, String& relayState)
--- End of inner exception stack trace ---
问题:
(1) 无法通过 HTTP post
(2)
ComponentSpace.SAML2 Verbose: 0 : 9:19:44 PM: Missing form variable SAMLResponse
ComponentSpace.SAML2 Verbose: 0 : 9:19:44 PM: Exception: ComponentSpace.SAML2.SAMLBindingException: The form is missing the variable SAMLResponse
分辨率:
SAML 异常日志指出 SAML 响应的 form/format 不正确。
Creating SAML Response for SSO提供以下示例代码来演示如何使用 ComponentSpace 库生成 SAML 响应。
// Create a SAML response with the user's local identity.
private SAMLResponse CreateSAMLResponse()
{
//Trace.Write("IdPreating SAML response");
SAMLResponse samlResponse = new SAMLResponse();
samlResponse.Destination = strAssertionConsumerServiceURL;
Issuer issuer = new Issuer(CreateAbsoluteURL("~/"));
samlResponse.Issuer = issuer;
samlResponse.Status = new Status(SAMLIdentifiers.PrimaryStatusCodes.Success, null);
SAMLAssertion samlAssertion = new SAMLAssertion();
samlAssertion.Issuer = issuer;
//Subject subject = new Subject(new NameID(User.Identity.Name));
Subject subject = new Subject(new NameID());
SubjectConfirmation subjectConfirmation = new SubjectConfirmation(SAMLIdentifiers.SubjectConfirmationMethods.Bearer);
SubjectConfirmationData subjectConfirmationData = new SubjectConfirmationData();
subjectConfirmationData.Recipient = strAssertionConsumerServiceURL;
subjectConfirmation.SubjectConfirmationData = subjectConfirmationData;
subject.SubjectConfirmations.Add(subjectConfirmation);
samlAssertion.Subject = subject;
samlAssertion.SetAttributeValue("MemberId", this.txtMemberId.Text);
samlAssertion.SetAttributeValue("Name", this.txtName.Text);
samlAssertion.SetAttributeValue("Phone", this.txtPhone.Text);
AuthnStatement authnStatement = new AuthnStatement();
authnStatement.AuthnContext = new AuthnContext();
authnStatement.AuthnContext.AuthnContextClassRef = new AuthnContextClassRef(SAMLIdentifiers.AuthnContextClasses.Password);
samlAssertion.Statements.Add(authnStatement);
samlResponse.Assertions.Add(samlAssertion);
return samlResponse;
}
// Send the SAML response to the SP.
private void SendSAMLResponse(SAMLResponse samlResponse, string relayState)
{
// Serialize the SAML response for transmission.
XmlElement samlResponseXml = samlResponse.ToXml();
// Sign the SAML response.
X509Certificate2 x509Certificate = (X509Certificate2)Application["IdPX509Certificate"];
SAMLMessageSignature.Generate(samlResponseXml, x509Certificate.PrivateKey, x509Certificate);
IdentityProvider.SendSAMLResponseByHTTPPost(Response, strAssertionConsumerServiceURL, samlResponseXml, relayState);
}
在使用 Firebug 控制台和 Fiddler2 进行多次尝试后,已确定当我尝试将数据发布到 AssertionConsumerServiceURL
页面时调用了 Http GET,尽管使用了 SendSAMLResponseByHTTPPost() 和 ReceiveSAMLResponseByHTTPPost()。
string strAssertionConsumerServiceURL = "http://localhost:58986/AssertionInternal.aspx";
上面的 AssertionConsumer 服务 url 被修改为如下,
string strAssertionConsumerServiceURL = "http://localhost:58986/AssertionInternal";
有了这个 URL,SAML POST 数据已成功接收。
指定 URL 扩展名为 .aspx 在我的应用程序中调用 GET Verb 而不是 POST 动词