summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/DotNetOpenAuth.Core/Messaging/Channel.cs9
-rw-r--r--src/DotNetOpenAuth.OAuth2.Client/OAuth2/OAuth2Strings.Designer.cs2
-rw-r--r--src/DotNetOpenAuth.OAuth2.Client/OAuth2/OAuth2Strings.resx1
-rw-r--r--src/DotNetOpenAuth.OAuth2.Client/OAuth2/WebServerClient.cs24
4 files changed, 26 insertions, 10 deletions
diff --git a/src/DotNetOpenAuth.Core/Messaging/Channel.cs b/src/DotNetOpenAuth.Core/Messaging/Channel.cs
index 0feb999..d8b25fa 100644
--- a/src/DotNetOpenAuth.Core/Messaging/Channel.cs
+++ b/src/DotNetOpenAuth.Core/Messaging/Channel.cs
@@ -599,6 +599,15 @@ namespace DotNetOpenAuth.Messaging {
}
/// <summary>
+ /// Gets the HTTP context for the current HTTP request.
+ /// </summary>
+ /// <returns>An HttpContextBase instance.</returns>
+ protected internal virtual HttpContextBase GetHttpContext() {
+ Requires.ValidState(HttpContext.Current != null, MessagingStrings.HttpContextRequired);
+ return new HttpContextWrapper(HttpContext.Current);
+ }
+
+ /// <summary>
/// Gets the current HTTP request being processed.
/// </summary>
/// <returns>The HttpRequestInfo for the current request.</returns>
diff --git a/src/DotNetOpenAuth.OAuth2.Client/OAuth2/OAuth2Strings.Designer.cs b/src/DotNetOpenAuth.OAuth2.Client/OAuth2/OAuth2Strings.Designer.cs
index d140b7e..74c0685 100644
--- a/src/DotNetOpenAuth.OAuth2.Client/OAuth2/OAuth2Strings.Designer.cs
+++ b/src/DotNetOpenAuth.OAuth2.Client/OAuth2/OAuth2Strings.Designer.cs
@@ -1,7 +1,7 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
-// Runtime Version:4.0.30319.239
+// Runtime Version:4.0.30319.261
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
diff --git a/src/DotNetOpenAuth.OAuth2.Client/OAuth2/OAuth2Strings.resx b/src/DotNetOpenAuth.OAuth2.Client/OAuth2/OAuth2Strings.resx
index 114b3e8..0a41e42 100644
--- a/src/DotNetOpenAuth.OAuth2.Client/OAuth2/OAuth2Strings.resx
+++ b/src/DotNetOpenAuth.OAuth2.Client/OAuth2/OAuth2Strings.resx
@@ -125,6 +125,7 @@
</data>
<data name="AuthorizationResponseUnexpectedMismatch" xml:space="preserve">
<value>Unexpected OAuth authorization response received with callback and client state that does not match an expected value.</value>
+ <comment>The error message generated when detecting a mismatch between the state sent to the authorization server originally and what we got back with successful authorization, or that the user sessions were not identical between the two requests, suggesting XSRF or other attack on the user (victim).</comment>
</data>
<data name="RequiredPropertyNotYetPreset" xml:space="preserve">
<value>The property {0} must be set before this operation is allowed.</value>
diff --git a/src/DotNetOpenAuth.OAuth2.Client/OAuth2/WebServerClient.cs b/src/DotNetOpenAuth.OAuth2.Client/OAuth2/WebServerClient.cs
index fe37dc3..42fa62b 100644
--- a/src/DotNetOpenAuth.OAuth2.Client/OAuth2/WebServerClient.cs
+++ b/src/DotNetOpenAuth.OAuth2.Client/OAuth2/WebServerClient.cs
@@ -39,36 +39,33 @@ namespace DotNetOpenAuth.OAuth2 {
/// Prepares a request for user authorization from an authorization server.
/// </summary>
/// <param name="scope">The scope of authorized access requested.</param>
- /// <param name="state">The state of the client that should be sent back with the authorization response.</param>
/// <param name="returnTo">The URL the authorization server should redirect the browser (typically on this site) to when the authorization is completed. If null, the current request's URL will be used.</param>
- public void RequestUserAuthorization(IEnumerable<string> scope = null, string state = null, Uri returnTo = null) {
+ public void RequestUserAuthorization(IEnumerable<string> scope = null, Uri returnTo = null) {
var authorizationState = new AuthorizationState(scope) {
Callback = returnTo,
};
- this.PrepareRequestUserAuthorization(authorizationState, state).Send();
+ this.PrepareRequestUserAuthorization(authorizationState).Send();
}
/// <summary>
/// Prepares a request for user authorization from an authorization server.
/// </summary>
/// <param name="scopes">The scope of authorized access requested.</param>
- /// <param name="state">The state of the client that should be sent back with the authorization response.</param>
/// <param name="returnTo">The URL the authorization server should redirect the browser (typically on this site) to when the authorization is completed. If null, the current request's URL will be used.</param>
/// <returns>The authorization request.</returns>
- public OutgoingWebResponse PrepareRequestUserAuthorization(IEnumerable<string> scopes = null, string state = null, Uri returnTo = null) {
+ public OutgoingWebResponse PrepareRequestUserAuthorization(IEnumerable<string> scopes = null, Uri returnTo = null) {
var authorizationState = new AuthorizationState(scopes) {
Callback = returnTo,
};
- return this.PrepareRequestUserAuthorization(authorizationState, state);
+ return this.PrepareRequestUserAuthorization(authorizationState);
}
/// <summary>
/// Prepares a request for user authorization from an authorization server.
/// </summary>
/// <param name="authorization">The authorization state to associate with this particular request.</param>
- /// <param name="state">The state of the client that should be sent back with the authorization response.</param>
/// <returns>The authorization request.</returns>
- public OutgoingWebResponse PrepareRequestUserAuthorization(IAuthorizationState authorization, string state = null) {
+ public OutgoingWebResponse PrepareRequestUserAuthorization(IAuthorizationState authorization) {
Requires.NotNull(authorization, "authorization");
Requires.ValidState(authorization.Callback != null || (HttpContext.Current != null && HttpContext.Current.Request != null), MessagingStrings.HttpContextRequired);
Requires.ValidState(!string.IsNullOrEmpty(this.ClientIdentifier), OAuth2Strings.RequiredPropertyNotYetPreset, "ClientIdentifier");
@@ -84,10 +81,17 @@ namespace DotNetOpenAuth.OAuth2 {
var request = new EndUserAuthorizationRequest(this.AuthorizationServer) {
ClientIdentifier = this.ClientIdentifier,
Callback = authorization.Callback,
- ClientState = state,
};
request.Scope.ResetContents(authorization.Scope);
+ // 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.
+ if (this.AuthorizationTracker == null) {
+ var context = this.Channel.GetHttpContext();
+ request.ClientState = context.Session.SessionID;
+ }
+
return this.Channel.PrepareResponse(request);
}
@@ -112,6 +116,8 @@ namespace DotNetOpenAuth.OAuth2 {
authorizationState = this.AuthorizationTracker.GetAuthorizationState(callback, response.ClientState);
ErrorUtilities.VerifyProtocol(authorizationState != null, OAuth2Strings.AuthorizationResponseUnexpectedMismatch);
} else {
+ var context = this.Channel.GetHttpContext();
+ ErrorUtilities.VerifyProtocol(String.Equals(response.ClientState, context.Session.SessionID, StringComparison.Ordinal), OAuth2Strings.AuthorizationResponseUnexpectedMismatch);
authorizationState = new AuthorizationState { Callback = callback };
}
var success = response as EndUserAuthorizationSuccessAuthCodeResponse;