summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--projecttemplates/RelyingPartyLogic/Model.Client.cs23
-rw-r--r--samples/OAuthConsumer/SampleWcf2.aspx.cs30
-rw-r--r--samples/OAuthConsumerWpf/Authorize2.xaml.cs14
-rw-r--r--samples/OAuthConsumerWpf/MainWindow.xaml.cs20
-rw-r--r--samples/OAuthServiceProvider/Code/Client.cs17
-rw-r--r--samples/OAuthServiceProvider/Members/Authorize.aspx.cs8
-rw-r--r--src/DotNetOpenAuth.Test/OAuth2/MessageFactoryTests.cs2
-rw-r--r--src/DotNetOpenAuth.Test/OAuth2/OAuth2ChannelTests.cs2
-rw-r--r--src/DotNetOpenAuth.Test/OAuth2/OAuth2TestBase.cs2
-rw-r--r--src/DotNetOpenAuth/Messaging/MessagingUtilities.cs1
-rw-r--r--src/DotNetOpenAuth/OAuth2/AuthorizationServer.cs24
-rw-r--r--src/DotNetOpenAuth/OAuth2/ChannelElements/AuthServerAllFlowsBindingElement.cs8
-rw-r--r--src/DotNetOpenAuth/OAuth2/IConsumerDescription.cs49
-rw-r--r--src/DotNetOpenAuth/OAuth2/Messages/AccessTokenRefreshRequest.cs1
-rw-r--r--src/DotNetOpenAuth/OAuth2/Messages/EndUserAuthorizationFailedResponse.cs5
-rw-r--r--src/DotNetOpenAuth/OAuth2/OAuthStrings.Designer.cs2
-rw-r--r--src/DotNetOpenAuth/OAuth2/OAuthStrings.resx2
-rw-r--r--src/DotNetOpenAuth/OAuth2/OAuthUtilities.cs14
-rw-r--r--src/DotNetOpenAuth/OAuth2/WebServerClient.cs1
19 files changed, 164 insertions, 61 deletions
diff --git a/projecttemplates/RelyingPartyLogic/Model.Client.cs b/projecttemplates/RelyingPartyLogic/Model.Client.cs
index 9426408..3b3bce5 100644
--- a/projecttemplates/RelyingPartyLogic/Model.Client.cs
+++ b/projecttemplates/RelyingPartyLogic/Model.Client.cs
@@ -6,13 +6,30 @@
namespace RelyingPartyLogic {
using System;
+ using System.Collections.Generic;
using DotNetOpenAuth.OAuth2;
public partial class Client : IConsumerDescription {
- public Uri Callback {
- get { return this.CallbackAsString != null ? new Uri(this.CallbackAsString) : null; }
- set { this.CallbackAsString = value != null ? value.AbsoluteUri : null; }
+ /// <summary>
+ /// Gets the allowed callback URIs that this client has pre-registered with the service provider, if any.
+ /// </summary>
+ /// <value>
+ /// The URIs that user authorization responses may be directed to; must not be <c>null</c>, but may be empty.
+ /// </value>
+ /// <remarks>
+ /// The first element in this list (if any) will be used as the default client redirect URL if the client sends an authorization request without a redirect URL.
+ /// If the list is empty, any callback is allowed for this client.
+ /// </remarks>
+ public List<Uri> AllowedCallbacks {
+ get {
+ var result = new List<Uri>();
+ if (this.CallbackAsString != null) {
+ result.Add(new Uri(this.CallbackAsString));
+ }
+
+ return result;
+ }
}
#region IConsumerDescription Members
diff --git a/samples/OAuthConsumer/SampleWcf2.aspx.cs b/samples/OAuthConsumer/SampleWcf2.aspx.cs
index 55154bc..68965be 100644
--- a/samples/OAuthConsumer/SampleWcf2.aspx.cs
+++ b/samples/OAuthConsumer/SampleWcf2.aspx.cs
@@ -21,6 +21,21 @@
private static readonly WebServerClient Client;
/// <summary>
+ /// The details about the sample OAuth-enabled WCF service that this sample client calls into.
+ /// </summary>
+ private static AuthorizationServerDescription authServerDescription = new AuthorizationServerDescription {
+ TokenEndpoint = new Uri("http://localhost:65169/OAuth.ashx"),
+ AuthorizationEndpoint = new Uri("http://localhost:65169/Members/Authorize.aspx"),
+ };
+
+ /// <summary>
+ /// Initializes static members of the <see cref="SampleWcf2"/> class.
+ /// </summary>
+ static SampleWcf2() {
+ Client = new WebServerClient(authServerDescription, "sampleconsumer", "samplesecret");
+ }
+
+ /// <summary>
/// Gets or sets the authorization details for the logged in user.
/// </summary>
/// <value>The authorization details.</value>
@@ -33,21 +48,6 @@
set { HttpContext.Current.Session["Authorization"] = value; }
}
- /// <summary>
- /// Initializes static members of the <see cref="SampleWcf2"/> class.
- /// </summary>
- static SampleWcf2() {
- Client = new WebServerClient(AuthServerDescription, "sampleconsumer", "samplesecret");
- }
-
- /// <summary>
- /// The details about the sample OAuth-enabled WCF service that this sample client calls into.
- /// </summary>
- private static AuthorizationServerDescription AuthServerDescription = new AuthorizationServerDescription {
- TokenEndpoint = new Uri("http://localhost:65169/OAuth.ashx"),
- AuthorizationEndpoint = new Uri("http://localhost:65169/Members/Authorize.aspx"),
- };
-
protected void Page_Load(object sender, EventArgs e) {
if (!IsPostBack) {
// Check to see if we're receiving a end user authorization response.
diff --git a/samples/OAuthConsumerWpf/Authorize2.xaml.cs b/samples/OAuthConsumerWpf/Authorize2.xaml.cs
index d303145..1480cd4 100644
--- a/samples/OAuthConsumerWpf/Authorize2.xaml.cs
+++ b/samples/OAuthConsumerWpf/Authorize2.xaml.cs
@@ -26,7 +26,7 @@
Contract.Requires(client != null, "client");
Contract.Requires(authorizationState != null, "authorizationState");
- InitializeComponent();
+ this.InitializeComponent();
this.client = client;
this.Authorization = authorizationState;
@@ -47,11 +47,11 @@
}
private void locationChanged(Uri location) {
- //if (location.Scheme == "res") {
- // this.DialogResult = false;
- // this.Close();
- // MessageBox.Show("An error occurred during authorization.");
- //}
+ ////if (location.Scheme == "res") {
+ //// this.DialogResult = false;
+ //// this.Close();
+ //// MessageBox.Show("An error occurred during authorization.");
+ ////}
if (SignificantlyEqual(location, this.Authorization.Callback, UriComponents.SchemeAndServer | UriComponents.Path)) {
try {
@@ -70,7 +70,7 @@
}
private void webBrowser_LocationChanged(object sender, EventArgs e) {
- this.locationChanged(webBrowser.Url);
+ this.locationChanged(this.webBrowser.Url);
}
}
} \ No newline at end of file
diff --git a/samples/OAuthConsumerWpf/MainWindow.xaml.cs b/samples/OAuthConsumerWpf/MainWindow.xaml.cs
index b194777..7a1f703 100644
--- a/samples/OAuthConsumerWpf/MainWindow.xaml.cs
+++ b/samples/OAuthConsumerWpf/MainWindow.xaml.cs
@@ -196,34 +196,34 @@
private void oauth2BeginButton_Click(object sender, RoutedEventArgs e) {
var authServer = new DotNetOpenAuth.OAuth2.AuthorizationServerDescription {
- AuthorizationEndpoint = new Uri(oauth2AuthorizationUrlBox.Text),
+ AuthorizationEndpoint = new Uri(this.oauth2AuthorizationUrlBox.Text),
};
- if (oauth2TokenEndpointBox.Text.Length > 0) {
- authServer.TokenEndpoint = new Uri(oauth2TokenEndpointBox.Text);
+ if (this.oauth2TokenEndpointBox.Text.Length > 0) {
+ authServer.TokenEndpoint = new Uri(this.oauth2TokenEndpointBox.Text);
}
try {
- var client = new OAuth2.UserAgentClient(authServer, oauth2ClientIdentifierBox.Text, oauth2ClientSecretBox.Text);
+ var client = new OAuth2.UserAgentClient(authServer, this.oauth2ClientIdentifierBox.Text, this.oauth2ClientSecretBox.Text);
- var authorization = new AuthorizationState(OAuthUtilities.SplitScopes(oauth2ScopeBox.Text));
+ var authorization = new AuthorizationState(OAuthUtilities.SplitScopes(this.oauth2ScopeBox.Text));
var authorizePopup = new Authorize2(client, authorization);
authorizePopup.Owner = this;
bool? result = authorizePopup.ShowDialog();
if (result.HasValue && result.Value) {
- var requestUri = new UriBuilder(oauth2ResourceUrlBox.Text);
- if (oauth2ResourceHttpMethodList.SelectedIndex > 0) {
+ var requestUri = new UriBuilder(this.oauth2ResourceUrlBox.Text);
+ if (this.oauth2ResourceHttpMethodList.SelectedIndex > 0) {
requestUri.AppendQueryArgument("access_token", authorization.AccessToken);
}
var request = (HttpWebRequest)WebRequest.Create(requestUri.Uri);
- request.Method = oauth2ResourceHttpMethodList.SelectedIndex < 2 ? "GET" : "POST";
- if (oauth2ResourceHttpMethodList.SelectedIndex == 0) {
+ request.Method = this.oauth2ResourceHttpMethodList.SelectedIndex < 2 ? "GET" : "POST";
+ if (this.oauth2ResourceHttpMethodList.SelectedIndex == 0) {
client.AuthorizeRequest(request, authorization);
}
using (var resourceResponse = request.GetResponse()) {
using (var responseStream = new StreamReader(resourceResponse.GetResponseStream())) {
- oauth2ResultsBox.Text = responseStream.ReadToEnd();
+ this.oauth2ResultsBox.Text = responseStream.ReadToEnd();
}
}
} else {
diff --git a/samples/OAuthServiceProvider/Code/Client.cs b/samples/OAuthServiceProvider/Code/Client.cs
index 43e282d..bb4007e 100644
--- a/samples/OAuthServiceProvider/Code/Client.cs
+++ b/samples/OAuthServiceProvider/Code/Client.cs
@@ -14,12 +14,25 @@ namespace OAuthServiceProvider.Code {
public partial class Client : IConsumerDescription {
#region IConsumerDescription Members
+ /// <summary>
+ /// Gets the client secret.
+ /// </summary>
string IConsumerDescription.Secret {
get { return this.ClientSecret; }
}
- Uri IConsumerDescription.Callback {
- get { return string.IsNullOrEmpty(this.Callback) ? null : new Uri(this.Callback); }
+ /// <summary>
+ /// Gets the allowed callback URIs that this client has pre-registered with the service provider, if any.
+ /// </summary>
+ /// <value>
+ /// The URIs that user authorization responses may be directed to; must not be <c>null</c>, but may be empty.
+ /// </value>
+ /// <remarks>
+ /// The first element in this list (if any) will be used as the default client redirect URL if the client sends an authorization request without a redirect URL.
+ /// If the list is empty, any callback is allowed for this client.
+ /// </remarks>
+ List<Uri> IConsumerDescription.AllowedCallbacks {
+ get { return string.IsNullOrEmpty(this.Callback) ? new List<Uri>() : new List<Uri>(new Uri[] { new Uri(this.Callback) }); }
}
#endregion
diff --git a/samples/OAuthServiceProvider/Members/Authorize.aspx.cs b/samples/OAuthServiceProvider/Members/Authorize.aspx.cs
index 48a7897..4cb266f 100644
--- a/samples/OAuthServiceProvider/Members/Authorize.aspx.cs
+++ b/samples/OAuthServiceProvider/Members/Authorize.aspx.cs
@@ -16,15 +16,15 @@
public partial class Authorize2 : System.Web.UI.Page {
private static readonly RandomNumberGenerator CryptoRandomDataGenerator = new RNGCryptoServiceProvider();
+ private EndUserAuthorizationRequest pendingRequest;
+
+ private Client client;
+
private string AuthorizationSecret {
get { return Session["OAuthAuthorizationSecret"] as string; }
set { Session["OAuthAuthorizationSecret"] = value; }
}
- private EndUserAuthorizationRequest pendingRequest;
-
- private Client client;
-
protected void Page_Load(object sender, EventArgs e) {
var getRequest = new HttpRequestInfo("GET", this.Request.Url, this.Request.RawUrl, new WebHeaderCollection(), null);
this.pendingRequest = Global.AuthorizationServer.ReadAuthorizationRequest(getRequest);
diff --git a/src/DotNetOpenAuth.Test/OAuth2/MessageFactoryTests.cs b/src/DotNetOpenAuth.Test/OAuth2/MessageFactoryTests.cs
index 2514f68..0e82154 100644
--- a/src/DotNetOpenAuth.Test/OAuth2/MessageFactoryTests.cs
+++ b/src/DotNetOpenAuth.Test/OAuth2/MessageFactoryTests.cs
@@ -105,7 +105,7 @@ namespace DotNetOpenAuth.Test.OAuth2 {
{ Protocol.client_secret, "abc" },
{ Protocol.grant_type, "basic-credentials" },
{ Protocol.username, "abc" },
- { Protocol.password , "abc" },
+ { Protocol.password, "abc" },
};
IDirectedProtocolMessage request = this.messageFactory.GetNewRequestMessage(this.recipient, fields);
Assert.IsInstanceOf(typeof(AccessTokenResourceOwnerPasswordCredentialsRequest), request);
diff --git a/src/DotNetOpenAuth.Test/OAuth2/OAuth2ChannelTests.cs b/src/DotNetOpenAuth.Test/OAuth2/OAuth2ChannelTests.cs
index 51d0656..c263eb6 100644
--- a/src/DotNetOpenAuth.Test/OAuth2/OAuth2ChannelTests.cs
+++ b/src/DotNetOpenAuth.Test/OAuth2/OAuth2ChannelTests.cs
@@ -1,5 +1,5 @@
//-----------------------------------------------------------------------
-// <copyright file="OAuthWrapChannelTests.cs" company="Andrew Arnott">
+// <copyright file="OAuth2ChannelTests.cs" company="Andrew Arnott">
// Copyright (c) Andrew Arnott. All rights reserved.
// </copyright>
//-----------------------------------------------------------------------
diff --git a/src/DotNetOpenAuth.Test/OAuth2/OAuth2TestBase.cs b/src/DotNetOpenAuth.Test/OAuth2/OAuth2TestBase.cs
index fa1ed40..6c13c5e 100644
--- a/src/DotNetOpenAuth.Test/OAuth2/OAuth2TestBase.cs
+++ b/src/DotNetOpenAuth.Test/OAuth2/OAuth2TestBase.cs
@@ -1,5 +1,5 @@
//-----------------------------------------------------------------------
-// <copyright file="OAuthWrapTestBase.cs" company="Andrew Arnott">
+// <copyright file="OAuth2TestBase.cs" company="Andrew Arnott">
// Copyright (c) Andrew Arnott. All rights reserved.
// </copyright>
//-----------------------------------------------------------------------
diff --git a/src/DotNetOpenAuth/Messaging/MessagingUtilities.cs b/src/DotNetOpenAuth/Messaging/MessagingUtilities.cs
index 9dbd1b9..08c536a 100644
--- a/src/DotNetOpenAuth/Messaging/MessagingUtilities.cs
+++ b/src/DotNetOpenAuth/Messaging/MessagingUtilities.cs
@@ -935,7 +935,6 @@ namespace DotNetOpenAuth.Messaging {
/// Tests whether two arrays are equal in contents and ordering,
/// guaranteeing roughly equivalent execution time regardless of where a signature mismatch may exist.
/// </summary>
- /// <typeparam name="T">The type of elements in the arrays.</typeparam>
/// <param name="first">The first array in the comparison. May not be null.</param>
/// <param name="second">The second array in the comparison. May not be null.</param>
/// <returns>True if the arrays equal; false otherwise.</returns>
diff --git a/src/DotNetOpenAuth/OAuth2/AuthorizationServer.cs b/src/DotNetOpenAuth/OAuth2/AuthorizationServer.cs
index 9eefb9d..f98dc79 100644
--- a/src/DotNetOpenAuth/OAuth2/AuthorizationServer.cs
+++ b/src/DotNetOpenAuth/OAuth2/AuthorizationServer.cs
@@ -66,6 +66,13 @@ namespace DotNetOpenAuth.OAuth2 {
return message;
}
+ /// <summary>
+ /// Approves an authorization request and sends an HTTP response to the user agent to redirect the user back to the Client.
+ /// </summary>
+ /// <param name="authorizationRequest">The authorization request to approve.</param>
+ /// <param name="username">The username of the account that approved the request (or whose data will be accessed by the client).</param>
+ /// <param name="scopes">The scope of access the client should be granted. If <c>null</c>, all scopes in the original request will be granted.</param>
+ /// <param name="callback">The Client callback URL to use when formulating the redirect to send the user agent back to the Client.</param>
public void ApproveAuthorizationRequest(EndUserAuthorizationRequest authorizationRequest, string username, IEnumerable<string> scopes = null, Uri callback = null) {
Contract.Requires<ArgumentNullException>(authorizationRequest != null, "authorizationRequest");
@@ -74,6 +81,11 @@ namespace DotNetOpenAuth.OAuth2 {
this.Channel.Send(response);
}
+ /// <summary>
+ /// Rejects an authorization request and sends an HTTP response to the user agent to redirect the user back to the Client.
+ /// </summary>
+ /// <param name="authorizationRequest">The authorization request to disapprove.</param>
+ /// <param name="callback">The Client callback URL to use when formulating the redirect to send the user agent back to the Client.</param>
public void RejectAuthorizationRequest(EndUserAuthorizationRequest authorizationRequest, Uri callback = null) {
Contract.Requires<ArgumentNullException>(authorizationRequest != null, "authorizationRequest");
@@ -123,6 +135,14 @@ namespace DotNetOpenAuth.OAuth2 {
return response;
}
+ /// <summary>
+ /// Approves an authorization request.
+ /// </summary>
+ /// <param name="authorizationRequest">The authorization request to approve.</param>
+ /// <param name="username">The username of the account that approved the request (or whose data will be accessed by the client).</param>
+ /// <param name="scopes">The scope of access the client should be granted. If <c>null</c>, all scopes in the original request will be granted.</param>
+ /// <param name="callback">The Client callback URL to use when formulating the redirect to send the user agent back to the Client.</param>
+ /// <returns>The authorization response message to send to the Client.</returns>
public EndUserAuthorizationSuccessResponseBase PrepareApproveAuthorizationRequest(EndUserAuthorizationRequest authorizationRequest, string username, IEnumerable<string> scopes = null, Uri callback = null) {
Contract.Requires<ArgumentNullException>(authorizationRequest != null, "authorizationRequest");
Contract.Requires<ArgumentException>(!String.IsNullOrEmpty(username));
@@ -196,8 +216,8 @@ namespace DotNetOpenAuth.OAuth2 {
}
var client = this.AuthorizationServerServices.GetClient(authorizationRequest.ClientIdentifier);
- if (client.Callback != null) {
- return client.Callback;
+ if (client.AllowedCallbacks.Any()) {
+ return client.AllowedCallbacks.First();
}
throw ErrorUtilities.ThrowProtocol(OAuthStrings.NoCallback);
diff --git a/src/DotNetOpenAuth/OAuth2/ChannelElements/AuthServerAllFlowsBindingElement.cs b/src/DotNetOpenAuth/OAuth2/ChannelElements/AuthServerAllFlowsBindingElement.cs
index 1bf8c79..7e69ae1 100644
--- a/src/DotNetOpenAuth/OAuth2/ChannelElements/AuthServerAllFlowsBindingElement.cs
+++ b/src/DotNetOpenAuth/OAuth2/ChannelElements/AuthServerAllFlowsBindingElement.cs
@@ -71,8 +71,12 @@ namespace DotNetOpenAuth.OAuth2.ChannelElements {
var authorizationRequest = message as EndUserAuthorizationRequest;
if (authorizationRequest != null) {
var client = this.AuthorizationServer.GetClientOrThrow(authorizationRequest.ClientIdentifier);
- ErrorUtilities.VerifyProtocol(client.Callback == null || client.Callback == authorizationRequest.Callback, OAuthStrings.CallbackMismatch, client.Callback, authorizationRequest.Callback);
- ErrorUtilities.VerifyProtocol(client.Callback != null || authorizationRequest.Callback != null, OAuthStrings.NoCallback);
+ ErrorUtilities.VerifyProtocol(
+ !client.AllowedCallbacks.Any() || client.AllowedCallbacks.Contains(authorizationRequest.Callback),
+ OAuthStrings.CallbackMismatch,
+ String.Join(" ", client.AllowedCallbacks.Select(v => v.AbsoluteUri).ToArray()),
+ authorizationRequest.Callback);
+ ErrorUtilities.VerifyProtocol(client.AllowedCallbacks.Any() || authorizationRequest.Callback != null, OAuthStrings.NoCallback);
return MessageProtections.None;
}
diff --git a/src/DotNetOpenAuth/OAuth2/IConsumerDescription.cs b/src/DotNetOpenAuth/OAuth2/IConsumerDescription.cs
index 4e2bc4f..f37bc9f 100644
--- a/src/DotNetOpenAuth/OAuth2/IConsumerDescription.cs
+++ b/src/DotNetOpenAuth/OAuth2/IConsumerDescription.cs
@@ -6,10 +6,13 @@
namespace DotNetOpenAuth.OAuth2 {
using System;
+ using System.Collections.Generic;
+ using System.Diagnostics.Contracts;
/// <summary>
/// A description of a client from an Authorization Server's point of view.
/// </summary>
+ [ContractClass(typeof(IConsumerDescriptionContract))]
public interface IConsumerDescription {
/// <summary>
/// Gets the client secret.
@@ -17,9 +20,49 @@ namespace DotNetOpenAuth.OAuth2 {
string Secret { get; }
/// <summary>
- /// Gets the callback URI that this client has pre-registered with the service provider, if any.
+ /// Gets the allowed callback URIs that this client has pre-registered with the service provider, if any.
/// </summary>
- /// <value>A URI that user authorization responses should be directed to; or <c>null</c> if no preregistered callback was arranged.</value>
- Uri Callback { get; }
+ /// <value>The URIs that user authorization responses may be directed to; must not be <c>null</c>, but may be empty.</value>
+ /// <remarks>
+ /// The first element in this list (if any) will be used as the default client redirect URL if the client sends an authorization request without a redirect URL.
+ /// If the list is empty, any callback is allowed for this client.
+ /// </remarks>
+ List<Uri> AllowedCallbacks { get; }
+ }
+
+ /// <summary>
+ /// Contract class for the <see cref="IConsumerDescription"/> interface.
+ /// </summary>
+ [ContractClassFor(typeof(IConsumerDescription))]
+ internal abstract class IConsumerDescriptionContract : IConsumerDescription {
+ #region IConsumerDescription Members
+
+ /// <summary>
+ /// Gets the client secret.
+ /// </summary>
+ /// <value></value>
+ string IConsumerDescription.Secret {
+ get { throw new NotImplementedException(); }
+ }
+
+ /// <summary>
+ /// Gets the allowed callback URIs that this client has pre-registered with the service provider, if any.
+ /// </summary>
+ /// <value>
+ /// The URIs that user authorization responses may be directed to; must not be <c>null</c>, but may be empty.
+ /// </value>
+ /// <remarks>
+ /// The first element in this list (if any) will be used as the default client redirect URL if the client sends an authorization request without a redirect URL.
+ /// If the list is empty, any callback is allowed for this client.
+ /// </remarks>
+ List<Uri> IConsumerDescription.AllowedCallbacks {
+ get {
+ Contract.Ensures(Contract.Result<List<Uri>>() != null);
+ Contract.Ensures(Contract.Result<List<Uri>>().TrueForAll(v => v != null && v.IsAbsoluteUri));
+ throw new NotImplementedException();
+ }
+ }
+
+ #endregion
}
}
diff --git a/src/DotNetOpenAuth/OAuth2/Messages/AccessTokenRefreshRequest.cs b/src/DotNetOpenAuth/OAuth2/Messages/AccessTokenRefreshRequest.cs
index f15f190..e325dd7 100644
--- a/src/DotNetOpenAuth/OAuth2/Messages/AccessTokenRefreshRequest.cs
+++ b/src/DotNetOpenAuth/OAuth2/Messages/AccessTokenRefreshRequest.cs
@@ -39,7 +39,6 @@ namespace DotNetOpenAuth.OAuth2.Messages {
get { return CodeOrTokenType.RefreshToken; }
}
-
/// <summary>
/// Gets or sets the verification code or refresh/access token.
/// </summary>
diff --git a/src/DotNetOpenAuth/OAuth2/Messages/EndUserAuthorizationFailedResponse.cs b/src/DotNetOpenAuth/OAuth2/Messages/EndUserAuthorizationFailedResponse.cs
index b125c67..14677f3 100644
--- a/src/DotNetOpenAuth/OAuth2/Messages/EndUserAuthorizationFailedResponse.cs
+++ b/src/DotNetOpenAuth/OAuth2/Messages/EndUserAuthorizationFailedResponse.cs
@@ -13,9 +13,12 @@ namespace DotNetOpenAuth.OAuth2.Messages {
using System.Text;
using DotNetOpenAuth.Messaging;
+ /// <summary>
+ /// The message that an Authorization Server responds to a Client with when the user denies a user authorization request.
+ /// </summary>
public class EndUserAuthorizationFailedResponse : MessageBase, IMessageWithClientState {
/// <summary>
- /// Initializes a new instance of the <see cref="EndUserAuthorizationSuccessResponseBase"/> class.
+ /// Initializes a new instance of the <see cref="EndUserAuthorizationFailedResponse"/> class.
/// </summary>
/// <param name="clientCallback">The URL to redirect to so the client receives the message. This may not be built into the request message if the client pre-registered the URL with the authorization server.</param>
/// <param name="version">The protocol version.</param>
diff --git a/src/DotNetOpenAuth/OAuth2/OAuthStrings.Designer.cs b/src/DotNetOpenAuth/OAuth2/OAuthStrings.Designer.cs
index f4a74cc..7b2c3c2 100644
--- a/src/DotNetOpenAuth/OAuth2/OAuthStrings.Designer.cs
+++ b/src/DotNetOpenAuth/OAuth2/OAuthStrings.Designer.cs
@@ -70,7 +70,7 @@ namespace DotNetOpenAuth.OAuth2 {
}
/// <summary>
- /// Looks up a localized string similar to Client&apos;s pre-registered callback URL ({0}) does not match the one found in the authorization request ({1})..
+ /// Looks up a localized string similar to None of the client&apos;s pre-registered callback URLs ({0}) match the one found in the authorization request ({1})..
/// </summary>
internal static string CallbackMismatch {
get {
diff --git a/src/DotNetOpenAuth/OAuth2/OAuthStrings.resx b/src/DotNetOpenAuth/OAuth2/OAuthStrings.resx
index dacd9fc..c5b2cdc 100644
--- a/src/DotNetOpenAuth/OAuth2/OAuthStrings.resx
+++ b/src/DotNetOpenAuth/OAuth2/OAuthStrings.resx
@@ -121,7 +121,7 @@
<value>The requested access scope ("{0}") exceeds the grant scope ("{1}").</value>
</data>
<data name="CallbackMismatch" xml:space="preserve">
- <value>Client's pre-registered callback URL ({0}) does not match the one found in the authorization request ({1}).</value>
+ <value>None of the client's pre-registered callback URLs ({0}) match the one found in the authorization request ({1}).</value>
</data>
<data name="CannotObtainAccessTokenWithReason" xml:space="preserve">
<value>Failed to obtain access token. Authorization Server reports reason: {0}</value>
diff --git a/src/DotNetOpenAuth/OAuth2/OAuthUtilities.cs b/src/DotNetOpenAuth/OAuth2/OAuthUtilities.cs
index 79ef278..64a6d0c 100644
--- a/src/DotNetOpenAuth/OAuth2/OAuthUtilities.cs
+++ b/src/DotNetOpenAuth/OAuth2/OAuthUtilities.cs
@@ -18,6 +18,9 @@ namespace DotNetOpenAuth.OAuth2 {
/// Some common utility methods for OAuth 2.0.
/// </summary>
public static class OAuthUtilities {
+ /// <summary>
+ /// The <see cref="StringComparer"/> instance to use when comparing scope equivalence.
+ /// </summary>
public static readonly StringComparer ScopeStringComparer = StringComparer.Ordinal;
/// <summary>
@@ -62,10 +65,8 @@ namespace DotNetOpenAuth.OAuth2 {
/// <summary>
/// Identifies individual scope elements
/// </summary>
- /// <param name="scope">The scope.</param>
- /// <param name="scopeComparer">The scope comparer, allowing scopes to be case sensitive or insensitive.
- /// Usually <see cref="StringComparer.Ordinal"/> or <see cref="StringComparer.OrdinalIgnoreCase"/>.</param>
- /// <returns></returns>
+ /// <param name="scope">The space-delimited list of scopes.</param>
+ /// <returns>A set of individual scopes, with any duplicates removed.</returns>
public static HashSet<string> SplitScopes(string scope) {
if (string.IsNullOrEmpty(scope)) {
return new HashSet<string>();
@@ -74,6 +75,11 @@ namespace DotNetOpenAuth.OAuth2 {
return new HashSet<string>(scope.Split(scopeDelimiter, StringSplitOptions.RemoveEmptyEntries), ScopeStringComparer);
}
+ /// <summary>
+ /// Serializes a set of scopes as a space-delimited list.
+ /// </summary>
+ /// <param name="scopes">The scopes to serialize.</param>
+ /// <returns>A space-delimited list.</returns>
public static string JoinScopes(HashSet<string> scopes) {
Contract.Requires<ArgumentNullException>(scopes != null, "scopes");
return string.Join(" ", scopes.ToArray());
diff --git a/src/DotNetOpenAuth/OAuth2/WebServerClient.cs b/src/DotNetOpenAuth/OAuth2/WebServerClient.cs
index 0998619..d50ab8f 100644
--- a/src/DotNetOpenAuth/OAuth2/WebServerClient.cs
+++ b/src/DotNetOpenAuth/OAuth2/WebServerClient.cs
@@ -40,7 +40,6 @@ namespace DotNetOpenAuth.OAuth2 {
/// </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>
- /// <returns>The authorization request as an HTTP response that causes a redirect.</returns>
public void RequestUserAuthorization(IEnumerable<string> scope = null, string state = null) {
this.PrepareRequestUserAuthorization(scope, state).Send();
}