diff options
11 files changed, 189 insertions, 65 deletions
diff --git a/projecttemplates/RelyingPartyLogic/OAuthAuthorizationServer.cs b/projecttemplates/RelyingPartyLogic/OAuthAuthorizationServer.cs index afc652b..f5b1186 100644 --- a/projecttemplates/RelyingPartyLogic/OAuthAuthorizationServer.cs +++ b/projecttemplates/RelyingPartyLogic/OAuthAuthorizationServer.cs @@ -119,46 +119,32 @@ namespace RelyingPartyLogic { /// <summary> /// Determines whether a given set of resource owner credentials is valid based on the authorization server's user database - /// and if so records an authorization entry such that subsequent calls to <see cref="IsAuthorizationValid"/> would + /// and if so records an authorization entry such that subsequent calls to <see cref="IsAuthorizationValid" /> would /// return <c>true</c>. /// </summary> /// <param name="userName">Username on the account.</param> /// <param name="password">The user's password.</param> - /// <param name="accessRequest"> - /// The access request the credentials came with. - /// This may be useful if the authorization server wishes to apply some policy based on the client that is making the request. - /// </param> - /// <param name="canonicalUserName"> - /// Receives the canonical username (normalized for the resource server) of the user, for valid credentials; - /// Or <c>null</c> if the return value is false. - /// </param> + /// <param name="accessRequest">The access request the credentials came with. + /// This may be useful if the authorization server wishes to apply some policy based on the client that is making the request.</param> /// <returns> - /// <c>true</c> if the given credentials are valid and the authorization granted; otherwise, <c>false</c>. + /// A value that describes the result of the authorization check. /// </returns> - /// <exception cref="NotSupportedException"> - /// May be thrown if the authorization server does not support the resource owner password credential grant type. - /// </exception> - public bool TryAuthorizeResourceOwnerCredentialGrant(string userName, string password, IAccessTokenRequest accessRequest, out string canonicalUserName) { + public AutomatedUserAuthorizationCheckResponse CheckAuthorizeResourceOwnerCredentialGrant(string userName, string password, IAccessTokenRequest accessRequest) { // This web site delegates user authentication to OpenID Providers, and as such no users have local passwords with this server. throw new NotSupportedException(); } /// <summary> /// Determines whether an access token request given a client credential grant should be authorized - /// and if so records an authorization entry such that subsequent calls to <see cref="IsAuthorizationValid"/> would + /// and if so records an authorization entry such that subsequent calls to <see cref="IsAuthorizationValid" /> would /// return <c>true</c>. /// </summary> - /// <param name="accessRequest"> - /// The access request the credentials came with. - /// This may be useful if the authorization server wishes to apply some policy based on the client that is making the request. - /// </param> + /// <param name="accessRequest">The access request the credentials came with. + /// This may be useful if the authorization server wishes to apply some policy based on the client that is making the request.</param> /// <returns> - /// <c>true</c> if the given credentials are valid and the authorization granted; otherwise, <c>false</c>. + /// A value that describes the result of the authorization check. /// </returns> - /// <exception cref="NotSupportedException"> - /// May be thrown if the authorization server does not support the client credential grant type. - /// </exception> - public bool TryAuthorizeClientCredentialsGrant(IAccessTokenRequest accessRequest) { + public AutomatedAuthorizationCheckResponse CheckAuthorizeClientCredentialsGrant(IAccessTokenRequest accessRequest) { throw new NotImplementedException(); } diff --git a/samples/OAuthAuthorizationServer/Code/OAuth2AuthorizationServer.cs b/samples/OAuthAuthorizationServer/Code/OAuth2AuthorizationServer.cs index eb7f1f5..6399112 100644 --- a/samples/OAuthAuthorizationServer/Code/OAuth2AuthorizationServer.cs +++ b/samples/OAuthAuthorizationServer/Code/OAuth2AuthorizationServer.cs @@ -78,12 +78,12 @@ return this.IsAuthorizationValid(authorization.Scope, authorization.ClientIdentifier, authorization.UtcIssued, authorization.User); } - public bool TryAuthorizeResourceOwnerCredentialGrant(string userName, string password, IAccessTokenRequest accessRequest, out string canonicalUserName) { + public AutomatedUserAuthorizationCheckResponse CheckAuthorizeResourceOwnerCredentialGrant(string userName, string password, IAccessTokenRequest accessRequest) { // This web site delegates user authentication to OpenID Providers, and as such no users have local passwords with this server. throw new NotSupportedException(); } - public bool TryAuthorizeClientCredentialsGrant(IAccessTokenRequest accessRequest) { + public AutomatedAuthorizationCheckResponse CheckAuthorizeClientCredentialsGrant(IAccessTokenRequest accessRequest) { throw new NotImplementedException(); } diff --git a/src/DotNetOpenAuth.OAuth2.AuthorizationServer/DotNetOpenAuth.OAuth2.AuthorizationServer.csproj b/src/DotNetOpenAuth.OAuth2.AuthorizationServer/DotNetOpenAuth.OAuth2.AuthorizationServer.csproj index bb782f0..73c563b 100644 --- a/src/DotNetOpenAuth.OAuth2.AuthorizationServer/DotNetOpenAuth.OAuth2.AuthorizationServer.csproj +++ b/src/DotNetOpenAuth.OAuth2.AuthorizationServer/DotNetOpenAuth.OAuth2.AuthorizationServer.csproj @@ -27,6 +27,8 @@ <DependentUpon>AuthServerStrings.resx</DependentUpon> </Compile> <Compile Include="OAuth2\AuthServerUtilities.cs" /> + <Compile Include="OAuth2\AutomatedAuthorizationCheckResponse.cs" /> + <Compile Include="OAuth2\AutomatedUserAuthorizationCheckResponse.cs" /> <Compile Include="OAuth2\ChannelElements\AggregatingClientCredentialReader.cs" /> <Compile Include="OAuth2\ChannelElements\ClientCredentialHttpBasicReader.cs" /> <Compile Include="OAuth2\ChannelElements\ClientCredentialMessagePartReader.cs" /> diff --git a/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/AutomatedAuthorizationCheckResponse.cs b/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/AutomatedAuthorizationCheckResponse.cs new file mode 100644 index 0000000..0179d05 --- /dev/null +++ b/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/AutomatedAuthorizationCheckResponse.cs @@ -0,0 +1,40 @@ +//----------------------------------------------------------------------- +// <copyright file="AutomatedAuthorizationCheckResponse.cs" company="Andrew Arnott"> +// Copyright (c) Andrew Arnott. All rights reserved. +// </copyright> +//----------------------------------------------------------------------- + +namespace DotNetOpenAuth.OAuth2 { + using System; + using System.Collections.Generic; + using System.Linq; + using System.Text; + using DotNetOpenAuth.OAuth2.Messages; + + /// <summary> + /// Describes the result of an automated authorization check, such as for client credential or resource owner password grants. + /// </summary> + public class AutomatedAuthorizationCheckResponse { + /// <summary> + /// Initializes a new instance of the <see cref="AutomatedAuthorizationCheckResponse" /> class. + /// </summary> + /// <param name="accessRequest">The access token request.</param> + /// <param name="approved">A value indicating whether the authorization should be approved.</param> + public AutomatedAuthorizationCheckResponse(IAccessTokenRequest accessRequest, bool approved) { + Requires.NotNull(accessRequest, "accessRequest"); + + this.IsApproved = approved; + this.ApprovedScope = new HashSet<string>(accessRequest.Scope); + } + + /// <summary> + /// Gets a value indicating whether the authorization should be approved. + /// </summary> + public bool IsApproved { get; private set; } + + /// <summary> + /// Gets the scope to be granted. + /// </summary> + public HashSet<string> ApprovedScope { get; private set; } + } +} diff --git a/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/AutomatedUserAuthorizationCheckResponse.cs b/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/AutomatedUserAuthorizationCheckResponse.cs new file mode 100644 index 0000000..b62807c --- /dev/null +++ b/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/AutomatedUserAuthorizationCheckResponse.cs @@ -0,0 +1,42 @@ +//----------------------------------------------------------------------- +// <copyright file="AutomatedUserAuthorizationCheckResponse.cs" company="Andrew Arnott"> +// Copyright (c) Andrew Arnott. All rights reserved. +// </copyright> +//----------------------------------------------------------------------- + +namespace DotNetOpenAuth.OAuth2 { + using System; + using System.Collections.Generic; + using System.Linq; + using System.Text; + + using DotNetOpenAuth.OAuth2.Messages; + + /// <summary> + /// Describes the result of an automated authorization check for resource owner grants. + /// </summary> + public class AutomatedUserAuthorizationCheckResponse : AutomatedAuthorizationCheckResponse { + /// <summary> + /// Initializes a new instance of the <see cref="AutomatedUserAuthorizationCheckResponse" /> class. + /// </summary> + /// <param name="accessRequest">The access token request.</param> + /// <param name="approved">A value indicating whether the authorization should be approved.</param> + /// <param name="canonicalUserName"> + /// Canonical username of the authorizing user (resource owner), as the resource server would recognize it. + /// Ignored if <paramref name="approved"/> is false. + /// </param> + public AutomatedUserAuthorizationCheckResponse(IAccessTokenRequest accessRequest, bool approved, string canonicalUserName) + : base(accessRequest, approved) { + if (approved) { + Requires.NotNullOrEmpty(canonicalUserName, "canonicalUserName"); + } + + this.CanonicalUserName = canonicalUserName; + } + + /// <summary> + /// Gets the canonical username of the authorizing user (resource owner). + /// </summary> + public string CanonicalUserName { get; private set; } + } +} diff --git a/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/ChannelElements/MessageValidationBindingElement.cs b/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/ChannelElements/MessageValidationBindingElement.cs index 27b71db..3eac5a6 100644 --- a/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/ChannelElements/MessageValidationBindingElement.cs +++ b/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/ChannelElements/MessageValidationBindingElement.cs @@ -120,11 +120,13 @@ namespace DotNetOpenAuth.OAuth2.ChannelElements { // Check that any resource owner password credential is correct. if (resourceOwnerPasswordCarrier != null) { try { - string canonicalUserName; - if (this.AuthorizationServer.TryAuthorizeResourceOwnerCredentialGrant(resourceOwnerPasswordCarrier.UserName, resourceOwnerPasswordCarrier.Password, resourceOwnerPasswordCarrier, out canonicalUserName)) { - ErrorUtilities.VerifyHost(!string.IsNullOrEmpty(canonicalUserName), "TryAuthorizeResourceOwnerCredentialGrant did not initialize out parameter."); + var authorizeResult = + this.AuthorizationServer.CheckAuthorizeResourceOwnerCredentialGrant( + resourceOwnerPasswordCarrier.UserName, resourceOwnerPasswordCarrier.Password, resourceOwnerPasswordCarrier); + if (authorizeResult.IsApproved) { resourceOwnerPasswordCarrier.CredentialsValidated = true; - resourceOwnerPasswordCarrier.UserName = canonicalUserName; + resourceOwnerPasswordCarrier.UserName = authorizeResult.CanonicalUserName; + resourceOwnerPasswordCarrier.Scope.ResetContents(authorizeResult.ApprovedScope); } else { Logger.OAuth.ErrorFormat( "Resource owner password credential for user \"{0}\" rejected by authorization server host.", @@ -140,12 +142,15 @@ namespace DotNetOpenAuth.OAuth2.ChannelElements { applied = true; } else if (clientCredentialOnly != null) { try { - if (!this.AuthorizationServer.TryAuthorizeClientCredentialsGrant(clientCredentialOnly)) { + var authorizeResult = this.AuthorizationServer.CheckAuthorizeClientCredentialsGrant(clientCredentialOnly); + if (!authorizeResult.IsApproved) { Logger.OAuth.ErrorFormat( "Client credentials grant access request for client \"{0}\" rejected by authorization server host.", clientCredentialOnly.ClientIdentifier); throw new TokenEndpointProtocolException(accessTokenRequest, Protocol.AccessTokenRequestErrorCodes.UnauthorizedClient); } + + clientCredentialOnly.Scope.ResetContents(authorizeResult.ApprovedScope); } catch (NotSupportedException) { throw new TokenEndpointProtocolException(accessTokenRequest, Protocol.AccessTokenRequestErrorCodes.UnsupportedGrantType); } catch (NotImplementedException) { diff --git a/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/IAuthorizationServerHost.cs b/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/IAuthorizationServerHost.cs index b75cb29..b9b5725 100644 --- a/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/IAuthorizationServerHost.cs +++ b/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/IAuthorizationServerHost.cs @@ -91,17 +91,11 @@ namespace DotNetOpenAuth.OAuth2 { /// The access request the credentials came with. /// This may be useful if the authorization server wishes to apply some policy based on the client that is making the request. /// </param> - /// <param name="canonicalUserName"> - /// Receives the canonical username (normalized for the resource server) of the user, for valid credentials; - /// Or <c>null</c> if the return value is false. - /// </param> - /// <returns> - /// <c>true</c> if the given credentials are valid and the authorization granted; otherwise, <c>false</c>. - /// </returns> + /// <returns>A value that describes the result of the authorization check.</returns> /// <exception cref="NotSupportedException"> /// May be thrown if the authorization server does not support the resource owner password credential grant type. /// </exception> - bool TryAuthorizeResourceOwnerCredentialGrant(string userName, string password, IAccessTokenRequest accessRequest, out string canonicalUserName); + AutomatedUserAuthorizationCheckResponse CheckAuthorizeResourceOwnerCredentialGrant(string userName, string password, IAccessTokenRequest accessRequest); /// <summary> /// Determines whether an access token request given a client credential grant should be authorized @@ -112,17 +106,15 @@ namespace DotNetOpenAuth.OAuth2 { /// The access request the credentials came with. /// This may be useful if the authorization server wishes to apply some policy based on the client that is making the request. /// </param> - /// <returns> - /// <c>true</c> if the given credentials are valid and the authorization granted; otherwise, <c>false</c>. - /// </returns> + /// <returns>A value that describes the result of the authorization check.</returns> /// <exception cref="NotSupportedException"> /// May be thrown if the authorization server does not support the client credential grant type. /// </exception> - bool TryAuthorizeClientCredentialsGrant(IAccessTokenRequest accessRequest); + AutomatedAuthorizationCheckResponse CheckAuthorizeClientCredentialsGrant(IAccessTokenRequest accessRequest); } /// <summary> - /// Code Contract for the <see cref="IAuthorizationServerHost"/> interface. + /// Code Contract for the <see cref="IAuthorizationServerHost" /> interface. /// </summary> [ContractClassFor(typeof(IAuthorizationServerHost))] internal abstract class IAuthorizationServerHostContract : IAuthorizationServerHost { @@ -203,40 +195,34 @@ namespace DotNetOpenAuth.OAuth2 { /// The access request the credentials came with. /// This may be useful if the authorization server wishes to apply some policy based on the client that is making the request. /// </param> - /// <param name="canonicalUserName"> - /// Receives the canonical username (normalized for the resource server) of the user, for valid credentials; - /// Or <c>null</c> if the return value is false. - /// </param> /// <returns> - /// <c>true</c> if the given credentials are valid and the authorization granted; otherwise, <c>false</c>. + /// A value that describes the result of the authorization check. /// </returns> /// <exception cref="NotSupportedException"> /// May be thrown if the authorization server does not support the resource owner password credential grant type. /// </exception> - bool IAuthorizationServerHost.TryAuthorizeResourceOwnerCredentialGrant(string userName, string password, IAccessTokenRequest accessRequest, out string canonicalUserName) { + AutomatedUserAuthorizationCheckResponse IAuthorizationServerHost.CheckAuthorizeResourceOwnerCredentialGrant(string userName, string password, IAccessTokenRequest accessRequest) { Contract.Requires(!string.IsNullOrEmpty(userName)); Contract.Requires(password != null); Contract.Requires(accessRequest != null); - Contract.Ensures(!Contract.Result<bool>() || !string.IsNullOrEmpty(Contract.ValueAtReturn<string>(out canonicalUserName))); + Contract.Ensures(Contract.Result<AutomatedUserAuthorizationCheckResponse>() != null); throw new NotImplementedException(); } /// <summary> /// Determines whether an access token request given a client credential grant should be authorized - /// and if so records an authorization entry such that subsequent calls to <see cref="IAuthorizationServerHost.IsAuthorizationValid"/> would + /// and if so records an authorization entry such that subsequent calls to <see cref="IAuthorizationServerHost.IsAuthorizationValid" /> would /// return <c>true</c>. /// </summary> - /// <param name="accessRequest"> - /// The access request the credentials came with. - /// This may be useful if the authorization server wishes to apply some policy based on the client that is making the request. - /// </param> + /// <param name="accessRequest">The access request the credentials came with. + /// This may be useful if the authorization server wishes to apply some policy based on the client that is making the request.</param> /// <returns> - /// <c>true</c> if the given credentials are valid and the authorization granted; otherwise, <c>false</c>. + /// A value that describes the result of the authorization check. /// </returns> - /// <exception cref="NotSupportedException"> - /// May be thrown if the authorization server does not support the client credential grant type. - /// </exception> - bool IAuthorizationServerHost.TryAuthorizeClientCredentialsGrant(IAccessTokenRequest accessRequest) { + /// <exception cref="NotSupportedException">May be thrown if the authorization server does not support the client credential grant type.</exception> + AutomatedAuthorizationCheckResponse IAuthorizationServerHost.CheckAuthorizeClientCredentialsGrant(IAccessTokenRequest accessRequest) { + Contract.Requires(accessRequest != null); + Contract.Ensures(Contract.Result<AutomatedAuthorizationCheckResponse>() != null); throw new NotImplementedException(); } diff --git a/src/DotNetOpenAuth.OAuth2.Client/OAuth2/ClientBase.cs b/src/DotNetOpenAuth.OAuth2.Client/OAuth2/ClientBase.cs index c983f8c..869afe8 100644 --- a/src/DotNetOpenAuth.OAuth2.Client/OAuth2/ClientBase.cs +++ b/src/DotNetOpenAuth.OAuth2.Client/OAuth2/ClientBase.cs @@ -372,6 +372,7 @@ namespace DotNetOpenAuth.OAuth2 { var failure = response as AccessTokenFailedResponse; ErrorUtilities.VerifyProtocol(success != null || failure != null, MessagingStrings.UnexpectedMessageReceivedOfMany); if (success != null) { + authorizationState.Scope.Clear(); // clear the scope we requested so that the response will repopulate it. UpdateAuthorizationWithResponse(authorizationState, success); } else { // failure Logger.OAuth.Info("Credentials rejected by the Authorization Server."); diff --git a/src/DotNetOpenAuth.Test/OAuth2/AuthorizationServerTests.cs b/src/DotNetOpenAuth.Test/OAuth2/AuthorizationServerTests.cs index 251cd67..3dc3839 100644 --- a/src/DotNetOpenAuth.Test/OAuth2/AuthorizationServerTests.cs +++ b/src/DotNetOpenAuth.Test/OAuth2/AuthorizationServerTests.cs @@ -12,6 +12,7 @@ namespace DotNetOpenAuth.Test.OAuth2 { using System.Threading.Tasks; using DotNetOpenAuth.OAuth2; using DotNetOpenAuth.OAuth2.Messages; + using Moq; using NUnit.Framework; /// <summary> @@ -73,5 +74,65 @@ namespace DotNetOpenAuth.Test.OAuth2 { }); coordinator.Run(); } + + [Test] + public void ResourceOwnerScopeOverride() { + var clientRequestedScopes = new[] { "scope1", "scope2" }; + var serverOverriddenScopes = new[] { "scope1", "differentScope" }; + 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); + response.ApprovedScope.Clear(); + response.ApprovedScope.UnionWith(serverOverriddenScopes); + 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, clientRequestedScopes); + Assert.That(result.Scope, Is.EquivalentTo(serverOverriddenScopes)); + }, + server => { + server.HandleTokenRequest().Respond(); + }); + coordinator.Run(); + } + + [Test] + public void ClientCredentialScopeOverride() { + var clientRequestedScopes = new[] { "scope1", "scope2" }; + var serverOverriddenScopes = new[] { "scope1", "differentScope" }; + var authServerMock = CreateAuthorizationServerMock(); + authServerMock + .Setup(a => a.CheckAuthorizeClientCredentialsGrant(It.IsAny<IAccessTokenRequest>())) + .Returns<IAccessTokenRequest>(req => { + var response = new AutomatedAuthorizationCheckResponse(req, true); + response.ApprovedScope.Clear(); + response.ApprovedScope.UnionWith(serverOverriddenScopes); + return response; + }); + var coordinator = new OAuth2Coordinator<WebServerClient>( + AuthorizationServerDescription, + authServerMock.Object, + new WebServerClient(AuthorizationServerDescription), + client => { + var authState = new AuthorizationState(TestScopes) { + Callback = ClientCallback, + }; + var result = client.GetClientAccessToken(clientRequestedScopes); + Assert.That(result.Scope, Is.EquivalentTo(serverOverriddenScopes)); + }, + server => { + server.HandleTokenRequest().Respond(); + }); + coordinator.Run(); + } } } diff --git a/src/DotNetOpenAuth.Test/OAuth2/OAuth2TestBase.cs b/src/DotNetOpenAuth.Test/OAuth2/OAuth2TestBase.cs index f43a349..b8b930c 100644 --- a/src/DotNetOpenAuth.Test/OAuth2/OAuth2TestBase.cs +++ b/src/DotNetOpenAuth.Test/OAuth2/OAuth2TestBase.cs @@ -53,8 +53,9 @@ namespace DotNetOpenAuth.Test.OAuth2 { d => d.ClientIdentifier == ClientId && d.User == ResourceOwnerUsername && MessagingUtilities.AreEquivalent(d.Scope, TestScopes)))).Returns(true); - string canonicalUserName = ResourceOwnerUsername; - authHostMock.Setup(m => m.TryAuthorizeResourceOwnerCredentialGrant(ResourceOwnerUsername, ResourceOwnerPassword, It.IsAny<IAccessTokenRequest>(), out canonicalUserName)).Returns(true); + authHostMock + .Setup(m => m.CheckAuthorizeResourceOwnerCredentialGrant(ResourceOwnerUsername, ResourceOwnerPassword, It.IsAny<IAccessTokenRequest>())) + .Returns<string, string, IAccessTokenRequest>((p1, p2, p3) => new AutomatedUserAuthorizationCheckResponse(p3, true, ResourceOwnerUsername)); authHostMock.Setup(m => m.CreateAccessToken(It.IsAny<IAccessTokenRequest>())).Returns(new AccessTokenResult(new AuthorizationServerAccessToken())); return authHostMock; } diff --git a/src/DotNetOpenAuth.Test/OAuth2/WebServerClientAuthorizeTests.cs b/src/DotNetOpenAuth.Test/OAuth2/WebServerClientAuthorizeTests.cs index 9a9c078..27b0050 100644 --- a/src/DotNetOpenAuth.Test/OAuth2/WebServerClientAuthorizeTests.cs +++ b/src/DotNetOpenAuth.Test/OAuth2/WebServerClientAuthorizeTests.cs @@ -84,8 +84,8 @@ namespace DotNetOpenAuth.Test.OAuth2 { a => a.IsAuthorizationValid(It.Is<IAuthorizationDescription>(d => d.User == null && d.ClientIdentifier == ClientId && MessagingUtilities.AreEquivalent(d.Scope, TestScopes)))) .Returns(true); authServer.Setup( - a => a.TryAuthorizeClientCredentialsGrant(It.Is<IAccessTokenRequest>(d => d.ClientIdentifier == ClientId && MessagingUtilities.AreEquivalent(d.Scope, TestScopes)))) - .Returns(true); + a => a.CheckAuthorizeClientCredentialsGrant(It.Is<IAccessTokenRequest>(d => d.ClientIdentifier == ClientId && MessagingUtilities.AreEquivalent(d.Scope, TestScopes)))) + .Returns<IAccessTokenRequest>(req => new AutomatedAuthorizationCheckResponse(req, true)); var coordinator = new OAuth2Coordinator<WebServerClient>( AuthorizationServerDescription, authServer.Object, |