Example #1
0
        /// <summary>
        /// Gets an association between this Relying Party and a given Provider
        /// if it already exists in the association store.
        /// </summary>
        /// <param name="provider">The provider to create an association with.</param>
        /// <returns>The association if one exists and has useful life remaining.  Otherwise <c>null</c>.</returns>
        internal Association GetExistingAssociation(IProviderEndpoint provider)
        {
            Requires.NotNull(provider, "provider");

            // If the RP has no application store for associations, there's no point in creating one.
            if (this.associationStore == null)
            {
                return(null);
            }

            Association association = this.associationStore.GetAssociation(provider.Uri, this.SecuritySettings);

            // If the returned association does not fulfill security requirements, ignore it.
            if (association != null && !this.SecuritySettings.IsAssociationInPermittedRange(association))
            {
                association = null;
            }

            if (association != null && !association.HasUsefulLifeRemaining)
            {
                association = null;
            }

            return(association);
        }
Example #2
0
        /// <summary>
        /// Creates a new association with a given Provider.
        /// </summary>
        /// <param name="provider">The provider to create an association with.</param>
        /// <param name="cancellationToken">The cancellation token.</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 async Task <Association> CreateNewAssociationAsync(IProviderEndpoint provider, CancellationToken cancellationToken)
        {
            Requires.NotNull(provider, "provider");

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

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

                const int RenegotiateRetries = 1;
                return(await this.CreateNewAssociationAsync(provider, associateRequest, RenegotiateRetries, cancellationToken));
            } 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);
            }
        }
Example #3
0
        /// <summary>
        /// Checks whether a given OP Endpoint is permitted by the host relying party.
        /// </summary>
        /// <param name="endpoint">The OP endpoint.</param>
        /// <returns><c>true</c> if the OP Endpoint is allowed; <c>false</c> otherwise.</returns>
        protected internal bool FilterEndpoint(IProviderEndpoint endpoint)
        {
            if (this.SecuritySettings.RejectAssertionsFromUntrustedProviders)
            {
                if (!this.SecuritySettings.TrustedProviderEndpoints.Contains(endpoint.Uri))
                {
                    Logger.OpenId.InfoFormat("Filtering out OP endpoint {0} because it is not on the exclusive trusted provider whitelist.", endpoint.Uri.AbsoluteUri);
                    return(false);
                }
            }

            if (endpoint.Version < Protocol.Lookup(this.SecuritySettings.MinimumRequiredOpenIdVersion).Version)
            {
                Logger.OpenId.InfoFormat(
                    "Filtering out OP endpoint {0} because it implements OpenID {1} but this relying party requires OpenID {2} or later.",
                    endpoint.Uri.AbsoluteUri,
                    endpoint.Version,
                    Protocol.Lookup(this.SecuritySettings.MinimumRequiredOpenIdVersion).Version);
                return(false);
            }

            if (this.EndpointFilter != null)
            {
                if (!this.EndpointFilter(endpoint))
                {
                    Logger.OpenId.InfoFormat("Filtering out OP endpoint {0} because the host rejected it.", endpoint.Uri.AbsoluteUri);
                    return(false);
                }
            }

            return(true);
        }
