/// <summary> /// Performs any transformation on an incoming message that may be necessary and/or /// validates an incoming message based on the rules of this channel binding element. /// </summary> /// <param name="message">The incoming message to process.</param> /// <returns> /// The protections (if any) that this binding element applied to the message. /// Null if this binding element did not even apply to this binding element. /// </returns> /// <exception cref="ProtocolException"> /// Thrown when the binding element rules indicate that this message is invalid and should /// NOT be processed. /// </exception> /// <remarks> /// Implementations that provide message protection must honor the /// <see cref="MessagePartAttribute.RequiredProtection"/> properties where applicable. /// </remarks> public MessageProtections?ProcessIncomingMessage(IProtocolMessage message) { IndirectSignedResponse response = message as IndirectSignedResponse; if (response != null) { // We can't use response.GetReturnToArgument(string) because that relies // on us already having validated this signature. NameValueCollection returnToParameters = HttpUtility.ParseQueryString(response.ReturnTo.Query); // Only check the return_to signature if one is present. if (returnToParameters[ReturnToSignatureHandleParameterName] != null) { // Set the safety flag showing whether the return_to url had a valid signature. byte[] expectedBytes = this.GetReturnToSignature(response.ReturnTo); string actual = returnToParameters[ReturnToSignatureParameterName]; actual = OpenIdUtilities.FixDoublyUriDecodedBase64String(actual); byte[] actualBytes = Convert.FromBase64String(actual); response.ReturnToParametersSignatureValidated = MessagingUtilities.AreEquivalentConstantTime(actualBytes, expectedBytes); if (!response.ReturnToParametersSignatureValidated) { Logger.Bindings.WarnFormat("The return_to signature failed verification."); } return(MessageProtections.None); } } return(null); }
/// <summary> /// Performs any transformation on an incoming message that may be necessary and/or /// validates an incoming message based on the rules of this channel binding element. /// </summary> /// <param name="message">The incoming message to process.</param> /// <returns> /// True if the <paramref name="message"/> applied to this binding element /// and the operation was successful. False if the operation did not apply to this message. /// </returns> /// <exception cref="ProtocolException"> /// Thrown when the binding element rules indicate that this message is invalid and should /// NOT be processed. /// </exception> /// <remarks> /// Implementations that provide message protection must honor the /// <see cref="MessagePartAttribute.RequiredProtection"/> properties where applicable. /// </remarks> public bool PrepareMessageForReceiving(IProtocolMessage message) { IndirectSignedResponse response = message as IndirectSignedResponse; if (response != null) { // We can't use response.GetReturnToArgument(string) because that relies // on us already having validated this signature. NameValueCollection returnToParameters = HttpUtility.ParseQueryString(response.ReturnTo.Query); // Only check the return_to signature if one is present. if (returnToParameters[ReturnToSignatureHandleParameterName] != null) { // Set the safety flag showing whether the return_to url had a valid signature. string expected = this.GetReturnToSignature(response.ReturnTo); string actual = returnToParameters[ReturnToSignatureParameterName]; actual = OpenIdUtilities.FixDoublyUriDecodedBase64String(actual); response.ReturnToParametersSignatureValidated = actual == expected; if (!response.ReturnToParametersSignatureValidated) { Logger.WarnFormat("The return_to signature failed verification."); } return(true); } } return(false); }