3

有一个关于在 ASP.Net Core 中使用 SAML的问题,但我需要更多帮助。

那里唯一的答案提到了 Kentor.AuthServices,但我不明白如何使用它。我在这个或其他 SAML 库、文档、博客文章和示例应用程序上找到的所有内容都是关于联系一些外部身份验证服务以及处理登录和注销。

但我不需要这些。我正在使用的设置在面向边缘的防火墙应用程序中执行此操作,并且登录/注销请求永远不会到达我的应用程序。我得到的只是 cookie 中的 SAML 令牌,我需要对其进行验证并将其转换为 ClaimsPrincipal。我不能(部署网络设置非常偏执)并且不想联系任何身份提供者。

目前我已经编写了一个中间件,它获取 cookie,解析它,并解析出我需要的声明主体的部分。但我不做任何验证,无论是 XML 签名还是 SAML 有效性(有效时间属性等)。使用 .Net Core 2.0 Preview 2 我可以进行 XML 签名验证,但我仍然坚持进行 SAML 验证。是否有一个库可以简单地验证 SAML 约束并且什么都不做(或者,至少,我可以忽略其他所有内容)?我相信 Kentor 或 ITfoxtec 或 elerch 的 SAML2.Core 必须包含这样的功能,但我不知道它在哪里。

4

2 回答 2

1

我已经使用 System.IdentityModel.Tokens 中的 SecurityTokenHandlerCollection 类完成了此操作,希望此代码对您有所帮助。

 public Saml2SecurityToken DeserializeSAMLResponse(string samlResponse)
    {
        //Deserializing saml response

        Saml2SecurityToken token;
        using (var reader = XmlReader.Create(new StringReader(samlResponse)))
        {
            reader.ReadToFollowing("Assertion", Infrastructure.Enumerations.StringEnum.GetStringValue(SAMLProtocoles.SAML_20_ASSERTION));
            // Deserialize the token so that data can be taken from it and plugged into the RSTR
            SecurityTokenHandlerCollection tokenHandlerCollection = SecurityTokenHandlerCollection.CreateDefaultSecurityTokenHandlerCollection();
            token = (Saml2SecurityToken)tokenHandlerCollection.ReadToken(reader.ReadSubtree());
        }

        //Deserializing successful
        return token;
    }

它将在内部验证 SAML 并在 Saml2SecurityToken 中对其进行解析 获得令牌后,您可以像这样使用用户凭据

  public User ReadSamlResponse(string samlResponse, string profileName, bool isSAMLProfile = true)
    {
        User User = new User();
        var DecodedSamlResponse = Convert.FromBase64String(samlResponse);
        string ResponseDecoded = coding.UTF8.GetString(DecodedSamlResponse);

            Saml2SecurityToken Token = _samlAuthenticationService.DeserializeSAMLResponse(ResponseDecoded);
            if ()// apply condition here if you need to validate signature
            {
                if (!_samlAuthenticationService.ValidateSamlToken(ResponseDecoded, AuthenticationConnector, isSAMLProfile))
                    throw new Exception("Signature is invalid");
            }

            User = GetUserFromToken(Token);
            return User;
        }

要获得安全令牌用户,您可以这样做

 public User GetUserFromToken(Saml2SecurityToken Token)
    {
        //Get user information from the token started
        User User = new User();
        if (Token != null)
        {
            if (Token.Assertion.Subject.NameId != null && (Token.Assertion.Subject.NameId.Format == null || Token.Assertion.Subject.NameId.Format.OriginalString == "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"))
                User.EmailAddress = Token.Assertion.Subject.NameId.Value;
            foreach (var Statement in Token.Assertion.Statements)
            {
                var AttributeStatement = Statement as Saml2AttributeStatement;
                var AuthenticationStatement = Statement as Saml2AuthenticationStatement;
                if (AttributeStatement != null)
                    foreach (var Saml2Attribute in AttributeStatement.Attributes)
                    {
                        if (Saml2Attribute.Name.Equals("mail") || Saml2Attribute.Name.Equals("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress"))
                            User.EmailAddress = Saml2Attribute.Values[0];
                        if (Saml2Attribute.Name.Equals("uid") || Saml2Attribute.Name.Equals("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name"))
                            User.Name = Saml2Attribute.Values[0];
                        if (Saml2Attribute.Name.Equals("phone"))
                            User.MobileNumber = Saml2Attribute.Values[0];
                        if (Saml2Attribute.Name.Equals("title"))
                            User.JobTitle = Saml2Attribute.Values[0];
                        if (Saml2Attribute.Name.Equals("company"))
                            User.CompanyName = Saml2Attribute.Values[0];
                    }
                if (AuthenticationStatement != null)
                {
                    User.SAMLSessionIndex = AuthenticationStatement.SessionIndex;
                }
            }
        }
        //Successfully parsed user credentials
        return User;
    }
于 2017-07-28T11:02:00.723 回答
0

http://blog.scottlogic.com/2015/11/19/oauth2-with-saml2.html

scott 的这个博客用简单的方式解释了它。

于 2017-07-28T10:33:42.450 回答