/// <summary> /// Validates the signature on the incoming token. /// </summary> /// <param name="CustomToken">The incoming <see cref="CustomToken"/>.</param> protected virtual void ValidateSignature(CustomToken CustomToken) { if (CustomToken == null) { throw new ArgumentNullException("CustomToken"); } if (String.IsNullOrEmpty(CustomToken.SerializedToken) || String.IsNullOrEmpty(CustomToken.Signature)) { throw new SecurityTokenValidationException("The token does not have a signature to verify"); } string serializedToken = CustomToken.SerializedToken; string unsignedToken = null; // Find the last parameter. The signature must be last per SWT specification. int lastSeparator = serializedToken.LastIndexOf(ParameterSeparator); // Check whether the last parameter is an hmac. if (lastSeparator > 0) { string lastParamStart = ParameterSeparator + CustomTokenConstants.Signature + "="; string lastParam = serializedToken.Substring(lastSeparator); // Strip the trailing hmac to obtain the original unsigned string for later hmac verification. if (lastParam.StartsWith(lastParamStart, StringComparison.Ordinal)) { unsignedToken = serializedToken.Substring(0, lastSeparator); } } CustomTokenKeyIdentifierClause clause = new CustomTokenKeyIdentifierClause(CustomToken.Audience); InMemorySymmetricSecurityKey securityKey = null; try { securityKey = (InMemorySymmetricSecurityKey)this.Configuration.IssuerTokenResolver.ResolveSecurityKey(clause); } catch (InvalidOperationException) { throw new SecurityTokenValidationException("A Symmetric key was not found for the given key identifier clause."); } string generatedSignature = GenerateSignature(unsignedToken, securityKey.GetSymmetricKey()); if (string.CompareOrdinal(HttpUtility.UrlDecode(generatedSignature), HttpUtility.UrlDecode(CustomToken.Signature)) != 0) { throw new SecurityTokenValidationException("The signature on the incoming token is invalid."); } }
protected override bool TryResolveSecurityKeyCore(SecurityKeyIdentifierClause keyIdentifierClause, out SecurityKey key) { key = null; CustomTokenKeyIdentifierClause keyClause = keyIdentifierClause as CustomTokenKeyIdentifierClause; if (keyClause != null) { string base64Key = null; _keys.TryGetValue(keyClause.Audience, out base64Key); if (!string.IsNullOrEmpty(base64Key)) { key = new InMemorySymmetricSecurityKey(Encoding.UTF8.GetBytes(base64Key)); return(true); } } return(false); }
/// <summary> /// Serializes the given SecurityToken to the XmlWriter. /// </summary> /// <param name="writer">XmlWriter into which the token is serialized.</param> /// <param name="token">SecurityToken to be serialized.</param> public override void WriteToken(XmlWriter writer, SecurityToken token) { CustomToken CustomToken = token as CustomToken; if (CustomToken == null) { throw new SecurityTokenException("The given token is not of the expected type 'CustomToken'."); } string signedToken = null; if (String.IsNullOrEmpty(CustomToken.SerializedToken)) { StringBuilder strBuilder = new StringBuilder(); bool skipDelimiter = true; NameValueCollection tokenProperties = CustomToken.GetAllProperties(); // Remove the signature if present if (String.IsNullOrEmpty(tokenProperties[CustomTokenConstants.Signature])) { tokenProperties.Remove(CustomTokenConstants.Signature); } foreach (string key in tokenProperties.Keys) { if (tokenProperties[key] != null) { if (!skipDelimiter) { strBuilder.Append(ParameterSeparator); } strBuilder.Append(String.Format( CultureInfo.InvariantCulture, "{0}={1}", HttpUtility.UrlEncode(key), HttpUtility.UrlEncode(tokenProperties[key]))); skipDelimiter = false; } } string serializedToken = strBuilder.ToString(); CustomTokenKeyIdentifierClause clause = new CustomTokenKeyIdentifierClause(CustomToken.Audience); InMemorySymmetricSecurityKey securityKey = null; try { securityKey = (InMemorySymmetricSecurityKey)this.Configuration.IssuerTokenResolver.ResolveSecurityKey(clause); } catch (InvalidOperationException) { throw new SecurityTokenValidationException("A Symmetric key was not found for the given key identifier clause."); } // append the signature string signature = GenerateSignature(serializedToken, securityKey.GetSymmetricKey()); strBuilder.Append(String.Format( CultureInfo.InvariantCulture, "{0}{1}={2}", ParameterSeparator, HttpUtility.UrlEncode(CustomTokenConstants.Signature), HttpUtility.UrlEncode(signature))); signedToken = strBuilder.ToString(); } else { // Reuse the stored serialized token if present signedToken = CustomToken.SerializedToken; } string encodedToken = Convert.ToBase64String(Encoding.UTF8.GetBytes(signedToken)); writer.WriteStartElement(BinarySecurityToken); writer.WriteAttributeString("Id", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd", token.Id); writer.WriteAttributeString(ValueType, CustomTokenConstants.ValueTypeUri); writer.WriteAttributeString(EncodingType, Base64EncodingType); writer.WriteString(encodedToken); writer.WriteEndElement(); }
/// <summary> /// Validates the signature on the incoming token. /// </summary> /// <param name="CustomToken">The incoming <see cref="CustomToken"/>.</param> protected virtual void ValidateSignature( CustomToken CustomToken ) { if ( CustomToken == null ) { throw new ArgumentNullException( "CustomToken" ); } if ( String.IsNullOrEmpty( CustomToken.SerializedToken ) || String.IsNullOrEmpty( CustomToken.Signature ) ) { throw new SecurityTokenValidationException( "The token does not have a signature to verify" ); } string serializedToken = CustomToken.SerializedToken; string unsignedToken = null; // Find the last parameter. The signature must be last per SWT specification. int lastSeparator = serializedToken.LastIndexOf( ParameterSeparator ); // Check whether the last parameter is an hmac. if ( lastSeparator > 0 ) { string lastParamStart = ParameterSeparator + CustomTokenConstants.Signature + "="; string lastParam = serializedToken.Substring( lastSeparator ); // Strip the trailing hmac to obtain the original unsigned string for later hmac verification. if ( lastParam.StartsWith( lastParamStart, StringComparison.Ordinal ) ) { unsignedToken = serializedToken.Substring( 0, lastSeparator ); } } CustomTokenKeyIdentifierClause clause = new CustomTokenKeyIdentifierClause(CustomToken.Audience); InMemorySymmetricSecurityKey securityKey = null; try { securityKey = (InMemorySymmetricSecurityKey)this.Configuration.IssuerTokenResolver.ResolveSecurityKey(clause); } catch (InvalidOperationException) { throw new SecurityTokenValidationException( "A Symmetric key was not found for the given key identifier clause."); } string generatedSignature = GenerateSignature( unsignedToken, securityKey.GetSymmetricKey() ); if ( string.CompareOrdinal( HttpUtility.UrlDecode( generatedSignature ), HttpUtility.UrlDecode( CustomToken.Signature ) ) != 0 ) { throw new SecurityTokenValidationException( "The signature on the incoming token is invalid.") ; } }
/// <summary> /// Serializes the given SecurityToken to the XmlWriter. /// </summary> /// <param name="writer">XmlWriter into which the token is serialized.</param> /// <param name="token">SecurityToken to be serialized.</param> public override void WriteToken( XmlWriter writer, SecurityToken token ) { CustomToken CustomToken = token as CustomToken; if ( CustomToken == null ) { throw new SecurityTokenException("The given token is not of the expected type 'CustomToken'."); } string signedToken = null; if ( String.IsNullOrEmpty( CustomToken.SerializedToken ) ) { StringBuilder strBuilder = new StringBuilder(); bool skipDelimiter = true; NameValueCollection tokenProperties = CustomToken.GetAllProperties(); // Remove the signature if present if ( String.IsNullOrEmpty( tokenProperties[CustomTokenConstants.Signature] ) ) { tokenProperties.Remove( CustomTokenConstants.Signature ); } foreach ( string key in tokenProperties.Keys ) { if ( tokenProperties[key] != null ) { if ( !skipDelimiter ) { strBuilder.Append( ParameterSeparator ); } strBuilder.Append( String.Format( CultureInfo.InvariantCulture, "{0}={1}", HttpUtility.UrlEncode( key ), HttpUtility.UrlEncode( tokenProperties[key] ) ) ); skipDelimiter = false; } } string serializedToken = strBuilder.ToString(); CustomTokenKeyIdentifierClause clause = new CustomTokenKeyIdentifierClause(CustomToken.Audience); InMemorySymmetricSecurityKey securityKey = null; try { securityKey = (InMemorySymmetricSecurityKey)this.Configuration.IssuerTokenResolver.ResolveSecurityKey(clause); } catch (InvalidOperationException) { throw new SecurityTokenValidationException("A Symmetric key was not found for the given key identifier clause."); } // append the signature string signature = GenerateSignature( serializedToken, securityKey.GetSymmetricKey() ); strBuilder.Append( String.Format( CultureInfo.InvariantCulture, "{0}{1}={2}", ParameterSeparator, HttpUtility.UrlEncode( CustomTokenConstants.Signature ), HttpUtility.UrlEncode( signature ) ) ); signedToken = strBuilder.ToString(); } else { // Reuse the stored serialized token if present signedToken = CustomToken.SerializedToken; } string encodedToken = Convert.ToBase64String( Encoding.UTF8.GetBytes( signedToken ) ); writer.WriteStartElement(BinarySecurityToken); writer.WriteAttributeString("Id", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd", token.Id); writer.WriteAttributeString( ValueType, CustomTokenConstants.ValueTypeUri ); writer.WriteAttributeString( EncodingType, Base64EncodingType ); writer.WriteString( encodedToken ); writer.WriteEndElement(); }