使用 SP public 证书加密 SAML 2.0 断言 - 组件 Space

Encrypt SAML 2.0 assertion with SP public certificate - Component Space

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

我不明白的是如何使用 SP 的证书对 XML 断言进行加密。我只找到了 "It's in the low-level api project",但找不到它。

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

我知道你可以使用"High-level API"的方式,你可以在saml.config文件中设置一些值来加密它,但我必须添加更多的属性而且我没有我想我可以使用 "High-level 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

ComponentSpace。SAML2.Assertions.EncryptedAssertion class 支持加密和解密 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 项目演示了这一点。