diff options
Diffstat (limited to 'src')
5 files changed, 44 insertions, 24 deletions
diff --git a/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/ChannelElements/MessageValidationBindingElement.cs b/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/ChannelElements/MessageValidationBindingElement.cs index 4821527..821e07a 100644 --- a/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/ChannelElements/MessageValidationBindingElement.cs +++ b/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/ChannelElements/MessageValidationBindingElement.cs @@ -8,6 +8,7 @@ namespace DotNetOpenAuth.OAuth2.ChannelElements { using System; using System.Collections.Generic; using System.Diagnostics.Contracts; + using System.Globalization; using System.Linq; using System.Text; using DotNetOpenAuth.OAuth2.Messages; @@ -94,22 +95,29 @@ namespace DotNetOpenAuth.OAuth2.ChannelElements { var clientCredentialOnly = message as AccessTokenClientCredentialsRequest; var authenticatedClientRequest = message as AuthenticatedClientRequestBase; var accessTokenRequest = authenticatedClientRequest as AccessTokenRequestBase; // currently the only type of message. + var resourceOwnerPasswordCarrier = message as AccessTokenResourceOwnerPasswordCredentialsRequest; if (authenticatedClientRequest != null) { string clientIdentifier; var result = this.clientAuthenticationModule.TryAuthenticateClient(this.AuthServerChannel.AuthorizationServer, authenticatedClientRequest, out clientIdentifier); - AuthServerUtilities.TokenEndpointVerify(result != ClientAuthenticationResult.ClientIdNotAuthenticated, accessTokenRequest, Protocol.AccessTokenRequestErrorCodes.UnauthorizedClient); // an empty secret is not allowed for client authenticated calls. - AuthServerUtilities.TokenEndpointVerify(result == ClientAuthenticationResult.ClientAuthenticated, accessTokenRequest, Protocol.AccessTokenRequestErrorCodes.InvalidClient, this.clientAuthenticationModule, AuthServerStrings.ClientSecretMismatch); - authenticatedClientRequest.ClientIdentifier = clientIdentifier; - - if (clientCredentialOnly != null) { - clientCredentialOnly.CredentialsValidated = true; + switch (result) { + case ClientAuthenticationResult.ClientAuthenticated: + break; + case ClientAuthenticationResult.NoAuthenticationRecognized: + case ClientAuthenticationResult.ClientIdNotAuthenticated: + // The only grant type that allows no client credentials is the resource owner credentials grant. + AuthServerUtilities.TokenEndpointVerify(resourceOwnerPasswordCarrier != null, accessTokenRequest, Protocol.AccessTokenRequestErrorCodes.InvalidClient, this.clientAuthenticationModule, AuthServerStrings.ClientSecretMismatch); + break; + default: + AuthServerUtilities.TokenEndpointVerify(false, accessTokenRequest, Protocol.AccessTokenRequestErrorCodes.InvalidClient, this.clientAuthenticationModule, AuthServerStrings.ClientSecretMismatch); + break; } + authenticatedClientRequest.ClientIdentifier = result == ClientAuthenticationResult.NoAuthenticationRecognized ? null : clientIdentifier; + accessTokenRequest.ClientAuthenticated = result == ClientAuthenticationResult.ClientAuthenticated; applied = true; } // Check that any resource owner password credential is correct. - var resourceOwnerPasswordCarrier = message as AccessTokenResourceOwnerPasswordCredentialsRequest; if (resourceOwnerPasswordCarrier != null) { try { string canonicalUserName; diff --git a/src/DotNetOpenAuth.OAuth2.Client/OAuth2/ClientCredentialApplicator.cs b/src/DotNetOpenAuth.OAuth2.Client/OAuth2/ClientCredentialApplicator.cs index 2a9a8a7..415c893 100644 --- a/src/DotNetOpenAuth.OAuth2.Client/OAuth2/ClientCredentialApplicator.cs +++ b/src/DotNetOpenAuth.OAuth2.Client/OAuth2/ClientCredentialApplicator.cs @@ -126,11 +126,13 @@ namespace DotNetOpenAuth.OAuth2 { /// <param name="clientIdentifier">The identifier by which the authorization server should recognize this client.</param> /// <param name="request">The outbound message to apply authentication information to.</param> public override void ApplyClientCredential(string clientIdentifier, HttpWebRequest request) { - if (this.credential != null && this.credential.UserName == clientIdentifier) { - ErrorUtilities.VerifyHost(false, "Client identifiers \"{0}\" and \"{1}\" do not match.", this.credential.UserName, clientIdentifier); - } + if (clientIdentifier != null) { + if (this.credential != null && this.credential.UserName == clientIdentifier) { + ErrorUtilities.VerifyHost(false, "Client identifiers \"{0}\" and \"{1}\" do not match.", this.credential.UserName, clientIdentifier); + } - request.Credentials = this.credential ?? new NetworkCredential(clientIdentifier, this.clientSecret); + request.Credentials = this.credential ?? new NetworkCredential(clientIdentifier, this.clientSecret); + } } } @@ -158,7 +160,9 @@ namespace DotNetOpenAuth.OAuth2 { /// <param name="clientIdentifier">The identifier by which the authorization server should recognize this client.</param> /// <param name="request">The outbound message to apply authentication information to.</param> public override void ApplyClientCredential(string clientIdentifier, AuthenticatedClientRequestBase request) { - request.ClientSecret = this.secret; + if (clientIdentifier != null) { + request.ClientSecret = this.secret; + } } } } diff --git a/src/DotNetOpenAuth.OAuth2.ClientAuthorization/OAuth2/Messages/AccessTokenClientCredentialsRequest.cs b/src/DotNetOpenAuth.OAuth2.ClientAuthorization/OAuth2/Messages/AccessTokenClientCredentialsRequest.cs index 48419eb..0eb9e7f 100644 --- a/src/DotNetOpenAuth.OAuth2.ClientAuthorization/OAuth2/Messages/AccessTokenClientCredentialsRequest.cs +++ b/src/DotNetOpenAuth.OAuth2.ClientAuthorization/OAuth2/Messages/AccessTokenClientCredentialsRequest.cs @@ -36,7 +36,7 @@ namespace DotNetOpenAuth.OAuth2.Messages { /// Gets the authorization that the code or token describes. /// </summary> IAuthorizationDescription IAuthorizationCarryingRequest.AuthorizationDescription { - get { return this.CredentialsValidated ? this : null; } + get { return this.ClientAuthenticated ? this : null; } } #endregion @@ -74,10 +74,5 @@ namespace DotNetOpenAuth.OAuth2.Messages { internal override GrantType GrantType { get { return Messages.GrantType.ClientCredentials; } } - - /// <summary> - /// Gets or sets a value indicating whether the resource owner's credentials have been validated at the authorization server. - /// </summary> - internal bool CredentialsValidated { get; set; } } } diff --git a/src/DotNetOpenAuth.OAuth2.ClientAuthorization/OAuth2/Messages/AccessTokenRequestBase.cs b/src/DotNetOpenAuth.OAuth2.ClientAuthorization/OAuth2/Messages/AccessTokenRequestBase.cs index b9f4c56..c2ab347 100644 --- a/src/DotNetOpenAuth.OAuth2.ClientAuthorization/OAuth2/Messages/AccessTokenRequestBase.cs +++ b/src/DotNetOpenAuth.OAuth2.ClientAuthorization/OAuth2/Messages/AccessTokenRequestBase.cs @@ -40,9 +40,7 @@ namespace DotNetOpenAuth.OAuth2.Messages { /// <value> /// Always true, because of our base class. /// </value> - bool IAccessTokenRequest.ClientAuthenticated { - get { return true; } - } + public bool ClientAuthenticated { get; internal set; } /// <summary> /// Gets or sets the access token creation parameters. diff --git a/src/DotNetOpenAuth.Test/OAuth2/WebServerClientAuthorizeTests.cs b/src/DotNetOpenAuth.Test/OAuth2/WebServerClientAuthorizeTests.cs index 6f46271..4e75d91 100644 --- a/src/DotNetOpenAuth.Test/OAuth2/WebServerClientAuthorizeTests.cs +++ b/src/DotNetOpenAuth.Test/OAuth2/WebServerClientAuthorizeTests.cs @@ -43,13 +43,28 @@ namespace DotNetOpenAuth.Test.OAuth2 { coordinator.Run(); } - [Test] - public void ResourceOwnerPasswordCredentialGrant() { + [Theory] + public void ResourceOwnerPasswordCredentialGrant(bool anonymousClient) { + var authHostMock = CreateAuthorizationServerMock(); + if (anonymousClient) { + authHostMock.Setup( + m => + m.IsAuthorizationValid( + It.Is<IAuthorizationDescription>( + d => + d.ClientIdentifier == null && d.User == ResourceOwnerUsername && + MessagingUtilities.AreEquivalent(d.Scope, TestScopes)))).Returns(true); + } + var coordinator = new OAuth2Coordinator<WebServerClient>( AuthorizationServerDescription, - AuthorizationServerMock, + authHostMock.Object, new WebServerClient(AuthorizationServerDescription), client => { + if (anonymousClient) { + client.ClientIdentifier = null; + } + var authState = client.ExchangeUserCredentialForToken(ResourceOwnerUsername, ResourceOwnerPassword, TestScopes); Assert.That(authState.AccessToken, Is.Not.Null.And.Not.Empty); Assert.That(authState.RefreshToken, Is.Not.Null.And.Not.Empty); |