C言語を用いたSAMLシングルサインオンインテグレーションの実施例


何がシングルサインオンですか?


あなたが人々がXの1つをするために使用しているウェブアプリケーションを持っていると仮定します、しかし、あなたはそれを偉大にしています.例えば、それはインターネットで見つけられる若干の面白いときれいなイメージをアップロードすることによって習慣的なTシャツ印刷を注文することができているウェブ店です.
あなたのユーザーのためのいくつかのより多くの機能を追加することによって、その機能性を拡張する方法を探していますが、あなたが最善を尽くしていることに焦点を失うことはありません.
つの方法は、クールなイメージプロバイダ、トレンドメーター、デリバリーサービスなどの他のサービスを使用してWebアプリケーションを統合することです.それはあなたのユーザーがシームレスに別のサービスの間で移動できるようになります(例えば:クールなイメージを探して、トレンドをチェックし、カスタム印刷サービスにこのイメージをアップロード)、あなたのWebアプリケーションだけを使用して複数のことを行う.
Single Sign-On認証フローを簡素化し、ユーザーがログイン/パスワード(またはそれ以上の革新的なメカニズム、例えば、FIDO2のような場合は、そのような場合)を使用して署名して、もう一度クリックしてログインする必要がなく簡単なクリックでより多くの統合サービスを使用することができます.それはあなたが比較的低投資でより多くの価値を追加することによって、製品の機能を拡張することができます.

SAML


SAMLはシングルサインオンを行う標準的な方法の一つです.長い間、広範なエンタープライズサービスは、ログイン、パスワード、電子メール、ユーザーアカウントなどのような敏感な認証と承認情報を交換する最も安全で実績のあるメソッドの1つとして、このメカニズムを使用していますが、それは小さな企業の間にこのソリューションを追加し、クールな統合を有効にすることは複雑ではありません.
SAMLは、他の多くのオプションの間で第三者と統合する最も安全な方法の一つです.これは、当事者は、安全なX . 509証明書に基づいて非対称の暗号化(RSA)を使用することができます.2021年現在、version 2に標準がある.
私は、あなたが証明された歴史で、そして、彼らのコードと全体的解決に責任があるベンダーから、多くの既存の箱入りの解決のうちの1つを信頼することがよりよいかもしれない点に注意しなければなりません.しかし、開発者として、私は、企業が製品の多くの柔軟性とカスタマイズを必要とする可能性があることを知っているので、私はより多くの詳細を提供したいとC Count .NETアプリケーション.

SAMLワークフロー


