summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/ChannelElements/MessageValidationBindingElement.cs6
-rw-r--r--src/DotNetOpenAuth.OAuth2.Client/OAuth2/ClientBase.cs2
-rw-r--r--src/DotNetOpenAuth.OAuth2.ClientAuthorization/OAuth2/Messages/AccessTokenRequestBase.cs17
-rw-r--r--src/DotNetOpenAuth.OAuth2.ClientAuthorization/OAuth2/Messages/AccessTokenResourceOwnerPasswordCredentialsRequest.cs14
-rw-r--r--src/DotNetOpenAuth.OAuth2.ClientAuthorization/OAuth2/Messages/EndUserAuthorizationImplicitRequest.cs17
-rw-r--r--src/DotNetOpenAuth.OAuth2.ClientAuthorization/OAuth2/Messages/IAccessTokenRequest.cs6
-rw-r--r--src/DotNetOpenAuth.Test/OAuth2/AuthorizationServerTests.cs94
7 files changed, 150 insertions, 6 deletions
diff --git a/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/ChannelElements/MessageValidationBindingElement.cs b/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/ChannelElements/MessageValidationBindingElement.cs
index 3eac5a6..500b91d 100644
--- a/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/ChannelElements/MessageValidationBindingElement.cs
+++ b/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/ChannelElements/MessageValidationBindingElement.cs
@@ -122,15 +122,15 @@ namespace DotNetOpenAuth.OAuth2.ChannelElements {
try {
var authorizeResult =
this.AuthorizationServer.CheckAuthorizeResourceOwnerCredentialGrant(
- resourceOwnerPasswordCarrier.UserName, resourceOwnerPasswordCarrier.Password, resourceOwnerPasswordCarrier);
+ resourceOwnerPasswordCarrier.RequestingUserName, resourceOwnerPasswordCarrier.Password, resourceOwnerPasswordCarrier);
if (authorizeResult.IsApproved) {
resourceOwnerPasswordCarrier.CredentialsValidated = true;
- resourceOwnerPasswordCarrier.UserName = authorizeResult.CanonicalUserName;
+ resourceOwnerPasswordCarrier.RequestingUserName = authorizeResult.CanonicalUserName;
resourceOwnerPasswordCarrier.Scope.ResetContents(authorizeResult.ApprovedScope);
} else {
Logger.OAuth.ErrorFormat(
"Resource owner password credential for user \"{0}\" rejected by authorization server host.",
- resourceOwnerPasswordCarrier.UserName);
+ resourceOwnerPasswordCarrier.RequestingUserName);
throw new TokenEndpointProtocolException(accessTokenRequest, Protocol.AccessTokenRequestErrorCodes.InvalidGrant, AuthServerStrings.InvalidResourceOwnerPasswordCredential);
}
} catch (NotSupportedException) {
diff --git a/src/DotNetOpenAuth.OAuth2.Client/OAuth2/ClientBase.cs b/src/DotNetOpenAuth.OAuth2.Client/OAuth2/ClientBase.cs
index e17a6a1..e9c952d 100644
--- a/src/DotNetOpenAuth.OAuth2.Client/OAuth2/ClientBase.cs
+++ b/src/DotNetOpenAuth.OAuth2.Client/OAuth2/ClientBase.cs
@@ -251,7 +251,7 @@ namespace DotNetOpenAuth.OAuth2 {
Requires.NotNull(password, "password");
var request = new AccessTokenResourceOwnerPasswordCredentialsRequest(this.AuthorizationServer.TokenEndpoint, this.AuthorizationServer.Version) {
- UserName = userName,
+ RequestingUserName = userName,
Password = password,
};
diff --git a/src/DotNetOpenAuth.OAuth2.ClientAuthorization/OAuth2/Messages/AccessTokenRequestBase.cs b/src/DotNetOpenAuth.OAuth2.ClientAuthorization/OAuth2/Messages/AccessTokenRequestBase.cs
index 9ab6837..e405a85 100644
--- a/src/DotNetOpenAuth.OAuth2.ClientAuthorization/OAuth2/Messages/AccessTokenRequestBase.cs
+++ b/src/DotNetOpenAuth.OAuth2.ClientAuthorization/OAuth2/Messages/AccessTokenRequestBase.cs
@@ -48,6 +48,23 @@ namespace DotNetOpenAuth.OAuth2.Messages {
IAccessTokenResult IAccessTokenRequestInternal.AccessTokenResult { get; set; }
/// <summary>
+ /// Gets the username of the authorizing user, when applicable.
+ /// </summary>
+ /// <value>
+ /// A non-empty string; or <c>null</c> when no user has authorized this access token.
+ /// </value>
+ public virtual string UserName {
+ get {
+ IAccessTokenRequestInternal request = this;
+ if (request.AccessTokenResult != null && request.AccessTokenResult.AccessToken != null) {
+ return request.AccessTokenResult.AccessToken.User;
+ }
+
+ return null;
+ }
+ }
+
+ /// <summary>
/// Gets the type of the grant.
/// </summary>
/// <value>The type of the grant.</value>
diff --git a/src/DotNetOpenAuth.OAuth2.ClientAuthorization/OAuth2/Messages/AccessTokenResourceOwnerPasswordCredentialsRequest.cs b/src/DotNetOpenAuth.OAuth2.ClientAuthorization/OAuth2/Messages/AccessTokenResourceOwnerPasswordCredentialsRequest.cs
index 52e65be..02859e1 100644
--- a/src/DotNetOpenAuth.OAuth2.ClientAuthorization/OAuth2/Messages/AccessTokenResourceOwnerPasswordCredentialsRequest.cs
+++ b/src/DotNetOpenAuth.OAuth2.ClientAuthorization/OAuth2/Messages/AccessTokenResourceOwnerPasswordCredentialsRequest.cs
@@ -51,7 +51,7 @@ namespace DotNetOpenAuth.OAuth2.Messages {
/// Gets the name on the account whose data on the resource server is accessible using this authorization.
/// </summary>
string IAuthorizationDescription.User {
- get { return this.UserName; }
+ get { return this.RequestingUserName; }
}
/// <summary>
@@ -64,6 +64,16 @@ namespace DotNetOpenAuth.OAuth2.Messages {
#endregion
/// <summary>
+ /// Gets the username of the authorizing user, when applicable.
+ /// </summary>
+ /// <value>
+ /// A non-empty string; or <c>null</c> when no user has authorized this access token.
+ /// </value>
+ public override string UserName {
+ get { return base.UserName ?? this.RequestingUserName; }
+ }
+
+ /// <summary>
/// Gets the type of the grant.
/// </summary>
/// <value>The type of the grant.</value>
@@ -76,7 +86,7 @@ namespace DotNetOpenAuth.OAuth2.Messages {
/// </summary>
/// <value>The username on the user's account.</value>
[MessagePart(Protocol.username, IsRequired = true)]
- internal string UserName { get; set; }
+ internal string RequestingUserName { get; set; }
/// <summary>
/// Gets or sets the user's password.
diff --git a/src/DotNetOpenAuth.OAuth2.ClientAuthorization/OAuth2/Messages/EndUserAuthorizationImplicitRequest.cs b/src/DotNetOpenAuth.OAuth2.ClientAuthorization/OAuth2/Messages/EndUserAuthorizationImplicitRequest.cs
index 8932cd3..6f7ba7d 100644
--- a/src/DotNetOpenAuth.OAuth2.ClientAuthorization/OAuth2/Messages/EndUserAuthorizationImplicitRequest.cs
+++ b/src/DotNetOpenAuth.OAuth2.ClientAuthorization/OAuth2/Messages/EndUserAuthorizationImplicitRequest.cs
@@ -48,6 +48,23 @@ namespace DotNetOpenAuth.OAuth2.Messages {
IAccessTokenResult IAccessTokenRequestInternal.AccessTokenResult { get; set; }
/// <summary>
+ /// Gets the username of the authorizing user, when applicable.
+ /// </summary>
+ /// <value>
+ /// A non-empty string; or <c>null</c> when no user has authorized this access token.
+ /// </value>
+ string IAccessTokenRequest.UserName {
+ get {
+ IAccessTokenRequestInternal request = this;
+ if (request.AccessTokenResult != null && request.AccessTokenResult.AccessToken != null) {
+ return request.AccessTokenResult.AccessToken.User;
+ }
+
+ return null;
+ }
+ }
+
+ /// <summary>
/// Gets a value indicating whether the client requesting the access token has authenticated itself.
/// </summary>
/// <value>
diff --git a/src/DotNetOpenAuth.OAuth2.ClientAuthorization/OAuth2/Messages/IAccessTokenRequest.cs b/src/DotNetOpenAuth.OAuth2.ClientAuthorization/OAuth2/Messages/IAccessTokenRequest.cs
index 65378f9..81acb77 100644
--- a/src/DotNetOpenAuth.OAuth2.ClientAuthorization/OAuth2/Messages/IAccessTokenRequest.cs
+++ b/src/DotNetOpenAuth.OAuth2.ClientAuthorization/OAuth2/Messages/IAccessTokenRequest.cs
@@ -30,6 +30,12 @@ namespace DotNetOpenAuth.OAuth2.Messages {
string ClientIdentifier { get; }
/// <summary>
+ /// Gets the username of the authorizing user, when applicable.
+ /// </summary>
+ /// <value>A non-empty string; or <c>null</c> when no user has authorized this access token.</value>
+ string UserName { get; }
+
+ /// <summary>
/// Gets the scope of operations the client is allowed to invoke.
/// </summary>
HashSet<string> Scope { get; }
diff --git a/src/DotNetOpenAuth.Test/OAuth2/AuthorizationServerTests.cs b/src/DotNetOpenAuth.Test/OAuth2/AuthorizationServerTests.cs
index 3dc3839..e1af8a5 100644
--- a/src/DotNetOpenAuth.Test/OAuth2/AuthorizationServerTests.cs
+++ b/src/DotNetOpenAuth.Test/OAuth2/AuthorizationServerTests.cs
@@ -11,6 +11,7 @@ namespace DotNetOpenAuth.Test.OAuth2 {
using System.Text;
using System.Threading.Tasks;
using DotNetOpenAuth.OAuth2;
+ using DotNetOpenAuth.OAuth2.ChannelElements;
using DotNetOpenAuth.OAuth2.Messages;
using Moq;
using NUnit.Framework;
@@ -106,6 +107,99 @@ namespace DotNetOpenAuth.Test.OAuth2 {
}
[Test]
+ public void CreateAccessTokenSeesAuthorizingUserResourceOwnerGrant() {
+ var authServerMock = CreateAuthorizationServerMock();
+ authServerMock
+ .Setup(a => a.CheckAuthorizeResourceOwnerCredentialGrant(ResourceOwnerUsername, ResourceOwnerPassword, It.IsAny<IAccessTokenRequest>()))
+ .Returns<string, string, IAccessTokenRequest>((un, pw, req) => {
+ var response = new AutomatedUserAuthorizationCheckResponse(req, true, ResourceOwnerUsername);
+ Assert.That(req.UserName, Is.EqualTo(ResourceOwnerUsername));
+ return response;
+ });
+ var coordinator = new OAuth2Coordinator<WebServerClient>(
+ AuthorizationServerDescription,
+ authServerMock.Object,
+ new WebServerClient(AuthorizationServerDescription),
+ client => {
+ var authState = new AuthorizationState(TestScopes) {
+ Callback = ClientCallback,
+ };
+ var result = client.ExchangeUserCredentialForToken(ResourceOwnerUsername, ResourceOwnerPassword, TestScopes);
+ Assert.That(result.AccessToken, Is.Not.Null);
+ },
+ server => {
+ server.HandleTokenRequest().Respond();
+ });
+ coordinator.Run();
+ }
+
+ [Test]
+ public void CreateAccessTokenSeesAuthorizingUserClientCredentialGrant() {
+ var authServerMock = CreateAuthorizationServerMock();
+ authServerMock
+ .Setup(a => a.CheckAuthorizeClientCredentialsGrant(It.IsAny<IAccessTokenRequest>()))
+ .Returns<IAccessTokenRequest>(req => {
+ Assert.That(req.UserName, Is.Null);
+ return new AutomatedAuthorizationCheckResponse(req, true);
+ });
+ var coordinator = new OAuth2Coordinator<WebServerClient>(
+ AuthorizationServerDescription,
+ authServerMock.Object,
+ new WebServerClient(AuthorizationServerDescription),
+ client => {
+ var authState = new AuthorizationState(TestScopes) {
+ Callback = ClientCallback,
+ };
+ var result = client.GetClientAccessToken(TestScopes);
+ Assert.That(result.AccessToken, Is.Not.Null);
+ },
+ server => {
+ server.HandleTokenRequest().Respond();
+ });
+ coordinator.Run();
+ }
+
+ [Test]
+ public void CreateAccessTokenSeesAuthorizingUserAuthorizationCodeGrant() {
+ var authServerMock = CreateAuthorizationServerMock();
+ authServerMock
+ .Setup(a => a.IsAuthorizationValid(It.IsAny<IAuthorizationDescription>()))
+ .Returns<IAuthorizationDescription>(req => {
+ Assert.That(req.User, Is.EqualTo(ResourceOwnerUsername));
+ return true;
+ });
+ var refreshTokenSource = new TaskCompletionSource<string>();
+ var coordinator = new OAuth2Coordinator<WebServerClient>(
+ AuthorizationServerDescription,
+ authServerMock.Object,
+ new WebServerClient(AuthorizationServerDescription),
+ client => {
+ try {
+ var authState = new AuthorizationState(TestScopes) {
+ Callback = ClientCallback,
+ };
+ client.PrepareRequestUserAuthorization(authState).Respond();
+ var result = client.ProcessUserAuthorization();
+ Assert.That(result.AccessToken, Is.Not.Null.And.Not.Empty);
+ Assert.That(result.RefreshToken, Is.Not.Null.And.Not.Empty);
+ refreshTokenSource.SetResult(result.RefreshToken);
+ } catch {
+ refreshTokenSource.TrySetCanceled();
+ }
+ },
+ server => {
+ var request = server.ReadAuthorizationRequest();
+ Assert.That(request, Is.Not.Null);
+ server.ApproveAuthorizationRequest(request, ResourceOwnerUsername);
+ server.HandleTokenRequest().Respond();
+ var authorization = server.DecodeRefreshToken(refreshTokenSource.Task.Result);
+ Assert.That(authorization, Is.Not.Null);
+ Assert.That(authorization.User, Is.EqualTo(ResourceOwnerUsername));
+ });
+ coordinator.Run();
+ }
+
+ [Test]
public void ClientCredentialScopeOverride() {
var clientRequestedScopes = new[] { "scope1", "scope2" };
var serverOverriddenScopes = new[] { "scope1", "differentScope" };