/// <summary> /// Creates a MyDecision type security token based on the description in the security token descriptor. /// </summary> /// <param name="tokenDescriptor">The token descriptor.</param> /// <returns>The security token.</returns> public override SecurityToken CreateToken(SecurityTokenDescriptor tokenDescriptor) { Console.WriteLine("CustomTokenHandler.CreateToken called"); SymmetricProofDescriptor symmetric = tokenDescriptor.Proof as SymmetricProofDescriptor; if (symmetric == null) { throw new InvalidOperationException("The MyDecisionToken must be symmetric key based."); } bool decision = false; // // Retrieve the decision from the issued claims // foreach (Claim claim in tokenDescriptor.Subject.Claims) { if (StringComparer.Ordinal.Equals(claim.ClaimType, DecisionClaimType) && StringComparer.Ordinal.Equals(claim.ValueType, ClaimValueTypes.Boolean)) { Console.WriteLine("- decision claim found: {0}", claim.Value); decision = Convert.ToBoolean(claim.Value); } } // // This is just an example to show how to issue a custom token. The key is created by the STS // through the proof token. // SecurityToken token = new MyDecisionToken(decision, tokenDescriptor.SigningCredentials, symmetric.GetKeyBytes()); // // Encrypt the token // EncryptingCredentials encryptingCredentials = GetEncryptingCredentials(tokenDescriptor); if (encryptingCredentials != null) { token = new EncryptedSecurityToken(token, encryptingCredentials); } return(token); }
private GenericXmlSecurityToken GenerateSAML2Token() { var signingCertificatePrivateKey = new X509Certificate2(Settings.Default.CertificatePath, Settings.Default.Passphrase); var encryptingCertificatePublicKey = signingCertificatePrivateKey; //new X509Certificate2(@"C:\Users\ed2ny1e\Documents\CommonWell\Integration Certificates\McKesson.cer"); string signingAlgorithm = SignatureAlgorithm.Sha256; string digestAlgorithm = DigestAlgorithm.Sha256; SigningCredentials signingCredentials = null; SymmetricProofDescriptor proof = CreateSymmetricProofDescriptor(encryptingCertificatePublicKey); switch (ComboBoxSigningAlgorithm.SelectedValue.ToString()) { case "SHA1": signingAlgorithm = SignatureAlgorithm.Sha1; break; case "SHA256": signingAlgorithm = SignatureAlgorithm.Sha256; break; } switch (ComboBoxDigestAlgorithm.SelectedValue.ToString()) { case "SHA1": digestAlgorithm = DigestAlgorithm.Sha1; break; case "SHA256": digestAlgorithm = DigestAlgorithm.Sha256; break; } if (Rsa.IsChecked.HasValue && Rsa.IsChecked.Value) { var rsa = signingCertificatePrivateKey.PrivateKey as RSACryptoServiceProvider; if (rsa != null) { var rsaKey = new RsaSecurityKey(rsa); var rsaClause = new RsaKeyIdentifierClause(rsa); var ski = new SecurityKeyIdentifier(new SecurityKeyIdentifierClause[] { rsaClause }); signingCredentials = new SigningCredentials(rsaKey, signingAlgorithm, digestAlgorithm, ski); } } else { var clause = new X509SecurityToken(signingCertificatePrivateKey) .CreateKeyIdentifierClause <X509RawDataKeyIdentifierClause>(); var ski = new SecurityKeyIdentifier(clause); signingCredentials = new X509SigningCredentials(signingCertificatePrivateKey, ski, signingAlgorithm, digestAlgorithm); } SecurityTokenDescriptor tokenDescriptor = BuildSAMLDescriptorUsingXspaProfile(); tokenDescriptor.TokenType = WSTrust.TokenType; tokenDescriptor.SigningCredentials = signingCredentials; if (CheckBoxEncrypt.IsChecked.HasValue && CheckBoxEncrypt.IsChecked.Value) { const string keyWrapAlgorithm = WSTrust.KeyWrapAlgorithm; const string encryptionAlgorithm = WSTrust.EncryptionAlgorithm; var encryptingCredentials = new EncryptedKeyEncryptingCredentials(encryptingCertificatePublicKey, keyWrapAlgorithm, WSTrust.KeySize, encryptionAlgorithm); tokenDescriptor.EncryptingCredentials = encryptingCredentials; } switch (ComboBoxConfirmation.SelectedValue.ToString()) { case "holder": if (AsymmetricKey.IsChecked != null && (bool)AsymmetricKey.IsChecked) { tokenDescriptor.Proof = CreateAsymmetricProofDescriptor(encryptingCertificatePublicKey); } else { tokenDescriptor.Proof = proof; } break; case "sender": //TODO break; } var tokenHandler = new CustomSaml2SecurityTokenHandler(); tokenDescriptor.AddAuthenticationClaims("uurn:oasis:names:tc:SAML:2.0:ac:classes:X509"); var outputToken = tokenHandler.CreateToken(tokenDescriptor) as Saml2SecurityToken; if (outputToken == null) { throw new Exception("Failed to create Saml2 Security token"); } // turn token into a generic xml security token var outputTokenString = outputToken.ToTokenXmlString(); // create attached and unattached references var attachedReference = tokenHandler.CreateSecurityTokenReference(outputToken, true); var unattachedReference = tokenHandler.CreateSecurityTokenReference(outputToken, false); GenericXmlSecurityToken xmlToken; if (ComboBoxConfirmation.SelectedValue.ToString().Equals("holder")) { xmlToken = new GenericXmlSecurityToken( GetElement(outputTokenString), new BinarySecretSecurityToken(proof.GetKeyBytes()), DateTime.UtcNow, DateTime.UtcNow.AddHours(1), attachedReference, unattachedReference, new ReadOnlyCollection <IAuthorizationPolicy>(new List <IAuthorizationPolicy>())); } else { xmlToken = new GenericXmlSecurityToken( GetElement(outputTokenString), null, DateTime.UtcNow, DateTime.UtcNow.AddHours(8), attachedReference, unattachedReference, new ReadOnlyCollection <IAuthorizationPolicy>(new List <IAuthorizationPolicy>())); } return(xmlToken); }
/// <summary> /// Gets the proof token. /// </summary> /// <param name="request">The incoming token request.</param> /// <param name="scope">The scope instance encapsulating information about the relying party.</param> /// <returns>The newly created proof decriptor that could be either asymmetric proof descriptor or symmetric proof descriptor or null in the bearer token case.</returns> protected virtual ProofDescriptor GetProofToken(RST request, Scope scope) { if (request == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("request"); } if (scope == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("scope"); } EncryptingCredentials requestorWrappingCredentials = GetRequestorProofEncryptingCredentials(request); if (scope.EncryptingCredentials != null && !(scope.EncryptingCredentials.SecurityKey is AsymmetricSecurityKey)) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new SecurityTokenException(SR.GetString(SR.ID4179))); } EncryptingCredentials targetWrappingCredentials = scope.EncryptingCredentials; // // Generate the proof key // string keyType = (string.IsNullOrEmpty(request.KeyType)) ? KeyTypes.Symmetric : request.KeyType; ProofDescriptor result = null; if (StringComparer.Ordinal.Equals(keyType, KeyTypes.Asymmetric)) { // // Asymmetric is only supported with UseKey // if (request.UseKey == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidRequestException(SR.GetString(SR.ID3091))); } result = new AsymmetricProofDescriptor(request.UseKey.SecurityKeyIdentifier); } else if (StringComparer.Ordinal.Equals(keyType, KeyTypes.Symmetric)) { // // Only support PSHA1. Overwrite STS to support custom key algorithm // if (request.ComputedKeyAlgorithm != null && !StringComparer.Ordinal.Equals(request.ComputedKeyAlgorithm, ComputedKeyAlgorithms.Psha1)) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new RequestFailedException(SR.GetString(SR.ID2011, request.ComputedKeyAlgorithm))); } // // We must wrap the symmetric key inside the security token // if (targetWrappingCredentials == null && scope.SymmetricKeyEncryptionRequired) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new RequestFailedException(SR.GetString(SR.ID4007))); } // // We are encrypting the proof token or the server entropy using client's encrypting credential if present, // which will be used to encrypt the key during serialization. // Otherwise, we can only send back the key in plain text. However, the current implementation of // WSTrustServiceContract sets the rst.ProofEncryption = null by default. Therefore, the server entropy // or the proof token will be sent in plain text no matter the client's entropy is sent encrypted or unencrypted. // if (request.KeySizeInBits.HasValue) { if (request.Entropy != null) { result = new SymmetricProofDescriptor(request.KeySizeInBits.Value, targetWrappingCredentials, requestorWrappingCredentials, request.Entropy.GetKeyBytes(), request.EncryptWith); } else { result = new SymmetricProofDescriptor(request.KeySizeInBits.Value, targetWrappingCredentials, requestorWrappingCredentials, request.EncryptWith); } } else { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new RequestFailedException(SR.GetString(SR.ID2059))); } } else if (StringComparer.Ordinal.Equals(keyType, KeyTypes.Bearer)) { // // Intentionally empty, no proofDescriptor // } return(result); }