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