コード例 #1
0
        /// <summary>
        /// Creates a new association with a given Provider.
        /// </summary>
        /// <param name="provider">The provider to create an association with.</param>
        /// <returns>
        /// The newly created association, or null if no association can be created with
        /// the given Provider given the current security settings.
        /// </returns>
        /// <remarks>
        /// A new association is created and returned even if one already exists in the
        /// association store.
        /// Any new association is automatically added to the <see cref="associationStore"/>.
        /// </remarks>
        private Association CreateNewAssociation(IProviderEndpoint provider)
        {
            Contract.Requires <ArgumentNullException>(provider != null);

            // If there is no association store, there is no point in creating an association.
            if (this.associationStore == null)
            {
                return(null);
            }

            try {
                var associateRequest = AssociateRequest.Create(this.securitySettings, provider);

                const int RenegotiateRetries = 1;
                return(this.CreateNewAssociation(provider, associateRequest, RenegotiateRetries));
            } catch (VerificationException ex) {
                // See Trac ticket #163.  In partial trust host environments, the
                // Diffie-Hellman implementation we're using for HTTP OP endpoints
                // sometimes causes the CLR to throw:
                // "VerificationException: Operation could destabilize the runtime."
                // Just give up and use dumb mode in this case.
                Logger.OpenId.ErrorFormat("VerificationException occurred while trying to create an association with {0}.  {1}", provider.Uri, ex);
                return(null);
            }
        }
コード例 #2
0
        public void AssociateRequestDeterminedBySecuritySettings()
        {
            Protocol         protocol         = Protocol.V20;
            SecuritySettings securitySettings = new RelyingPartySecuritySettings();

            securitySettings.MinimumHashBitLength = 160;
            securitySettings.MaximumHashBitLength = 160;
            ProviderEndpointDescription provider = new ProviderEndpointDescription(OPUri, protocol.Version);

            Assert.AreEqual(AssociateRequest.Create(securitySettings, provider).AssociationType, protocol.Args.SignatureAlgorithm.HMAC_SHA1);

            securitySettings.MinimumHashBitLength = 384;
            securitySettings.MaximumHashBitLength = 384;
            Assert.AreEqual(AssociateRequest.Create(securitySettings, provider).AssociationType, protocol.Args.SignatureAlgorithm.HMAC_SHA384);
        }
コード例 #3
0
        /// <summary>
        /// Creates a new association with a given Provider.
        /// </summary>
        /// <param name="provider">The provider to create an association with.</param>
        /// <returns>
        /// The newly created association, or null if no association can be created with
        /// the given Provider given the current security settings.
        /// </returns>
        /// <remarks>
        /// A new association is created and returned even if one already exists in the
        /// association store.
        /// Any new association is automatically added to the <see cref="associationStore"/>.
        /// </remarks>
        private Association CreateNewAssociation(IProviderEndpoint provider)
        {
            Contract.Requires <ArgumentNullException>(provider != null);

            // If there is no association store, there is no point in creating an association.
            if (this.associationStore == null)
            {
                return(null);
            }

            var associateRequest = AssociateRequest.Create(this.securitySettings, provider);

            const int RenegotiateRetries = 1;

            return(this.CreateNewAssociation(provider, associateRequest, RenegotiateRetries));
        }
コード例 #4
0
        /// <summary>
        /// Creates a new association with a given Provider.
        /// </summary>
        /// <param name="provider">The provider to create an association with.</param>
        /// <returns>
        /// The newly created association, or null if no association can be created with
        /// the given Provider given the current security settings.
        /// </returns>
        /// <remarks>
        /// A new association is created and returned even if one already exists in the
        /// association store.
        /// Any new association is automatically added to the <see cref="associationStore"/>.
        /// </remarks>
        private Association CreateNewAssociation(ProviderEndpointDescription provider)
        {
            ErrorUtilities.VerifyArgumentNotNull(provider, "provider");

            // If there is no association store, there is no point in creating an association.
            if (this.associationStore == null)
            {
                return(null);
            }

            var associateRequest = AssociateRequest.Create(this.securitySettings, provider);

            const int RenegotiateRetries = 1;

            return(this.CreateNewAssociation(provider, associateRequest, RenegotiateRetries));
        }