Example #4
0
        public void UriTest()
        {
            OpenIdRelyingParty     rp       = TestSupport.CreateRelyingParty(null);
            Identifier             id       = MockHttpRequest.RegisterMockXrdsResponse("/Discovery/xrdsdiscovery/xrds20.xml");
            IAuthenticationRequest request  = rp.CreateRequest(id, TestSupport.Realm, TestSupport.ReturnTo);
            IProviderEndpoint      provider = request.Provider;

            Assert.AreEqual(new Uri("http://a/b"), provider.Uri);
        }
        /// <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));
        }
		/// <summary>
		/// Creates an association request message that is appropriate for a given Provider.
		/// </summary>
		/// <param name="securityRequirements">The set of requirements the selected association type must comply to.</param>
		/// <param name="provider">The provider to create an association with.</param>
		/// <returns>
		/// The message to send to the Provider to request an association.
		/// Null if no association could be created that meet the security requirements
		/// and the provider OpenID version.
		/// </returns>
		internal static AssociateRequest Create(SecuritySettings securityRequirements, IProviderEndpoint provider) {
			Requires.NotNull(securityRequirements, "securityRequirements");
			Requires.NotNull(provider, "provider");

			// Apply our knowledge of the endpoint's transport, OpenID version, and
			// security requirements to decide the best association.
			bool unencryptedAllowed = provider.Uri.IsTransportSecure();
			bool useDiffieHellman = !unencryptedAllowed;
			string associationType, sessionType;
			if (!HmacShaAssociation.TryFindBestAssociation(Protocol.Lookup(provider.Version), true, securityRequirements, useDiffieHellman, out associationType, out sessionType)) {
				// There are no associations that meet all requirements.
				Logger.OpenId.Warn("Security requirements and protocol combination knock out all possible association types.  Dumb mode forced.");
				return null;
			}

			return Create(securityRequirements, provider, associationType, sessionType);
		}
