AuthenticationRequest(ServiceEndpoint endpoint, Realm realm, Uri returnToUrl, OpenIdRelyingParty relyingParty) { if (endpoint == null) { throw new ArgumentNullException("endpoint"); } if (realm == null) { throw new ArgumentNullException("realm"); } if (returnToUrl == null) { throw new ArgumentNullException("returnToUrl"); } if (relyingParty == null) { throw new ArgumentNullException("relyingParty"); } this.endpoint = endpoint; RelyingParty = relyingParty; Realm = realm; ReturnToUrl = returnToUrl; Mode = AuthenticationRequestMode.Setup; OutgoingExtensions = ExtensionArgumentsManager.CreateOutgoingExtensions(endpoint.Protocol); ReturnToArgs = new Dictionary <string, string>(); }
public void CreateIncomingSimpleSomeExtensions() { var args = new Dictionary <string, string>() { { "arg1", "val1" }, { "arg2", "val2" }, { "openid.qq.k1", "v1" }, { "openid.ns.qq", "QQExtTypeUri" }, { "openid.ns.ss", "SSExtTypeUri" }, { "openid.ss.k2", "v2" }, { "openid.ns.mt", "MTExtTypeUri" }, }; var mgr = ExtensionArgumentsManager.CreateIncomingExtensions(args); Assert.IsTrue(mgr.ContainsExtension("QQExtTypeUri")); Assert.IsTrue(mgr.ContainsExtension("SSExtTypeUri")); Assert.IsFalse(mgr.ContainsExtension("MTExtTypeUri"), "A declared alias without any arguments should not be considered a present extension."); var qq = mgr.GetExtensionArguments("QQExtTypeUri"); var ss = mgr.GetExtensionArguments("SSExtTypeUri"); var mt = mgr.GetExtensionArguments("MTExtTypeUri"); Assert.IsNotNull(qq); Assert.IsNotNull(ss); Assert.IsNull(mt); Assert.AreEqual(1, qq.Count); Assert.AreEqual(1, ss.Count); Assert.AreEqual("v1", qq["k1"]); Assert.AreEqual("v2", ss["k2"]); }
public void GetArgumentsToSend() { var ext1args = new Dictionary <string, string> { { "e1k1", "e1v1" }, { "e1k2", "e1v2" }, }; var ext2args = new Dictionary <string, string> { { "e2k1", "e2v1" }, { "e2k2", "e2v2" }, }; var mgr = ExtensionArgumentsManager.CreateOutgoingExtensions(protocol); mgr.AddExtensionArguments("e1URI", ext1args); mgr.AddExtensionArguments("e2URI", ext2args); var results = mgr.GetArgumentsToSend(true); Assert.AreEqual(6, results.Count); var mgrRoundtrip = ExtensionArgumentsManager.CreateIncomingExtensions(results); Assert.IsTrue(mgrRoundtrip.ContainsExtension("e1URI")); Assert.IsTrue(mgrRoundtrip.ContainsExtension("e2URI")); Assert.AreEqual("e1v1", mgrRoundtrip.GetExtensionArguments("e1URI")["e1k1"]); Assert.AreEqual("e1v2", mgrRoundtrip.GetExtensionArguments("e1URI")["e1k2"]); Assert.AreEqual("e2v1", mgrRoundtrip.GetExtensionArguments("e2URI")["e2k1"]); Assert.AreEqual("e2v2", mgrRoundtrip.GetExtensionArguments("e2URI")["e2k2"]); }
/// <summary> /// Gets the extensions on a message. /// </summary> /// <param name="message">The carrier of the extensions.</param> /// <param name="ignoreUnsigned">If set to <c>true</c> only signed extensions will be available.</param> /// <param name="extensionFilter">A optional filter that takes an extension type URI and /// returns a value indicating whether that extension should be deserialized and /// returned in the sequence. May be null.</param> /// <returns>A sequence of extensions in the message.</returns> private IEnumerable <IOpenIdMessageExtension> GetExtensions(IProtocolMessageWithExtensions message, bool ignoreUnsigned, Func <string, bool> extensionFilter) { bool isAtProvider = message is SignedResponseRequest; // 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.CreateIncomingExtensions(this.GetExtensionsDictionary(message, ignoreUnsigned)); foreach (string typeUri in extensionManager.GetExtensionTypeUris()) { // Our caller may have already obtained a signed version of this extension, // so skip it if they don't want this one. if (extensionFilter != null && !extensionFilter(typeUri)) { continue; } var extensionData = extensionManager.GetExtensionArguments(typeUri); // Initialize this particular extension. IOpenIdMessageExtension extension = this.ExtensionFactory.Create(typeUri, extensionData, message, isAtProvider); if (extension != null) { try { // Make sure the extension fulfills spec requirements before deserializing it. MessageDescription messageDescription = this.Channel.MessageDescriptions.Get(extension); messageDescription.EnsureMessagePartsPassBasicValidation(extensionData); // Deserialize the extension. MessageDictionary extensionDictionary = messageDescription.GetDictionary(extension); foreach (var pair in extensionData) { extensionDictionary[pair.Key] = pair.Value; } // Give extensions that require custom serialization a chance to do their work. var customSerializingExtension = extension as IMessageWithEvents; if (customSerializingExtension != null) { customSerializingExtension.OnReceiving(); } } catch (ProtocolException ex) { Logger.OpenId.ErrorFormat(OpenIdStrings.BadExtension, extension.GetType(), ex); extension = null; } if (extension != null) { yield return(extension); } } else { Logger.OpenId.DebugFormat("Extension with type URI '{0}' ignored because it is not a recognized extension.", typeUri); } } }
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); }
public void ReadExtensionWithEmptyKey() { var args = new Dictionary <string, string> { { "openid.sreg", "v1" }, }; var mgr = ExtensionArgumentsManager.CreateIncomingExtensions(args); var result = mgr.GetExtensionArguments(Constants.sreg_ns); Assert.AreEqual("v1", result[string.Empty]); }
public void CreateIncomingSimpleNoExtensions() { var args = new Dictionary <string, string>() { { "arg1", "val1" }, { "openid.arg2", "val2" }, }; ExtensionArgumentsManager.CreateIncomingExtensions(args); }
public void ReadMultipleAliasesForOneNamespace() { // This scenario is called out in the spec and forbidden. var args = new Dictionary <string, string>() { { "openid.ns.qq1", "QQExtTypeUri" }, { "openid.ns.qq2", "QQExtTypeUri" }, }; ExtensionArgumentsManager.CreateIncomingExtensions(args); }
protected Request(OpenIdProvider provider) { if (provider == null) { throw new ArgumentNullException("provider"); } Provider = provider; Query = provider.Query; Protocol = Protocol.Detect(Query); IncomingExtensions = ExtensionArgumentsManager.CreateIncomingExtensions(Query); OutgoingExtensions = ExtensionArgumentsManager.CreateOutgoingExtensions(Protocol); }
/// <summary> /// Prepares a message for sending based on the rules of this channel binding element. /// </summary> /// <param name="message">The message to prepare for sending.</param> /// <returns> /// True if the <paramref name="message"/> applied to this binding element /// and the operation was successful. False otherwise. /// </returns> /// <remarks> /// Implementations that provide message protection must honor the /// <see cref="MessagePartAttribute.RequiredProtection"/> properties where applicable. /// </remarks> public bool PrepareMessageForSending(IProtocolMessage message) { ErrorUtilities.VerifyArgumentNotNull(message, "message"); var extendableMessage = message as IProtocolMessageWithExtensions; if (extendableMessage != null) { Protocol protocol = Protocol.Lookup(message.Version); MessageDictionary baseMessageDictionary = new MessageDictionary(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) { // 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); var extensionDictionary = MessageSerializer.Get(extension.GetType()).Serialize(extension); extensionManager.AddExtensionArguments(extension.TypeUri, extensionDictionary); } else { Logger.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. extendableMessage.AddExtraParameters(extensionManager.GetArgumentsToSend(includeOpenIdPrefix)); return(true); } return(false); }
public void AddExtensionArgsTwiceInSameNamespace() { var args1 = new Dictionary <string, string>() { { "k1", "v1" }, }; var args2 = new Dictionary <string, string>() { { "k2", "v2" }, }; var mgr = ExtensionArgumentsManager.CreateOutgoingExtensions(protocol); mgr.AddExtensionArguments("extTypeURI", args1); mgr.AddExtensionArguments("extTypeURI", args2); }
public void TestWritingNoPrefix() { var args = new Dictionary <string, string>() { { "nickname", "andy" }, }; var mgr = ExtensionArgumentsManager.CreateOutgoingExtensions(protocol); mgr.AddExtensionArguments(Constants.sreg_ns, args); var results = mgr.GetArgumentsToSend(false); Assert.IsTrue(results.ContainsKey("ns.sreg")); Assert.AreEqual(Constants.sreg_ns, results["ns.sreg"]); Assert.IsTrue(results.ContainsKey("sreg.nickname")); Assert.AreEqual("andy", results["sreg.nickname"]); }
public void WriteExtensionWithEmptyKey() { var args = new Dictionary <string, string> { { "", "v1" }, }; var mgr = ExtensionArgumentsManager.CreateOutgoingExtensions(protocol); mgr.AddExtensionArguments(Constants.sreg_ns, args); var result = mgr.GetArgumentsToSend(true); Assert.AreEqual(2, result.Count); Assert.AreEqual("v1", result["openid.sreg"]); result = mgr.GetArgumentsToSend(false); Assert.AreEqual(2, result.Count); Assert.AreEqual("v1", result["sreg"]); }
internal AuthenticationResponse(AuthenticationStatus status, ServiceEndpoint provider, IDictionary <string, string> query) { if (provider == null) { throw new ArgumentNullException("provider"); } if (query == null) { throw new ArgumentNullException("query"); } if (status == AuthenticationStatus.Authenticated) { Logger.InfoFormat("Verified positive authentication assertion for: {0}", provider.ClaimedIdentifier); } else { Logger.InfoFormat("Negative authentication assertion received: {0}", status); } // TODO: verify signature on callback args CallbackArguments = cleanQueryForCallbackArguments(query); Status = status; Provider = provider; signedArguments = new Dictionary <string, string>(); string signed; if (query.TryGetValue(Provider.Protocol.openid.signed, out signed)) { foreach (string fieldNoPrefix in signed.Split(',')) { string fieldWithPrefix = Provider.Protocol.openid.Prefix + fieldNoPrefix; string val; if (!query.TryGetValue(fieldWithPrefix, out val)) { val = string.Empty; } signedArguments[fieldWithPrefix] = val; } } // Only read extensions from signed argument list. IncomingExtensions = ExtensionArgumentsManager.CreateIncomingExtensions(signedArguments); }
/// <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) { var extendableMessage = message as IProtocolMessageWithExtensions; if (extendableMessage != null) { // 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.CreateIncomingExtensions(this.GetExtensionsDictionary(message)); foreach (string typeUri in extensionManager.GetExtensionTypeUris()) { var extensionData = extensionManager.GetExtensionArguments(typeUri); // Initialize this particular extension. IOpenIdMessageExtension extension = this.ExtensionFactory.Create(typeUri, extensionData, extendableMessage); if (extension != null) { MessageDictionary extensionDictionary = new MessageDictionary(extension); foreach (var pair in extensionData) { extensionDictionary[pair.Key] = pair.Value; } // Give extensions that require custom serialization a chance to do their work. var customSerializingExtension = extension as IMessageWithEvents; if (customSerializingExtension != null) { customSerializingExtension.OnReceiving(); } extendableMessage.Extensions.Add(extension); } else { Logger.WarnFormat("Extension with type URI '{0}' ignored because it is not a recognized extension.", typeUri); } } return(true); } return(false); }
public void TestSregReadingAffinity() { // Construct a dictionary that doesn't define sreg but uses it. var args = new Dictionary <string, string>() { { "openid.sreg.nickname", "andy" }, }; IIncomingExtensions mgr = ExtensionArgumentsManager.CreateIncomingExtensions(args); Assert.IsTrue(mgr.ContainsExtension(Constants.sreg_ns)); Assert.AreEqual("andy", mgr.GetExtensionArguments(Constants.sreg_ns)["nickname"]); // Now imagine that sreg was used explicitly by something else... args = new Dictionary <string, string>() { { "openid.sreg.nickname", "andy" }, { "openid.ns.sreg", "someOtherNS" }, }; mgr = ExtensionArgumentsManager.CreateIncomingExtensions(args); Assert.IsFalse(mgr.ContainsExtension(Constants.sreg_ns)); Assert.AreEqual("andy", mgr.GetExtensionArguments("someOtherNS")["nickname"]); }
public void WritingModeContainsExtension() { var mgr = ExtensionArgumentsManager.CreateOutgoingExtensions(protocol); mgr.ContainsExtension("some"); }
public void CreateIncomingNull() { ExtensionArgumentsManager.CreateIncomingExtensions(null); }
public void ReadingModeGetArgumentsToSend() { var mgr = ExtensionArgumentsManager.CreateIncomingExtensions(new Dictionary <string, string>()); mgr.GetArgumentsToSend(true); }
public void ReadingModeAddExtension() { var mgr = ExtensionArgumentsManager.CreateIncomingExtensions(new Dictionary <string, string>()); mgr.AddExtensionArguments("some", new Dictionary <string, string>()); }
public void CreateOutgoing() { var mgr = ExtensionArgumentsManager.CreateOutgoingExtensions(protocol); Assert.IsNotNull(mgr); }
public void WritingModeGetExtensionArguments() { var mgr = ExtensionArgumentsManager.CreateOutgoingExtensions(protocol); mgr.GetExtensionArguments("some"); }
public void CreateIncomingEmpty() { var mgr = ExtensionArgumentsManager.CreateIncomingExtensions(new Dictionary <string, string>()); }