How to encrypt the SAML Assertion?

Encrypt SAML 2.0 assertion with SP public certificate - Component Space

  • I understand (for the most part) the SAML process since I wrote it prior to using Component Space in WIF .NET 4.5. What I do not understand is how to encrypt the XML assertion using the SP's certificate. All I've found is "It's in the low-level api project", but I cannot locate it. In the method, SendSAMLResponse, I'm using my pfx for signing the certificate. How do I use the SP's public certificate to encrypt the assertion into the element <saml2:EncryptedAssertion>? I know that you can use the "High-level API" way and you can set some values in the saml.config file to encrypt it, but I have to add a lot more attributes and I don't think I can use the "High-level API" way. 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); } http://www.componentspace.com/Forums/1229/Encrypt-Saml-Assertion-with-SP-Public-Certificate-and-sign#bm1233

  • Answer:

    The ComponentSpace.SAML2.Assertions.EncryptedAssertion class supports encrypting and decrypting SAML assertions. In your code, replace the line: samlResponse.Assertions.Add(samlAssertion); with: // 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); If you used the SAML high-level API instead then, in the SAML configuration sam.config file, all you would have to do is specify the service provider's certificate and that you to encrypted the SAML assertion. For example, your saml.config would include: <PartnerServiceProvider Name="urn:componentspace:ExampleServiceProvider" EncryptAssertion="true" PartnerCertificateFile="sp.cer" This means that when sending a SAML assertion to the specified partner service provider the SAML assertion will be encrypted using partner's certificate file. And your code to construct and send a SAML response, including an encrypted SAML assertion would be: SAMLIdentityProvider.InitiateSSO(Response, userName, attributes, targetUrl, partnerSP); The high-level API ExampleIdentityProvider and MvcExampleIdentityProvider projects that we ship demonstrate this.

Rob Scott at Stack Overflow Visit the source

Was this solution helpful to you?

Related Q & A:

Just Added Q & A:

Find solution

For every problem there is a solution! Proved by Solucija.

  • Got an issue and looking for advice?

  • Ask Solucija to search every corner of the Web for help.

  • Get workable solutions and helpful tips in a moment.

Just ask Solucija about an issue you face and immediately get a list of ready solutions, answers and tips from other Internet users. We always provide the most suitable and complete answer to your question at the top, along with a few good alternatives below.