使用 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);
}
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 项目演示了这一点。
我了解(大部分)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);
}
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 项目演示了这一点。