正在使用的 Nuget 包:
- Microsoft.AspNetCore.App - 2.1.1
- Microsoft.NETCore.App - 2.1.0
- Sustainsys.Saml2.AspNetCore2 - 2.2.0
点网核心版本:2.1.302
执行
在ConfigureServices(IServiceCollection services)
方法的startup.cs文件中添加以下代码:
services.AddSaml2("saml2", options =>
{
options.SPOptions.EntityId = new Sustainsys.Saml2.Metadata.EntityId(this.Configuration.Get<AppSetting>().SPEntityId);
options.SPOptions.MinIncomingSigningAlgorithm = "http://www.w3.org/2000/09/xmldsig#rsa-sha1";
options.SPOptions.NameIdPolicy = new Sustainsys.Saml2.Saml2P.Saml2NameIdPolicy(true, Sustainsys.Saml2.Saml2P.NameIdFormat.Unspecified);
options.IdentityProviders.Add(
new Sustainsys.Saml2.IdentityProvider(
new Sustainsys.Saml2.Metadata.EntityId(this.Configuration.Get<AppSetting>().SPMetadata), options.SPOptions)
{
LoadMetadata = true,
Binding = Sustainsys.Saml2.WebSso.Saml2BindingType.HttpPost
});
})
身份验证由以下控制器操作触发:
[HttpGet]
public IActionResult Login(string returnUrl = null)
{
var redirectUrl = Url.Content("~/Saml/Callback");
return Challenge(
new AuthenticationProperties { RedirectUri = redirectUrl }, "saml2");
}
https://SP-Server-xxxx/server/Saml2/Acs
与 ID 服务器的身份验证已成功完成,并在本文末尾根据 XML 以POST 请求的形式接收响应。但是,随后会返回以下错误,并带有 HTTP 代码 500:
{
error: "IDX13102: Exception thrown while reading '[PII is hidden]' for Saml2SecurityToken. Inner exception: 'System.ArgumentException'."
}
请提出设置或实施有什么问题。
响应 XML:
<samlp:Response xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" Consent="urn:oasis:names:tc:SAML:2.0:consent:obtained" Destination="https://SP-Server-xxxx/server/Saml2/Acs" ID="XXXXX" InResponseTo="XXXXX" IssueInstant="2018-11-28T06:26:12Z" Version="2.0">
<saml:Issuer>https://ID-Server-yyyy/zzzz/saml2/metadata</saml:Issuer>
<samlp:Status>
<samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/>
</samlp:Status>
<saml:Assertion ID="XXXXX" IssueInstant="2018-11-28T06:26:12Z" Version="2.0">
<saml:Issuer>https://ID-Server-yyyy/zzzz/saml2/metadata</saml:Issuer>
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:SignedInfo>
<CanonicalizationMethod xmlns="http://www.w3.org/2000/09/xmldsig#" Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
<ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
<ds:Reference URI="#yyyyy">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<DigestValue xmlns="http://www.w3.org/2000/09/xmldsig#">zzzzz</DigestValue>
</ds:Reference>
</ds:SignedInfo>
<SignatureValue xmlns="http://www.w3.org/2000/09/xmldsig#"> 'removed the signature value' </SignatureValue>
<ds:KeyInfo>
<ds:X509Data>
<ds:X509Certificate> 'removed the certificate' </ds:X509Certificate>
</ds:X509Data>
</ds:KeyInfo>
</ds:Signature>
<saml:Subject>
<saml:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress" NameQualifier="https://ID-Server-yyyy/zzzz/saml2/metadata" SPNameQualifier="https://SP-Server-xxxx">
abc@xyz.com
</saml:NameID>
<saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
<saml:SubjectConfirmationData InResponseTo="XXXXX" NotOnOrAfter="2018-11-28T06:31:12Z" Recipient="https://SP-Server-xxxx/server/Saml2/Acs"/>
</saml:SubjectConfirmation>
</saml:Subject>
<saml:Conditions NotBefore="2018-11-28T06:21:12Z" NotOnOrAfter="2018-11-28T06:31:12Z">
<saml:AudienceRestriction>
<saml:Audience>https://SP-Server-xxxx</saml:Audience>
</saml:AudienceRestriction>
</saml:Conditions>
<saml:AuthnStatement AuthnInstant="2018-11-28T06:26:09Z" SessionIndex="XXXXX">
<saml:AuthnContext>
<saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:Password</saml:AuthnContextClassRef>
<saml:AuthnContextDeclRef>name/password/uri</saml:AuthnContextDeclRef>
</saml:AuthnContext>
</saml:AuthnStatement>
<saml:AttributeStatement>
<saml:Attribute xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" Name="LastName" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified">
<saml:AttributeValue xsi:type="xs:string">Last Name</saml:AttributeValue>
</saml:Attribute>
<saml:Attribute xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" Name="mail" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified">
<saml:AttributeValue xsi:type="xs:string">abc@xyz.com</saml:AttributeValue>
</saml:Attribute>
<saml:Attribute xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" Name="MiddleName" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified">
<saml:AttributeValue xsi:type="xs:string">Middle Name</saml:AttributeValue>
</saml:Attribute>
<saml:Attribute xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" Name="FirstName" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified">
<saml:AttributeValue xsi:type="xs:string">First Name</saml:AttributeValue>
</saml:Attribute>
<saml:Attribute xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" Name="Id" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified">
<saml:AttributeValue xsi:type="xs:string">Id Value</saml:AttributeValue>
</saml:Attribute>
</saml:AttributeStatement>
</saml:Assertion>
</samlp:Response>
更新:
设置IdentityModelEventSource.ShowPII
为 true 后,错误响应更改如下:
{
error: "IDX13102: Exception thrown while reading 'AuthnContext' for Saml2SecurityToken. Inner exception: 'System.ArgumentException: IDX13300: 'value' must be an absolute Uri, was: 'name/password/uri' at Microsoft.IdentityModel.Tokens.Saml2.Saml2AuthenticationContext.set_DeclarationReference(Uri value) at Microsoft.IdentityModel.Tokens.Saml2.Saml2AuthenticationContext..ctor(Uri classReference, Uri declarationReference) at Microsoft.IdentityModel.Tokens.Saml2.Saml2Serializer.ReadAuthenticationContext(XmlDictionaryReader reader)'."
}
根据错误消息,我假设 ID 服务器需要使用有效的 URI 设置 AuthnContext。请确认。
以下是堆栈跟踪:
2018-11-29 08:45:10.700 +01:00 [Debug] Signature validation passed for Saml Response Microsoft.IdentityModel.Tokens.Saml2.Saml2Id
2018-11-29 08:45:10.759 +01:00 [Error] Exception is occurred
Microsoft.IdentityModel.Tokens.Saml2.Saml2SecurityTokenReadException: IDX13102: Exception thrown while reading 'AuthnContext' for Saml2SecurityToken. Inner exception: 'System.ArgumentException: IDX13300: 'value' must be an absolute Uri, was: 'name/password/uri'
at Microsoft.IdentityModel.Tokens.Saml2.Saml2AuthenticationContext.set_DeclarationReference(Uri value)
at Microsoft.IdentityModel.Tokens.Saml2.Saml2AuthenticationContext..ctor(Uri classReference, Uri declarationReference)
at Microsoft.IdentityModel.Tokens.Saml2.Saml2Serializer.ReadAuthenticationContext(XmlDictionaryReader reader)'. ---> System.ArgumentException: IDX13300: 'value' must be an absolute Uri, was: 'name/password/uri'
at Microsoft.IdentityModel.Tokens.Saml2.Saml2AuthenticationContext.set_DeclarationReference(Uri value)
at Microsoft.IdentityModel.Tokens.Saml2.Saml2AuthenticationContext..ctor(Uri classReference, Uri declarationReference)
at Microsoft.IdentityModel.Tokens.Saml2.Saml2Serializer.ReadAuthenticationContext(XmlDictionaryReader reader)
--- End of inner exception stack trace ---
at Microsoft.IdentityModel.Tokens.Saml2.Saml2Serializer.ReadAuthenticationContext(XmlDictionaryReader reader)
at Microsoft.IdentityModel.Tokens.Saml2.Saml2Serializer.ReadAuthenticationStatement(XmlDictionaryReader reader)
at Sustainsys.Saml2.Saml2P.Saml2PSerializer.ReadAssertion(XmlReader reader)
at Microsoft.IdentityModel.Tokens.Saml2.Saml2SecurityTokenHandler.ReadSaml2Token(String token)
at Microsoft.IdentityModel.Tokens.Saml2.Saml2SecurityTokenHandler.ValidateToken(String token, TokenValidationParameters validationParameters, SecurityToken& validatedToken)
at Sustainsys.Saml2.Saml2P.Saml2Response.CreateClaims(IOptions options, IdentityProvider idp)+MoveNext()
at System.Collections.Generic.List`1.AddEnumerable(IEnumerable`1 enumerable)
at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
at Sustainsys.Saml2.Saml2P.Saml2Response.GetClaims(IOptions options, IDictionary`2 relayData)
at Sustainsys.Saml2.WebSso.AcsCommand.ProcessResponse(IOptions options, Saml2Response samlResponse, StoredRequestState storedRequestState)
at Sustainsys.Saml2.WebSso.AcsCommand.Run(HttpRequestData request, IOptions options)
at Sustainsys.Saml2.AspNetCore2.Saml2Handler.HandleRequestAsync()
at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
at Service.Provider.Middleware.LanguageHandlingMiddleware.Invoke(HttpContext context) in X:\Projects\Service-Provider\Middleware\LanguageHandlingMiddleware.cs:line 21
at Service.Provider.Middleware.ErrorHandlingMiddleware.Invoke(HttpContext context, ILogger`1 logger) in X:\Projects\Service-Provider\Middleware\ErrorHandlingMiddleware.cs:line 22
更新 2
感谢@Anders 的回复。由于我们无法控制 ipd,我已要求 idp 开发人员考虑上述更改。但与此同时,我们试图进一步挖掘这些选项。我已经提到了这里托管的文件之一:https ://media.readthedocs.org/pdf/saml2/latest/saml2.pdf 。2.18.1 节列出了 Element 的属性。它提到了IgnoreAuthenticationContextInResponse
属性。根据属性的描述,似乎将其设为 astrue
将解决上述错误。options.SPOptions.Compatibility.IgnoreAuthenticationContextInResponse
但是在 SPOtions ( ?)中配置 Compatibility 元素时我找不到这个属性
我们正在使用 Sustainsys.Saml2.AspNetCore2 包版本 2.2.0。
是不是该Compatibility.IgnoreAuthenticationContextInResponse
属性在 2.2.0 版本中还不可用?