/// <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); }
/// <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); } }
/// <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); }
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); }
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; } } }
/// <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; } }
/// <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); } }
/// <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; }
/// <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); }
/// <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)); }
/// <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); }
/// <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; } }
/// <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); } } }
/// <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); }