summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAndrew Arnott <andrewarnott@gmail.com>2012-11-26 17:06:00 -0800
committerAndrew Arnott <andrewarnott@gmail.com>2012-11-26 17:06:00 -0800
commitf4589005375571770d5b47eed18adf2a73d0afa6 (patch)
tree8ed0bbb79bc0511e330e469ae9e5516a4b066198 /src
parentd8aa2dbf93d3d48de8f5fe5fdf51e524a14b76fd (diff)
parente0772aec6a14265af869a8e4db2a2330cc2feb1f (diff)
downloadDotNetOpenAuth-f4589005375571770d5b47eed18adf2a73d0afa6.zip
DotNetOpenAuth-f4589005375571770d5b47eed18adf2a73d0afa6.tar.gz
DotNetOpenAuth-f4589005375571770d5b47eed18adf2a73d0afa6.tar.bz2
Merge pull request #235 from dotnetjunky/v4.1
Fix bug in the LinkedInClient not working Fixes #232
Diffstat (limited to 'src')
-rw-r--r--src/DotNetOpenAuth.AspNet/Clients/OAuth/AuthenticationOnlyCookieOAuthTokenManager.cs46
-rw-r--r--src/DotNetOpenAuth.AspNet/Clients/OAuth/CookieOAuthTokenManager.cs74
-rw-r--r--src/DotNetOpenAuth.AspNet/Clients/OAuth/LinkedInClient.cs2
-rw-r--r--src/DotNetOpenAuth.AspNet/DotNetOpenAuth.AspNet.csproj3
4 files changed, 112 insertions, 13 deletions
diff --git a/src/DotNetOpenAuth.AspNet/Clients/OAuth/AuthenticationOnlyCookieOAuthTokenManager.cs b/src/DotNetOpenAuth.AspNet/Clients/OAuth/AuthenticationOnlyCookieOAuthTokenManager.cs
index 2ec988b..efc382f 100644
--- a/src/DotNetOpenAuth.AspNet/Clients/OAuth/AuthenticationOnlyCookieOAuthTokenManager.cs
+++ b/src/DotNetOpenAuth.AspNet/Clients/OAuth/AuthenticationOnlyCookieOAuthTokenManager.cs
@@ -17,7 +17,7 @@ namespace DotNetOpenAuth.AspNet.Clients {
/// <summary>
/// Key used for token cookie
/// </summary>
- private const string TokenCookieKey = "OAuthTokenSecret";
+ protected const string TokenCookieKey = "OAuthTokenSecret";
/// <summary>
/// Primary request context.
@@ -41,7 +41,7 @@ namespace DotNetOpenAuth.AspNet.Clients {
/// <summary>
/// Gets the effective HttpContext object to use.
/// </summary>
- private HttpContextBase Context {
+ protected HttpContextBase Context {
get {
return this.primaryContext ?? new HttpContextWrapper(HttpContext.Current);
}
@@ -54,15 +54,13 @@ namespace DotNetOpenAuth.AspNet.Clients {
/// <returns>
/// The token's secret
/// </returns>
- public string GetTokenSecret(string token) {
+ public virtual string GetTokenSecret(string token) {
HttpCookie cookie = this.Context.Request.Cookies[TokenCookieKey];
if (cookie == null || string.IsNullOrEmpty(cookie.Values[token])) {
return null;
}
- byte[] cookieBytes = HttpServerUtility.UrlTokenDecode(cookie.Values[token]);
- byte[] clearBytes = MachineKeyUtil.Unprotect(cookieBytes, TokenCookieKey, "Token:" + token);
- string secret = Encoding.UTF8.GetString(clearBytes);
+ string secret = DecodeAndUnprotectToken(token, cookie.Values[token]);
return secret;
}
@@ -72,7 +70,7 @@ namespace DotNetOpenAuth.AspNet.Clients {
/// <param name="requestToken">The request token.</param>
/// <param name="accessToken">The access token.</param>
/// <param name="accessTokenSecret">The access token secret.</param>
- public void ReplaceRequestTokenWithAccessToken(string requestToken, string accessToken, string accessTokenSecret) {
+ public virtual void ReplaceRequestTokenWithAccessToken(string requestToken, string accessToken, string accessTokenSecret) {
var cookie = new HttpCookie(TokenCookieKey) {
Value = string.Empty,
Expires = DateTime.UtcNow.AddDays(-5)
@@ -85,7 +83,7 @@ namespace DotNetOpenAuth.AspNet.Clients {
/// </summary>
/// <param name="requestToken">The request token.</param>
/// <param name="requestTokenSecret">The request token secret.</param>
- public void StoreRequestToken(string requestToken, string requestTokenSecret) {
+ public virtual void StoreRequestToken(string requestToken, string requestTokenSecret) {
var cookie = new HttpCookie(TokenCookieKey) {
HttpOnly = true
};
@@ -94,10 +92,36 @@ namespace DotNetOpenAuth.AspNet.Clients {
cookie.Secure = true;
}
- byte[] cookieBytes = Encoding.UTF8.GetBytes(requestTokenSecret);
- var secretBytes = MachineKeyUtil.Protect(cookieBytes, TokenCookieKey, "Token:" + requestToken);
- cookie.Values[requestToken] = HttpServerUtility.UrlTokenEncode(secretBytes);
+ var encryptedToken = ProtectAndEncodeToken(requestToken, requestTokenSecret);
+ cookie.Values[requestToken] = encryptedToken;
+
this.Context.Response.Cookies.Set(cookie);
}
+
+ /// <summary>
+ /// Protect and url-encode the specified token secret.
+ /// </summary>
+ /// <param name="token">The token to be used as a key.</param>
+ /// <param name="tokenSecret">The token secret to be protected</param>
+ /// <returns>The encrypted and protected string.</returns>
+ protected static string ProtectAndEncodeToken(string token, string tokenSecret)
+ {
+ byte[] cookieBytes = Encoding.UTF8.GetBytes(tokenSecret);
+ var secretBytes = MachineKeyUtil.Protect(cookieBytes, TokenCookieKey, "Token:" + token);
+ return HttpServerUtility.UrlTokenEncode(secretBytes);
+ }
+
+ /// <summary>
+ /// Url-decode and unprotect the specified encrypted token string.
+ /// </summary>
+ /// <param name="token">The token to be used as a key.</param>
+ /// <param name="encryptedToken">The encrypted token to be decrypted</param>
+ /// <returns>The original token secret</returns>
+ protected static string DecodeAndUnprotectToken(string token, string encryptedToken)
+ {
+ byte[] cookieBytes = HttpServerUtility.UrlTokenDecode(encryptedToken);
+ byte[] clearBytes = MachineKeyUtil.Unprotect(cookieBytes, TokenCookieKey, "Token:" + token);
+ return Encoding.UTF8.GetString(clearBytes);
+ }
}
} \ No newline at end of file
diff --git a/src/DotNetOpenAuth.AspNet/Clients/OAuth/CookieOAuthTokenManager.cs b/src/DotNetOpenAuth.AspNet/Clients/OAuth/CookieOAuthTokenManager.cs
new file mode 100644
index 0000000..835b6f1
--- /dev/null
+++ b/src/DotNetOpenAuth.AspNet/Clients/OAuth/CookieOAuthTokenManager.cs
@@ -0,0 +1,74 @@
+using System.Web;
+using System.Web.Security;
+
+namespace DotNetOpenAuth.AspNet.Clients {
+
+ /// <summary>
+ /// Stores OAuth tokens in the current request's cookie.
+ /// </summary>
+ /// <remarks>
+ /// This class is different from the <see cref="AuthenticationOnlyCookieOAuthTokenManager"/> in that
+ /// it also stores the access token after the authentication has succeeded.
+ /// </remarks>
+ public class CookieOAuthTokenManager : AuthenticationOnlyCookieOAuthTokenManager {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="CookieOAuthTokenManager"/> class.
+ /// </summary>
+ public CookieOAuthTokenManager() {
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="CookieOAuthTokenManager"/> class.
+ /// </summary>
+ /// <param name="context">The current request context.</param>
+ public CookieOAuthTokenManager(HttpContextBase context)
+ : base(context) {
+ }
+
+ /// <summary>
+ /// Gets the token secret from the specified token.
+ /// </summary>
+ /// <param name="token">The token.</param>
+ /// <returns>
+ /// The token's secret
+ /// </returns>
+ public override string GetTokenSecret(string token) {
+ string secret = base.GetTokenSecret(token);
+ if (secret != null) {
+ return secret;
+ }
+
+ // The base class checks for cookies in the Request object.
+ // Here we check in the Response object as well because we
+ // may have set it earlier in the request life cycle.
+ HttpCookie cookie = this.Context.Response.Cookies[TokenCookieKey];
+ if (cookie == null || string.IsNullOrEmpty(cookie.Values[token])) {
+ return null;
+ }
+
+ secret = DecodeAndUnprotectToken(token, cookie.Values[token]);
+ return secret;
+ }
+
+ /// <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>
+ public override void ReplaceRequestTokenWithAccessToken(string requestToken, string accessToken, string accessTokenSecret) {
+ var cookie = new HttpCookie(TokenCookieKey) {
+ HttpOnly = true
+ };
+
+ if (FormsAuthentication.RequireSSL) {
+ cookie.Secure = true;
+ }
+
+ var encryptedToken = ProtectAndEncodeToken(accessToken, accessTokenSecret);
+ cookie.Values[accessToken] = encryptedToken;
+
+ this.Context.Response.Cookies.Set(cookie);
+ }
+ }
+} \ 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 26bc88d..3c157f3 100644
--- a/src/DotNetOpenAuth.AspNet/Clients/OAuth/LinkedInClient.cs
+++ b/src/DotNetOpenAuth.AspNet/Clients/OAuth/LinkedInClient.cs
@@ -60,7 +60,7 @@ namespace DotNetOpenAuth.AspNet.Clients {
[SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope",
Justification = "We can't dispose the object because we still need it through the app lifetime.")]
public LinkedInClient(string consumerKey, string consumerSecret)
- : this(consumerKey, consumerSecret, new AuthenticationOnlyCookieOAuthTokenManager()) { }
+ : this(consumerKey, consumerSecret, new CookieOAuthTokenManager()) { }
/// <summary>
/// Initializes a new instance of the <see cref="LinkedInClient"/> class.
diff --git a/src/DotNetOpenAuth.AspNet/DotNetOpenAuth.AspNet.csproj b/src/DotNetOpenAuth.AspNet/DotNetOpenAuth.AspNet.csproj
index 2f03ec7..405ac3c 100644
--- a/src/DotNetOpenAuth.AspNet/DotNetOpenAuth.AspNet.csproj
+++ b/src/DotNetOpenAuth.AspNet/DotNetOpenAuth.AspNet.csproj
@@ -28,7 +28,7 @@
<Import Project="$(ProjectRoot)tools\DotNetOpenAuth.props" />
<Import Project="$(ProjectRoot)tools\DotNetOpenAuth.Product.props" />
<PropertyGroup>
- <RootNamespace>DotNetOpenAuth.AspNet</RootNamespace>
+ <RootNamespace>DotNetOpenAuth.AspNet</RootNamespace>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
@@ -48,6 +48,7 @@
<Compile Include="Clients\OAuth\AuthenticationOnlyCookieOAuthTokenManager.cs">
<SubType>Code</SubType>
</Compile>
+ <Compile Include="Clients\OAuth\CookieOAuthTokenManager.cs" />
<Compile Include="Clients\OAuth\IOAuthTokenManager.cs" />
<Compile Include="Clients\OAuth\SimpleConsumerTokenManager.cs" />
<Compile Include="IAuthenticationClient.cs" />