Example #7
0
        public void IsExtensionSupportedTest()
        {
            OpenIdRelyingParty     rp       = TestSupport.CreateRelyingParty(null);
            Identifier             id       = MockHttpRequest.RegisterMockXrdsResponse("/Discovery/xrdsdiscovery/xrds20.xml");
            IAuthenticationRequest request  = rp.CreateRequest(id, TestSupport.Realm, TestSupport.ReturnTo);
            IProviderEndpoint      provider = request.Provider;

            Assert.IsTrue(provider.IsExtensionSupported <ClaimsRequest>());
            Assert.IsTrue(provider.IsExtensionSupported(typeof(ClaimsRequest)));
            Assert.IsFalse(provider.IsExtensionSupported <FetchRequest>());
            Assert.IsFalse(provider.IsExtensionSupported(typeof(FetchRequest)));

            // Test the AdditionalTypeUris list by pulling from an XRDS page with one of the
            // TypeURIs that only shows up in that list.
            id      = MockHttpRequest.RegisterMockXrdsResponse("/Discovery/xrdsdiscovery/xrds10.xml");
            request = rp.CreateRequest(id, realm, returnTo);
            Assert.IsTrue(provider.IsExtensionSupported <ClaimsRequest>());
            Assert.IsTrue(provider.IsExtensionSupported(typeof(ClaimsRequest)));
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="PositiveAnonymousResponse"/> class.
        /// </summary>
        /// <param name="response">The response message.</param>
        protected internal PositiveAnonymousResponse(IndirectSignedResponse response)
        {
            Requires.NotNull(response, "response");

            this.response = response;
            if (response.ProviderEndpoint != null && response.Version != null)
            {
                this.provider = new ProviderEndpointDescription(response.ProviderEndpoint, response.Version);
            }

            // Derived types of this are responsible to log an appropriate message for themselves.
            if (Logger.OpenId.IsInfoEnabled && this.GetType() == typeof(PositiveAnonymousResponse))
            {
                Logger.OpenId.Info("Received anonymous (identity-less) positive assertion.");
            }

            if (response.ProviderEndpoint != null)
            {
                Reporting.RecordEventOccurrence(this, response.ProviderEndpoint.AbsoluteUri);
            }
        }
		/// <summary>
		/// Creates an association request message that is appropriate for a given Provider.
		/// </summary>
		/// <param name="securityRequirements">The set of requirements the selected association type must comply to.</param>
		/// <param name="provider">The provider to create an association with.</param>
		/// <param name="associationType">Type of the association.</param>
		/// <param name="sessionType">Type of the session.</param>
		/// <returns>
		/// The message to send to the Provider to request an association.
		/// Null if no association could be created that meet the security requirements
		/// and the provider OpenID version.
		/// </returns>
		internal static AssociateRequest Create(SecuritySettings securityRequirements, IProviderEndpoint provider, string associationType, string sessionType) {
			Requires.NotNull(securityRequirements, "securityRequirements");
			Requires.NotNull(provider, "provider");
			Requires.NotNullOrEmpty(associationType, "associationType");
			Requires.NotNull(sessionType, "sessionType");

			bool unencryptedAllowed = provider.Uri.IsTransportSecure();
			if (unencryptedAllowed) {
				var associateRequest = new AssociateUnencryptedRequest(provider.Version, provider.Uri);
				associateRequest.AssociationType = associationType;
				return associateRequest;
			} else {
				if (OpenIdUtilities.IsDiffieHellmanPresent) {
					var associateRequest = new AssociateDiffieHellmanRequest(provider.Version, provider.Uri);
					associateRequest.AssociationType = associationType;
					associateRequest.SessionType = sessionType;
					associateRequest.InitializeRequest();
					return associateRequest;
				} else {
					return null;
				}
			}
		}
Example #10
0
		/// <summary>
		/// Creates an association request message that is appropriate for a given Provider.
		/// </summary>
		/// <param name="securityRequirements">The set of requirements the selected association type must comply to.</param>
		/// <param name="provider">The provider to create an association with.</param>
		/// <param name="associationType">Type of the association.</param>
		/// <param name="sessionType">Type of the session.</param>
		/// <returns>
		/// The message to send to the Provider to request an association.
		/// Null if no association could be created that meet the security requirements
		/// and the provider OpenID version.
		/// </returns>
		internal static AssociateRequest Create(SecuritySettings securityRequirements, IProviderEndpoint provider, string associationType, string sessionType) {
			Contract.Requires<ArgumentNullException>(securityRequirements != null);
			Contract.Requires<ArgumentNullException>(provider != null);
			Contract.Requires<ArgumentException>(!String.IsNullOrEmpty(associationType));
			Contract.Requires<ArgumentNullException>(sessionType != null);

			bool unencryptedAllowed = provider.Uri.IsTransportSecure();
			if (unencryptedAllowed) {
				var associateRequest = new AssociateUnencryptedRequest(provider.Version, provider.Uri);
				associateRequest.AssociationType = associationType;
				return associateRequest;
			} else {
				var associateRequest = new AssociateDiffieHellmanRequest(provider.Version, provider.Uri);
				associateRequest.AssociationType = associationType;
				associateRequest.SessionType = sessionType;
				associateRequest.InitializeRequest();
				return associateRequest;
			}
		}
Example #11
0
        /// <summary>
        /// Creates an association request message that is appropriate for a given Provider.
        /// </summary>
        /// <param name="securityRequirements">The set of requirements the selected association type must comply to.</param>
        /// <param name="provider">The provider to create an association with.</param>
        /// <param name="associationType">Type of the association.</param>
        /// <param name="sessionType">Type of the session.</param>
        /// <returns>
        /// The message to send to the Provider to request an association.
        /// Null if no association could be created that meet the security requirements
        /// and the provider OpenID version.
        /// </returns>
        internal static AssociateRequest Create(SecuritySettings securityRequirements, IProviderEndpoint provider, string associationType, string sessionType)
        {
            Contract.Requires <ArgumentNullException>(securityRequirements != null);
            Contract.Requires <ArgumentNullException>(provider != null);
            Contract.Requires <ArgumentException>(!String.IsNullOrEmpty(associationType));
            Contract.Requires <ArgumentNullException>(sessionType != null);

            bool unencryptedAllowed = provider.Uri.IsTransportSecure();

            if (unencryptedAllowed)
            {
                var associateRequest = new AssociateUnencryptedRequest(provider.Version, provider.Uri);
                associateRequest.AssociationType = associationType;
                return(associateRequest);
            }
            else
            {
                var associateRequest = new AssociateDiffieHellmanRequest(provider.Version, provider.Uri);
                associateRequest.AssociationType = associationType;
                associateRequest.SessionType     = sessionType;
                associateRequest.InitializeRequest();
                return(associateRequest);
            }
        }
Example #12
0
		/// <summary>
		/// Gets an association between this Relying Party and a given Provider
		/// if it already exists in the association store.
		/// </summary>
		/// <param name="provider">The provider to create an association with.</param>
		/// <returns>The association if one exists and has useful life remaining.  Otherwise <c>null</c>.</returns>
		internal Association GetExistingAssociation(IProviderEndpoint provider) {
			Contract.Requires<ArgumentNullException>(provider != null);

			// If the RP has no application store for associations, there's no point in creating one.
			if (this.associationStore == null) {
				return null;
			}

			Association association = this.associationStore.GetAssociation(provider.Uri, this.SecuritySettings);

			// If the returned association does not fulfill security requirements, ignore it.
			if (association != null && !this.SecuritySettings.IsAssociationInPermittedRange(association)) {
				association = null;
			}

			if (association != null && !association.HasUsefulLifeRemaining) {
				association = null;
			}

			return association;
		}
Example #13
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>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <returns>
        /// The newly created association, or null if no association can be created with
        /// the given Provider given the current security settings.
        /// </returns>
        /// <exception cref="ProtocolException">Create if an error occurs while creating the new association.</exception>
        private async Task <Association> CreateNewAssociationAsync(IProviderEndpoint provider, AssociateRequest associateRequest, int retriesRemaining, CancellationToken cancellationToken)
        {
            Requires.NotNull(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);
            }

            Exception exception = null;

            try {
                var associateResponse = await this.channel.RequestAsync(associateRequest, cancellationToken);

                var associateSuccessfulResponse   = associateResponse as IAssociateSuccessfulResponseRelyingParty;
                var associateUnsuccessfulResponse = associateResponse as AssociateUnsuccessfulResponse;
                if (associateSuccessfulResponse != null)
                {
                    Association association = associateSuccessfulResponse.CreateAssociationAtRelyingParty(associateRequest);
                    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 = AssociateRequestRelyingParty.Create(this.securitySettings, provider, associateUnsuccessfulResponse.AssociationType, associateUnsuccessfulResponse.SessionType);
                    return(await this.CreateNewAssociationAsync(provider, associateRequest, retriesRemaining - 1, cancellationToken));
                }
                else
                {
                    throw new ProtocolException(MessagingStrings.UnexpectedMessageReceivedOfMany);
                }
            } catch (ProtocolException ex) {
                exception = ex;
            }

            Assumes.NotNull(exception);

            // 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 (UntrustedWebRequestHandler.IsExceptionFrom417ExpectationFailed(exception))
            {
                return(await this.CreateNewAssociationAsync(provider, associateRequest, retriesRemaining - 1, cancellationToken));
            }

            // 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, exception);
            return(null);
        }