コード例 #5
0
        private HttpRequestInfo CreateAssociateRequest(Uri opEndpoint)
        {
            var rp = CreateRelyingParty(true);
            AssociateRequest associateMessage = AssociateRequest.Create(rp.SecuritySettings, new ProviderEndpointDescription(opEndpoint, Protocol.Default.Version));
            Channel          rpChannel        = rp.Channel;
            MemoryStream     ms       = new MemoryStream();
            StreamWriter     mswriter = new StreamWriter(ms);

            mswriter.Write(MessagingUtilities.CreateQueryString(rpChannel.MessageDescriptions.GetAccessor(associateMessage)));
            mswriter.Flush();
            ms.Position = 0;
            var headers = new WebHeaderCollection();

            headers.Add(HttpRequestHeader.ContentType, Channel.HttpFormUrlEncoded);
            var httpRequest = new HttpRequestInfo("POST", opEndpoint, opEndpoint.PathAndQuery, headers, ms);

            return(httpRequest);
        }
コード例 #6
0
        public void GetRequest()
        {
            HttpRequestInfo httpInfo = new HttpRequestInfo();

            httpInfo.UrlBeforeRewriting = new Uri("http://someUri");
            Assert.IsNull(this.provider.GetRequest(httpInfo), "An irrelevant request should return null.");
            var providerDescription = new ProviderEndpointDescription(OpenIdTestBase.OPUri, Protocol.Default.Version);

            // Test some non-empty request scenario.
            OpenIdCoordinator coordinator = new OpenIdCoordinator(
                rp => {
                rp.Channel.Request(AssociateRequest.Create(rp.SecuritySettings, providerDescription));
            },
                op => {
                IRequest request = op.GetRequest();
                Assert.IsInstanceOf <AutoResponsiveRequest>(request);
                op.SendResponse(request);
            });

            coordinator.Run();
        }
コード例 #7
0
        /// <summary>
        /// Creates a new association with a given Provider.
        /// </summary>
        /// <param name="provider">The provider to create an association with.</param>
        /// <param name="associateRequest">The associate request.  May be <c>null</c>, which will always result in a <c>null</c> return value..</param>
        /// <param name="retriesRemaining">The number of times to try the associate request again if the Provider suggests it.</param>
        /// <returns>
        /// The newly created association, or null if no association can be created with
        /// the given Provider given the current security settings.
        /// </returns>
        private Association CreateNewAssociation(IProviderEndpoint provider, AssociateRequest associateRequest, int retriesRemaining)
        {
            Contract.Requires <ArgumentNullException>(provider != null);

            if (associateRequest == null || retriesRemaining < 0)
            {
                // this can happen if security requirements and protocol conflict
                // to where there are no association types to choose from.
                return(null);
            }

            try {
                var associateResponse             = this.channel.Request(associateRequest);
                var associateSuccessfulResponse   = associateResponse as AssociateSuccessfulResponse;
                var associateUnsuccessfulResponse = associateResponse as AssociateUnsuccessfulResponse;
                if (associateSuccessfulResponse != null)
                {
                    Association association = associateSuccessfulResponse.CreateAssociation(associateRequest, null);
                    this.associationStore.StoreAssociation(provider.Uri, association);
                    return(association);
                }
                else if (associateUnsuccessfulResponse != null)
                {
                    if (string.IsNullOrEmpty(associateUnsuccessfulResponse.AssociationType))
                    {
                        Logger.OpenId.Debug("Provider rejected an association request and gave no suggestion as to an alternative association type.  Giving up.");
                        return(null);
                    }

                    if (!this.securitySettings.IsAssociationInPermittedRange(Protocol.Lookup(provider.Version), associateUnsuccessfulResponse.AssociationType))
                    {
                        Logger.OpenId.DebugFormat("Provider rejected an association request and suggested '{0}' as an association to try, which this Relying Party does not support.  Giving up.", associateUnsuccessfulResponse.AssociationType);
                        return(null);
                    }

                    if (retriesRemaining <= 0)
                    {
                        Logger.OpenId.Debug("Unable to agree on an association type with the Provider in the allowed number of retries.  Giving up.");
                        return(null);
                    }

                    // Make sure the Provider isn't suggesting an incompatible pair of association/session types.
                    Protocol protocol = Protocol.Lookup(provider.Version);
                    ErrorUtilities.VerifyProtocol(
                        HmacShaAssociation.IsDHSessionCompatible(protocol, associateUnsuccessfulResponse.AssociationType, associateUnsuccessfulResponse.SessionType),
                        OpenIdStrings.IncompatibleAssociationAndSessionTypes,
                        associateUnsuccessfulResponse.AssociationType,
                        associateUnsuccessfulResponse.SessionType);

                    associateRequest = AssociateRequest.Create(this.securitySettings, provider, associateUnsuccessfulResponse.AssociationType, associateUnsuccessfulResponse.SessionType);
                    return(this.CreateNewAssociation(provider, associateRequest, retriesRemaining - 1));
                }
                else
                {
                    throw new ProtocolException(MessagingStrings.UnexpectedMessageReceivedOfMany);
                }
            } catch (ProtocolException ex) {
                // If the association failed because the remote server can't handle Expect: 100 Continue headers,
                // then our web request handler should have already accomodated for future calls.  Go ahead and
                // immediately make one of those future calls now to try to get the association to succeed.
                if (StandardWebRequestHandler.IsExceptionFrom417ExpectationFailed(ex))
                {
                    return(this.CreateNewAssociation(provider, associateRequest, retriesRemaining - 1));
                }

                // Since having associations with OPs is not totally critical, we'll log and eat
                // the exception so that auth may continue in dumb mode.
                Logger.OpenId.ErrorFormat("An error occurred while trying to create an association with {0}.  {1}", provider.Uri, ex);
                return(null);
            }
        }
