diff options
Diffstat (limited to 'src/DotNetOpenAuth.Test/OAuth2')
7 files changed, 209 insertions, 27 deletions
diff --git a/src/DotNetOpenAuth.Test/OAuth2/AuthorizationServerTests.cs b/src/DotNetOpenAuth.Test/OAuth2/AuthorizationServerTests.cs index f3d8feb..3791e28 100644 --- a/src/DotNetOpenAuth.Test/OAuth2/AuthorizationServerTests.cs +++ b/src/DotNetOpenAuth.Test/OAuth2/AuthorizationServerTests.cs @@ -28,7 +28,7 @@ namespace DotNetOpenAuth.Test.OAuth2 { AuthorizationServerMock, new UserAgentClient(AuthorizationServerDescription), client => { - var request = new AccessTokenAuthorizationCodeRequest(AuthorizationServerDescription) + var request = new AccessTokenAuthorizationCodeRequestC(AuthorizationServerDescription) { ClientIdentifier = ClientId, ClientSecret = ClientSecret, AuthorizationCode = "foo" }; var response = client.Channel.Request<AccessTokenFailedResponse>(request); diff --git a/src/DotNetOpenAuth.Test/OAuth2/MessageFactoryTests.cs b/src/DotNetOpenAuth.Test/OAuth2/MessageFactoryTests.cs index bec85e2..52b5371 100644 --- a/src/DotNetOpenAuth.Test/OAuth2/MessageFactoryTests.cs +++ b/src/DotNetOpenAuth.Test/OAuth2/MessageFactoryTests.cs @@ -17,18 +17,22 @@ namespace DotNetOpenAuth.Test.OAuth2 { using NUnit.Framework; /// <summary> - /// Verifies that the WRAP message types are recognized. + /// Verifies that the OAuth 2 message types are recognized. /// </summary> public class MessageFactoryTests : OAuth2TestBase { private readonly MessageReceivingEndpoint recipient = new MessageReceivingEndpoint("http://who", HttpDeliveryMethods.PostRequest); - private OAuth2AuthorizationServerChannel channel; - private IMessageFactory messageFactory; + private IMessageFactory authServerMessageFactory; + + private IMessageFactory clientMessageFactory; public override void SetUp() { base.SetUp(); - this.channel = new OAuth2AuthorizationServerChannel(new Mock<IAuthorizationServer>().Object); - this.messageFactory = this.channel.MessageFactoryTestHook; + var authServerChannel = new OAuth2AuthorizationServerChannel(new Mock<IAuthorizationServerHost>().Object, new Mock<ClientAuthenticationModule>().Object); + this.authServerMessageFactory = authServerChannel.MessageFactoryTestHook; + + var clientChannel = new OAuth2ClientChannel(); + this.clientMessageFactory = clientChannel.MessageFactoryTestHook; } #region End user authorization messages @@ -40,7 +44,7 @@ namespace DotNetOpenAuth.Test.OAuth2 { { Protocol.client_id, "abc" }, { Protocol.redirect_uri, "abc" }, }; - IDirectedProtocolMessage request = this.messageFactory.GetNewRequestMessage(this.recipient, fields); + IDirectedProtocolMessage request = this.authServerMessageFactory.GetNewRequestMessage(this.recipient, fields); Assert.That(request, Is.InstanceOf(typeof(EndUserAuthorizationRequest))); } @@ -51,7 +55,7 @@ namespace DotNetOpenAuth.Test.OAuth2 { { Protocol.client_id, "abc" }, { Protocol.redirect_uri, "abc" }, }; - IDirectedProtocolMessage request = this.messageFactory.GetNewRequestMessage(this.recipient, fields); + IDirectedProtocolMessage request = this.authServerMessageFactory.GetNewRequestMessage(this.recipient, fields); Assert.That(request, Is.InstanceOf(typeof(EndUserAuthorizationImplicitRequest))); } @@ -60,7 +64,7 @@ namespace DotNetOpenAuth.Test.OAuth2 { var fields = new Dictionary<string, string> { { Protocol.code, "abc" }, }; - IDirectedProtocolMessage request = this.messageFactory.GetNewRequestMessage(this.recipient, fields); + IDirectedProtocolMessage request = this.clientMessageFactory.GetNewRequestMessage(this.recipient, fields); Assert.That(request, Is.InstanceOf(typeof(EndUserAuthorizationSuccessResponseBase))); } @@ -70,7 +74,7 @@ namespace DotNetOpenAuth.Test.OAuth2 { { Protocol.access_token, "abc" }, { Protocol.token_type, "bearer" }, }; - IDirectedProtocolMessage request = this.messageFactory.GetNewRequestMessage(this.recipient, fields); + IDirectedProtocolMessage request = this.clientMessageFactory.GetNewRequestMessage(this.recipient, fields); Assert.That(request, Is.InstanceOf(typeof(EndUserAuthorizationSuccessResponseBase))); } @@ -79,7 +83,7 @@ namespace DotNetOpenAuth.Test.OAuth2 { var fields = new Dictionary<string, string> { { Protocol.error, "access-denied" }, }; - IDirectedProtocolMessage request = this.messageFactory.GetNewRequestMessage(this.recipient, fields); + IDirectedProtocolMessage request = this.clientMessageFactory.GetNewRequestMessage(this.recipient, fields); Assert.That(request, Is.InstanceOf(typeof(EndUserAuthorizationFailedResponse))); } @@ -94,7 +98,7 @@ namespace DotNetOpenAuth.Test.OAuth2 { { Protocol.refresh_token, "abc" }, { Protocol.grant_type, "refresh-token" }, }; - IDirectedProtocolMessage request = this.messageFactory.GetNewRequestMessage(this.recipient, fields); + IDirectedProtocolMessage request = this.authServerMessageFactory.GetNewRequestMessage(this.recipient, fields); Assert.That(request, Is.InstanceOf(typeof(AccessTokenRefreshRequest))); } @@ -106,7 +110,7 @@ namespace DotNetOpenAuth.Test.OAuth2 { { Protocol.grant_type, "authorization-code" }, { Protocol.redirect_uri, "http://someUri" }, }; - IDirectedProtocolMessage request = this.messageFactory.GetNewRequestMessage(this.recipient, fields); + IDirectedProtocolMessage request = this.authServerMessageFactory.GetNewRequestMessage(this.recipient, fields); Assert.That(request, Is.InstanceOf(typeof(AccessTokenAuthorizationCodeRequest))); } @@ -119,7 +123,7 @@ namespace DotNetOpenAuth.Test.OAuth2 { { Protocol.username, "abc" }, { Protocol.password, "abc" }, }; - IDirectedProtocolMessage request = this.messageFactory.GetNewRequestMessage(this.recipient, fields); + IDirectedProtocolMessage request = this.authServerMessageFactory.GetNewRequestMessage(this.recipient, fields); Assert.That(request, Is.InstanceOf(typeof(AccessTokenResourceOwnerPasswordCredentialsRequest))); } @@ -130,7 +134,7 @@ namespace DotNetOpenAuth.Test.OAuth2 { { Protocol.client_secret, "abc" }, { Protocol.grant_type, "none" }, }; - IDirectedProtocolMessage request = this.messageFactory.GetNewRequestMessage(this.recipient, fields); + IDirectedProtocolMessage request = this.authServerMessageFactory.GetNewRequestMessage(this.recipient, fields); Assert.That(request, Is.InstanceOf(typeof(AccessTokenClientCredentialsRequest))); } diff --git a/src/DotNetOpenAuth.Test/OAuth2/OAuth2Coordinator.cs b/src/DotNetOpenAuth.Test/OAuth2/OAuth2Coordinator.cs index 993cad5..6494585 100644 --- a/src/DotNetOpenAuth.Test/OAuth2/OAuth2Coordinator.cs +++ b/src/DotNetOpenAuth.Test/OAuth2/OAuth2Coordinator.cs @@ -8,6 +8,7 @@ namespace DotNetOpenAuth.Test.OAuth2 { using System; using System.Collections.Generic; using System.Linq; + using System.Net; using System.Text; using DotNetOpenAuth.OAuth2; using DotNetOpenAuth.Test.Mocks; @@ -15,12 +16,12 @@ namespace DotNetOpenAuth.Test.OAuth2 { internal class OAuth2Coordinator<TClient> : CoordinatorBase<TClient, AuthorizationServer> where TClient : ClientBase { private readonly AuthorizationServerDescription serverDescription; - private readonly IAuthorizationServer authServerHost; + private readonly IAuthorizationServerHost authServerHost; private readonly TClient client; internal OAuth2Coordinator( AuthorizationServerDescription serverDescription, - IAuthorizationServer authServerHost, + IAuthorizationServerHost authServerHost, TClient client, Action<TClient> clientAction, Action<AuthorizationServer> authServerAction) @@ -34,13 +35,13 @@ namespace DotNetOpenAuth.Test.OAuth2 { this.client = client; this.client.ClientIdentifier = OAuth2TestBase.ClientId; - this.client.ClientSecret = OAuth2TestBase.ClientSecret; + this.client.ClientCredentialApplicator = ClientCredentialApplicator.PostParameter(OAuth2TestBase.ClientSecret); } internal override void Run() { var authServer = new AuthorizationServer(this.authServerHost); - var rpCoordinatingChannel = new CoordinatingChannel(this.client.Channel, this.IncomingMessageFilter, this.OutgoingMessageFilter); + var rpCoordinatingChannel = new CoordinatingOAuth2ClientChannel(this.client.Channel, this.IncomingMessageFilter, this.OutgoingMessageFilter); var opCoordinatingChannel = new CoordinatingOAuth2AuthServerChannel(authServer.Channel, this.IncomingMessageFilter, this.OutgoingMessageFilter); rpCoordinatingChannel.RemoteChannel = opCoordinatingChannel; opCoordinatingChannel.RemoteChannel = rpCoordinatingChannel; diff --git a/src/DotNetOpenAuth.Test/OAuth2/OAuth2TestBase.cs b/src/DotNetOpenAuth.Test/OAuth2/OAuth2TestBase.cs index 87d91f7..b9e32fe 100644 --- a/src/DotNetOpenAuth.Test/OAuth2/OAuth2TestBase.cs +++ b/src/DotNetOpenAuth.Test/OAuth2/OAuth2TestBase.cs @@ -8,11 +8,13 @@ namespace DotNetOpenAuth.Test.OAuth2 { using System; using System.Collections.Generic; using System.Linq; + using System.Security.Cryptography; using System.Text; using DotNetOpenAuth.Messaging; using DotNetOpenAuth.Messaging.Bindings; using DotNetOpenAuth.OAuth2; using DotNetOpenAuth.OAuth2.ChannelElements; + using DotNetOpenAuth.OAuth2.Messages; using Moq; public class OAuth2TestBase : TestBase { @@ -28,6 +30,8 @@ namespace DotNetOpenAuth.Test.OAuth2 { protected static readonly Uri ClientCallback = new Uri("http://client/callback"); + protected static readonly RSACryptoServiceProvider AsymmetricKey = new RSACryptoServiceProvider(512); + protected static readonly AuthorizationServerDescription AuthorizationServerDescription = new AuthorizationServerDescription { AuthorizationEndpoint = new Uri("https://authserver/authorize"), TokenEndpoint = new Uri("https://authserver/token"), @@ -38,10 +42,10 @@ namespace DotNetOpenAuth.Test.OAuth2 { ClientCallback, ClientType.Confidential); - protected static readonly IAuthorizationServer AuthorizationServerMock = CreateAuthorizationServerMock().Object; + protected static readonly IAuthorizationServerHost AuthorizationServerMock = CreateAuthorizationServerMock().Object; - protected static Mock<IAuthorizationServer> CreateAuthorizationServerMock() { - var authHostMock = new Mock<IAuthorizationServer>(); + protected static Mock<IAuthorizationServerHost> CreateAuthorizationServerMock() { + var authHostMock = new Mock<IAuthorizationServerHost>(); var cryptoStore = new MemoryCryptoKeyStore(); authHostMock.Setup(m => m.GetClient(ClientId)).Returns(ClientDescription); authHostMock.SetupGet(m => m.CryptoKeyStore).Returns(cryptoStore); @@ -52,7 +56,9 @@ namespace DotNetOpenAuth.Test.OAuth2 { d => d.ClientIdentifier == ClientId && d.User == ResourceOwnerUsername && MessagingUtilities.AreEquivalent(d.Scope, TestScopes)))).Returns(true); - authHostMock.Setup(m => m.IsResourceOwnerCredentialValid(ResourceOwnerUsername, ResourceOwnerPassword)).Returns(true); + string canonicalUserName = ResourceOwnerUsername; + authHostMock.Setup(m => m.TryAuthorizeResourceOwnerCredentialGrant(ResourceOwnerUsername, ResourceOwnerPassword, It.IsAny<IAccessTokenRequest>(), out canonicalUserName)).Returns(true); + authHostMock.Setup(m => m.CreateAccessToken(It.IsAny<IAccessTokenRequest>())).Returns(new AccessTokenResult(new AuthorizationServerAccessToken() { AccessTokenSigningKey = AsymmetricKey })); return authHostMock; } } diff --git a/src/DotNetOpenAuth.Test/OAuth2/ResourceServerTests.cs b/src/DotNetOpenAuth.Test/OAuth2/ResourceServerTests.cs new file mode 100644 index 0000000..a4d09de --- /dev/null +++ b/src/DotNetOpenAuth.Test/OAuth2/ResourceServerTests.cs @@ -0,0 +1,110 @@ +//----------------------------------------------------------------------- +// <copyright file="ResourceServerTests.cs" company="Andrew Arnott"> +// Copyright (c) Andrew Arnott. All rights reserved. +// </copyright> +//----------------------------------------------------------------------- + +namespace DotNetOpenAuth.Test.OAuth2 { + using System; + using System.Collections.Generic; + using System.Collections.Specialized; + using System.Linq; + using System.Security.Cryptography; + using System.Text; + using DotNetOpenAuth.Messaging; + using DotNetOpenAuth.OAuth2; + using DotNetOpenAuth.OAuth2.ChannelElements; + using DotNetOpenAuth.OAuth2.Messages; + using Moq; + using NUnit.Framework; + + [TestFixture] + public class ResourceServerTests : OAuth2TestBase { + [Test] + public void GetAccessTokenWithMissingAccessToken() { + var resourceServer = new ResourceServer(new StandardAccessTokenAnalyzer(AsymmetricKey, null)); + + var requestHeaders = new NameValueCollection { + { "Authorization", "Bearer " }, + }; + var request = new HttpRequestInfo("GET", new Uri("http://localhost/resource"), headers: requestHeaders); + Assert.That(() => resourceServer.GetAccessToken(request), Throws.InstanceOf<ProtocolException>()); + } + + [Test] + public void GetPrincipalWithMissingAccessToken() { + var resourceServer = new ResourceServer(new StandardAccessTokenAnalyzer(AsymmetricKey, null)); + + var requestHeaders = new NameValueCollection { + { "Authorization", "Bearer " }, + }; + var request = new HttpRequestInfo("GET", new Uri("http://localhost/resource"), headers: requestHeaders); + Assert.That(() => resourceServer.GetPrincipal(request), Throws.InstanceOf<ProtocolException>()); + } + + [Test] + public void GetAccessTokenWithTotallyFakeToken() { + var resourceServer = new ResourceServer(new StandardAccessTokenAnalyzer(AsymmetricKey, null)); + + var requestHeaders = new NameValueCollection { + { "Authorization", "Bearer foobar" }, + }; + var request = new HttpRequestInfo("GET", new Uri("http://localhost/resource"), headers: requestHeaders); + Assert.That(() => resourceServer.GetAccessToken(request), Throws.InstanceOf<ProtocolException>()); + } + + [Test] + public void GetAccessTokenWithCorruptedToken() { + var accessToken = this.ObtainValidAccessToken(); + + var resourceServer = new ResourceServer(new StandardAccessTokenAnalyzer(AsymmetricKey, null)); + + var requestHeaders = new NameValueCollection { + { "Authorization", "Bearer " + accessToken.Substring(0, accessToken.Length - 1) + "zzz" }, + }; + var request = new HttpRequestInfo("GET", new Uri("http://localhost/resource"), headers: requestHeaders); + Assert.That(() => resourceServer.GetAccessToken(request), Throws.InstanceOf<ProtocolException>()); + } + + [Test] + public void GetAccessTokenWithValidToken() { + var accessToken = this.ObtainValidAccessToken(); + + var resourceServer = new ResourceServer(new StandardAccessTokenAnalyzer(AsymmetricKey, null)); + + var requestHeaders = new NameValueCollection { + { "Authorization", "Bearer " + accessToken }, + }; + var request = new HttpRequestInfo("GET", new Uri("http://localhost/resource"), headers: requestHeaders); + var resourceServerDecodedToken = resourceServer.GetAccessToken(request); + Assert.That(resourceServerDecodedToken, Is.Not.Null); + } + + private string ObtainValidAccessToken() { + string accessToken = null; + var authServer = CreateAuthorizationServerMock(); + authServer.Setup( + 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); + var coordinator = new OAuth2Coordinator<WebServerClient>( + AuthorizationServerDescription, + authServer.Object, + new WebServerClient(AuthorizationServerDescription), + client => { + var authState = client.GetClientAccessToken(TestScopes); + Assert.That(authState.AccessToken, Is.Not.Null.And.Not.Empty); + Assert.That(authState.RefreshToken, Is.Null); + accessToken = authState.AccessToken; + }, + server => { + server.HandleTokenRequest().Respond(); + }); + coordinator.Run(); + + return accessToken; + } + } +} diff --git a/src/DotNetOpenAuth.Test/OAuth2/UserAgentClientAuthorizeTests.cs b/src/DotNetOpenAuth.Test/OAuth2/UserAgentClientAuthorizeTests.cs index 97c0f56..ae03b0c 100644 --- a/src/DotNetOpenAuth.Test/OAuth2/UserAgentClientAuthorizeTests.cs +++ b/src/DotNetOpenAuth.Test/OAuth2/UserAgentClientAuthorizeTests.cs @@ -73,7 +73,7 @@ namespace DotNetOpenAuth.Test.OAuth2 { server.ApproveAuthorizationRequest(request, ResourceOwnerUsername); }); - coordinatorClient.ClientSecret = null; // implicit grant clients don't need a secret. + coordinatorClient.ClientCredentialApplicator = null; // implicit grant clients don't need a secret. coordinator.Run(); } } diff --git a/src/DotNetOpenAuth.Test/OAuth2/WebServerClientAuthorizeTests.cs b/src/DotNetOpenAuth.Test/OAuth2/WebServerClientAuthorizeTests.cs index fe0abd2..9a9c078 100644 --- a/src/DotNetOpenAuth.Test/OAuth2/WebServerClientAuthorizeTests.cs +++ b/src/DotNetOpenAuth.Test/OAuth2/WebServerClientAuthorizeTests.cs @@ -8,7 +8,10 @@ namespace DotNetOpenAuth.Test.OAuth2 { using System; using System.Collections.Generic; using System.Linq; + using System.Net; + using System.Net.Http; using System.Text; + using System.Threading.Tasks; using DotNetOpenAuth.Messaging; using DotNetOpenAuth.OAuth2; using DotNetOpenAuth.OAuth2.ChannelElements; @@ -42,13 +45,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); @@ -65,6 +83,9 @@ namespace DotNetOpenAuth.Test.OAuth2 { authServer.Setup( 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); var coordinator = new OAuth2Coordinator<WebServerClient>( AuthorizationServerDescription, authServer.Object, @@ -79,5 +100,45 @@ namespace DotNetOpenAuth.Test.OAuth2 { }); coordinator.Run(); } + + [Test] + public void CreateAuthorizingHandlerBearer() { + var client = new WebServerClient(AuthorizationServerDescription); + string bearerToken = "mytoken"; + var tcs = new TaskCompletionSource<HttpResponseMessage>(); + var expectedResponse = new HttpResponseMessage(); + + var mockHandler = new Mocks.MockHttpMessageHandler((req, ct) => { + Assert.That(req.Headers.Authorization.Scheme, Is.EqualTo(Protocol.BearerHttpAuthorizationScheme)); + Assert.That(req.Headers.Authorization.Parameter, Is.EqualTo(bearerToken)); + tcs.SetResult(expectedResponse); + return tcs.Task; + }); + var applicator = client.CreateAuthorizingHandler("mytoken", mockHandler); + var httpClient = new HttpClient(applicator); + var actualResponse = httpClient.GetAsync("http://localhost/someMessage").Result; + Assert.That(actualResponse, Is.SameAs(expectedResponse)); + } + + [Test] + public void CreateAuthorizingHandlerAuthorization() { + var client = new WebServerClient(AuthorizationServerDescription); + string bearerToken = "mytoken"; + var authorization = new Mock<IAuthorizationState>(); + authorization.SetupGet(a => a.AccessToken).Returns(bearerToken); + var tcs = new TaskCompletionSource<HttpResponseMessage>(); + var expectedResponse = new HttpResponseMessage(); + + var mockHandler = new Mocks.MockHttpMessageHandler((req, ct) => { + Assert.That(req.Headers.Authorization.Scheme, Is.EqualTo(Protocol.BearerHttpAuthorizationScheme)); + Assert.That(req.Headers.Authorization.Parameter, Is.EqualTo(bearerToken)); + tcs.SetResult(expectedResponse); + return tcs.Task; + }); + var applicator = client.CreateAuthorizingHandler(authorization.Object, mockHandler); + var httpClient = new HttpClient(applicator); + var actualResponse = httpClient.GetAsync("http://localhost/someMessage").Result; + Assert.That(actualResponse, Is.SameAs(expectedResponse)); + } } } |