diff options
author | Andrew Arnott <andrewarnott@gmail.com> | 2012-05-01 08:51:13 -0700 |
---|---|---|
committer | Andrew Arnott <andrewarnott@gmail.com> | 2012-05-01 08:51:13 -0700 |
commit | fa7356deb5d07f7ae3fbf0c2a2d887d380371f04 (patch) | |
tree | 402454ac7e3c5784fff8a549ffc22510c1314544 /src | |
parent | 01d8c73f818d30b20f86630d35d230b5168215d1 (diff) | |
parent | d5ce85a1441fc9e315c96c6453f42c3f02dd4dbb (diff) | |
download | DotNetOpenAuth-fa7356deb5d07f7ae3fbf0c2a2d887d380371f04.zip DotNetOpenAuth-fa7356deb5d07f7ae3fbf0c2a2d887d380371f04.tar.gz DotNetOpenAuth-fa7356deb5d07f7ae3fbf0c2a2d887d380371f04.tar.bz2 |
Merge branch 'v4.0'
Conflicts:
nuget/DotNetOpenAuth.AspNet.nuspec
nuget/DotNetOpenAuth.Core.UI.nuspec
nuget/DotNetOpenAuth.Core.nuspec
nuget/DotNetOpenAuth.InfoCard.UI.nuspec
nuget/DotNetOpenAuth.InfoCard.nuspec
nuget/DotNetOpenAuth.OAuth.Common.nuspec
nuget/DotNetOpenAuth.OAuth.Consumer.nuspec
nuget/DotNetOpenAuth.OAuth.ServiceProvider.nuspec
nuget/DotNetOpenAuth.OAuth.nuspec
nuget/DotNetOpenAuth.OAuth2.AuthorizationServer.nuspec
nuget/DotNetOpenAuth.OAuth2.Client.UI.nuspec
nuget/DotNetOpenAuth.OAuth2.Client.nuspec
nuget/DotNetOpenAuth.OAuth2.ResourceServer.nuspec
nuget/DotNetOpenAuth.OAuth2.nuspec
nuget/DotNetOpenAuth.OpenId.Provider.UI.nuspec
nuget/DotNetOpenAuth.OpenId.Provider.nuspec
nuget/DotNetOpenAuth.OpenId.RelyingParty.UI.nuspec
nuget/DotNetOpenAuth.OpenId.RelyingParty.nuspec
nuget/DotNetOpenAuth.OpenId.UI.nuspec
nuget/DotNetOpenAuth.OpenId.nuspec
nuget/DotNetOpenAuth.OpenIdInfoCard.UI.nuspec
nuget/DotNetOpenAuth.OpenIdOAuth.nuspec
nuget/nuget.proj
src/version.txt
Diffstat (limited to 'src')
11 files changed, 255 insertions, 26 deletions
diff --git a/src/DotNetOpenAuth.AspNet/Clients/OAuth/IOAuthTokenManager.cs b/src/DotNetOpenAuth.AspNet/Clients/OAuth/IOAuthTokenManager.cs new file mode 100644 index 0000000..92f1c22 --- /dev/null +++ b/src/DotNetOpenAuth.AspNet/Clients/OAuth/IOAuthTokenManager.cs @@ -0,0 +1,38 @@ +//----------------------------------------------------------------------- +// <copyright file="IOAuthTokenManager.cs" company="Microsoft"> +// Copyright (c) Microsoft. All rights reserved. +// </copyright> +//----------------------------------------------------------------------- + +namespace DotNetOpenAuth.AspNet.Clients { + /// <summary> + /// A token manager for use by a web site in its role as a consumer of + /// an individual ServiceProvider. + /// </summary> + /// <remarks> + /// This interface is used by clients of the DotNetOpenAuth.AspNet classes. + /// </remarks> + public interface IOAuthTokenManager { + /// <summary> + /// Gets the token secret from the specified token. + /// </summary> + /// <param name="token">The token.</param> + /// <returns>The token's secret</returns> + string GetTokenSecret(string token); + + /// <summary> + /// Stores the request token together with its secret. + /// </summary> + /// <param name="requestToken">The request token.</param> + /// <param name="requestTokenSecret">The request token secret.</param> + void StoreRequestToken(string requestToken, string requestTokenSecret); + + /// <summary> + /// Replaces the request token with access token. + /// </summary> + /// <param name="requestToken">The request token.</param> + /// <param name="accessToken">The access token.</param> + /// <param name="accessTokenSecret">The access token secret.</param> + void ReplaceRequestTokenWithAccessToken(string requestToken, string accessToken, string accessTokenSecret); + } +}
\ No newline at end of file diff --git a/src/DotNetOpenAuth.AspNet/Clients/OAuth/LinkedInClient.cs b/src/DotNetOpenAuth.AspNet/Clients/OAuth/LinkedInClient.cs index 631636b..d349576 100644 --- a/src/DotNetOpenAuth.AspNet/Clients/OAuth/LinkedInClient.cs +++ b/src/DotNetOpenAuth.AspNet/Clients/OAuth/LinkedInClient.cs @@ -59,6 +59,16 @@ namespace DotNetOpenAuth.AspNet.Clients { public LinkedInClient(string consumerKey, string consumerSecret) : base("linkedIn", LinkedInServiceDescription, consumerKey, consumerSecret) { } + /// <summary> + /// Initializes a new instance of the <see cref="LinkedInClient"/> class. + /// </summary> + /// <param name="consumerKey">The consumer key.</param> + /// <param name="consumerSecret">The consumer secret.</param> + /// <param name="tokenManager">The token manager.</param> + public LinkedInClient(string consumerKey, string consumerSecret, IOAuthTokenManager tokenManager) + : base("linkedIn", LinkedInServiceDescription, new SimpleConsumerTokenManager(consumerKey, consumerSecret, tokenManager)) { + } + #endregion #region Methods diff --git a/src/DotNetOpenAuth.AspNet/Clients/OAuth/OAuthClient.cs b/src/DotNetOpenAuth.AspNet/Clients/OAuth/OAuthClient.cs index 89cefad..3f9e85a 100644 --- a/src/DotNetOpenAuth.AspNet/Clients/OAuth/OAuthClient.cs +++ b/src/DotNetOpenAuth.AspNet/Clients/OAuth/OAuthClient.cs @@ -54,7 +54,8 @@ namespace DotNetOpenAuth.AspNet.Clients { [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "I don't know how to ensure this rule is followed given this API")] protected OAuthClient( string providerName, ServiceProviderDescription serviceDescription, IConsumerTokenManager tokenManager) - : this(providerName, new DotNetOpenAuthWebConsumer(serviceDescription, tokenManager)) { } + : this(providerName, new DotNetOpenAuthWebConsumer(serviceDescription, tokenManager)) { + } /// <summary> /// Initializes a new instance of the <see cref="OAuthClient"/> class. diff --git a/src/DotNetOpenAuth.AspNet/Clients/OAuth/SimpleConsumerTokenManager.cs b/src/DotNetOpenAuth.AspNet/Clients/OAuth/SimpleConsumerTokenManager.cs new file mode 100644 index 0000000..22156e9 --- /dev/null +++ b/src/DotNetOpenAuth.AspNet/Clients/OAuth/SimpleConsumerTokenManager.cs @@ -0,0 +1,103 @@ +//----------------------------------------------------------------------- +// <copyright file="SimpleConsumerTokenManager.cs" company="Microsoft"> +// Copyright (c) Microsoft. All rights reserved. +// </copyright> +//----------------------------------------------------------------------- + +namespace DotNetOpenAuth.AspNet.Clients { + using System; + using DotNetOpenAuth.OAuth.ChannelElements; + + /// <summary> + /// Simple wrapper around IConsumerTokenManager + /// </summary> + public class SimpleConsumerTokenManager : IConsumerTokenManager { + /// <summary> + /// Store the token manager. + /// </summary> + private readonly IOAuthTokenManager tokenManager; + + /// <summary> + /// Initializes a new instance of the <see cref="SimpleConsumerTokenManager"/> class. + /// </summary> + /// <param name="consumerKey">The consumer key.</param> + /// <param name="consumerSecret">The consumer secret.</param> + /// <param name="tokenManager">The OAuth token manager.</param> + public SimpleConsumerTokenManager(string consumerKey, string consumerSecret, IOAuthTokenManager tokenManager) { + Requires.NotNullOrEmpty(consumerKey, "consumerKey"); + Requires.NotNullOrEmpty(consumerSecret, "consumerSecret"); + Requires.NotNull(tokenManager, "oAuthTokenManager"); + + this.ConsumerKey = consumerKey; + this.ConsumerSecret = consumerSecret; + this.tokenManager = tokenManager; + } + + /// <summary> + /// Gets the consumer key. + /// </summary> + /// <value> + /// The consumer key. + /// </value> + public string ConsumerKey { + get; + private set; + } + + /// <summary> + /// Gets the consumer secret. + /// </summary> + /// <value> + /// The consumer secret. + /// </value> + public string ConsumerSecret { + get; + private set; + } + + /// <summary> + /// Gets the Token Secret given a request or access token. + /// </summary> + /// <param name="token">The request or access token.</param> + /// <returns> + /// The secret associated with the given token. + /// </returns> + /// <exception cref="ArgumentException">Thrown if the secret cannot be found for the given token.</exception> + public string GetTokenSecret(string token) { + return this.tokenManager.GetTokenSecret(token); + } + + /// <summary> + /// Stores a newly generated unauthorized request token, secret, and optional + /// application-specific parameters for later recall. + /// </summary> + /// <param name="request">The request message that resulted in the generation of a new unauthorized request token.</param> + /// <param name="response">The response message that includes the unauthorized request token.</param> + /// <exception cref="ArgumentException">Thrown if the consumer key is not registered, or a required parameter was not found in the parameters collection.</exception> + public void StoreNewRequestToken(DotNetOpenAuth.OAuth.Messages.UnauthorizedTokenRequest request, DotNetOpenAuth.OAuth.Messages.ITokenSecretContainingMessage response) { + this.tokenManager.StoreRequestToken(response.Token, response.TokenSecret); + } + + /// <summary> + /// Deletes a request token and its associated secret and stores a new access token and secret. + /// </summary> + /// <param name="consumerKey">The Consumer that is exchanging its request token for an access token.</param> + /// <param name="requestToken">The Consumer's request token that should be deleted/expired.</param> + /// <param name="accessToken">The new access token that is being issued to the Consumer.</param> + /// <param name="accessTokenSecret">The secret associated with the newly issued access token.</param> + public void ExpireRequestTokenAndStoreNewAccessToken(string consumerKey, string requestToken, string accessToken, string accessTokenSecret) { + this.tokenManager.ReplaceRequestTokenWithAccessToken(requestToken, accessToken, accessTokenSecret); + } + + /// <summary> + /// Classifies a token as a request token or an access token. + /// </summary> + /// <param name="token">The token to classify.</param> + /// <returns> + /// Request or Access token, or invalid if the token is not recognized. + /// </returns> + public TokenType GetTokenType(string token) { + throw new NotSupportedException(); + } + } +}
\ No newline at end of file diff --git a/src/DotNetOpenAuth.AspNet/Clients/OAuth/TwitterClient.cs b/src/DotNetOpenAuth.AspNet/Clients/OAuth/TwitterClient.cs index ceaffd4..0ec0780 100644 --- a/src/DotNetOpenAuth.AspNet/Clients/OAuth/TwitterClient.cs +++ b/src/DotNetOpenAuth.AspNet/Clients/OAuth/TwitterClient.cs @@ -28,15 +28,15 @@ namespace DotNetOpenAuth.AspNet.Clients { public static readonly ServiceProviderDescription TwitterServiceDescription = new ServiceProviderDescription { RequestTokenEndpoint = new MessageReceivingEndpoint( - "http://twitter.com/oauth/request_token", + "https://twitter.com/oauth/request_token", HttpDeliveryMethods.GetRequest | HttpDeliveryMethods.AuthorizationHeaderRequest), UserAuthorizationEndpoint = new MessageReceivingEndpoint( - "http://twitter.com/oauth/authenticate", + "https://twitter.com/oauth/authenticate", HttpDeliveryMethods.GetRequest | HttpDeliveryMethods.AuthorizationHeaderRequest), AccessTokenEndpoint = new MessageReceivingEndpoint( - "http://twitter.com/oauth/access_token", + "https://twitter.com/oauth/access_token", HttpDeliveryMethods.GetRequest | HttpDeliveryMethods.AuthorizationHeaderRequest), TamperProtectionElements = new ITamperProtectionChannelBindingElement[] { new HmacSha1SigningBindingElement() }, }; @@ -59,6 +59,16 @@ namespace DotNetOpenAuth.AspNet.Clients { public TwitterClient(string consumerKey, string consumerSecret) : base("twitter", TwitterServiceDescription, consumerKey, consumerSecret) { } + /// <summary> + /// Initializes a new instance of the <see cref="TwitterClient"/> class. + /// </summary> + /// <param name="consumerKey">The consumer key.</param> + /// <param name="consumerSecret">The consumer secret.</param> + /// <param name="tokenManager">The token manager.</param> + public TwitterClient(string consumerKey, string consumerSecret, IOAuthTokenManager tokenManager) + : base("twitter", TwitterServiceDescription, new SimpleConsumerTokenManager(consumerKey, consumerSecret, tokenManager)) { + } + #endregion #region Methods diff --git a/src/DotNetOpenAuth.AspNet/Clients/OAuth2/OAuth2Client.cs b/src/DotNetOpenAuth.AspNet/Clients/OAuth2/OAuth2Client.cs index 016d92e..cac4261 100644 --- a/src/DotNetOpenAuth.AspNet/Clients/OAuth2/OAuth2Client.cs +++ b/src/DotNetOpenAuth.AspNet/Clients/OAuth2/OAuth2Client.cs @@ -86,7 +86,20 @@ namespace DotNetOpenAuth.AspNet.Clients { /// <returns> /// An instance of <see cref="AuthenticationResult"/> containing authentication result. /// </returns> - public virtual AuthenticationResult VerifyAuthentication(HttpContextBase context) { + public AuthenticationResult VerifyAuthentication(HttpContextBase context) { + Requires.NotNull(this.returnUrl, "this.returnUrl"); + return VerifyAuthentication(context, this.returnUrl); + } + + /// <summary> + /// Check if authentication succeeded after user is redirected back from the service provider. + /// </summary> + /// <param name="context">The context.</param> + /// <param name="returnPageUrl">The return URL which should match the value passed to RequestAuthentication() method.</param> + /// <returns> + /// An instance of <see cref="AuthenticationResult"/> containing authentication result. + /// </returns> + public virtual AuthenticationResult VerifyAuthentication(HttpContextBase context, Uri returnPageUrl) { Requires.NotNull(context, "context"); string code = context.Request.QueryString["code"]; @@ -94,7 +107,7 @@ namespace DotNetOpenAuth.AspNet.Clients { return AuthenticationResult.Failed; } - string accessToken = this.QueryAccessToken(this.returnUrl, code); + string accessToken = this.QueryAccessToken(returnPageUrl, code); if (accessToken == null) { return AuthenticationResult.Failed; } @@ -133,7 +146,7 @@ namespace DotNetOpenAuth.AspNet.Clients { /// <returns> /// An absolute URL. /// </returns> - [SuppressMessage("Microsoft.Naming", "CA1726:UsePreferredTerms", MessageId = "Login", + [SuppressMessage("Microsoft.Naming", "CA1726:UsePreferredTerms", MessageId = "Login", Justification = "Login is used more consistently in ASP.Net")] protected abstract Uri GetServiceLoginUrl(Uri returnUrl); diff --git a/src/DotNetOpenAuth.AspNet/Clients/OpenID/OpenIDClient.cs b/src/DotNetOpenAuth.AspNet/Clients/OpenID/OpenIDClient.cs index 6ced1a6..bd706f5 100644 --- a/src/DotNetOpenAuth.AspNet/Clients/OpenID/OpenIDClient.cs +++ b/src/DotNetOpenAuth.AspNet/Clients/OpenID/OpenIDClient.cs @@ -20,18 +20,20 @@ namespace DotNetOpenAuth.AspNet.Clients { #region Constants and Fields /// <summary> - /// The _openid relaying party. + /// The openid relying party. /// </summary> - private static readonly OpenIdRelyingParty RelyingParty = - new OpenIdRelyingParty(new StandardRelyingPartyApplicationStore()); + /// <remarks> + /// Pass null as applicationStore to specify dumb mode + /// </remarks> + private static readonly OpenIdRelyingParty RelyingParty = new OpenIdRelyingParty(applicationStore: null); /// <summary> - /// The _provider identifier. + /// The provider identifier. /// </summary> private readonly Identifier providerIdentifier; /// <summary> - /// The _provider name. + /// The provider name. /// </summary> private readonly string providerName; diff --git a/src/DotNetOpenAuth.AspNet/DotNetOpenAuth.AspNet.csproj b/src/DotNetOpenAuth.AspNet/DotNetOpenAuth.AspNet.csproj index f28f96f..f1fbacd 100644 --- a/src/DotNetOpenAuth.AspNet/DotNetOpenAuth.AspNet.csproj +++ b/src/DotNetOpenAuth.AspNet/DotNetOpenAuth.AspNet.csproj @@ -42,6 +42,8 @@ <ItemGroup> <Compile Include="AuthenticationResult.cs" /> <Compile Include="Clients\DictionaryExtensions.cs" /> + <Compile Include="Clients\OAuth\IOAuthTokenManager.cs" /> + <Compile Include="Clients\OAuth\SimpleConsumerTokenManager.cs" /> <Compile Include="IAuthenticationClient.cs" /> <Compile Include="Clients\OAuth2\FacebookClient.cs" /> <Compile Include="Clients\OAuth2\FacebookGraphData.cs" /> diff --git a/src/DotNetOpenAuth.AspNet/OpenAuthSecurityManager.cs b/src/DotNetOpenAuth.AspNet/OpenAuthSecurityManager.cs index 463f056..06ca161 100644 --- a/src/DotNetOpenAuth.AspNet/OpenAuthSecurityManager.cs +++ b/src/DotNetOpenAuth.AspNet/OpenAuthSecurityManager.cs @@ -8,6 +8,7 @@ namespace DotNetOpenAuth.AspNet { using System; using System.Diagnostics.CodeAnalysis; using System.Web; + using DotNetOpenAuth.AspNet.Clients; using DotNetOpenAuth.Messaging; /// <summary> @@ -168,6 +169,46 @@ namespace DotNetOpenAuth.AspNet { return result; } + /// <summary> + /// Checks if user is successfully authenticated when user is redirected back to this user. + /// </summary> + /// <param name="returnUrl">The return Url which must match exactly the Url passed into RequestAuthentication() earlier.</param> + /// <returns> + /// The result of the authentication. + /// </returns> + public AuthenticationResult VerifyAuthentication(string returnUrl) { + Requires.NotNullOrEmpty(returnUrl, "returnUrl"); + + // Only OAuth2 requires the return url value for the verify authenticaiton step + OAuth2Client oauth2Client = this.authenticationProvider as OAuth2Client; + if (oauth2Client != null) { + // convert returnUrl to an absolute path + Uri uri; + if (!string.IsNullOrEmpty(returnUrl)) { + uri = UriHelper.ConvertToAbsoluteUri(returnUrl, this.requestContext); + } + else { + uri = this.requestContext.Request.GetPublicFacingUrl(); + } + + AuthenticationResult result = oauth2Client.VerifyAuthentication(this.requestContext, uri); + if (!result.IsSuccessful) { + // if the result is a Failed result, creates a new Failed response which has providerName info. + result = new AuthenticationResult( + isSuccessful: false, + provider: this.authenticationProvider.ProviderName, + providerUserId: null, + userName: null, + extraData: null); + } + + return result; + } + else { + return this.VerifyAuthentication(); + } + } + #endregion } -} +}
\ No newline at end of file diff --git a/src/DotNetOpenAuth.Core/Messaging/Reflection/MessageDescriptionCollection.cs b/src/DotNetOpenAuth.Core/Messaging/Reflection/MessageDescriptionCollection.cs index 1fa9252..3517abc 100644 --- a/src/DotNetOpenAuth.Core/Messaging/Reflection/MessageDescriptionCollection.cs +++ b/src/DotNetOpenAuth.Core/Messaging/Reflection/MessageDescriptionCollection.cs @@ -9,6 +9,7 @@ namespace DotNetOpenAuth.Messaging.Reflection { using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Diagnostics.Contracts; + using System.Linq; /// <summary> /// A cache of <see cref="MessageDescription"/> instances. @@ -35,7 +36,10 @@ namespace DotNetOpenAuth.Messaging.Reflection { /// An <see cref="T:System.Collections.IEnumerator"/> object that can be used to iterate through the collection. /// </returns> public IEnumerator<MessageDescription> GetEnumerator() { - return this.reflectedMessageTypes.Values.GetEnumerator(); + lock (this.reflectedMessageTypes) { + // We must clone the collection so that it's thread-safe to the caller as it leaves our lock. + return this.reflectedMessageTypes.Values.ToList().GetEnumerator(); + } } #endregion @@ -49,7 +53,7 @@ namespace DotNetOpenAuth.Messaging.Reflection { /// An <see cref="T:System.Collections.IEnumerator"/> object that can be used to iterate through the collection. /// </returns> System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { - return this.reflectedMessageTypes.Values.GetEnumerator(); + return this.GetEnumerator(); } #endregion @@ -71,15 +75,23 @@ namespace DotNetOpenAuth.Messaging.Reflection { MessageTypeAndVersion key = new MessageTypeAndVersion(messageType, messageVersion); MessageDescription result; - if (!this.reflectedMessageTypes.TryGetValue(key, out result)) { + lock (this.reflectedMessageTypes) { + this.reflectedMessageTypes.TryGetValue(key, out result); + } + + if (result == null) { + // Construct the message outside the lock. + var newDescription = new MessageDescription(messageType, messageVersion); + + // Then use the lock again to either acquire what someone else has created in the meantime, or + // set and use our own result. lock (this.reflectedMessageTypes) { if (!this.reflectedMessageTypes.TryGetValue(key, out result)) { - this.reflectedMessageTypes[key] = result = new MessageDescription(messageType, messageVersion); + this.reflectedMessageTypes[key] = result = newDescription; } } } - Contract.Assume(result != null, "We should never assign null values to this dictionary."); return result; } diff --git a/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/OpenIdRelyingParty.cs b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/OpenIdRelyingParty.cs index 4dba624..6264041 100644 --- a/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/OpenIdRelyingParty.cs +++ b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/OpenIdRelyingParty.cs @@ -99,7 +99,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { /// <summary> /// Initializes a new instance of the <see cref="OpenIdRelyingParty"/> class. /// </summary> - /// <param name="applicationStore">The application store. If <c>null</c>, the relying party will always operate in "dumb mode".</param> + /// <param name="applicationStore">The application store. If <c>null</c>, the relying party will always operate in "stateless/dumb mode".</param> public OpenIdRelyingParty(IOpenIdApplicationStore applicationStore) : this(applicationStore, applicationStore) { } @@ -107,8 +107,8 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { /// <summary> /// Initializes a new instance of the <see cref="OpenIdRelyingParty"/> class. /// </summary> - /// <param name="cryptoKeyStore">The association store. If null, the relying party will always operate in "dumb mode".</param> - /// <param name="nonceStore">The nonce store to use. If null, the relying party will always operate in "dumb mode".</param> + /// <param name="cryptoKeyStore">The association store. If <c>null</c>, the relying party will always operate in "stateless/dumb mode".</param> + /// <param name="nonceStore">The nonce store to use. If <c>null</c>, the relying party will always operate in "stateless/dumb mode".</param> [SuppressMessage("Microsoft.Maintainability", "CA1506:AvoidExcessiveClassCoupling", Justification = "Unavoidable")] private OpenIdRelyingParty(ICryptoKeyStore cryptoKeyStore, INonceStore nonceStore) { // If we are a smart-mode RP (supporting associations), then we MUST also be @@ -133,12 +133,9 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { this.SecuritySettings.MinimumRequiredOpenIdVersion = ProtocolVersion.V20; } - if (cryptoKeyStore == null) { - cryptoKeyStore = new MemoryCryptoKeyStore(); - } - this.channel = new OpenIdRelyingPartyChannel(cryptoKeyStore, nonceStore, this.SecuritySettings); - this.AssociationManager = new AssociationManager(this.Channel, new CryptoKeyStoreAsRelyingPartyAssociationStore(cryptoKeyStore), this.SecuritySettings); + var associationStore = cryptoKeyStore != null ? new CryptoKeyStoreAsRelyingPartyAssociationStore(cryptoKeyStore) : null; + this.AssociationManager = new AssociationManager(this.Channel, associationStore, this.SecuritySettings); this.discoveryServices = new IdentifierDiscoveryServices(this); Reporting.RecordFeatureAndDependencyUse(this, cryptoKeyStore, nonceStore); |