Example #14
0
		/// <summary>
		/// Gets an existing association with the specified Provider, or attempts to create
		/// a new association of one does not already exist.
		/// </summary>
		/// <param name="provider">The provider to get an association for.</param>
		/// <returns>The existing or new association; <c>null</c> if none existed and one could not be created.</returns>
		internal Association GetOrCreateAssociation(IProviderEndpoint provider) {
			return this.GetExistingAssociation(provider) ?? this.CreateNewAssociation(provider);
		}
Example #15
0
 /// <summary>
 /// Gets an existing association with the specified Provider, or attempts to create
 /// a new association of one does not already exist.
 /// </summary>
 /// <param name="provider">The provider to get an association for.</param>
 /// <param name="cancellationToken">The cancellation token.</param>
 /// <returns>The existing or new association; <c>null</c> if none existed and one could not be created.</returns>
 internal async Task <Association> GetOrCreateAssociationAsync(IProviderEndpoint provider, CancellationToken cancellationToken)
 {
     return(this.GetExistingAssociation(provider) ?? await this.CreateNewAssociationAsync(provider, cancellationToken));
 }
Example #16
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;
			}
		}
 /// <summary>
 /// Gets an existing association with the specified Provider, or attempts to create
 /// a new association of one does not already exist.
 /// </summary>
 /// <param name="provider">The provider to get an association for.</param>
 /// <returns>The existing or new association; <c>null</c> if none existed and one could not be created.</returns>
 internal Association GetOrCreateAssociation(IProviderEndpoint provider)
 {
     return(this.GetExistingAssociation(provider) ?? this.CreateNewAssociation(provider));
 }
		/// <summary>
		/// Gets an existing association with the specified Provider, or attempts to create
		/// a new association of one does not already exist.
		/// </summary>
		/// <param name="provider">The provider to get an association for.</param>
		/// <param name="cancellationToken">The cancellation token.</param>
		/// <returns>The existing or new association; <c>null</c> if none existed and one could not be created.</returns>
		internal async Task<Association> GetOrCreateAssociationAsync(IProviderEndpoint provider, CancellationToken cancellationToken) {
			return this.GetExistingAssociation(provider) ?? await this.CreateNewAssociationAsync(provider, cancellationToken);
		}