通常、「古典的な」SAMLワークフローは、3つの党を含みます:
  • サービスプロバイダ-これは
  • と統合するサードパーティサービスです
  • アイデンティティプロバイダー-これはいくつかの(エンタープライズ)認証された認証サービスです.
  • ユーザーエージェント-あなたのウェブストアをもつブラウザは、ユーザー
  • によって開きました
    この「古典的な」シナリオはエンタープライズに適しています.以下のワークフロー図を見ることができます.
    Wikipedia
    しかし、我々は中小企業ですか?それで、通常、我々は企業レベルアイデンティティプロバイダーとの複雑な協定を持っていません、しかし、我々はまだ第三者と統合する必要があります.それがどのように我々のために見えるかについて見ましょう.

    統合の第一歩


    まず第一に、サービスプロバイダとの契約があります.今回は特にSAMLプロトコルに焦点を当てていますが、多くの中小サービスによって使用されているカスタムメイドの統合アルゴリズムを知っています.彼らはカスタムHTTP API、休息、WCF、XML、およびJSONベースのデータ形式、jwtoensとoauthを使用し、時にはすべてのものを結合する.どんなオプションでも使用すると、初期のテスト接続を確立するためにいくつかの設定パラメータを提供する必要があります.
    SAMLベースの統合のために、彼らはあなたにいわゆる「メタデータ情報」を提供するよう頼みますそれはあなたのサービスに関する情報を含む小さなXMLファイルです.このファイルはサービスプロバイダによって自動的に接続をテストできるようにする認証(別名テスト)エンドポイントを作成し、すべてのロードブロックを解決し、公開する前にすべてを認証します.
    ここで重要なのは、このファイルのXMLコンテンツです.もちろん、あなたは1つを購入する必要があります.一部のプロバイダは、テスト目的のために自己署名資格を使用することができます.それはサービスプロバイダとのあなたの合意の問題です.
    私は、オープンソースで、私のGithub口座で公的に利用できるいくつかのコードを準備しました. メタデータを生成できます.XMLファイルを正しく秘密鍵で署名します.
    さて、あなたはパブリックX . 509証明書(This small console application)とこのメタデータを送るべきです.セキュアチャネルによるXML
    サービスプロバイダーがいくつかの接続終点で返答するとすぐに、最初の部分は終わっているかもしれません.

    として.CRTファイルまたはPEMテキスト 統合ワークフロー


    あなたは、いくつかの認証のワークフローを実装し、ユーザーがログインとパスワードでログインできるようにWebアプリケーションがあります.それは、あなたがアイデンティティプロバイダーであることを意味します、そして、これをすることによって、あなたはいくつかの冗長なステップを排除して、より単純なプロセスを作ることができます.したがって、アイデンティティプロバイダーとWebストアを一つのエンティティにまとめることを想像してください.

    それは全体的な画像を簡素化します.しかし、それはフードの下では簡単ではない.最後に実際に起こるべきことは、base 64で準備されエンコードされたsamlresponseと呼ばれるXMLドキュメントを持つべきです.HTTPドキュメントリクエストを経由してこのドキュメントをサービスプロバイダに送信して認証を行い、サードパーティのターゲットサービスに自動的にリダイレクトする必要があります.

    再び、私はを準備しましたので、簡単にWebアプリケーションの手順を実行する方法を確認できます.
    以下は、そのプロセスのすべての重要な側面に私のコメントを見つけることができます.しかし、私は、a set of utility classes written in C# ->メソッドBuildEndededsamlResponse(...)での手順に従って、より簡単になります.
    ステップ1.SAMLアサーションXMLの作成は、通常のXMLドキュメントを作成するよりは難しくありません.しかし、適切なフィールド名を使用するために、サービスプロバイダによって提供されるSAML仕様とドキュメントに従う必要があります.実施例はSamlIntegrationSteps.csである.
    AssertionType assertion = new AssertionType
    {
        ID = ...Assertion Id ...,
        IssueInstant = ...UTC Time...,
        Version = "2.0",
        Issuer = new NameIDType
        {
            Value = "...your Web Store URL here..."
        },
        Subject = new SubjectType
        {
            Items = new object[]
            {
                new NameIDType
                {
                    Format = "urn:oasis:names:tc:SAML:2.0:nameid-format:emailAddress",
                    Value = userData.GetUserEmail()
                },
                new SubjectConfirmationType
                {
                    Method = "urn:oasis:names:tc:SAML:2.0:cm:bearer",
                    SubjectConfirmationData = new SubjectConfirmationDataType
                    {
                        NotOnOrAfter = ...UTC Time....AddMinutes(3),
                        NotOnOrAfterSpecified = true,
                        Recipient = settings.Recipient
                    }
                }
            }
        },
        Conditions = new ConditionsType
        {
            NotBefore = ...UTC Time...,
            NotBeforeSpecified = true,
            NotOnOrAfter = ...UTC Time....AddMinutes(3),
            NotOnOrAfterSpecified = true,
            Items = ...conditions that you need...
        },
        Items = new StatementAbstractType[]
        {
            new AttributeStatementType
            {
                // ReSharper disable once CoVariantArrayConversion
                Items = ...attributes array...
            },
            new AuthnStatementType
            {
                AuthnInstant = ...UTC Time...,
                SessionIndex = ...Assertion Id ...,
                AuthnContext = new AuthnContextType
                {
                    ItemsElementName = new [] { ItemsChoiceType5.AuthnContextClassRef },
                    Items = new object[] { "urn:federation:authentication:windows" }
                }
            }
        }
    };
    
    手順2.SAMLアサーションの署名は、公式SamlAssertionAlgorithms.csに記載されているように行うことができる.実施例はMicrosoft docsである.
    ステップ3.SAMLアサーションの暗号化は、システムを使用してSamlAssertionAlgorithms.csで実装されます.セキュリティ暗号.XML
    X509Certificate2 x509 = ...get certificate...
    
    xmlElement.SigningKey = x509.PrivateKey;
    xmlElement.SignedInfo.CanonicalizationMethod = SamlSignedXml.XmlDsigExcC14NTransformUrl;
    
    // Create a reference to be signed. 
    Reference reference = new Reference
    {
        Uri = "#" + referenceValue
    };
    
    reference.AddTransform(new XmlDsigEnvelopedSignatureTransform());
    reference.AddTransform(new XmlDsigExcC14NTransform());
    
    // Add the reference to the SignedXml object. 
    xmlElement.AddReference(reference);
    
    // Add an RSAKeyValue KeyInfo (optional; helps recipient find key to validate). 
    KeyInfo keyInfo = new KeyInfo();
    keyInfo.AddClause(new KeyInfoX509Data(certificate));
    
    xmlElement.KeyInfo = keyInfo;
    
    // Compute the signature. 
    xmlElement.ComputeSignature();
    
    // Put the sign as the first child of main Request tag.
    xmlAssertion?.InsertAfter(xmlElement, xmlAssertion.ChildNodes[0]);
    
    ステップ4.SamlResponseにアサーションドキュメントを追加するには、XMLを追加するだけです.
    XmlDocument encryptedAssertion = new XmlDocument();
    
    // Add namespaces
    XmlDeclaration xmlDeclaration = encryptedAssertion.CreateXmlDeclaration("1.0", "UTF-8", null);
    XmlElement encryptedRoot = encryptedAssertion.DocumentElement;
    encryptedAssertion.InsertBefore(xmlDeclaration, encryptedRoot);
    
    // Form Assertion element
    XmlElement encryptedAssertionElement = encryptedAssertion.CreateElement("saml",
        "EncryptedAssertion", "urn:oasis:names:tc:SAML:2.0:assertion");
    encryptedAssertion.AppendChild(encryptedAssertionElement);
    
    // Add encrypted content
    var encryptedDataNode = encryptedAssertion.ImportNode(encryptedData.GetXml(), true);
    encryptedAssertionElement.AppendChild(encryptedDataNode);
    
    // Form a document
    var root = xmlDocument.DocumentElement;
    var node = root.OwnerDocument.ImportNode(encryptedAssertionElement, true);
    root.RemoveChild(xmlAssertionSource ?? throw new InvalidOperationException());
    root.AppendChild(node);
    
    ステップ5.SamlResponseに署名することは、アサーションをためすのとほぼ同じです.実施例はSamlAssertionAlgorithms.csである.

    SamlResponseAlgorithm。cs 終わり


    一部のサービスプロバイダは、特定の手順を回避したり、署名や暗号化を必要としません.この場合、コードのこれらの部分を削除できます.全体的に、あなたのアプリで私の例を使用して自由に感じ、そしてこれはあなたとあなたのアプリケーションは、ユーザーに従事し、顧客ベースを育てるのを助けることを願っています.
    乾杯!

    関連リンク



    Examples of SAML responses .