【问题标题】:Encrypt SAML 2.0 assertion with SP public certificate - Component Space使用 SP 公共证书加密 SAML 2.0 断言 - 组件空间
【发布时间】:2015-05-08 00:33:59
【问题描述】:

我了解(大部分)SAML 流程,因为我是在 WIF .NET 4.5 中使用组件空间之前编写的。

我不明白的是如何使用 SP 的证书加密 XML 断言。我找到的只是“它在低级 api 项目中”,但我找不到它。

在方法 SendSAMLResponse 中,我使用我的 pfx 来签署证书。如何使用 SP 的公共证书将断言加密到元素 <saml2:EncryptedAssertion> 中?

我知道你可以使用“高级 API”的方式,你可以在 saml.config 文件中设置一些值来加密它,但是我必须添加更多的属性,我认为我不能使用“高级 API”的方式。

    private SAMLResponse CreateSAMLResponse(string username, string uniqueKey)
    {
        SAMLResponse samlResponse = new SAMLResponse();
        samlResponse.Destination = EquatorConstants.ConsumerUrl;

        samlResponse.ID = "_" + Guid.NewGuid();

        Issuer issuer = new Issuer(EquatorConstants.Issuer);
        samlResponse.Issuer = issuer;

        samlResponse.Status = new Status(SAMLIdentifiers.PrimaryStatusCodes.Success, null);

        SAMLAssertion samlAssertion = new SAMLAssertion();
        samlAssertion.Issuer = issuer;

        //Subject subject = new Subject(new NameID(User.Identity.Name));
        Subject subject = new Subject(new NameID());
        SubjectConfirmation subjectConfirmation = new SubjectConfirmation(SAMLIdentifiers.SubjectConfirmationMethods.Bearer);
        SubjectConfirmationData subjectConfirmationData = new SubjectConfirmationData();
        subjectConfirmationData.Recipient = EquatorConstants.ConsumerUrl;
        subjectConfirmation.SubjectConfirmationData = subjectConfirmationData;
        subject.SubjectConfirmations.Add(subjectConfirmation);
        samlAssertion.Subject = subject;

        AuthnStatement authnStatement = new AuthnStatement();
        authnStatement.AuthnContext = new AuthnContext();
        authnStatement.AuthnContext.AuthnContextClassRef = new AuthnContextClassRef(SAMLIdentifiers.AuthnContextClasses.Password);
        authnStatement.AuthnInstant = DateTime.UtcNow;
        authnStatement.SessionNotOnOrAfter = DateTime.UtcNow.AddMinutes(double.Parse(SAMLConstants.TokenLifetime.ToString()));
        samlAssertion.Statements.Add(authnStatement);
        samlAssertion.Conditions.NotBefore = DateTime.UtcNow;
        samlAssertion.Conditions.NotOnOrAfter = DateTime.UtcNow.AddMinutes(double.Parse(SAMLConstants.TokenLifetime.ToString()));

        samlAssertion.IssueInstant = DateTime.UtcNow;
        samlAssertion.Version = "2.0";

        AttributeStatement attribStatement = new AttributeStatement();
        SAMLAttribute attribute = new SAMLAttribute("UserExternalKey", SAMLIdentifiers.AttributeNameFormats.Unspecified, null, uniqueKey);
        attribStatement.Attributes.Add(attribute);

        SAMLAttribute attribute2 = new SAMLAttribute("UserType", SAMLIdentifiers.AttributeNameFormats.Unspecified, null, "Workstation");
        attribStatement.Attributes.Add(attribute2);
        samlAssertion.Statements.Add(attribStatement);

        samlResponse.Assertions.Add(samlAssertion);

        return samlResponse;
    }

    private void SendSAMLResponse(SAMLResponse samlResponse, string relayState, HttpResponse response)
    {
        // Serialize the SAML response for transmission.
        XmlElement samlResponseXml = samlResponse.ToXml();

        // Sign the SAML response.
        X509Certificate2 x509Certificate = (X509Certificate2)LoadCertificate(string.Format("{0}/{1}.pfx", AppDomain.CurrentDomain.BaseDirectory, SAMLConstants.CertificateFileName), SAMLConstants.PfxPassword);
        SAMLMessageSignature.Generate(samlResponseXml, x509Certificate.PrivateKey, x509Certificate);

        IdentityProvider.SendSAMLResponseByHTTPPost(response, EquatorConstants.ConsumerUrl, samlResponseXml, relayState);
    }

Low Level API mention

【问题讨论】:

    标签: c# xml encryption saml-2.0


    【解决方案1】:

    ComponentSpace.SAML2.Assertions.EncryptedAssertion 类支持加密和解密 SAML 断言。

    在您的代码中,替换以下行:

    samlResponse.Assertions.Add(samlAssertion);
    

    与:

    // Encrypt the SAML assertion using the service provider's public key.
    // Loading the x509Certificate is not shown but it could be loaded from a .CER file.        
    EncryptedAssertion encryptedAssertion = new EncryptedAssertion(samlAssertion, x509Certificate);
    
    // Add the encrypted assertion to the SAML response.        
    samlResponse.Assertions.Add(encryptedAssertion);
    

    如果您改用 SAML 高级 API,那么您只需在 SAML 配置 sam.config 文件中指定服务提供商的证书并加密 SAML 断言即可。

    例如,您的 saml.config 将包括:

    <PartnerServiceProvider Name="urn:componentspace:ExampleServiceProvider" 
                            EncryptAssertion="true" 
                            PartnerCertificateFile="sp.cer"
    

    这意味着当向指定的合作伙伴服务提供商发送 SAML 断言时,SAML 断言将使用合作伙伴的证书文件进行加密。

    您构建和发送 SAML 响应(包括加密的 SAML 断言)的代码将是:

    SAMLIdentityProvider.InitiateSSO(Response, userName, attributes, targetUrl, partnerSP);
    

    我们发布的高级 API ExampleIdentityProvider 和 MvcExampleIdentityProvider 项目证明了这一点。

    【讨论】:

    • 稍后我会试试这个 - 谢谢。为什么我在这里,我想将“saml.config”文件放在项目的另一个文件夹中,而不是在根目录中。我知道配置文件会自动在同一个文件夹中查找 .pfx 和 .cer - 但我不知道如何告诉 Assertion 对象在该文件夹中查找。示例 - /rootProject/saml/saml.config
    • 在您的应用程序的 web.config 中,您可以包含一个指定 saml.config 路径的应用程序设置。 如果您没有产品的相对较新版本,您可能没有此功能。给我们发电子邮件了解更多详情。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-14
    • 2014-11-04
    • 2016-09-14
    • 1970-01-01
    • 2015-09-20
    • 1970-01-01
    相关资源
    最近更新 更多