jjzjj

c# - 查询 XML [SAML 2.0 响应]

coder 2024-07-03 原文

下面的 xml 给我带来了困难。我需要用 c# 从 XML 中检索以下内容,你能帮忙吗?还有在 c# 中读取/解析 SAML 2.0 响应的更好方法吗?

  • 来自 <samlp:StatusCode value="urn:oasis:names:tc:SAML:2.0:status:**Success**"/> 的状态代码

  • 名字值

  • 姓氏值
  • 邮件值(value)
  • 发行人 <saml:Issuer>**sso.localhost.dev**</saml:Issuer>
  • 观众来自 <saml:Audience>**Application-Test**</saml:Audience>

XML

    <samlp:Response Destination="http://localhost/SamlAuthenticate" IssueInstant="2014-03-27T14:49:35.395Z" ID="kBWlU3VWF.Ee6DKbkEpFomtlDAT" Version="2.0" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol">
<saml:Issuer xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">sso.localhost.dev</saml:Issuer>
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#"><ds:SignedInfo>
<ds:CanonicalizationMethod 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="#kBWlU3VWF.Ee6DKbkEpFomtlDAT"><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"/>
<ds:DigestValue>LgH7ZZJWwp5fN02IPteWxh9oAQ8=</ds:DigestValue></ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>gBCZ4upHHdYzrVUcTe4Nf+fElY51UFQOJcf81DFPFNKfFxZfLjnX88NwJ6O7CVU3YNo08EINoEpkvEu+f2oxI3VQVnYnT1EYpLGy1+6qpxsFaPbXaQ8h1/NCwAygir1NDu/sktAzRZ2tg2i5rVn2sevY3Y+47SKnB+hG4ukVHusmNumD0NXyKwKNPflG9XEhrLj3bw5xuftr5CAREX5s1VotANFs1HeJA7OE1Yq2yLhw7GmPsa1+fgYQh5tfFRCmvdnpVoiT+SXwoxlRSbWlf2BWgBOLbC8W4dhTpMFmp70lndk0Pwpnxj6z4jFAHT3z/SdGgm0Ow+TbuutceBIIAQ==</ds:SignatureValue>
</ds:Signature>
<samlp:Status><samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/></samlp:Status>
<saml:Assertion Version="2.0" IssueInstant="2014-03-27T14:49:35.404Z" ID="w4BForMipBizsG1TA7d9QzhCM0-" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">
<saml:Issuer>sso.localhost.dev</saml:Issuer>
<saml:Subject>
<saml:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified">JSMITH009</saml:NameID>
<saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
<saml:SubjectConfirmationData NotOnOrAfter="2014-03-27T14:54:35.404Z" Recipient="http://localhost/SamlAuthenticate"/></saml:SubjectConfirmation>
</saml:Subject>
<saml:Conditions NotOnOrAfter="2014-03-27T14:54:35.404Z" NotBefore="2014-03-27T14:44:35.404Z">
<saml:AudienceRestriction>
<saml:Audience>Application-Test</saml:Audience>
</saml:AudienceRestriction>
</saml:Conditions>
<saml:AuthnStatement AuthnInstant="2014-03-27T14:49:35.404Z" SessionIndex="w4BForMipBizsG1TA7d9QzhCM0-">
<saml:AuthnContext>
<saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:unspecified</saml:AuthnContextClassRef>
</saml:AuthnContext>
</saml:AuthnStatement>
<saml:AttributeStatement xmlns:xs="http://www.w3.org/2001/XMLSchema">
<saml:Attribute NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic" Name="FIRSTNAME">
<saml:AttributeValue xsi:type="xs:string" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">john</saml:AttributeValue>
</saml:Attribute>
<saml:Attribute NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic" Name="MAIL">
<saml:AttributeValue xsi:type="xs:string" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">john.smith@email.localhost.dev</saml:AttributeValue></saml:Attribute>
<saml:Attribute NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic" Name="LASTNAME"><saml:AttributeValue xsi:type="xs:string" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">smith</saml:AttributeValue></saml:Attribute>
</saml:AttributeStatement>
</saml:Assertion>
</samlp:Response>

