【问题标题】:Ignore AuthenticationContext In SAML2 Response忽略 SAML2 响应中的 AuthenticationContext
【发布时间】:2021-09-14 07:17:00
【问题描述】:

我们有一个 asp.net 5 网络应用程序,它将作为我们用户的服务提供商。
为此,我们选择了ITfoxtec Identity SAML 2.0 库。
请求成功,但在响应中我们收到以下错误:

System.ArgumentException:IDX13300:“System.String”必须是绝对 Uri,原为:“System.Uri”

为了完整起见,这里是完整的堆栈跟踪:

Microsoft.IdentityModel.Tokens.Saml2.Saml2SecurityTokenReadException:IDX13102:读取 Saml2SecurityToken 的“System.String”时引发异常。内部异常:“System.ArgumentException”。 ---> System.ArgumentException:IDX13300:“System.String”必须是绝对 Uri,原为:“System.Uri” 在 Microsoft.IdentityModel.Tokens.Saml2.Saml2AuthenticationContext.set_DeclarationReference(Uri 值) 在 Microsoft.IdentityModel.Tokens.Saml2.Saml2Serializer.ReadAuthenticationContext(XmlDictionaryReader 阅读器) --- 内部异常堆栈跟踪结束 --- 在 Microsoft.IdentityModel.Tokens.Saml2.Saml2Serializer.ReadAuthenticationContext(XmlDictionaryReader 阅读器) 在 Microsoft.IdentityModel.Tokens.Saml2.Saml2Serializer.ReadAuthenticationStatement(XmlDictionaryReader 阅读器) 在 Microsoft.IdentityModel.Tokens.Saml2.Saml2Serializer.ReadAssertion(XmlReader 阅读器) 在 Microsoft.IdentityModel.Tokens.Saml2.Saml2SecurityTokenHandler.ReadSaml2Token(XmlReader 阅读器) 在 Microsoft.IdentityModel.Tokens.Saml2.Saml2SecurityTokenHandler.ReadSaml2Token(字符串令牌) 在 ITfoxtec.Identity.Saml2.Saml2AuthnResponse.ReadSecurityToken(字符串 tokenString) 在 ITfoxtec.Identity.Saml2.Saml2AuthnResponse.Read(字符串 xml,布尔 validateXmlSignature) 在 ITfoxtec.Identity.Saml2.Saml2PostBinding.Read(HttpRequest 请求,Saml2Request saml2RequestResponse,字符串 messageName,布尔 validateXmlSignature) 在 ITfoxtec.Identity.Saml2.Saml2Binding1.ReadSamlResponse(HttpRequest 请求,Saml2Response saml2Response) 在 F:\Dev\ashilon\SsoGovIlApi\Controllers\SamlController.cs:line 45 中的 SsoGovILApi.Controllers.SamlController.AssertionConsumerService() 在 Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.TaskOfIActionResultExecutor.Execute(IActionResultTypeMapper 映射器,ObjectMethodExecutor 执行器,对象控制器,对象 [] 参数) 在 Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.g__Awaited|12_0(ControllerActionInvoker 调用程序,ValueTask1 actionResultValueTask) 在 Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.g__Awaited|10_0(ControllerActionInvoker 调用程序,任务 lastTask,下一个状态,作用域范围,对象状态,布尔 isCompleted) 在 Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed 上下文) 在 Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(状态&下一个,范围&范围,对象&状态,布尔& isCompleted) 在 Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeInnerFilterAsync() --- 上一个位置的堆栈跟踪结束 --- 在 Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|19_0(ResourceInvoker 调用程序,任务 lastTask,下一个状态,作用域范围,对象状态,布尔 isCompleted) 在 Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Logged|17_1(ResourceInvoker 调用程序) 在 Microsoft.AspNetCore.Routing.EndpointMiddleware.g__AwaitRequestTask|6_0(端点端点,任务 requestTask,ILogger 记录器) 在 Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext 上下文) 在 Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext 上下文) 在 Serilog.AspNetCore.RequestLoggingMiddleware.Invoke(HttpContext httpContext) 在 Microsoft.AspNetCore.Builder.Extensions.UsePathBaseMiddleware.Invoke(HttpContext 上下文) 在 Microsoft.AspNetCore.Server.IIS.Core.IISHttpContextOfT1.ProcessRequestAsync()

我查了一下错误,发现可以忽略身份验证上下文,有些库给出了这个选项,比如这个:
IgnoreAuthenticationContextInResponse compatibility flag

在 ITfoxtec 库中是否也有这种方法?

提前致谢,
阿什隆

【问题讨论】:

    标签: asp.net-core .net-5 itfoxtec-identity-saml2


    【解决方案1】:

    您可以实现自己的Saml2AuthnResponse 版本,并在Saml2SecurityTokenHandler 属性上设置您自己的Saml2ResponseSecurityTokenHandler 实现。

    我认为应该可以在您自己的Saml2ResponseSecurityTokenHandler 实现中更改身份验证上下文验证。

    【讨论】:

    • 感谢安德斯,但我找到了一种更简单的方法来解决这个问题。我会发布它作为答案。
    • 我想知道为什么签名仍然有效?
    • 你是对的。我收到签名错误。
    • 我还通过新的 IdP 遇到了这个问题。如果可以将库配置为处理此问题,那就太好了。此用户也有问题:stackoverflow.com/questions/69830260/authncontextdeclref-issue
    【解决方案2】:

    作为解决此问题的简单方法,我所做的只是从响应的 xml 中删除 saml:AuthnContextDeclRef 元素。
    这是清理之前处于 POC 状态的代码:

        public async Task<IActionResult> AssertionConsumerService()
        {
            var binding = new Saml2PostBinding();
            var saml2AuthnResponse = new Saml2AuthnResponse(_config);
    
            var httpRequest = Request.ToGenericHttpRequest();
    
            // Remove AuthnContextDeclRef element
            var samlResponseXml = Encoding.UTF8.GetString(Convert.FromBase64String(httpRequest.Form["SAMLResponse"] ?? string.Empty));
            var root = XElement.Parse(samlResponseXml);
            XNamespace ns = "urn:oasis:names:tc:SAML:2.0:assertion";
            root.Element(ns + "Assertion")?.Element(ns + "AuthnStatement")?.Element(ns + "AuthnContext")?.Element(ns + "AuthnContextDeclRef")?.Remove();
            httpRequest.Form["SAMLResponse"] = Convert.ToBase64String(Encoding.UTF8.GetBytes(root.ToString()));
    
            binding.ReadSamlResponse(httpRequest, saml2AuthnResponse);
            if (saml2AuthnResponse.Status != Saml2StatusCodes.Success)
            {
                throw new AuthenticationException($"SAML Response status: {saml2AuthnResponse.Status}");
            }
            binding.Unbind(httpRequest, saml2AuthnResponse);
            await saml2AuthnResponse.CreateSession(HttpContext, claimsTransform: ClaimsTransform.Transform);
    
            var relayStateQuery = binding.GetRelayStateQuery();
            var returnUrl = relayStateQuery.ContainsKey(RelayStateReturnUrl) ? relayStateQuery[RelayStateReturnUrl] : Url.Content("~/");
            return Redirect(returnUrl);
        }  
    

    【讨论】:

    • 我理解反对意见,因为它可能对其他人有所帮助,不要那样做,没有捷径,有正确的方法可以做到这一点。谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-17
    • 2020-04-10
    • 2013-03-21
    • 2013-12-15
    • 2019-07-05
    相关资源
    最近更新 更多