Skip to content
This repository was archived by the owner on Mar 20, 2019. It is now read-only.

Commit c7509b6

Browse files
committed
Merge branch 'v4.1'
Conflicts: src/DotNetOpenAuth.OAuth2.ResourceServer/OAuth2/StandardAccessTokenAnalyzer.cs src/DotNetOpenAuth.Test/OAuth2/OAuth2TestBase.cs src/version.txt
2 parents 67f3936 + 84ef4b7 commit c7509b6

26 files changed

Lines changed: 338 additions & 38 deletions

File tree

samples/OAuthAuthorizationServer/OAuthAuthorizationServer.csproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,10 @@
6363
<RequiredTargetFramework>3.5</RequiredTargetFramework>
6464
</Reference>
6565
<Reference Include="System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL" />
66+
<Reference Include="System.Net.Http, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
67+
<SpecificVersion>False</SpecificVersion>
68+
<HintPath>..\..\lib\net-v4.0\System.Net.Http.dll</HintPath>
69+
</Reference>
6670
<Reference Include="System.Xml.Linq">
6771
<RequiredTargetFramework>3.5</RequiredTargetFramework>
6872
</Reference>

src/DotNetOpenAuth.AspNet/Clients/OAuth/AuthenticationOnlyCookieOAuthTokenManager.cs