コード例 #8
0
        /// <summary>
        /// Creates a new association with a given Provider.
        /// </summary>
        /// <param name="provider">The provider to create an association with.</param>
        /// <param name="associateRequest">The associate request.  May be <c>null</c>, which will always result in a <c>null</c> return value..</param>
        /// <param name="retriesRemaining">The number of times to try the associate request again if the Provider suggests it.</param>
        /// <returns>
        /// The newly created association, or null if no association can be created with
        /// the given Provider given the current security settings.
        /// </returns>
        private Association CreateNewAssociation(ProviderEndpointDescription provider, AssociateRequest associateRequest, int retriesRemaining)
        {
            ErrorUtilities.VerifyArgumentNotNull(provider, "provider");

            if (associateRequest == null || retriesRemaining < 0)
            {
                // this can happen if security requirements and protocol conflict
                // to where there are no association types to choose from.
                return(null);
            }

            try {
                var associateResponse             = this.channel.Request(associateRequest);
                var associateSuccessfulResponse   = associateResponse as AssociateSuccessfulResponse;
                var associateUnsuccessfulResponse = associateResponse as AssociateUnsuccessfulResponse;
                if (associateSuccessfulResponse != null)
                {
                    Association association = associateSuccessfulResponse.CreateAssociation(associateRequest, null);
                    this.associationStore.StoreAssociation(provider.Endpoint, association);
                    return(association);
                }
                else if (associateUnsuccessfulResponse != null)
                {
                    if (string.IsNullOrEmpty(associateUnsuccessfulResponse.AssociationType))
                    {
                        Logger.Debug("Provider rejected an association request and gave no suggestion as to an alternative association type.  Giving up.");
                        return(null);
                    }

                    if (!this.securitySettings.IsAssociationInPermittedRange(Protocol.Lookup(provider.ProtocolVersion), associateUnsuccessfulResponse.AssociationType))
                    {
                        Logger.DebugFormat("Provider rejected an association request and suggested '{0}' as an association to try, which this Relying Party does not support.  Giving up.", associateUnsuccessfulResponse.AssociationType);
                        return(null);
                    }

                    if (retriesRemaining <= 0)
                    {
                        Logger.Debug("Unable to agree on an association type with the Provider in the allowed number of retries.  Giving up.");
                        return(null);
                    }

                    // Make sure the Provider isn't suggesting an incompatible pair of association/session types.
                    Protocol protocol = Protocol.Lookup(provider.ProtocolVersion);
                    ErrorUtilities.VerifyProtocol(
                        HmacShaAssociation.IsDHSessionCompatible(protocol, associateUnsuccessfulResponse.AssociationType, associateUnsuccessfulResponse.SessionType),
                        OpenIdStrings.IncompatibleAssociationAndSessionTypes,
                        associateUnsuccessfulResponse.AssociationType,
                        associateUnsuccessfulResponse.SessionType);

                    associateRequest = AssociateRequest.Create(this.securitySettings, provider, associateUnsuccessfulResponse.AssociationType, associateUnsuccessfulResponse.SessionType);
                    return(this.CreateNewAssociation(provider, associateRequest, retriesRemaining - 1));
                }
                else
                {
                    throw new ProtocolException(MessagingStrings.UnexpectedMessageReceivedOfMany);
                }
            } catch (ProtocolException ex) {
                // Since having associations with OPs is not totally critical, we'll log and eat
                // the exception so that auth may continue in dumb mode.
                Logger.ErrorFormat("An error occurred while trying to create an association with {0}.  {1}", provider.Endpoint, ex);
                return(null);
            }
        }