最佳答案

找到解决方案了!

public class SAMLProcessor
{

    #region Properties
    public string DecodedSAML { get; set; }
    public string EncodedeSAML { get; set; }
    public string Audience { get; set; }
    public string SubjectNameID { get; set; }
    public string FirstName { get; set; }
    public string Mail { get; set; }
    public string LastName { get; set; }
    public bool AuthenticationStatus { get; set; }
    public string Issuer { get; set; }
    public string Destination { get; set; }
    public string ResponseID { get; set; }
    public bool VerifiedResponse { get; set; }
    public string SignatureValue { get; set; }
    public string SignatureReferenceDigestValue { get; set; }
    public DateTime AutheticationTime { get; set; }
    public string AuthenticationSession { get; set; }
    #endregion


    #region Ctror
    public SAMLProcessor(string rawSamlData)
    {
        EncodedeSAML = rawSamlData;
        // the sample data sent us may be already encoded, 
        // which results in double encoding
        if (rawSamlData.Contains('%'))
        {
            rawSamlData = HttpUtility.UrlDecode(rawSamlData);
        }

        // read the base64 encoded bytes
        string samlAssertion = Decode64Bit(rawSamlData);
        DecodedSAML = samlAssertion;
        SamlParser(DecodedSAML);
    }
    #endregion