Lines changed: 35 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ public class AuthenticationOnlyCookieOAuthTokenManager : IOAuthTokenManager {
1717
/// <summary>
1818
/// Key used for token cookie
1919
/// </summary>
20-
private const string TokenCookieKey = "OAuthTokenSecret";
20+
protected const string TokenCookieKey = "OAuthTokenSecret";
2121

2222
/// <summary>
2323
/// Primary request context.
@@ -41,7 +41,7 @@ public AuthenticationOnlyCookieOAuthTokenManager(HttpContextBase context) {
4141
/// <summary>
4242
/// Gets the effective HttpContext object to use.
4343
/// </summary>
44-
private HttpContextBase Context {
44+
protected HttpContextBase Context {
4545
get {
4646
return this.primaryContext ?? new HttpContextWrapper(HttpContext.Current);
4747
}
@@ -54,15 +54,13 @@ private HttpContextBase Context {
5454
/// <returns>
5555
/// The token's secret
5656
/// </returns>
57-
public string GetTokenSecret(string token) {
57+
public virtual string GetTokenSecret(string token) {
5858
HttpCookie cookie = this.Context.Request.Cookies[TokenCookieKey];
5959
if (cookie == null || string.IsNullOrEmpty(cookie.Values[token])) {
6060
return null;
6161
}
62-
byte[] cookieBytes = HttpServerUtility.UrlTokenDecode(cookie.Values[token]);
63-
byte[] clearBytes = MachineKeyUtil.Unprotect(cookieBytes, TokenCookieKey, "Token:" + token);
6462

65-
string secret = Encoding.UTF8.GetString(clearBytes);
63+
string secret = DecodeAndUnprotectToken(token, cookie.Values[token]);
6664
return secret;
6765
}
6866

@@ -72,7 +70,7 @@ public string GetTokenSecret(string token) {
7270
/// <param name="requestToken">The request token.</param>
7371
/// <param name="accessToken">The access token.</param>
7472
/// <param name="accessTokenSecret">The access token secret.</param>
75-
public void ReplaceRequestTokenWithAccessToken(string requestToken, string accessToken, string accessTokenSecret) {
73+
public virtual void ReplaceRequestTokenWithAccessToken(string requestToken, string accessToken, string accessTokenSecret) {
7674
var cookie = new HttpCookie(TokenCookieKey) {
7775
Value = string.Empty,
7876
Expires = DateTime.UtcNow.AddDays(-5)
@@ -85,7 +83,7 @@ public void ReplaceRequestTokenWithAccessToken(string requestToken, string acces
8583
/// </summary>
8684
/// <param name="requestToken">The request token.</param>
8785
/// <param name="requestTokenSecret">The request token secret.</param>
88-
public void StoreRequestToken(string requestToken, string requestTokenSecret) {
86+
public virtual void StoreRequestToken(string requestToken, string requestTokenSecret) {
8987
var cookie = new HttpCookie(TokenCookieKey) {
9088
HttpOnly = true
9189
};
@@ -94,10 +92,36 @@ public void StoreRequestToken(string requestToken, string requestTokenSecret) {
9492
cookie.Secure = true;
9593
}
9694

97-
byte[] cookieBytes = Encoding.UTF8.GetBytes(requestTokenSecret);
98-
var secretBytes = MachineKeyUtil.Protect(cookieBytes, TokenCookieKey, "Token:" + requestToken);
99-
cookie.Values[requestToken] = HttpServerUtility.UrlTokenEncode(secretBytes);
95+
var encryptedToken = ProtectAndEncodeToken(requestToken, requestTokenSecret);
96+
cookie.Values[requestToken] = encryptedToken;
97+
10098
this.Context.Response.Cookies.Set(cookie);
10199
}
100+
101+
/// <summary>
102+
/// Protect and url-encode the specified token secret.
103+
/// </summary>
104+
/// <param name="token">The token to be used as a key.</param>
105+
/// <param name="tokenSecret">The token secret to be protected</param>
106+
/// <returns>The encrypted and protected string.</returns>
107+
protected static string ProtectAndEncodeToken(string token, string tokenSecret)
108+
{
109+
byte[] cookieBytes = Encoding.UTF8.GetBytes(tokenSecret);
110+
var secretBytes = MachineKeyUtil.Protect(cookieBytes, TokenCookieKey, "Token:" + token);
111+
return HttpServerUtility.UrlTokenEncode(secretBytes);
112+
}
113+
114+
/// <summary>
115+
/// Url-decode and unprotect the specified encrypted token string.
116+
/// </summary>
117+
/// <param name="token">The token to be used as a key.</param>
118+
/// <param name="encryptedToken">The encrypted token to be decrypted</param>
119+
/// <returns>The original token secret</returns>
120+
protected static string DecodeAndUnprotectToken(string token, string encryptedToken)
121+
{
122+
byte[] cookieBytes = HttpServerUtility.UrlTokenDecode(encryptedToken);
123+
byte[] clearBytes = MachineKeyUtil.Unprotect(cookieBytes, TokenCookieKey, "Token:" + token);
124+
return Encoding.UTF8.GetString(clearBytes);
125+
}
102126
}
103127
}
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
//-----------------------------------------------------------------------
2+
// <copyright file="CookieOAuthTokenManager.cs" company="Microsoft">
3+
// Copyright (c) Microsoft. All rights reserved.
4+
// </copyright>
5+
//-----------------------------------------------------------------------
6+
7+
namespace DotNetOpenAuth.AspNet.Clients {
8+
using System.Web;
9+
using System.Web.Security;
10+
11+
/// <summary>
12+
/// Stores OAuth tokens in the current request's cookie.
13+
/// </summary>
14+
/// <remarks>
15+
/// This class is different from the <see cref="AuthenticationOnlyCookieOAuthTokenManager"/> in that
16+
/// it also stores the access token after the authentication has succeeded.
17+
/// </remarks>
18+
public class CookieOAuthTokenManager : AuthenticationOnlyCookieOAuthTokenManager {
19+
/// <summary>
20+
/// Initializes a new instance of the <see cref="CookieOAuthTokenManager"/> class.
21+
/// </summary>
22+
public CookieOAuthTokenManager() {
23+
}
24+
25+
/// <summary>
26+
/// Initializes a new instance of the <see cref="CookieOAuthTokenManager"/> class.
27+
/// </summary>
28+
/// <param name="context">The current request context.</param>
29+
public CookieOAuthTokenManager(HttpContextBase context)
30+
: base(context) {
31+
}
32+
33+
/// <summary>
34+
/// Gets the token secret from the specified token.
35+
/// </summary>
36+
/// <param name="token">The token.</param>
37+
/// <returns>
38+
/// The token's secret
39+
/// </returns>
40+
public override string GetTokenSecret(string token) {
41+
string secret = base.GetTokenSecret(token);
42+
if (secret != null) {
43+
return secret;
44+
}
45+
46+
// The base class checks for cookies in the Request object.
47+
// Here we check in the Response object as well because we
48+
// may have set it earlier in the request life cycle.
49+
HttpCookie cookie = this.Context.Response.Cookies[TokenCookieKey];
50+
if (cookie == null || string.IsNullOrEmpty(cookie.Values[token])) {
51+
return null;
52+
}
53+
54+
secret = DecodeAndUnprotectToken(token, cookie.Values[token]);
55+
return secret;
56+
}
57+
58+
/// <summary>
59+
/// Replaces the request token with access token.
60+
/// </summary>
61+
/// <param name="requestToken">The request token.</param>
62+
/// <param name="accessToken">The access token.</param>
63+
/// <param name="accessTokenSecret">The access token secret.</param>
64+
public override void ReplaceRequestTokenWithAccessToken(string requestToken, string accessToken, string accessTokenSecret) {
65+
var cookie = new HttpCookie(TokenCookieKey) {
66+
HttpOnly = true
67+
};
68+
69+
if (FormsAuthentication.RequireSSL) {
70+
cookie.Secure = true;
71+
}
72+
73+
var encryptedToken = ProtectAndEncodeToken(accessToken, accessTokenSecret);
74+
cookie.Values[accessToken] = encryptedToken;
75+
76+
this.Context.Response.Cookies.Set(cookie);
77+
}
78+
}
79+
}

src/DotNetOpenAuth.AspNet/Clients/OAuth/DotNetOpenAuthWebConsumer.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ public AuthorizedTokenResponse ProcessUserAuthorization() {
7777
/// The callback.
7878
/// </param>
7979
public void RequestAuthentication(Uri callback) {
80-
var redirectParameters = new Dictionary<string, string> { { "force_login", "false" } };
80+
var redirectParameters = new Dictionary<string, string>();
8181
UserAuthorizationRequest request = this.webConsumer.PrepareRequestUserAuthorization(
8282
callback, null, redirectParameters);
8383
this.webConsumer.Channel.PrepareResponse(request).Send();

src/DotNetOpenAuth.AspNet/Clients/OAuth/LinkedInClient.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ public sealed class LinkedInClient : OAuthClient {
6060
[SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope",
6161
Justification = "We can't dispose the object because we still need it through the app lifetime.")]
6262
public LinkedInClient(string consumerKey, string consumerSecret)
63-
: this(consumerKey, consumerSecret, new AuthenticationOnlyCookieOAuthTokenManager()) { }
63+
: this(consumerKey, consumerSecret, new CookieOAuthTokenManager()) { }
6464

6565
/// <summary>
6666
/// Initializes a new instance of the <see cref="LinkedInClient"/> class.

src/DotNetOpenAuth.AspNet/Clients/OAuth2/MicrosoftClient.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,12 @@ public class MicrosoftClient : OAuth2Client {
2020
/// <summary>
2121
/// The authorization endpoint.
2222
/// </summary>
23-
private const string AuthorizationEndpoint = "https://oauth.live.com/authorize";
23+
private const string AuthorizationEndpoint = "https://login.live.com/oauth20_authorize.srf";
2424

2525
/// <summary>
2626
/// The token endpoint.
2727
/// </summary>
28-
private const string TokenEndpoint = "https://oauth.live.com/token";
28+
private const string TokenEndpoint = "https://login.live.com/oauth20_token.srf";
2929

3030
/// <summary>
3131
/// The _app id.

src/DotNetOpenAuth.AspNet/DotNetOpenAuth.AspNet.csproj

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
<Import Project="$(ProjectRoot)tools\DotNetOpenAuth.props" />
2929
<Import Project="$(ProjectRoot)tools\DotNetOpenAuth.Product.props" />
3030
<PropertyGroup>
31-
<RootNamespace>DotNetOpenAuth.AspNet</RootNamespace>
31+
<RootNamespace>DotNetOpenAuth.AspNet</RootNamespace>
3232
</PropertyGroup>
3333
<ItemGroup>
3434
<Reference Include="System" />
@@ -48,6 +48,7 @@
4848
<Compile Include="Clients\OAuth\AuthenticationOnlyCookieOAuthTokenManager.cs">
4949
<SubType>Code</SubType>
5050
</Compile>
51+
<Compile Include="Clients\OAuth\CookieOAuthTokenManager.cs" />
5152
<Compile Include="Clients\OAuth\IOAuthTokenManager.cs" />
5253
<Compile Include="Clients\OAuth\SimpleConsumerTokenManager.cs" />
5354
<Compile Include="IAuthenticationClient.cs" />

src/DotNetOpenAuth.Core/Messaging/DataBagFormatterBase.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -215,8 +215,8 @@ public void Deserialize(T message, string value, IProtocolMessage containingMess
215215
if (this.signed) {
216216
using (var dataStream = new MemoryStream(data)) {
217217
var dataReader = new BinaryReader(dataStream);
218-
signature = dataReader.ReadBuffer();
219-
data = dataReader.ReadBuffer();
218+
signature = dataReader.ReadBuffer(1024);
219+
data = dataReader.ReadBuffer(8 * 1024);
220220
}
221221

222222
// Verify that the verification code was issued by message authorization server.

src/DotNetOpenAuth.Core/Messaging/MessagingStrings.Designer.cs

Lines changed: 10 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/DotNetOpenAuth.Core/Messaging/MessagingStrings.resx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,10 +112,10 @@
112112
<value>2.0</value>
113113
</resheader>
114114
<resheader name="reader">
115-
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
115+
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
116116
</resheader>
117117
<resheader name="writer">
118-
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
118+
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
119119
</resheader>
120120
<data name="ArgumentPropertyMissing" xml:space="preserve">
121121
<value>Argument's {0}.{1} property is required but is empty or null.</value>
@@ -333,4 +333,7 @@
333333
<data name="UnexpectedBufferLength" xml:space="preserve">
334334
<value>Unexpected buffer length.</value>
335335
</data>
336+
<data name="DataCorruptionDetected" xml:space="preserve">
337+
<value>Decoding failed due to data corruption.</value>
338+
</data>
336339
</root>

0 commit comments

Comments
 (0)