/// <summary> /// Constructs an encrypting credential based on the x509 token. /// </summary> /// <param name="token">The x509 security token.</param> internal X509EncryptingCredentials(X509SecurityToken token) : this( token, new SecurityKeyIdentifier(token.CreateKeyIdentifierClause<X509IssuerSerialKeyIdentifierClause>()), SecurityAlgorithms.DefaultAsymmetricKeyWrapAlgorithm) { }
/// <summary> /// Constructs an encrypting credential based on the x509 token. /// </summary> /// <param name="token">The x509 security token.</param> internal X509EncryptingCredentials(X509SecurityToken token) : this( token, new SecurityKeyIdentifier(token.CreateKeyIdentifierClause <X509IssuerSerialKeyIdentifierClause>()), SecurityAlgorithms.DefaultAsymmetricKeyWrapAlgorithm) { }
/// <summary> /// Creates a SAML assertion based on a symmetric proof key /// </summary> /// <param name="claims">A ClaimSet containing the claims to be placed into the SAML assertion</param> /// <param name="signatureToken">An X509SecurityToken that will be used to sign the SAML assertion</param> /// <param name="encryptionToken">An X509SecurityToken that will be used to encrypt the proof key</param> /// <param name="proofToken">A BinarySecretSecurityToken containing the proof key</param> /// <param name="algoSuite">The algorithm suite to use when performing cryptographic operations</param> /// <returns>A SAML assertion containing the passed in claims and proof key, signed by the provided signature token</returns> public static SamlAssertion CreateSymmetricKeyBasedAssertion(ClaimSet claims, X509SecurityToken signatureToken, X509SecurityToken encryptionToken, BinarySecretSecurityToken proofToken, SecurityAlgorithmSuite algoSuite) { // Check various input parameters if (claims == null) throw new ArgumentNullException("claims"); if (claims.Count == 0) throw new ArgumentException("Provided ClaimSet must contain at least one claim"); if (proofToken == null) throw new ArgumentNullException("proofToken"); if (signatureToken == null) throw new ArgumentNullException("signatureToken"); if (encryptionToken == null) throw new ArgumentNullException("encryptionToken"); if (proofToken == null) throw new ArgumentNullException("proofToken"); if (algoSuite == null) throw new ArgumentNullException("algoSuite"); // Get signing key and a key identifier for same SecurityKey signatureKey = signatureToken.SecurityKeys[0]; SecurityKeyIdentifierClause signatureSkic = signatureToken.CreateKeyIdentifierClause<X509ThumbprintKeyIdentifierClause>(); SecurityKeyIdentifier signatureKeyIdentifier = new SecurityKeyIdentifier(signatureSkic); // Get encryption key and a key identifier for same SecurityKey encryptionKey = encryptionToken.SecurityKeys[0]; SecurityKeyIdentifierClause encryptionSkic = encryptionToken.CreateKeyIdentifierClause<X509ThumbprintKeyIdentifierClause>(); SecurityKeyIdentifier encryptionKeyIdentifier = new SecurityKeyIdentifier(encryptionSkic); // Encrypt the proof key and create a key identifier for same byte[] proofKey = proofToken.GetKeyBytes(); byte[] encryptedSecret = new byte[proofKey.Length]; encryptedSecret = encryptionKey.EncryptKey(algoSuite.DefaultAsymmetricKeyWrapAlgorithm, proofKey); SecurityKeyIdentifier proofKeyIdentifier = new SecurityKeyIdentifier(new EncryptedKeyIdentifierClause(encryptedSecret, algoSuite.DefaultAsymmetricKeyWrapAlgorithm, encryptionKeyIdentifier)); // Create the assertion return CreateAssertion(claims, signatureKey, signatureKeyIdentifier, proofKeyIdentifier, algoSuite); }
/// <summary> /// Constructs an encrypting credential based on the x509 token and key wrapping algorithm. /// </summary> /// <param name="token">The x509 security token.</param> /// <param name="keyWrappingAlgorithm">The key wrapping al----htm.</param> internal X509EncryptingCredentials(X509SecurityToken token, string keyWrappingAlgorithm) : this(token, new SecurityKeyIdentifier(token.CreateKeyIdentifierClause <X509IssuerSerialKeyIdentifierClause>()), keyWrappingAlgorithm) { }
/// <summary> /// Creates a SAML token for the specified email address. /// </summary> public static UserIdentity CreateSAMLToken(string emailAddress) { // Normally this would be done by a server that is capable of verifying that // the user is a legimate holder of email address. Using a local certficate to // signed the SAML token is a short cut that would never be done in a real system. CertificateIdentifier userid = new CertificateIdentifier(); userid.StoreType = CertificateStoreType.Windows; userid.StorePath = "LocalMachine\\My"; userid.SubjectName = "UA Sample Client"; X509Certificate2 certificate = userid.Find(); X509SecurityToken signingToken = new X509SecurityToken(certificate); // Create list of confirmation strings List<string> confirmations = new List<string>(); // Add holder-of-key string to list of confirmation strings confirmations.Add("urn:oasis:names:tc:SAML:1.0:cm:bearer"); // Create SAML subject statement based on issuer member variable, confirmation string collection // local variable and proof key identifier parameter SamlSubject subject = new SamlSubject("urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress", null, emailAddress); // Create a list of SAML attributes List<SamlAttribute> attributes = new List<SamlAttribute>(); Claim claim = Claim.CreateNameClaim(emailAddress); attributes.Add(new SamlAttribute(claim)); // Create list of SAML statements List<SamlStatement> statements = new List<SamlStatement>(); // Add a SAML attribute statement to the list of statements. Attribute statement is based on // subject statement and SAML attributes resulting from claims statements.Add(new SamlAttributeStatement(subject, attributes)); // Create a valid from/until condition DateTime validFrom = DateTime.UtcNow; DateTime validTo = DateTime.UtcNow.AddHours(12); SamlConditions conditions = new SamlConditions(validFrom, validTo); // Create the SAML assertion SamlAssertion assertion = new SamlAssertion( "_" + Guid.NewGuid().ToString(), signingToken.Certificate.Subject, validFrom, conditions, null, statements); SecurityKey signingKey = new System.IdentityModel.Tokens.RsaSecurityKey((RSA)signingToken.Certificate.PrivateKey); // Set the signing credentials for the SAML assertion assertion.SigningCredentials = new SigningCredentials( signingKey, System.IdentityModel.Tokens.SecurityAlgorithms.RsaSha1Signature, System.IdentityModel.Tokens.SecurityAlgorithms.Sha1Digest, new SecurityKeyIdentifier(signingToken.CreateKeyIdentifierClause<X509ThumbprintKeyIdentifierClause>())); return new UserIdentity(new SamlSecurityToken(assertion)); }
public static ExtendedEntityDescriptor CreateMetadata(this ISPOptions spOptions, AuthServicesUrls urls) { var ed = new ExtendedEntityDescriptor { EntityId = spOptions.EntityId, Organization = spOptions.Organization, CacheDuration = spOptions.MetadataCacheDuration }; foreach (var contact in spOptions.Contacts) { ed.Contacts.Add(contact); } var spsso = new ExtendedServiceProviderSingleSignOnDescriptor(); spsso.ProtocolsSupported.Add(new Uri("urn:oasis:names:tc:SAML:2.0:protocol")); spsso.AssertionConsumerServices.Add(0, new IndexedProtocolEndpoint() { Index = 0, IsDefault = true, Binding = Saml2Binding.HttpPostUri, Location = urls.AssertionConsumerServiceUrl }); foreach(var attributeService in spOptions.AttributeConsumingServices) { spsso.AttributeConsumingServices.Add(attributeService); } if (spOptions.ServiceCertificate != null) { using (var securityToken = new X509SecurityToken(spOptions.ServiceCertificate)) { spsso.Keys.Add( new KeyDescriptor { Use = KeyType.Encryption, KeyInfo = new SecurityKeyIdentifier(securityToken.CreateKeyIdentifierClause<X509RawDataKeyIdentifierClause>()) } ); } } if (spOptions.DiscoveryServiceUrl != null && !string.IsNullOrEmpty(spOptions.DiscoveryServiceUrl.OriginalString)) { spsso.Extensions.DiscoveryResponse = new IndexedProtocolEndpoint { Binding = Saml2Binding.DiscoveryResponseUri, Index = 0, IsDefault = true, Location = urls.SignInUrl }; } ed.RoleDescriptors.Add(spsso); return ed; }
public static ExtendedEntityDescriptor CreateMetadata(this ISPOptions spOptions, AuthServicesUrls urls, string entityIdSuffix) { var eid = string.IsNullOrEmpty(entityIdSuffix) ? spOptions.EntityId : new EntityId(spOptions.EntityId.Id + entityIdSuffix); var ed = new ExtendedEntityDescriptor { EntityId = eid, Organization = spOptions.Organization, CacheDuration = spOptions.MetadataCacheDuration, }; if(spOptions.MetadataValidDuration.HasValue) { ed.ValidUntil = DateTime.UtcNow.Add(spOptions.MetadataValidDuration.Value); } foreach (var contact in spOptions.Contacts) { ed.Contacts.Add(contact); } var spsso = new ExtendedServiceProviderSingleSignOnDescriptor() { WantAssertionsSigned = spOptions.WantAssertionsSigned, AuthenticationRequestsSigned = spOptions.AuthenticateRequestSigningBehavior == SigningBehavior.Always }; spsso.ProtocolsSupported.Add(new Uri("urn:oasis:names:tc:SAML:2.0:protocol")); spsso.AssertionConsumerServices.Add(0, new IndexedProtocolEndpoint() { Index = 0, IsDefault = true, Binding = Saml2Binding.HttpPostUri, Location = urls.AssertionConsumerServiceUrl }); spsso.AssertionConsumerServices.Add(1, new IndexedProtocolEndpoint() { Index = 1, IsDefault = false, Binding = Saml2Binding.HttpArtifactUri, Location = urls.AssertionConsumerServiceUrl }); foreach(var attributeService in spOptions.AttributeConsumingServices) { spsso.AttributeConsumingServices.Add(attributeService); } if (spOptions.ServiceCertificates != null) { var publishCertificates = spOptions.MetadataCertificates; foreach (var serviceCert in publishCertificates) { using (var securityToken = new X509SecurityToken(serviceCert.Certificate)) { spsso.Keys.Add( new KeyDescriptor { Use = (KeyType)(byte)serviceCert.Use, KeyInfo = new SecurityKeyIdentifier(securityToken.CreateKeyIdentifierClause<X509RawDataKeyIdentifierClause>()) } ); } } } if(spOptions.SigningServiceCertificate != null) { spsso.SingleLogoutServices.Add(new ProtocolEndpoint( Saml2Binding.HttpRedirectUri, urls.LogoutUrl)); spsso.SingleLogoutServices.Add(new ProtocolEndpoint( Saml2Binding.HttpPostUri, urls.LogoutUrl)); } if (spOptions.DiscoveryServiceUrl != null && !string.IsNullOrEmpty(spOptions.DiscoveryServiceUrl.OriginalString)) { spsso.Extensions.DiscoveryResponse = new IndexedProtocolEndpoint { Binding = Saml2Binding.DiscoveryResponseUri, Index = 0, IsDefault = true, Location = urls.SignInUrl }; } ed.RoleDescriptors.Add(spsso); return ed; }
/// <summary> /// Constructs an encrypting credential based on the x509 token and key wrapping algorithm. /// </summary> /// <param name="token">The x509 security token.</param> /// <param name="keyWrappingAlgorithm">The key wrapping al----htm.</param> internal X509EncryptingCredentials(X509SecurityToken token, string keyWrappingAlgorithm) : this(token, new SecurityKeyIdentifier(token.CreateKeyIdentifierClause<X509IssuerSerialKeyIdentifierClause>()), keyWrappingAlgorithm) { }
public void WriteWrappedKeySecurityToken () { StringWriter sw = new StringWriter (); byte [] bytes = new byte [64]; for (byte i = 1; i < 64; i++) bytes [i] = i; SecurityToken wt = new X509SecurityToken (cert); SecurityKeyIdentifier ski = new SecurityKeyIdentifier ( wt.CreateKeyIdentifierClause< X509ThumbprintKeyIdentifierClause> ()); WrappedKeySecurityToken t = new WrappedKeySecurityToken ( "urn:wrapper-key:1", bytes, SecurityAlgorithms.RsaOaepKeyWrap, wt, ski); using (XmlWriter w = XmlWriter.Create (sw, GetWriterSettings ())) { WSSecurityTokenSerializer.DefaultInstance.WriteToken (w, t); } string actual = sw.ToString (); int idx = actual.IndexOf ("<e:CipherValue>", StringComparison.Ordinal); Assert.IsTrue (idx >= 0, "No <CipherValue>"); actual = actual.Substring (0, idx) + "<e:CipherValue>removed here" + actual.Substring (actual.IndexOf ("</e:CipherValue>", StringComparison.Ordinal)); Assert.AreEqual ("GQ3YHlGQhDF1bvMixHliX4uLjlY=", Convert.ToBase64String (cert.GetCertHash ()), "premise#1"); Assert.AreEqual ( String.Format ("<e:EncryptedKey Id=\"urn:wrapper-key:1\" xmlns:e=\"{0}\"><e:EncryptionMethod Algorithm=\"{1}\"><DigestMethod Algorithm=\"{2}\" xmlns=\"{3}\" /></e:EncryptionMethod><KeyInfo xmlns=\"{3}\"><o:SecurityTokenReference xmlns:o=\"{4}\"><o:KeyIdentifier ValueType=\"{5}\">{6}</o:KeyIdentifier></o:SecurityTokenReference></KeyInfo><e:CipherData><e:CipherValue>removed here</e:CipherValue></e:CipherData></e:EncryptedKey>", EncryptedXml.XmlEncNamespaceUrl, SecurityAlgorithms.RsaOaepKeyWrap, SignedXml.XmlDsigSHA1Url, SignedXml.XmlDsigNamespaceUrl, "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd", "http://docs.oasis-open.org/wss/oasis-wss-soap-message-security-1.1#ThumbprintSHA1", Convert.ToBase64String (cert.GetCertHash ())),// "GQ3YHlGQhDF1bvMixHliX4uLjlY=" actual); }
public void WriteGenericXmlSecurityToken1 () { StringWriter sw = new StringWriter (); XmlElement xml = new XmlDocument ().CreateElement ("foo"); SecurityToken token = new X509SecurityToken (new X509Certificate2 ("Test/Resources/test.pfx", "mono")); SecurityKeyIdentifierClause intref = token.CreateKeyIdentifierClause<X509IssuerSerialKeyIdentifierClause> (); SecurityKeyIdentifierClause extref = null; // token.CreateKeyIdentifierClause<X509IssuerSerialKeyIdentifierClause> (); ReadOnlyCollection<IAuthorizationPolicy> policies = new ReadOnlyCollection<IAuthorizationPolicy> ( new IAuthorizationPolicy [0]); GenericXmlSecurityToken t = new GenericXmlSecurityToken (xml, token, DateTime.Now, new DateTime (2112, 9, 3), intref, extref, policies); using (XmlWriter w = XmlWriter.Create (sw, GetWriterSettings ())) { WSSecurityTokenSerializer.DefaultInstance.WriteToken (w, t); } // Huh? Assert.AreEqual ("<foo />", sw.ToString ()); }
/// <summary> /// Creates a SAML token for the specified email address and security token. /// </summary> private SamlSecurityToken CreateSAMLToken( string emailAddress, X509SecurityToken issuerToken) { // Create list of confirmation strings List<string> confirmations = new List<string>(); // Add holder-of-key string to list of confirmation strings confirmations.Add("urn:oasis:names:tc:SAML:1.0:cm:bearer"); // Create SAML subject statement based on issuer member variable, confirmation string collection // local variable and proof key identifier parameter SamlSubject subject = new SamlSubject("urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress", null, emailAddress); // Create a list of SAML attributes List<SamlAttribute> attributes = new List<SamlAttribute>(); Claim claim = Claim.CreateNameClaim(emailAddress); attributes.Add(new SamlAttribute(claim)); // Create list of SAML statements List<SamlStatement> statements = new List<SamlStatement>(); // Add a SAML attribute statement to the list of statements. Attribute statement is based on // subject statement and SAML attributes resulting from claims statements.Add(new SamlAttributeStatement(subject, attributes)); // Create a valid from/until condition DateTime validFrom = DateTime.UtcNow; DateTime validTo = DateTime.UtcNow.AddHours(12); SamlConditions conditions = new SamlConditions(validFrom, validTo); // Create the SAML assertion SamlAssertion assertion = new SamlAssertion( "_" + Guid.NewGuid().ToString(), issuerToken.Certificate.Subject, validFrom, conditions, null, statements); SecurityKey signingKey = new System.IdentityModel.Tokens.RsaSecurityKey((RSA)issuerToken.Certificate.PrivateKey); // Set the signing credentials for the SAML assertion assertion.SigningCredentials = new SigningCredentials( signingKey, System.IdentityModel.Tokens.SecurityAlgorithms.RsaSha1Signature, System.IdentityModel.Tokens.SecurityAlgorithms.Sha1Digest, new SecurityKeyIdentifier(issuerToken.CreateKeyIdentifierClause<X509ThumbprintKeyIdentifierClause>())); return new SamlSecurityToken(assertion); }
/// <summary> /// Build the contents of the SAML token /// </summary> /// <param name="writer"><b>XmlDictionaryWriter</b> to write the contents of this token to</param> protected override void OnWriteBodyContents(XmlDictionaryWriter writer) { // Subject SamlSubject subject = new SamlSubject(); if ( this.useKey != null ) { // Add the key and the Holder-Of-Key confirmation method subject.KeyIdentifier = this.useKey; subject.ConfirmationMethods.Add( SamlConstants.HolderOfKey ); } else { // This is a bearer token subject.ConfirmationMethods.Add( SamlConstants.SenderVouches ); } // Attributes, statements, conditions, and assertions List<SamlStatement> statements = new List<SamlStatement>(); List<SamlAttribute> attributes = GetTokenAttributes(); statements.Add(new SamlAuthenticationStatement(subject, Constants.Saml.AuthenticationMethods.Unspecified, DateTime.Now, null, null, null)); statements.Add(new SamlAttributeStatement(subject, attributes)); SamlConditions conditions = new SamlConditions(DateTime.Now, (DateTime.Now + TimeSpan.FromHours(8.0))); SamlAssertion assertion = new SamlAssertion("uuid-" + Guid.NewGuid(), Program.Issuer, DateTime.Now, conditions, null, statements); // Build the signing token SecurityToken signingToken = new X509SecurityToken(Program.SigningCertificate); SecurityKeyIdentifier keyIdentifier = new SecurityKeyIdentifier(signingToken.CreateKeyIdentifierClause<X509RawDataKeyIdentifierClause>()); SigningCredentials signingCredentials = new SigningCredentials(signingToken.SecurityKeys[0], SecurityAlgorithms.RsaSha1Signature, SecurityAlgorithms.Sha1Digest, keyIdentifier); assertion.SigningCredentials = signingCredentials; // Build the SAML token SamlSecurityToken token = new SamlSecurityToken(assertion); SecurityKeyIdentifierClause attachedReference = token.CreateKeyIdentifierClause<SamlAssertionKeyIdentifierClause>(); SecurityKeyIdentifierClause unattachedReference = token.CreateKeyIdentifierClause<SamlAssertionKeyIdentifierClause>(); // // Write the XML // //writer = XmlDictionaryWriter.CreateTextWriter(File.CreateText("output.xml").BaseStream); // RSTR writer.WriteStartElement(Constants.WSTrust.NamespaceUri.Prefix, Constants.WSTrust.Elements.RequestSecurityTokenResponse, Constants.WSTrust.NamespaceUri.Uri); if (context != null) { writer.WriteAttributeString(Constants.WSTrust.Attributes.Context, context); } // TokenType writer.WriteElementString(Constants.WSTrust.NamespaceUri.Prefix, Constants.WSTrust.Elements.TokenType, Constants.WSTrust.NamespaceUri.Uri, Constants.WSTrust.TokenTypes.Saml10Assertion); // RequestedSecurityToken (the SAML token) SecurityTokenSerializer tokenSerializer = new WSSecurityTokenSerializer(); writer.WriteStartElement(Constants.WSTrust.NamespaceUri.Prefix, Constants.WSTrust.Elements.RequestedSecurityToken, Constants.WSTrust.NamespaceUri.Uri); tokenSerializer.WriteToken(writer, token); writer.WriteEndElement(); // RequestedAttachedReference writer.WriteStartElement(Constants.WSTrust.NamespaceUri.Prefix, Constants.WSTrust.Elements.RequestedAttachedReference, Constants.WSTrust.NamespaceUri.Uri); tokenSerializer.WriteKeyIdentifierClause(writer, attachedReference); writer.WriteEndElement(); // RequestedUnattachedReference writer.WriteStartElement(Constants.WSTrust.NamespaceUri.Prefix, Constants.WSTrust.Elements.RequestedUnattachedReference, Constants.WSTrust.NamespaceUri.Uri); tokenSerializer.WriteKeyIdentifierClause(writer, unattachedReference); writer.WriteEndElement(); // RequestedDisplayToken (display token) string displayTokenNS = "http://schemas.xmlsoap.org/ws/2005/05/identity"; writer.WriteStartElement("wsid", "RequestedDisplayToken", displayTokenNS); writer.WriteStartElement("wsid", "DisplayToken", displayTokenNS); foreach (SamlAttribute attribute in attributes) { writer.WriteStartElement("wsid", "DisplayClaim", displayTokenNS); writer.WriteAttributeString("Uri", attribute.Namespace + "/" + attribute.Name); writer.WriteStartElement("wsid", "DisplayTag", displayTokenNS); writer.WriteValue(attribute.Name); writer.WriteEndElement(); writer.WriteStartElement("wsid", "Description", displayTokenNS); writer.WriteValue(attribute.Namespace + "/" + attribute.Name); writer.WriteEndElement(); foreach (string attributeValue in attribute.AttributeValues) { writer.WriteStartElement("wsid", "DisplayValue", displayTokenNS); writer.WriteValue(attributeValue); writer.WriteEndElement(); } writer.WriteEndElement(); } writer.WriteEndElement(); writer.WriteEndElement(); // RSTR End writer.WriteEndElement(); //writer.Close(); }