Example #19
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, 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;
			}
		}
Example #20
0
        /// <summary>
        /// Creates an association request message that is appropriate for a given Provider.
        /// </summary>
        /// <param name="securityRequirements">The set of requirements the selected association type must comply to.</param>
        /// <param name="provider">The provider to create an association with.</param>
        /// <param name="associationType">Type of the association.</param>
        /// <param name="sessionType">Type of the session.</param>
        /// <returns>
        /// The message to send to the Provider to request an association.
        /// Null if no association could be created that meet the security requirements
        /// and the provider OpenID version.
        /// </returns>
        internal static AssociateRequest Create(SecuritySettings securityRequirements, IProviderEndpoint provider, string associationType, string sessionType)
        {
            Requires.NotNull(securityRequirements, "securityRequirements");
            Requires.NotNull(provider, "provider");
            Requires.NotNullOrEmpty(associationType, "associationType");
            Requires.NotNull(sessionType, "sessionType");

            bool unencryptedAllowed = provider.Uri.IsTransportSecure();

            if (unencryptedAllowed)
            {
                var associateRequest = new AssociateUnencryptedRequest(provider.Version, provider.Uri);
                associateRequest.AssociationType = associationType;
                return(associateRequest);
            }
            else
            {
                if (OpenIdUtilities.IsDiffieHellmanPresent)
                {
                    var associateRequest = new AssociateDiffieHellmanRequest(provider.Version, provider.Uri);
                    associateRequest.AssociationType = associationType;
                    associateRequest.SessionType     = sessionType;
                    associateRequest.InitializeRequest();
                    return(associateRequest);
                }
                else
                {
                    return(null);
                }
            }
        }
Example #21
0
        /// <summary>
        /// Creates an association request message that is appropriate for a given Provider.
        /// </summary>
        /// <param name="securityRequirements">The set of requirements the selected association type must comply to.</param>
        /// <param name="provider">The provider to create an association with.</param>
        /// <returns>
        /// The message to send to the Provider to request an association.
        /// Null if no association could be created that meet the security requirements
        /// and the provider OpenID version.
        /// </returns>
        internal static AssociateRequest Create(SecuritySettings securityRequirements, IProviderEndpoint provider)
        {
            Contract.Requires <ArgumentNullException>(securityRequirements != null);
            Contract.Requires <ArgumentNullException>(provider != null);

            // Apply our knowledge of the endpoint's transport, OpenID version, and
            // security requirements to decide the best association.
            bool   unencryptedAllowed = provider.Uri.IsTransportSecure();
            bool   useDiffieHellman = !unencryptedAllowed;
            string associationType, sessionType;

            if (!HmacShaAssociation.TryFindBestAssociation(Protocol.Lookup(provider.Version), true, securityRequirements, useDiffieHellman, out associationType, out sessionType))
            {
                // There are no associations that meet all requirements.
                Logger.OpenId.Warn("Security requirements and protocol combination knock out all possible association types.  Dumb mode forced.");
                return(null);
            }

            return(Create(securityRequirements, provider, associationType, sessionType));
        }
		/// <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);
		}