/// <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 (this.UseRequestNonce(response)) { if (!response.ReturnToParametersSignatureValidated) { Logger.OpenId.Error("Incoming message is expected to have a nonce, but the return_to parameter is not signed."); } string nonceValue = response.GetReturnToArgument(NonceParameter); ErrorUtilities.VerifyProtocol( nonceValue != null && response.ReturnToParametersSignatureValidated, this.securitySettings.RejectUnsolicitedAssertions ? OpenIdStrings.UnsolicitedAssertionsNotAllowed : OpenIdStrings.UnsolicitedAssertionsNotAllowedFrom1xOPs); CustomNonce nonce = CustomNonce.Deserialize(nonceValue); DateTime expirationDate = nonce.CreationDateUtc + MaximumMessageAge; if (expirationDate < DateTime.UtcNow) { throw new ExpiredMessageException(expirationDate, message); } IReplayProtectedProtocolMessage replayResponse = response; if (!this.nonceStore.StoreNonce(replayResponse.NonceContext, nonce.RandomPartAsString, nonce.CreationDateUtc)) { Logger.OpenId.ErrorFormat("Replayed nonce detected ({0} {1}). Rejecting message.", replayResponse.Nonce, replayResponse.UtcCreationDate); throw new ReplayedMessageException(message); } return(MessageProtections.ReplayProtection); } 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 && response.Version.Major < 2) { string nonceValue = response.GetReturnToArgument(NonceParameter); ErrorUtilities.VerifyProtocol(nonceValue != null, OpenIdStrings.UnsolicitedAssertionsNotAllowedFrom1xOPs); CustomNonce nonce = CustomNonce.Deserialize(nonceValue); DateTime expirationDate = nonce.CreationDateUtc + MaximumMessageAge; if (expirationDate < DateTime.UtcNow) { throw new ExpiredMessageException(expirationDate, message); } if (!this.nonceStore.StoreNonce(nonce.RandomPartAsString, nonce.CreationDateUtc)) { throw new ReplayedMessageException(message); } return(true); } return(false); }