public Task <MessageProtections?> ProcessOutgoingMessageAsync(IProtocolMessage message, CancellationToken cancellationToken) { var extendableMessage = message as IProtocolMessageWithExtensions; if (extendableMessage != null) { Protocol protocol = Protocol.Lookup(message.Version); MessageDictionary baseMessageDictionary = this.Channel.MessageDescriptions.GetAccessor(message); // We have a helper class that will do all the heavy-lifting of organizing // all the extensions, their aliases, and their parameters. var extensionManager = ExtensionArgumentsManager.CreateOutgoingExtensions(protocol); foreach (IExtensionMessage protocolExtension in extendableMessage.Extensions) { var extension = protocolExtension as IOpenIdMessageExtension; if (extension != null) { Reporting.RecordFeatureUse(protocolExtension); // Give extensions that require custom serialization a chance to do their work. var customSerializingExtension = extension as IMessageWithEvents; if (customSerializingExtension != null) { customSerializingExtension.OnSending(); } // OpenID 2.0 Section 12 forbids two extensions with the same TypeURI in the same message. ErrorUtilities.VerifyProtocol(!extensionManager.ContainsExtension(extension.TypeUri), OpenIdStrings.ExtensionAlreadyAddedWithSameTypeURI, extension.TypeUri); // Ensure that we're sending out a valid extension. var extensionDescription = this.Channel.MessageDescriptions.Get(extension); var extensionDictionary = extensionDescription.GetDictionary(extension).Serialize(); extensionDescription.EnsureMessagePartsPassBasicValidation(extensionDictionary); // Add the extension to the outgoing message payload. extensionManager.AddExtensionArguments(extension.TypeUri, extensionDictionary); } else { Logger.OpenId.WarnFormat("Unexpected extension type {0} did not implement {1}.", protocolExtension.GetType(), typeof(IOpenIdMessageExtension).Name); } } // We use a cheap trick (for now at least) to determine whether the 'openid.' prefix // belongs on the parameters by just looking at what other parameters do. // Technically, direct message responses from Provider to Relying Party are the only // messages that leave off the 'openid.' prefix. bool includeOpenIdPrefix = baseMessageDictionary.Keys.Any(key => key.StartsWith(protocol.openid.Prefix, StringComparison.Ordinal)); // Add the extension parameters to the base message for transmission. baseMessageDictionary.AddExtraParameters(extensionManager.GetArgumentsToSend(includeOpenIdPrefix)); return(NoneTask); } return(NullTask); }