diff options
-rw-r--r-- | src/DotNetOpenAuth/Logger.cs | 10 | ||||
-rw-r--r-- | src/DotNetOpenAuth/OAuthWrap/ClientBase.cs | 14 | ||||
-rw-r--r-- | src/DotNetOpenAuth/OAuthWrap/IClientTokenManager.cs | 5 | ||||
-rw-r--r-- | src/DotNetOpenAuth/OAuthWrap/OAuthWrapStrings.Designer.cs | 18 | ||||
-rw-r--r-- | src/DotNetOpenAuth/OAuthWrap/OAuthWrapStrings.resx | 6 | ||||
-rw-r--r-- | src/DotNetOpenAuth/OAuthWrap/WebAppClient.cs | 10 |
6 files changed, 59 insertions, 4 deletions
diff --git a/src/DotNetOpenAuth/Logger.cs b/src/DotNetOpenAuth/Logger.cs index 48007ed..7c8691c 100644 --- a/src/DotNetOpenAuth/Logger.cs +++ b/src/DotNetOpenAuth/Logger.cs @@ -75,6 +75,11 @@ namespace DotNetOpenAuth { private static readonly ILog oauth = Create("DotNetOpenAuth.OAuth"); /// <summary> + /// Backing field for the <see cref="Wrap"/> property. + /// </summary> + private static readonly ILog wrap = Create("DotNetOpenAuth.WRAP"); + + /// <summary> /// Backing field for the <see cref="InfoCard"/> property. /// </summary> private static readonly ILog infocard = Create("DotNetOpenAuth.InfoCard"); @@ -130,6 +135,11 @@ namespace DotNetOpenAuth { internal static ILog OAuth { get { return oauth; } } /// <summary> + /// Gets the logger for the high-level OAuth WRAP events. + /// </summary> + internal static ILog Wrap { get { return wrap; } } + + /// <summary> /// Gets the logger for high-level InfoCard events. /// </summary> internal static ILog InfoCard { get { return infocard; } } diff --git a/src/DotNetOpenAuth/OAuthWrap/ClientBase.cs b/src/DotNetOpenAuth/OAuthWrap/ClientBase.cs index a36759d..fefa005 100644 --- a/src/DotNetOpenAuth/OAuthWrap/ClientBase.cs +++ b/src/DotNetOpenAuth/OAuthWrap/ClientBase.cs @@ -50,5 +50,19 @@ namespace DotNetOpenAuth.OAuthWrap { Contract.Requires<ArgumentException>(!string.IsNullOrEmpty(accessToken)); WrapUtilities.AuthorizeWithOAuthWrap(request, accessToken); } + + /// <summary> + /// Adds the necessary HTTP Authorization header to an HTTP request for protected resources + /// so that the Service Provider will allow the request through. + /// </summary> + /// <param name="request">The request for protected resources from the service provider.</param> + /// <param name="authorization">The authorization for this request previously obtained via OAuth WRAP.</param> + public static void AuthorizeRequest(HttpWebRequest request, IWrapAuthorization authorization) { + Contract.Requires<ArgumentNullException>(request != null); + Contract.Requires<ArgumentNullException>(authorization != null); + Contract.Requires<ArgumentException>(!string.IsNullOrEmpty(authorization.AccessToken)); + Contract.Requires<ProtocolException>(authorization.AccessTokenExpirationUtc < DateTime.UtcNow); + AuthorizeRequest(request, authorization.AccessToken); + } } } diff --git a/src/DotNetOpenAuth/OAuthWrap/IClientTokenManager.cs b/src/DotNetOpenAuth/OAuthWrap/IClientTokenManager.cs index 4cedaee..1f2e99d 100644 --- a/src/DotNetOpenAuth/OAuthWrap/IClientTokenManager.cs +++ b/src/DotNetOpenAuth/OAuthWrap/IClientTokenManager.cs @@ -16,7 +16,8 @@ using System.Diagnostics.Contracts; IWrapAuthorization GetAuthorizationState(Uri callbackUrl, string clientState); } - internal class IClientTokenManagerContract : IClientTokenManager { + [ContractClassFor(typeof(IClientTokenManager))] + internal abstract class IClientTokenManagerContract : IClientTokenManager { private IClientTokenManagerContract() { } @@ -30,7 +31,6 @@ using System.Diagnostics.Contracts; #endregion } - public interface IWrapAuthorization { Uri Callback { get; set; } string RefreshToken { get; set; } @@ -39,5 +39,6 @@ using System.Diagnostics.Contracts; string Scope { get; set; } void Delete(); + void SaveChanges(); } } diff --git a/src/DotNetOpenAuth/OAuthWrap/OAuthWrapStrings.Designer.cs b/src/DotNetOpenAuth/OAuthWrap/OAuthWrapStrings.Designer.cs index 27879c4..326beb6 100644 --- a/src/DotNetOpenAuth/OAuthWrap/OAuthWrapStrings.Designer.cs +++ b/src/DotNetOpenAuth/OAuthWrap/OAuthWrapStrings.Designer.cs @@ -61,6 +61,15 @@ namespace DotNetOpenAuth.OAuthWrap { } /// <summary> + /// Looks up a localized string similar to Failed to obtain access token. Authorization Server reports reason: {0}. + /// </summary> + internal static string CannotObtainAccessTokenWithReason { + get { + return ResourceManager.GetString("CannotObtainAccessTokenWithReason", resourceCulture); + } + } + + /// <summary> /// Looks up a localized string similar to This message can only be sent over HTTPS.. /// </summary> internal static string HttpsRequired { @@ -68,5 +77,14 @@ namespace DotNetOpenAuth.OAuthWrap { return ResourceManager.GetString("HttpsRequired", resourceCulture); } } + + /// <summary> + /// Looks up a localized string similar to Failed to obtain access token due to invalid Client Identifier or Client Secret.. + /// </summary> + internal static string InvalidClientCredentials { + get { + return ResourceManager.GetString("InvalidClientCredentials", resourceCulture); + } + } } } diff --git a/src/DotNetOpenAuth/OAuthWrap/OAuthWrapStrings.resx b/src/DotNetOpenAuth/OAuthWrap/OAuthWrapStrings.resx index b8a8d62..d488810 100644 --- a/src/DotNetOpenAuth/OAuthWrap/OAuthWrapStrings.resx +++ b/src/DotNetOpenAuth/OAuthWrap/OAuthWrapStrings.resx @@ -117,7 +117,13 @@ <resheader name="writer"> <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> </resheader> + <data name="CannotObtainAccessTokenWithReason" xml:space="preserve"> + <value>Failed to obtain access token. Authorization Server reports reason: {0}</value> + </data> <data name="HttpsRequired" xml:space="preserve"> <value>This message can only be sent over HTTPS.</value> </data> + <data name="InvalidClientCredentials" xml:space="preserve"> + <value>Failed to obtain access token due to invalid Client Identifier or Client Secret.</value> + </data> </root>
\ No newline at end of file diff --git a/src/DotNetOpenAuth/OAuthWrap/WebAppClient.cs b/src/DotNetOpenAuth/OAuthWrap/WebAppClient.cs index f107180..d0ebb09 100644 --- a/src/DotNetOpenAuth/OAuthWrap/WebAppClient.cs +++ b/src/DotNetOpenAuth/OAuthWrap/WebAppClient.cs @@ -48,6 +48,7 @@ namespace DotNetOpenAuth.OAuthWrap { if (authorizationState.Callback == null) { authorizationState.Callback = this.Channel.GetRequestFromContext().UrlBeforeRewriting; + authorizationState.SaveChanges(); } var request = new WebAppRequest(this.AuthorizationServer) { @@ -90,12 +91,17 @@ namespace DotNetOpenAuth.OAuthWrap { authorizationState.AccessToken = accessTokenSuccess.AccessToken; authorizationState.RefreshToken = accessTokenSuccess.RefreshToken; authorizationState.AccessTokenExpirationUtc = DateTime.UtcNow + accessTokenSuccess.Lifetime; + authorizationState.SaveChanges(); } else if (badClientAccessTokenResponse != null) { - ErrorUtilities.ThrowProtocol("Failed to obtain access token due to invalid Client Identifier or Client Secret."); + authorizationState.Delete(); + ErrorUtilities.ThrowProtocol(OAuthWrapStrings.InvalidClientCredentials); } else { // failedAccessTokenResponse != null - ErrorUtilities.ThrowProtocol("Failed to obtain access token. Authorization Server reports reason: {0}", failedAccessTokenResponse.ErrorReason); + authorizationState.Delete(); + ErrorUtilities.ThrowProtocol(OAuthWrapStrings.CannotObtainAccessTokenWithReason, failedAccessTokenResponse.ErrorReason); } } else { // failure + Logger.Wrap.Info("User refused to grant the requested authorization at the Authorization Server."); + authorizationState.Delete(); } return authorizationState; |