summaryrefslogtreecommitdiffstats
path: root/src/DotNetOpenAuth.OAuth2.Client/OAuth2/WebServerClient.cs
diff options
context:
space:
mode:
authorAndrew Arnott <andrewarnott@gmail.com>2012-12-24 18:08:15 -0800
committerAndrew Arnott <andrewarnott@gmail.com>2012-12-24 18:08:15 -0800
commitde8497efbe0cc8ce84e3cd9c08391afa486c41ab (patch)
tree6feb9f19265f95756735bcecbb68063bbfc09b16 /src/DotNetOpenAuth.OAuth2.Client/OAuth2/WebServerClient.cs
parentd3f4149dd35b85b7ce00cb9a4b3208cab6065b86 (diff)
downloadDotNetOpenAuth-de8497efbe0cc8ce84e3cd9c08391afa486c41ab.zip
DotNetOpenAuth-de8497efbe0cc8ce84e3cd9c08391afa486c41ab.tar.gz
DotNetOpenAuth-de8497efbe0cc8ce84e3cd9c08391afa486c41ab.tar.bz2
Replaces use of ASP.NET session id with random key.
Fixes #229
Diffstat (limited to 'src/DotNetOpenAuth.OAuth2.Client/OAuth2/WebServerClient.cs')
-rw-r--r--src/DotNetOpenAuth.OAuth2.Client/OAuth2/WebServerClient.cs37
1 files changed, 26 insertions, 11 deletions
diff --git a/src/DotNetOpenAuth.OAuth2.Client/OAuth2/WebServerClient.cs b/src/DotNetOpenAuth.OAuth2.Client/OAuth2/WebServerClient.cs
index 939d1df..4fc8687 100644
--- a/src/DotNetOpenAuth.OAuth2.Client/OAuth2/WebServerClient.cs
+++ b/src/DotNetOpenAuth.OAuth2.Client/OAuth2/WebServerClient.cs
@@ -8,10 +8,14 @@ namespace DotNetOpenAuth.OAuth2 {
using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
+ using System.Globalization;
using System.Linq;
using System.Net;
using System.Text;
using System.Web;
+ using System.Web.Security;
+
+ using DotNetOpenAuth.Configuration;
using DotNetOpenAuth.Messaging;
using DotNetOpenAuth.OAuth2.Messages;
@@ -20,6 +24,11 @@ namespace DotNetOpenAuth.OAuth2 {
/// </summary>
public class WebServerClient : ClientBase {
/// <summary>
+ /// The cookie name for XSRF mitigation during authorization code grant flows.
+ /// </summary>
+ private const string XsrfCookieName = "DotNetOpenAuth.WebServerClient.XSRF-Session";
+
+ /// <summary>
/// Initializes a new instance of the <see cref="WebServerClient"/> class.
/// </summary>
/// <param name="authorizationServer">The authorization server.</param>
@@ -100,16 +109,25 @@ namespace DotNetOpenAuth.OAuth2 {
// Mitigate XSRF attacks by including a state value that would be unpredictable between users, but
// verifiable for the same user/session.
// If the host is implementing the authorization tracker though, they're handling this protection themselves.
+ HttpCookie cookie = null;
if (this.AuthorizationTracker == null) {
var context = this.Channel.GetHttpContext();
- if (context.Session != null) {
- request.ClientState = context.Session.SessionID;
- } else {
- Logger.OAuth.WarnFormat("No request context discovered, so no client state parameter could be set to mitigate XSRF attacks.");
- }
+
+ string xsrfKey = (new Random()).Next().ToString(CultureInfo.InvariantCulture);
+ cookie = new HttpCookie(XsrfCookieName, xsrfKey) {
+ HttpOnly = true,
+ Secure = FormsAuthentication.RequireSSL,
+ Expires = DateTime.Now.Add(OAuth2ClientSection.Configuration.MaxAuthorizationTime),
+ };
+ request.ClientState = xsrfKey;
+ }
+
+ var response = this.Channel.PrepareResponse(request);
+ if (cookie != null) {
+ response.Cookies.Add(cookie);
}
- return this.Channel.PrepareResponse(request);
+ return response;
}
/// <summary>
@@ -134,12 +152,9 @@ namespace DotNetOpenAuth.OAuth2 {
ErrorUtilities.VerifyProtocol(authorizationState != null, ClientStrings.AuthorizationResponseUnexpectedMismatch);
} else {
var context = this.Channel.GetHttpContext();
- if (context.Session != null) {
- ErrorUtilities.VerifyProtocol(string.Equals(response.ClientState, context.Session.SessionID, StringComparison.Ordinal), ClientStrings.AuthorizationResponseUnexpectedMismatch);
- } else {
- Logger.OAuth.WarnFormat("No request context discovered, so no client state parameter could be checked to mitigate XSRF attacks.");
- }
+ HttpCookie cookie = request.Cookies[XsrfCookieName];
+ ErrorUtilities.VerifyProtocol(cookie != null && string.Equals(response.ClientState, cookie.Value, StringComparison.Ordinal), ClientStrings.AuthorizationResponseUnexpectedMismatch);
authorizationState = new AuthorizationState { Callback = callback };
}
var success = response as EndUserAuthorizationSuccessAuthCodeResponse;