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>();
        }
Exemple #2
0
        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"]);
        }
Exemple #3
0
        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);
        }
Exemple #6
0
        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]);
        }
Exemple #7
0
        public void CreateIncomingSimpleNoExtensions()
        {
            var args = new Dictionary <string, string>()
            {
                { "arg1", "val1" },
                { "openid.arg2", "val2" },
            };

            ExtensionArgumentsManager.CreateIncomingExtensions(args);
        }
Exemple #8
0
        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);
        }
Exemple #9
0
 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);
        }
Exemple #11
0
        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);
        }
Exemple #12
0
        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"]);
        }
Exemple #13
0
        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"]);
        }
Exemple #14
0
        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);
        }
Exemple #16
0
        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"]);
        }
Exemple #17
0
        public void WritingModeContainsExtension()
        {
            var mgr = ExtensionArgumentsManager.CreateOutgoingExtensions(protocol);

            mgr.ContainsExtension("some");
        }
Exemple #18
0
 public void CreateIncomingNull()
 {
     ExtensionArgumentsManager.CreateIncomingExtensions(null);
 }
Exemple #19
0
        public void ReadingModeGetArgumentsToSend()
        {
            var mgr = ExtensionArgumentsManager.CreateIncomingExtensions(new Dictionary <string, string>());

            mgr.GetArgumentsToSend(true);
        }
Exemple #20
0
        public void ReadingModeAddExtension()
        {
            var mgr = ExtensionArgumentsManager.CreateIncomingExtensions(new Dictionary <string, string>());

            mgr.AddExtensionArguments("some", new Dictionary <string, string>());
        }
Exemple #21
0
        public void CreateOutgoing()
        {
            var mgr = ExtensionArgumentsManager.CreateOutgoingExtensions(protocol);

            Assert.IsNotNull(mgr);
        }
Exemple #22
0
        public void WritingModeGetExtensionArguments()
        {
            var mgr = ExtensionArgumentsManager.CreateOutgoingExtensions(protocol);

            mgr.GetExtensionArguments("some");
        }
Exemple #23
0
 public void CreateIncomingEmpty()
 {
     var mgr = ExtensionArgumentsManager.CreateIncomingExtensions(new Dictionary <string, string>());
 }