    private static string Decode64Bit(string rawSamlData)
    {
        byte[] samlData = Convert.FromBase64String(rawSamlData);

        // read back into a UTF string
        string samlAssertion = Encoding.UTF8.GetString(samlData);
        return samlAssertion;
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="samldata"></param>
    /// <returns></returns>
    public string SamlParser(string samlXMLdata)
    {

        //samldata = Decode64Bit("PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4=") + samldata;
        string samldata = samlXMLdata;

        if (!samldata.StartsWith(@"<?xml version="))
        {
            samldata = Decode64Bit("PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4=") + samldata;
        }

        string firstName = string.Empty;
        XmlDocument xDoc = new XmlDocument();
        samldata = samldata.Replace(@"\", "");
        xDoc.LoadXml(samldata);
        //xDoc.Load(new System.IO.TextReader());//Suppose the xml you have provided is stored in this xml file.

        XmlNamespaceManager xMan = new XmlNamespaceManager(xDoc.NameTable);
        xMan.AddNamespace("samlp", "urn:oasis:names:tc:SAML:2.0:protocol");
        xMan.AddNamespace("saml", "urn:oasis:names:tc:SAML:2.0:assertion");
        xMan.AddNamespace("ds", "http://www.w3.org/2000/09/xmldsig#");


        XmlNode xNode = xDoc.SelectSingleNode("/samlp:Response/samlp:Status/samlp:StatusCode/@Value", xMan);
        if (xNode != null)
        {
            this.AuthenticationStatus = false;
            string statusCode = xNode.Value;
            if (statusCode.EndsWith("status:Success"))
            {
                this.AuthenticationStatus = true;
            }

        }

        xNode = xDoc.SelectSingleNode("/samlp:Response/@Destination", xMan);
        if (xNode != null)
        {
            this.Destination = xNode.Value;
        }
        xNode = xDoc.SelectSingleNode("/samlp:Response/@IssueInstant", xMan);
        if (xNode != null)
        {
            this.AutheticationTime = Convert.ToDateTime(xNode.Value);
        }
        xNode = xDoc.SelectSingleNode("/samlp:Response/@ID", xMan);
        if (xNode != null)
        {
            this.ResponseID = xNode.Value;
        }
        xNode = xDoc.SelectSingleNode("/samlp:Response/saml:Issuer", xMan);
        if (xNode != null)
        {
            this.Issuer = xNode.InnerText;
        }

        xNode = xDoc.SelectSingleNode("/samlp:Response/ds:Signature/ds:SignedInfo/ds:Reference/ds:DigestValue", xMan);
        if (xNode != null)
        {
            this.SignatureReferenceDigestValue = xNode.InnerText;
        }
        xNode = xDoc.SelectSingleNode("/samlp:Response/ds:Signature/ds:SignatureValue", xMan);
        if (xNode != null)
        {
            this.SignatureValue = xNode.InnerText;
        }
        xNode = xDoc.SelectSingleNode("/samlp:Response/saml:Assertion/@ID", xMan);
        if (xNode != null)
        {
            this.AuthenticationSession = xNode.Value;
        }

        xNode = xDoc.SelectSingleNode("/samlp:Response/saml:Assertion/saml:Subject/saml:NameID", xMan);
        if (xNode != null)
        {
            this.SubjectNameID = xNode.InnerText;
        }
        xNode = xDoc.SelectSingleNode("/samlp:Response/saml:Assertion/saml:Conditions/saml:AudienceRestriction/saml:Audience", xMan);
        if (xNode != null)
        {
            this.Audience = xNode.InnerText;
        }

        //reverse order
        //</saml:AttributeValue></saml:Attribute></saml:AttributeStatement></saml:Assertion></samlp:Response>

        //string xQryStr = "//NewPatient[Name='" + name + "']";

        //XmlNode matchedNode = xDoc.SelectSingleNode(xQryStr);
        // samlp:Response  saml:Assertion saml:AttributeStatement saml:Attribute
        xNode = xDoc.SelectSingleNode("/samlp:Response/saml:Assertion/saml:AttributeStatement/saml:Attribute[@Name = 'FIRSTNAME']/saml:AttributeValue", xMan);
        if (xNode != null)
        {
            this.FirstName = xNode.InnerText;
        }

        // samlp:Response  saml:Assertion saml:AttributeStatement saml:Attribute
        xNode = xDoc.SelectSingleNode("/samlp:Response/saml:Assertion/saml:AttributeStatement/saml:Attribute[@Name = 'MAIL']/saml:AttributeValue", xMan);
        if (xNode != null)
        {
            this.Mail = xNode.InnerText;
        }

        // samlp:Response  saml:Assertion saml:AttributeStatement saml:Attribute
        xNode = xDoc.SelectSingleNode("/samlp:Response/saml:Assertion/saml:AttributeStatement/saml:Attribute[@Name = 'LASTNAME']/saml:AttributeValue", xMan);
        if (xNode != null)
        {
            this.LastName = xNode.InnerText;
        }

        return this.FirstName;
    }
}

关于c# - 查询 XML [SAML 2.0 响应],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22692704/

有关c# - 查询 XML [SAML 2.0 响应]的更多相关文章

  1. ruby - ECONNRESET (Whois::ConnectionError) - 尝试在 Ruby 中查询 Whois 时出错 - 2

    我正在用Ruby编写一个简单的程序来检查域列表是否被占用。基本上它循环遍历列表,并使用以下函数进行检查。require'rubygems'require'whois'defcheck_domain(domain)c=Whois::Client.newc.query("google.com").available?end程序不断出错(即使我在google.com中进行硬编码),并打印以下消息。鉴于该程序非常简单,我已经没有什么想法了-有什么建议吗?/Library/Ruby/Gems/1.8/gems/whois-2.0.2/lib/whois/server/adapters/base.

  2. ruby-on-rails - 如何从 format.xml 中删除 <hash></hash> - 2

    我有一个对象has_many应呈现为xml的子对象。这不是问题。我的问题是我创建了一个Hash包含此数据,就像解析器需要它一样。但是rails自动将整个文件包含在.........我需要摆脱type="array"和我该如何处理?我没有在文档中找到任何内容。 最佳答案 我遇到了同样的问题;这是我的XML:我在用这个:entries.to_xml将散列数据转换为XML,但这会将条目的数据包装到中所以我修改了:entries.to_xml(root:"Contacts")但这仍然将转换后的XML包装在“联系人”中,将我的XML代码修改为

  3. ruby-on-rails - 在 Rails 和 ActiveRecord 中查询时忽略某些字段 - 2

    我知道我可以指定某些字段来使用pluck查询数据库。ids=Item.where('due_at但是我想知道,是否有一种方法可以指定我想避免从数据库查询的某些字段。某种反拔?posts=Post.where(published:true).do_not_lookup(:enormous_field) 最佳答案 Model#attribute_names应该返回列/属性数组。您可以排除其中一些并传递给pluck或select方法。像这样:posts=Post.where(published:true).select(Post.attr

  4. ruby-on-rails - 每次我尝试部署时,我都会得到 - (gcloud.preview.app.deploy) 错误响应 : [4] DEADLINE_EXCEEDED - 2

    我是Google云的新手,我正在尝试对其进行首次部署。我的第一个部署是RubyonRails项目。我基本上是在关注thisguideinthegoogleclouddocumentation.唯一的区别是我使用的是我自己的项目,而不是他们提供的“helloworld”项目。这是我的app.yaml文件runtime:customvm:trueentrypoint:bundleexecrackup-p8080-Eproductionconfig.ruresources:cpu:0.5memory_gb:1.3disk_size_gb:10当我转到我的项目目录并运行gcloudprevie

  5. c# - 如何在 ruby​​ 中调用 C# dll? - 2

    如何在ruby​​中调用C#dll? 最佳答案 我能想到几种可能性:为您的DLL编写(或找人编写)一个COM包装器,如果它还没有,则使用Ruby的WIN32OLE库来调用它;看看RubyCLR,其中一位作者是JohnLam,他继续在Microsoft从事IronRuby方面的工作。(估计不会再维护了,可能不支持.Net2.0以上的版本);正如其他地方已经提到的,看看使用IronRuby,如果这是您的技术选择。有一个主题是here.请注意,最后一篇文章实际上来自JohnLam(看起来像是2009年3月),他似乎很自在地断言RubyCL

  6. C# 到 Ruby sha1 base64 编码 - 2

    我正在尝试在Ruby中复制Convert.ToBase64String()行为。这是我的C#代码:varsha1=newSHA1CryptoServiceProvider();varpasswordBytes=Encoding.UTF8.GetBytes("password");varpasswordHash=sha1.ComputeHash(passwordBytes);returnConvert.ToBase64String(passwordHash);//returns"W6ph5Mm5Pz8GgiULbPgzG37mj9g="当我在Ruby中尝试同样的事情时,我得到了相同sha

  7. 基于C#实现简易绘图工具【100010177】 - 2

    C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.

  8. sql - 查询忽略时间戳日期的时间范围 - 2

    我正在尝试查询我的Rails数据库(Postgres)中的购买表,我想查询时间范围。例如,我想知道在所有日期的下午2点到3点之间进行了多少次购买。此表中有一个created_at列,但我不知道如何在不搜索特定日期的情况下完成此操作。我试过:Purchases.where("created_atBETWEEN?and?",Time.now-1.hour,Time.now)但这最终只会搜索今天与那些时间的日期。 最佳答案 您需要使用PostgreSQL'sdate_part/extractfunction从created_at中提取小时

  9. ruby-on-rails - 在 Ruby on Rails 中发送响应之前如何等待多个异步操作完成? - 2

    在我做的一些网络开发中,我有多个操作开始,比如对外部API的GET请求,我希望它们同时开始,因为一个不依赖另一个的结果。我希望事情能够在后台运行。我找到了concurrent-rubylibrary这似乎运作良好。通过将其混合到您创建的类中,该类的方法具有在后台线程上运行的异步版本。这导致我编写如下代码,其中FirstAsyncWorker和SecondAsyncWorker是我编写的类,我在其中混合了Concurrent::Async模块,并编写了一个名为“work”的方法来发送HTTP请求:defindexop1_result=FirstAsyncWorker.new.async.

  10. ruby-on-rails - solr 清理查询 - 2

    我在Rails上使用带有ruby​​的solr。一切正常,我只需要知道是否有任何现有代码来清理用户输入,比如以?开头的查询。或* 最佳答案 我不知道执行此操作的任何代码,但理论上可以通过查看parsingcodeinLucene来完成并搜索thrownewParseException(只有16个匹配!)。在实践中,我认为您最好只捕获代码中的任何solr异常并显示“无效查询”消息或类似信息。编辑:这里有几个“sanitizer”:http://pivotallabs.com/users/zach/blog/articles/937-s

随机推荐