diff options
Diffstat (limited to 'src')
27 files changed, 1714 insertions, 1931 deletions
diff --git a/src/DotNetOpenAuth.AspNet.Test/OAuth2ClientTest.cs b/src/DotNetOpenAuth.AspNet.Test/OAuth2ClientTest.cs index bc28f63..d24cf77 100644 --- a/src/DotNetOpenAuth.AspNet.Test/OAuth2ClientTest.cs +++ b/src/DotNetOpenAuth.AspNet.Test/OAuth2ClientTest.cs @@ -1,140 +1,127 @@ -using System; -using System.Collections.Generic; -using System.Collections.Specialized; -using System.Web; -using DotNetOpenAuth.AspNet.Clients; -using Moq; -using NUnit.Framework; - -namespace DotNetOpenAuth.AspNet.Test -{ - [TestFixture] - public class OAuth2ClientTest - { - [TestCase] - public void TestProviderName() - { - // Arrange - var client = new MockOAuth2Client(); - - // Act - string providerName = client.ProviderName; - - // Assert - Assert.AreEqual("mockprovider", providerName); - } - - [TestCase] - public void RequestAuthenticationIssueCorrectRedirect() - { - // Arrange - var client = new MockOAuth2Client(); - var context = new Mock<HttpContextBase>(MockBehavior.Strict); - context.Setup(c => c.Response.Redirect("http://live.com/?q=http://return.to.me/", true)).Verifiable(); - - // Act - client.RequestAuthentication(context.Object, new Uri("http://return.to.me")); - - // Assert - context.Verify(); - } - - [TestCase] - public void VerifyAuthenticationThrowsIfContextIsNull() - { - // Arrange - var client = new MockOAuth2Client(); - - // Act && Assert - Assert.Throws<ArgumentNullException>(() => client.VerifyAuthentication(null)); - } - - [TestCase] - public void VerifyAuthenticationFailsIfCodeIsNotPresent() - { - // Arrange - var client = new MockOAuth2Client(); - var context = new Mock<HttpContextBase>(MockBehavior.Strict); - var queryStrings = new NameValueCollection(); - context.Setup(c => c.Request.QueryString).Returns(queryStrings); - - // Act - AuthenticationResult result = client.VerifyAuthentication(context.Object); - - // Assert - Assert.IsFalse(result.IsSuccessful); - } - - [TestCase] - public void VerifyAuthenticationFailsIfAccessTokenIsNull() - { - // Arrange - var client = new MockOAuth2Client(); - var context = new Mock<HttpContextBase>(MockBehavior.Strict); - var queryStrings = new NameValueCollection(); - queryStrings.Add("code", "random"); - context.Setup(c => c.Request.QueryString).Returns(queryStrings); - - // Act - AuthenticationResult result = client.VerifyAuthentication(context.Object); - - // Assert - Assert.IsFalse(result.IsSuccessful); - } - - [TestCase] - public void VerifyAuthenticationSucceeds() - { - // Arrange - var client = new MockOAuth2Client(); - var context = new Mock<HttpContextBase>(MockBehavior.Strict); - var queryStrings = new NameValueCollection(); - queryStrings.Add("code", "secret"); - context.Setup(c => c.Request.QueryString).Returns(queryStrings); - - // Act - AuthenticationResult result = client.VerifyAuthentication(context.Object); - - // Assert - Assert.True(result.IsSuccessful); - Assert.AreEqual("mockprovider", result.Provider); - Assert.AreEqual("12345", result.ProviderUserId); - Assert.AreEqual("John Doe", result.UserName); - Assert.NotNull(result.ExtraData); - Assert.AreEqual("abcde", result.ExtraData["token"]); - } - - private class MockOAuth2Client : OAuth2Client - { - public MockOAuth2Client() : base("mockprovider") - { - } - - protected override Uri GetServiceLoginUrl(Uri returnUrl) - { - string url = "http://live.com/?q=" + returnUrl.ToString(); - return new Uri(url); - } - - protected override string QueryAccessToken(Uri returnUrl, string authorizationCode) - { - return (authorizationCode == "secret") ? "abcde" : null; - } - - protected override IDictionary<string, string> GetUserData(string accessToken) - { - if (accessToken == "abcde") - { - return new Dictionary<string, string> +namespace DotNetOpenAuth.AspNet.Test { + using System; + using System.Collections.Generic; + using System.Collections.Specialized; + using System.Web; + using DotNetOpenAuth.AspNet.Clients; + using Moq; + using NUnit.Framework; + + [TestFixture] + public class OAuth2ClientTest { + [TestCase] + public void TestProviderName() { + // Arrange + var client = new MockOAuth2Client(); + + // Act + string providerName = client.ProviderName; + + // Assert + Assert.AreEqual("mockprovider", providerName); + } + + [TestCase] + public void RequestAuthenticationIssueCorrectRedirect() { + // Arrange + var client = new MockOAuth2Client(); + var context = new Mock<HttpContextBase>(MockBehavior.Strict); + context.Setup(c => c.Response.Redirect("http://live.com/?q=http://return.to.me/", true)).Verifiable(); + + // Act + client.RequestAuthentication(context.Object, new Uri("http://return.to.me")); + + // Assert + context.Verify(); + } + + [TestCase] + public void VerifyAuthenticationThrowsIfContextIsNull() { + // Arrange + var client = new MockOAuth2Client(); + + // Act && Assert + Assert.Throws<ArgumentNullException>(() => client.VerifyAuthentication(null)); + } + + [TestCase] + public void VerifyAuthenticationFailsIfCodeIsNotPresent() { + // Arrange + var client = new MockOAuth2Client(); + var context = new Mock<HttpContextBase>(MockBehavior.Strict); + var queryStrings = new NameValueCollection(); + context.Setup(c => c.Request.QueryString).Returns(queryStrings); + + // Act + AuthenticationResult result = client.VerifyAuthentication(context.Object); + + // Assert + Assert.IsFalse(result.IsSuccessful); + } + + [TestCase] + public void VerifyAuthenticationFailsIfAccessTokenIsNull() { + // Arrange + var client = new MockOAuth2Client(); + var context = new Mock<HttpContextBase>(MockBehavior.Strict); + var queryStrings = new NameValueCollection(); + queryStrings.Add("code", "random"); + context.Setup(c => c.Request.QueryString).Returns(queryStrings); + + // Act + AuthenticationResult result = client.VerifyAuthentication(context.Object); + + // Assert + Assert.IsFalse(result.IsSuccessful); + } + + [TestCase] + public void VerifyAuthenticationSucceeds() { + // Arrange + var client = new MockOAuth2Client(); + var context = new Mock<HttpContextBase>(MockBehavior.Strict); + var queryStrings = new NameValueCollection(); + queryStrings.Add("code", "secret"); + context.Setup(c => c.Request.QueryString).Returns(queryStrings); + + // Act + AuthenticationResult result = client.VerifyAuthentication(context.Object); + + // Assert + Assert.True(result.IsSuccessful); + Assert.AreEqual("mockprovider", result.Provider); + Assert.AreEqual("12345", result.ProviderUserId); + Assert.AreEqual("John Doe", result.UserName); + Assert.NotNull(result.ExtraData); + Assert.AreEqual("abcde", result.ExtraData["token"]); + } + + private class MockOAuth2Client : OAuth2Client { + public MockOAuth2Client() + : base("mockprovider") { + } + + protected override Uri GetServiceLoginUrl(Uri returnUrl) { + string url = "http://live.com/?q=" + returnUrl.ToString(); + return new Uri(url); + } + + protected override string QueryAccessToken(Uri returnUrl, string authorizationCode) { + return (authorizationCode == "secret") ? "abcde" : null; + } + + protected override IDictionary<string, string> GetUserData(string accessToken) { + if (accessToken == "abcde") { + return new Dictionary<string, string> { {"id", "12345"}, {"token", accessToken}, {"name", "John Doe"} }; - } + } - return null; - } - } - } + return null; + } + } + } } diff --git a/src/DotNetOpenAuth.AspNet.Test/OAuthAuthenticationTickerHelperTest.cs b/src/DotNetOpenAuth.AspNet.Test/OAuthAuthenticationTickerHelperTest.cs index f3fea5c..78b8ca6 100644 --- a/src/DotNetOpenAuth.AspNet.Test/OAuthAuthenticationTickerHelperTest.cs +++ b/src/DotNetOpenAuth.AspNet.Test/OAuthAuthenticationTickerHelperTest.cs @@ -1,152 +1,143 @@ -using System; -using System.Web; -using System.Web.Security; -using DotNetOpenAuth.AspNet; -using Moq; -using NUnit.Framework; - -namespace DotNetOpenAuth.Test.Web -{ - [TestFixture] - public class OAuthAuthenticationTickerHelperTest - { - [TestCase] - public void SetAuthenticationTicketSetCookieOnHttpResponseWithPersistentSet() - { - SetAuthenticationTicketSetCookieOnHttpResponse(isPersistent: true); - } - - [TestCase] - public void SetAuthenticationTicketSetCookieOnHttpResponseWithPersistentNotSet() - { - SetAuthenticationTicketSetCookieOnHttpResponse(isPersistent: false); - } - - [TestCase] - public void IsOAuthAuthenticationTicketReturnsTrueIfCookieIsPresent() - { - // Arrange - var ticket = new FormsAuthenticationTicket( - 2, - "username", - DateTime.Now, - DateTime.Now.Add(FormsAuthentication.Timeout), - false, - "OAuth", - FormsAuthentication.FormsCookiePath); - - var cookie = new HttpCookie(name: FormsAuthentication.FormsCookieName, - value: FormsAuthentication.Encrypt(ticket)); - var cookies = new HttpCookieCollection {cookie}; - - var context = new Mock<HttpContextBase>(); - context.Setup(c => c.Request.Cookies).Returns(cookies); - - // Act - bool result = OpenAuthAuthenticationTicketHelper.IsValidAuthenticationTicket(context.Object); - - // Assert - Assert.IsTrue(result); - } - - [TestCase] - public void IsOAuthAuthenticationTicketReturnsFalseIfCookieIsNotPresent() - { - // Arrange - var context = new Mock<HttpContextBase>(); - context.Setup(c => c.Request.Cookies).Returns(new HttpCookieCollection()); - - // Act - bool result = OpenAuthAuthenticationTicketHelper.IsValidAuthenticationTicket(context.Object); - - // Assert - Assert.IsFalse(result); - } - - [TestCase] - public void IsOAuthAuthenticationTicketReturnsFalseIfCookieIsPresentButDoesNotHaveOAuthData() - { - // Arrange - var ticket = new FormsAuthenticationTicket( - 2, - "username", - DateTime.Now, - DateTime.Now.Add(FormsAuthentication.Timeout), - false, - null, - FormsAuthentication.FormsCookiePath); - - var cookie = new HttpCookie(name: FormsAuthentication.FormsCookieName, - value: FormsAuthentication.Encrypt(ticket)); - var cookies = new HttpCookieCollection { cookie }; - - var context = new Mock<HttpContextBase>(); - context.Setup(c => c.Request.Cookies).Returns(cookies); - - // Act - bool result = OpenAuthAuthenticationTicketHelper.IsValidAuthenticationTicket(context.Object); - - // Assert - Assert.IsFalse(result); - } - - [TestCase] - public void IsOAuthAuthenticationTicketReturnsFalseIfCookieIsPresentButDoesNotHaveCorrectName() - { - // Arrange - var response = new Mock<HttpResponseBase>(); - - var ticket = new FormsAuthenticationTicket( - 2, - "username", - DateTime.Now, - DateTime.Now.Add(FormsAuthentication.Timeout), - false, - "OAuth", - FormsAuthentication.FormsCookiePath); - - var cookie = new HttpCookie(name: "random cookie name", - value: FormsAuthentication.Encrypt(ticket)); - var cookies = new HttpCookieCollection { cookie }; - - var context = new Mock<HttpContextBase>(); - context.Setup(c => c.Request.Cookies).Returns(cookies); - - // Act - bool result = OpenAuthAuthenticationTicketHelper.IsValidAuthenticationTicket(context.Object); - - // Assert - Assert.IsFalse(result); - } - - private void SetAuthenticationTicketSetCookieOnHttpResponse(bool isPersistent) - { - // Arrange - var cookies = new HttpCookieCollection(); - - var context = new Mock<HttpContextBase>(); - context.Setup(c => c.Request.IsSecureConnection).Returns(true); - context.Setup(c => c.Response.Cookies).Returns(cookies); - - // Act - OpenAuthAuthenticationTicketHelper.SetAuthenticationTicket(context.Object, "user", isPersistent); - - // Assert - Assert.AreEqual(1, cookies.Count); - HttpCookie addedCookie = cookies[0]; - - Assert.AreEqual(FormsAuthentication.FormsCookieName, addedCookie.Name); - Assert.IsTrue(addedCookie.HttpOnly); - Assert.AreEqual("/", addedCookie.Path); - Assert.IsFalse(addedCookie.Secure); - Assert.IsNotNullOrEmpty(addedCookie.Value); - - FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(addedCookie.Value); - Assert.NotNull(ticket); - Assert.AreEqual(2, ticket.Version); - Assert.AreEqual("user", ticket.Name); - Assert.AreEqual("OAuth", ticket.UserData); - Assert.AreEqual(isPersistent, ticket.IsPersistent); - } - } +namespace DotNetOpenAuth.Test.Web { + using System; + using System.Web; + using System.Web.Security; + using DotNetOpenAuth.AspNet; + using Moq; + using NUnit.Framework; + + [TestFixture] + public class OAuthAuthenticationTickerHelperTest { + [TestCase] + public void SetAuthenticationTicketSetCookieOnHttpResponseWithPersistentSet() { + SetAuthenticationTicketSetCookieOnHttpResponse(isPersistent: true); + } + + [TestCase] + public void SetAuthenticationTicketSetCookieOnHttpResponseWithPersistentNotSet() { + SetAuthenticationTicketSetCookieOnHttpResponse(isPersistent: false); + } + + [TestCase] + public void IsOAuthAuthenticationTicketReturnsTrueIfCookieIsPresent() { + // Arrange + var ticket = new FormsAuthenticationTicket( + 2, + "username", + DateTime.Now, + DateTime.Now.Add(FormsAuthentication.Timeout), + false, + "OAuth", + FormsAuthentication.FormsCookiePath); + + var cookie = new HttpCookie(name: FormsAuthentication.FormsCookieName, + value: FormsAuthentication.Encrypt(ticket)); + var cookies = new HttpCookieCollection { cookie }; + + var context = new Mock<HttpContextBase>(); + context.Setup(c => c.Request.Cookies).Returns(cookies); + + // Act + bool result = OpenAuthAuthenticationTicketHelper.IsValidAuthenticationTicket(context.Object); + + // Assert + Assert.IsTrue(result); + } + + [TestCase] + public void IsOAuthAuthenticationTicketReturnsFalseIfCookieIsNotPresent() { + // Arrange + var context = new Mock<HttpContextBase>(); + context.Setup(c => c.Request.Cookies).Returns(new HttpCookieCollection()); + + // Act + bool result = OpenAuthAuthenticationTicketHelper.IsValidAuthenticationTicket(context.Object); + + // Assert + Assert.IsFalse(result); + } + + [TestCase] + public void IsOAuthAuthenticationTicketReturnsFalseIfCookieIsPresentButDoesNotHaveOAuthData() { + // Arrange + var ticket = new FormsAuthenticationTicket( + 2, + "username", + DateTime.Now, + DateTime.Now.Add(FormsAuthentication.Timeout), + false, + null, + FormsAuthentication.FormsCookiePath); + + var cookie = new HttpCookie(name: FormsAuthentication.FormsCookieName, + value: FormsAuthentication.Encrypt(ticket)); + var cookies = new HttpCookieCollection { cookie }; + + var context = new Mock<HttpContextBase>(); + context.Setup(c => c.Request.Cookies).Returns(cookies); + + // Act + bool result = OpenAuthAuthenticationTicketHelper.IsValidAuthenticationTicket(context.Object); + + // Assert + Assert.IsFalse(result); + } + + [TestCase] + public void IsOAuthAuthenticationTicketReturnsFalseIfCookieIsPresentButDoesNotHaveCorrectName() { + // Arrange + var response = new Mock<HttpResponseBase>(); + + var ticket = new FormsAuthenticationTicket( + 2, + "username", + DateTime.Now, + DateTime.Now.Add(FormsAuthentication.Timeout), + false, + "OAuth", + FormsAuthentication.FormsCookiePath); + + var cookie = new HttpCookie(name: "random cookie name", + value: FormsAuthentication.Encrypt(ticket)); + var cookies = new HttpCookieCollection { cookie }; + + var context = new Mock<HttpContextBase>(); + context.Setup(c => c.Request.Cookies).Returns(cookies); + + // Act + bool result = OpenAuthAuthenticationTicketHelper.IsValidAuthenticationTicket(context.Object); + + // Assert + Assert.IsFalse(result); + } + + private void SetAuthenticationTicketSetCookieOnHttpResponse(bool isPersistent) { + // Arrange + var cookies = new HttpCookieCollection(); + + var context = new Mock<HttpContextBase>(); + context.Setup(c => c.Request.IsSecureConnection).Returns(true); + context.Setup(c => c.Response.Cookies).Returns(cookies); + + // Act + OpenAuthAuthenticationTicketHelper.SetAuthenticationTicket(context.Object, "user", isPersistent); + + // Assert + Assert.AreEqual(1, cookies.Count); + HttpCookie addedCookie = cookies[0]; + + Assert.AreEqual(FormsAuthentication.FormsCookieName, addedCookie.Name); + Assert.IsTrue(addedCookie.HttpOnly); + Assert.AreEqual("/", addedCookie.Path); + Assert.IsFalse(addedCookie.Secure); + Assert.IsNotNullOrEmpty(addedCookie.Value); + + FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(addedCookie.Value); + Assert.NotNull(ticket); + Assert.AreEqual(2, ticket.Version); + Assert.AreEqual("user", ticket.Name); + Assert.AreEqual("OAuth", ticket.UserData); + Assert.AreEqual(isPersistent, ticket.IsPersistent); + } + } } diff --git a/src/DotNetOpenAuth.AspNet.Test/OAuthClientTest.cs b/src/DotNetOpenAuth.AspNet.Test/OAuthClientTest.cs index 6c14927..bec7f8a 100644 --- a/src/DotNetOpenAuth.AspNet.Test/OAuthClientTest.cs +++ b/src/DotNetOpenAuth.AspNet.Test/OAuthClientTest.cs @@ -1,143 +1,130 @@ -using System; -using System.Web; -using DotNetOpenAuth.Messaging; -using DotNetOpenAuth.OAuth.Messages; -using DotNetOpenAuth.AspNet.Clients; -using Moq; -using NUnit.Framework; -using DotNetOpenAuth.AspNet; - -namespace DotNetOpenAuth.AspNet.Test -{ - [TestFixture] - public class OAuthClientTest - { - [TestCase] - public void TestProviderNamePropertyIsCorrect() - { - // Arrange - var client = new MockOAuthClient(); - - // Act - var provider = client.ProviderName; - - // Assert - Assert.AreEqual("mockoauth", provider); - } - - [TestCase] - public void RequestAuthenticationInvokeMethodOnWebWorker() - { - // Arrange - var webWorker = new Mock<IOAuthWebWorker>(MockBehavior.Strict); - webWorker.Setup( - w => w.RequestAuthentication( - It.Is<Uri>(u => u.ToString().Equals("http://live.com/my/path.cshtml?q=one")))) - .Verifiable(); - - var client = new MockOAuthClient(webWorker.Object); - var returnUri = new Uri("http://live.com/my/path.cshtml?q=one"); - var context = new Mock<HttpContextBase>(); - - // Act - client.RequestAuthentication(context.Object, returnUri); - - // Assert - webWorker.Verify(); - } - - [TestCase] - public void VerifyAuthenticationFailsIfResponseTokenIsNull() - { - // Arrange - var webWorker = new Mock<IOAuthWebWorker>(MockBehavior.Strict); - webWorker.Setup(w => w.ProcessUserAuthorization()).Returns((AuthorizedTokenResponse)null); - - var client = new MockOAuthClient(webWorker.Object); - var context = new Mock<HttpContextBase>(); - - // Act - client.VerifyAuthentication(context.Object); - - // Assert - webWorker.Verify(); - } - - [TestCase] - public void VerifyAuthenticationFailsIfAccessTokenIsInvalid() - { - // Arrange - var endpoint = new MessageReceivingEndpoint("http://live.com/path/?a=b", HttpDeliveryMethods.GetRequest); - var request = new AuthorizedTokenRequest(endpoint, new Version("1.0")); - var response = new AuthorizedTokenResponse(request) - { - AccessToken = "invalid token" - }; - - var webWorker = new Mock<IOAuthWebWorker>(MockBehavior.Strict); - webWorker.Setup(w => w.ProcessUserAuthorization()).Returns(response).Verifiable(); - - var client = new MockOAuthClient(webWorker.Object); - var context = new Mock<HttpContextBase>(); - - // Act - AuthenticationResult result = client.VerifyAuthentication(context.Object); - - // Assert - webWorker.Verify(); - - Assert.False(result.IsSuccessful); - } - - [TestCase] - public void VerifyAuthenticationSucceeds() - { - // Arrange - var endpoint = new MessageReceivingEndpoint("http://live.com/path/?a=b", HttpDeliveryMethods.GetRequest); - var request = new AuthorizedTokenRequest(endpoint, new Version("1.0")); - var response = new AuthorizedTokenResponse(request) - { - AccessToken = "ok" - }; - - var webWorker = new Mock<IOAuthWebWorker>(MockBehavior.Strict); - webWorker.Setup(w => w.ProcessUserAuthorization()).Returns(response).Verifiable(); - - var client = new MockOAuthClient(webWorker.Object); - var context = new Mock<HttpContextBase>(); - - // Act - AuthenticationResult result = client.VerifyAuthentication(context.Object); - - // Assert - webWorker.Verify(); - - Assert.True(result.IsSuccessful); - Assert.AreEqual("mockoauth", result.Provider); - Assert.AreEqual("12345", result.ProviderUserId); - Assert.AreEqual("super", result.UserName); - } - - private class MockOAuthClient : OAuthClient - { - public MockOAuthClient() - : this(new Mock<IOAuthWebWorker>().Object) - { - } - - public MockOAuthClient(IOAuthWebWorker worker) : base("mockoauth", worker) - { - } - - protected override AuthenticationResult VerifyAuthenticationCore(AuthorizedTokenResponse response) - { - if (response.AccessToken == "ok") - { - return new AuthenticationResult(true, "mockoauth", "12345", "super", response.ExtraData); - } - - return AuthenticationResult.Failed; - } - } - } +namespace DotNetOpenAuth.AspNet.Test { + using System; + using System.Web; + using DotNetOpenAuth.Messaging; + using DotNetOpenAuth.OAuth.Messages; + using DotNetOpenAuth.AspNet.Clients; + using Moq; + using NUnit.Framework; + using DotNetOpenAuth.AspNet; + + [TestFixture] + public class OAuthClientTest { + [TestCase] + public void TestProviderNamePropertyIsCorrect() { + // Arrange + var client = new MockOAuthClient(); + + // Act + var provider = client.ProviderName; + + // Assert + Assert.AreEqual("mockoauth", provider); + } + + [TestCase] + public void RequestAuthenticationInvokeMethodOnWebWorker() { + // Arrange + var webWorker = new Mock<IOAuthWebWorker>(MockBehavior.Strict); + webWorker.Setup( + w => w.RequestAuthentication( + It.Is<Uri>(u => u.ToString().Equals("http://live.com/my/path.cshtml?q=one")))) + .Verifiable(); + + var client = new MockOAuthClient(webWorker.Object); + var returnUri = new Uri("http://live.com/my/path.cshtml?q=one"); + var context = new Mock<HttpContextBase>(); + + // Act + client.RequestAuthentication(context.Object, returnUri); + + // Assert + webWorker.Verify(); + } + + [TestCase] + public void VerifyAuthenticationFailsIfResponseTokenIsNull() { + // Arrange + var webWorker = new Mock<IOAuthWebWorker>(MockBehavior.Strict); + webWorker.Setup(w => w.ProcessUserAuthorization()).Returns((AuthorizedTokenResponse)null); + + var client = new MockOAuthClient(webWorker.Object); + var context = new Mock<HttpContextBase>(); + + // Act + client.VerifyAuthentication(context.Object); + + // Assert + webWorker.Verify(); + } + + [TestCase] + public void VerifyAuthenticationFailsIfAccessTokenIsInvalid() { + // Arrange + var endpoint = new MessageReceivingEndpoint("http://live.com/path/?a=b", HttpDeliveryMethods.GetRequest); + var request = new AuthorizedTokenRequest(endpoint, new Version("1.0")); + var response = new AuthorizedTokenResponse(request) { + AccessToken = "invalid token" + }; + + var webWorker = new Mock<IOAuthWebWorker>(MockBehavior.Strict); + webWorker.Setup(w => w.ProcessUserAuthorization()).Returns(response).Verifiable(); + + var client = new MockOAuthClient(webWorker.Object); + var context = new Mock<HttpContextBase>(); + + // Act + AuthenticationResult result = client.VerifyAuthentication(context.Object); + + // Assert + webWorker.Verify(); + + Assert.False(result.IsSuccessful); + } + + [TestCase] + public void VerifyAuthenticationSucceeds() { + // Arrange + var endpoint = new MessageReceivingEndpoint("http://live.com/path/?a=b", HttpDeliveryMethods.GetRequest); + var request = new AuthorizedTokenRequest(endpoint, new Version("1.0")); + var response = new AuthorizedTokenResponse(request) { + AccessToken = "ok" + }; + + var webWorker = new Mock<IOAuthWebWorker>(MockBehavior.Strict); + webWorker.Setup(w => w.ProcessUserAuthorization()).Returns(response).Verifiable(); + + var client = new MockOAuthClient(webWorker.Object); + var context = new Mock<HttpContextBase>(); + + // Act + AuthenticationResult result = client.VerifyAuthentication(context.Object); + + // Assert + webWorker.Verify(); + + Assert.True(result.IsSuccessful); + Assert.AreEqual("mockoauth", result.Provider); + Assert.AreEqual("12345", result.ProviderUserId); + Assert.AreEqual("super", result.UserName); + } + + private class MockOAuthClient : OAuthClient { + public MockOAuthClient() + : this(new Mock<IOAuthWebWorker>().Object) { + } + + public MockOAuthClient(IOAuthWebWorker worker) + : base("mockoauth", worker) { + } + + protected override AuthenticationResult VerifyAuthenticationCore(AuthorizedTokenResponse response) { + if (response.AccessToken == "ok") { + return new AuthenticationResult(true, "mockoauth", "12345", "super", response.ExtraData); + } + + return AuthenticationResult.Failed; + } + } + } } diff --git a/src/DotNetOpenAuth.AspNet.Test/UriHelperTest.cs b/src/DotNetOpenAuth.AspNet.Test/UriHelperTest.cs index 53a2b52..ea78a76 100644 --- a/src/DotNetOpenAuth.AspNet.Test/UriHelperTest.cs +++ b/src/DotNetOpenAuth.AspNet.Test/UriHelperTest.cs @@ -1,17 +1,14 @@ -using System; -using DotNetOpenAuth.AspNet.Clients; -using NUnit.Framework; +namespace DotNetOpenAuth.AspNet.Test { + using System; + using DotNetOpenAuth.AspNet.Clients; + using NUnit.Framework; -namespace DotNetOpenAuth.AspNet.Test -{ - [TestFixture] - public class UriHelperTest - { - [TestCase] - public void TestAttachQueryStringParameterMethod() - { - // Arrange - string[] input = new string[] + [TestFixture] + public class UriHelperTest { + [TestCase] + public void TestAttachQueryStringParameterMethod() { + // Arrange + string[] input = new string[] { "http://x.com", "https://xxx.com/one?s=123", @@ -19,7 +16,7 @@ namespace DotNetOpenAuth.AspNet.Test "https://zzz.com/default.aspx?name=sd" }; - string[] expectedOutput = new string[] + string[] expectedOutput = new string[] { "http://x.com/?s=awesome", "https://xxx.com/one?s=awesome", @@ -27,15 +24,14 @@ namespace DotNetOpenAuth.AspNet.Test "https://zzz.com/default.aspx?name=sd&s=awesome" }; - for (int i = 0; i < input.Length; i++) - { - // Act - var inputUrl = new Uri(input[i]); - var outputUri = UriHelper.AttachQueryStringParameter(inputUrl, "s", "awesome"); + for (int i = 0; i < input.Length; i++) { + // Act + var inputUrl = new Uri(input[i]); + var outputUri = UriHelper.AttachQueryStringParameter(inputUrl, "s", "awesome"); - // Assert - Assert.AreEqual(expectedOutput[i], outputUri.ToString()); - } - } - } + // Assert + Assert.AreEqual(expectedOutput[i], outputUri.ToString()); + } + } + } } diff --git a/src/DotNetOpenAuth.AspNet/AuthenticationResult.cs b/src/DotNetOpenAuth.AspNet/AuthenticationResult.cs index b1e4dbf..9656a56 100644 --- a/src/DotNetOpenAuth.AspNet/AuthenticationResult.cs +++ b/src/DotNetOpenAuth.AspNet/AuthenticationResult.cs @@ -1,108 +1,102 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; -using DotNetOpenAuth.Messaging; +namespace DotNetOpenAuth.AspNet { + using System; + using System.Collections.Generic; + using System.Diagnostics.CodeAnalysis; + using DotNetOpenAuth.Messaging; -namespace DotNetOpenAuth.AspNet -{ - /// <summary> - /// Represents the result of OAuth & OpenId authentication - /// </summary> - public class AuthenticationResult - { - /// <summary> - /// Returns an instance which indicates failed authentication. - /// </summary> - [SuppressMessage( - "Microsoft.Security", - "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes", - Justification = "This type is immutable.")] - public static readonly AuthenticationResult Failed = new AuthenticationResult(isSuccessful: false); + /// <summary> + /// Represents the result of OAuth & OpenId authentication + /// </summary> + public class AuthenticationResult { + /// <summary> + /// Returns an instance which indicates failed authentication. + /// </summary> + [SuppressMessage( + "Microsoft.Security", + "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes", + Justification = "This type is immutable.")] + public static readonly AuthenticationResult Failed = new AuthenticationResult(isSuccessful: false); - /// <summary> - /// Gets a value indicating whether the authentication step is successful. - /// </summary> - /// <value> - /// <c>true</c> if authentication is successful; otherwise, <c>false</c>. - /// </value> - public bool IsSuccessful { get; private set; } + /// <summary> + /// Gets a value indicating whether the authentication step is successful. + /// </summary> + /// <value> + /// <c>true</c> if authentication is successful; otherwise, <c>false</c>. + /// </value> + public bool IsSuccessful { get; private set; } - /// <summary> - /// Gets the provider's name. - /// </summary> - public string Provider { get; private set; } + /// <summary> + /// Gets the provider's name. + /// </summary> + public string Provider { get; private set; } - /// <summary> - /// Gets the unique user id that is returned from the provider. - /// </summary> - public string ProviderUserId { get; private set; } + /// <summary> + /// Gets the unique user id that is returned from the provider. + /// </summary> + public string ProviderUserId { get; private set; } - /// <summary> - /// Gets the user name that is returned from the provider. - /// </summary> - public string UserName { get; private set; } + /// <summary> + /// Gets the user name that is returned from the provider. + /// </summary> + public string UserName { get; private set; } - /// <summary> - /// Gets the optional extra data that may be returned from the provider - /// </summary> - public IDictionary<string, string> ExtraData { get; private set; } + /// <summary> + /// Gets the optional extra data that may be returned from the provider + /// </summary> + public IDictionary<string, string> ExtraData { get; private set; } - /// <summary> - /// Gets the error that may have occured during the authentication process - /// </summary> - public Exception Error { get; private set; } + /// <summary> + /// Gets the error that may have occured during the authentication process + /// </summary> + public Exception Error { get; private set; } - /// <summary> - /// Initializes a new instance of the <see cref="AuthenticationResult"/> class. - /// </summary> - /// <param name="isSuccessful">if set to <c>true</c> [is successful].</param> - public AuthenticationResult(bool isSuccessful) : - this(isSuccessful, - provider: null, - providerUserId: null, - userName: null, - extraData: null) - { - } + /// <summary> + /// Initializes a new instance of the <see cref="AuthenticationResult"/> class. + /// </summary> + /// <param name="isSuccessful">if set to <c>true</c> [is successful].</param> + public AuthenticationResult(bool isSuccessful) : + this(isSuccessful, + provider: null, + providerUserId: null, + userName: null, + extraData: null) { + } - /// <summary> - /// Initializes a new instance of the <see cref="AuthenticationResult"/> class. - /// </summary> - /// <param name="exception">The exception.</param> - public AuthenticationResult(Exception exception) : this(isSuccessful: false) - { - if (exception == null) - { - throw new ArgumentNullException("exception"); - } + /// <summary> + /// Initializes a new instance of the <see cref="AuthenticationResult"/> class. + /// </summary> + /// <param name="exception">The exception.</param> + public AuthenticationResult(Exception exception) + : this(isSuccessful: false) { + if (exception == null) { + throw new ArgumentNullException("exception"); + } - Error = exception; - } + Error = exception; + } - /// <summary> - /// Initializes a new instance of the <see cref="AuthenticationResult"/> class. - /// </summary> - /// <param name="isSuccessful">if set to <c>true</c> [is successful].</param> - /// <param name="provider">The provider.</param> - /// <param name="providerUserId">The provider user id.</param> - /// <param name="userName">Name of the user.</param> - /// <param name="extraData">The extra data.</param> - public AuthenticationResult( - bool isSuccessful, - string provider, - string providerUserId, - string userName, - IDictionary<string, string> extraData) - { - IsSuccessful = isSuccessful; - Provider = provider; - ProviderUserId = providerUserId; - UserName = userName; - if (extraData != null) - { - // wrap extraData in a read-only dictionary - ExtraData = new ReadOnlyDictionary<string, string>(extraData); - } - } - } + /// <summary> + /// Initializes a new instance of the <see cref="AuthenticationResult"/> class. + /// </summary> + /// <param name="isSuccessful">if set to <c>true</c> [is successful].</param> + /// <param name="provider">The provider.</param> + /// <param name="providerUserId">The provider user id.</param> + /// <param name="userName">Name of the user.</param> + /// <param name="extraData">The extra data.</param> + public AuthenticationResult( + bool isSuccessful, + string provider, + string providerUserId, + string userName, + IDictionary<string, string> extraData) { + IsSuccessful = isSuccessful; + Provider = provider; + ProviderUserId = providerUserId; + UserName = userName; + if (extraData != null) { + // wrap extraData in a read-only dictionary + ExtraData = new ReadOnlyDictionary<string, string>(extraData); + } + } + } }
\ No newline at end of file diff --git a/src/DotNetOpenAuth.AspNet/Clients/DictionaryExtensions.cs b/src/DotNetOpenAuth.AspNet/Clients/DictionaryExtensions.cs index 1e29851..ce7891d 100644 --- a/src/DotNetOpenAuth.AspNet/Clients/DictionaryExtensions.cs +++ b/src/DotNetOpenAuth.AspNet/Clients/DictionaryExtensions.cs @@ -1,46 +1,39 @@ -using System; -using System.Collections.Generic; -using System.Xml.Linq; +namespace DotNetOpenAuth.AspNet.Clients { + using System; + using System.Collections.Generic; + using System.Xml.Linq; -namespace DotNetOpenAuth.AspNet.Clients -{ - internal static class DictionaryExtensions - { - /// <summary> - /// Adds a key/value pair to the specified dictionary if the value is not null or empty. - /// </summary> - /// <param name="dictionary">The dictionary.</param> - /// <param name="key">The key.</param> - /// <param name="value">The value.</param> - public static void AddItemIfNotEmpty(this IDictionary<string, string> dictionary, string key, string value) - { - if (key == null) - { - throw new ArgumentNullException("key"); - } + internal static class DictionaryExtensions { + /// <summary> + /// Adds a key/value pair to the specified dictionary if the value is not null or empty. + /// </summary> + /// <param name="dictionary">The dictionary.</param> + /// <param name="key">The key.</param> + /// <param name="value">The value.</param> + public static void AddItemIfNotEmpty(this IDictionary<string, string> dictionary, string key, string value) { + if (key == null) { + throw new ArgumentNullException("key"); + } - if (!String.IsNullOrEmpty(value)) - { - dictionary[key] = value; - } - } + if (!String.IsNullOrEmpty(value)) { + dictionary[key] = value; + } + } - /// <summary> - /// Adds the value from an XDocument with the specified element name if it's not empty. - /// </summary> - /// <param name="dictionary">The dictionary.</param> - /// <param name="document">The document.</param> - /// <param name="elementName">Name of the element.</param> - public static void AddDataIfNotEmpty( - this Dictionary<string, string> dictionary, - XDocument document, - string elementName) - { - var element = document.Root.Element(elementName); - if (element != null) - { - dictionary.AddItemIfNotEmpty(elementName, element.Value); - } - } - } + /// <summary> + /// Adds the value from an XDocument with the specified element name if it's not empty. + /// </summary> + /// <param name="dictionary">The dictionary.</param> + /// <param name="document">The document.</param> + /// <param name="elementName">Name of the element.</param> + public static void AddDataIfNotEmpty( + this Dictionary<string, string> dictionary, + XDocument document, + string elementName) { + var element = document.Root.Element(elementName); + if (element != null) { + dictionary.AddItemIfNotEmpty(elementName, element.Value); + } + } + } } diff --git a/src/DotNetOpenAuth.AspNet/Clients/OAuth/DotNetOpenAuthWebConsumer.cs b/src/DotNetOpenAuth.AspNet/Clients/OAuth/DotNetOpenAuthWebConsumer.cs index 2e86238..5ad709c 100644 --- a/src/DotNetOpenAuth.AspNet/Clients/OAuth/DotNetOpenAuthWebConsumer.cs +++ b/src/DotNetOpenAuth.AspNet/Clients/OAuth/DotNetOpenAuthWebConsumer.cs @@ -1,47 +1,39 @@ -using System; -using System.Collections.Generic; -using System.Net; -using DotNetOpenAuth.Messaging; -using DotNetOpenAuth.OAuth; -using DotNetOpenAuth.OAuth.ChannelElements; -using DotNetOpenAuth.OAuth.Messages; +namespace DotNetOpenAuth.AspNet.Clients { + using System; + using System.Collections.Generic; + using System.Net; + using DotNetOpenAuth.Messaging; + using DotNetOpenAuth.OAuth; + using DotNetOpenAuth.OAuth.ChannelElements; + using DotNetOpenAuth.OAuth.Messages; -namespace DotNetOpenAuth.AspNet.Clients -{ - public class DotNetOpenAuthWebConsumer : IOAuthWebWorker - { - private readonly WebConsumer _webConsumer; + public class DotNetOpenAuthWebConsumer : IOAuthWebWorker { + private readonly WebConsumer _webConsumer; - public DotNetOpenAuthWebConsumer(ServiceProviderDescription serviceDescription, IConsumerTokenManager tokenManager) - { - if (serviceDescription == null) - { - throw new ArgumentNullException("consumer"); - } + public DotNetOpenAuthWebConsumer(ServiceProviderDescription serviceDescription, IConsumerTokenManager tokenManager) { + if (serviceDescription == null) { + throw new ArgumentNullException("consumer"); + } - if (tokenManager == null) - { - throw new ArgumentNullException("tokenManager"); - } + if (tokenManager == null) { + throw new ArgumentNullException("tokenManager"); + } - _webConsumer = new WebConsumer(serviceDescription, tokenManager); - } + _webConsumer = new WebConsumer(serviceDescription, tokenManager); + } - public void RequestAuthentication(Uri callback) - { - var redirectParameters = new Dictionary<string, string>() { { "force_login", "false" } }; - UserAuthorizationRequest request = _webConsumer.PrepareRequestUserAuthorization(callback, null, redirectParameters); - _webConsumer.Channel.PrepareResponse(request).Send(); - } + public void RequestAuthentication(Uri callback) { + var redirectParameters = new Dictionary<string, string>() { { "force_login", "false" } }; + UserAuthorizationRequest request = _webConsumer.PrepareRequestUserAuthorization(callback, null, redirectParameters); + _webConsumer.Channel.PrepareResponse(request).Send(); + } - public AuthorizedTokenResponse ProcessUserAuthorization() - { - return _webConsumer.ProcessUserAuthorization(); - } + public AuthorizedTokenResponse ProcessUserAuthorization() { + return _webConsumer.ProcessUserAuthorization(); + } - public HttpWebRequest PrepareAuthorizedRequest(MessageReceivingEndpoint profileEndpoint, string accessToken) - { - return _webConsumer.PrepareAuthorizedRequest(profileEndpoint, accessToken); - } - } + public HttpWebRequest PrepareAuthorizedRequest(MessageReceivingEndpoint profileEndpoint, string accessToken) { + return _webConsumer.PrepareAuthorizedRequest(profileEndpoint, accessToken); + } + } }
\ No newline at end of file diff --git a/src/DotNetOpenAuth.AspNet/Clients/OAuth/IOAuthWebWorker.cs b/src/DotNetOpenAuth.AspNet/Clients/OAuth/IOAuthWebWorker.cs index 73f258d..cca8298 100644 --- a/src/DotNetOpenAuth.AspNet/Clients/OAuth/IOAuthWebWorker.cs +++ b/src/DotNetOpenAuth.AspNet/Clients/OAuth/IOAuthWebWorker.cs @@ -1,14 +1,12 @@ -using System; -using System.Net; -using DotNetOpenAuth.Messaging; -using DotNetOpenAuth.OAuth.Messages; +namespace DotNetOpenAuth.AspNet.Clients { + using System; + using System.Net; + using DotNetOpenAuth.Messaging; + using DotNetOpenAuth.OAuth.Messages; -namespace DotNetOpenAuth.AspNet.Clients -{ - public interface IOAuthWebWorker - { - void RequestAuthentication(Uri callback); - AuthorizedTokenResponse ProcessUserAuthorization(); - HttpWebRequest PrepareAuthorizedRequest(MessageReceivingEndpoint profileEndpoint, string accessToken); - } + public interface IOAuthWebWorker { + void RequestAuthentication(Uri callback); + AuthorizedTokenResponse ProcessUserAuthorization(); + HttpWebRequest PrepareAuthorizedRequest(MessageReceivingEndpoint profileEndpoint, string accessToken); + } }
\ No newline at end of file diff --git a/src/DotNetOpenAuth.AspNet/Clients/OAuth/InMemoryOAuthTokenManager.cs b/src/DotNetOpenAuth.AspNet/Clients/OAuth/InMemoryOAuthTokenManager.cs index c8a6758..9dbf3d8 100644 --- a/src/DotNetOpenAuth.AspNet/Clients/OAuth/InMemoryOAuthTokenManager.cs +++ b/src/DotNetOpenAuth.AspNet/Clients/OAuth/InMemoryOAuthTokenManager.cs @@ -1,128 +1,117 @@ -using System; -using System.Collections.Generic; -using DotNetOpenAuth.OAuth.ChannelElements; -using DotNetOpenAuth.OAuth.Messages; +namespace DotNetOpenAuth.AspNet.Clients { + using System; + using System.Collections.Generic; + using DotNetOpenAuth.OAuth.ChannelElements; + using DotNetOpenAuth.OAuth.Messages; -namespace DotNetOpenAuth.AspNet.Clients -{ - /// <summary> - /// An implementation of IOAuthTokenManager which stores keys in memory. - /// </summary> - public sealed class InMemoryOAuthTokenManager : IConsumerTokenManager - { - private readonly Dictionary<string, string> _tokensAndSecrets = new Dictionary<string, string>(); + /// <summary> + /// An implementation of IOAuthTokenManager which stores keys in memory. + /// </summary> + public sealed class InMemoryOAuthTokenManager : IConsumerTokenManager { + private readonly Dictionary<string, string> _tokensAndSecrets = new Dictionary<string, string>(); - /// <summary> - /// Initializes a new instance of the <see cref="InMemoryOAuthTokenManager"/> class. - /// </summary> - /// <param name="consumerKey">The consumer key.</param> - /// <param name="consumerSecret">The consumer secret.</param> - public InMemoryOAuthTokenManager(string consumerKey, string consumerSecret) - { - if (consumerKey == null) - { - throw new ArgumentNullException("consumerKey"); - } + /// <summary> + /// Initializes a new instance of the <see cref="InMemoryOAuthTokenManager"/> class. + /// </summary> + /// <param name="consumerKey">The consumer key.</param> + /// <param name="consumerSecret">The consumer secret.</param> + public InMemoryOAuthTokenManager(string consumerKey, string consumerSecret) { + if (consumerKey == null) { + throw new ArgumentNullException("consumerKey"); + } - if (consumerSecret == null) - { - throw new ArgumentNullException("consumerSecret"); - } + if (consumerSecret == null) { + throw new ArgumentNullException("consumerSecret"); + } - ConsumerKey = consumerKey; - ConsumerSecret = consumerSecret; - } + ConsumerKey = consumerKey; + ConsumerSecret = consumerSecret; + } - /// <summary> - /// Gets the consumer key. - /// </summary> - public string ConsumerKey - { - get; - private set; - } + /// <summary> + /// Gets the consumer key. + /// </summary> + public string ConsumerKey { + get; + private set; + } - /// <summary> - /// Gets the consumer secret. - /// </summary> - public string ConsumerSecret - { - get; - private set; - } + /// <summary> + /// Gets the consumer secret. + /// </summary> + public string ConsumerSecret { + get; + private set; + } - #region ITokenManager Members + #region ITokenManager Members - /// <summary> - /// Gets the Token Secret given a request or access token. - /// </summary> - /// <param name="token">The request or access token.</param> - /// <returns> - /// The secret associated with the given token. - /// </returns> - /// <exception cref="ArgumentException">Thrown if the secret cannot be found for the given token.</exception> - public string GetTokenSecret(string token) - { - return _tokensAndSecrets[token]; - } + /// <summary> + /// Gets the Token Secret given a request or access token. + /// </summary> + /// <param name="token">The request or access token.</param> + /// <returns> + /// The secret associated with the given token. + /// </returns> + /// <exception cref="ArgumentException">Thrown if the secret cannot be found for the given token.</exception> + public string GetTokenSecret(string token) { + return _tokensAndSecrets[token]; + } - /// <summary> - /// Stores a newly generated unauthorized request token, secret, and optional - /// application-specific parameters for later recall. - /// </summary> - /// <param name="request">The request message that resulted in the generation of a new unauthorized request token.</param> - /// <param name="response">The response message that includes the unauthorized request token.</param> - /// <exception cref="ArgumentException">Thrown if the consumer key is not registered, or a required parameter was not found in the parameters collection.</exception> - /// <remarks> - /// Request tokens stored by this method SHOULD NOT associate any user account with this token. - /// It usually opens up security holes in your application to do so. Instead, you associate a user - /// account with access tokens (not request tokens) in the <see cref="ExpireRequestTokenAndStoreNewAccessToken"/> - /// method. - /// </remarks> - public void StoreNewRequestToken(UnauthorizedTokenRequest request, ITokenSecretContainingMessage response) - { - _tokensAndSecrets[response.Token] = response.TokenSecret; - } + /// <summary> + /// Stores a newly generated unauthorized request token, secret, and optional + /// application-specific parameters for later recall. + /// </summary> + /// <param name="request">The request message that resulted in the generation of a new unauthorized request token.</param> + /// <param name="response">The response message that includes the unauthorized request token.</param> + /// <exception cref="ArgumentException">Thrown if the consumer key is not registered, or a required parameter was not found in the parameters collection.</exception> + /// <remarks> + /// Request tokens stored by this method SHOULD NOT associate any user account with this token. + /// It usually opens up security holes in your application to do so. Instead, you associate a user + /// account with access tokens (not request tokens) in the <see cref="ExpireRequestTokenAndStoreNewAccessToken"/> + /// method. + /// </remarks> + public void StoreNewRequestToken(UnauthorizedTokenRequest request, ITokenSecretContainingMessage response) { + _tokensAndSecrets[response.Token] = response.TokenSecret; + } - /// <summary> - /// Deletes a request token and its associated secret and stores a new access token and secret. - /// </summary> - /// <param name="consumerKey">The Consumer that is exchanging its request token for an access token.</param> - /// <param name="requestToken">The Consumer's request token that should be deleted/expired.</param> - /// <param name="accessToken">The new access token that is being issued to the Consumer.</param> - /// <param name="accessTokenSecret">The secret associated with the newly issued access token.</param> - /// <remarks> - /// <para> - /// Any scope of granted privileges associated with the request token from the - /// original call to <see cref="StoreNewRequestToken"/> should be carried over - /// to the new Access Token. - /// </para> - /// <para> - /// To associate a user account with the new access token, - /// <see cref="System.Web.HttpContext.User">HttpContext.Current.User</see> may be - /// useful in an ASP.NET web application within the implementation of this method. - /// Alternatively you may store the access token here without associating with a user account, - /// and wait until <see cref="WebConsumer.ProcessUserAuthorization()"/> or - /// <see cref="DesktopConsumer.ProcessUserAuthorization(string, string)"/> return the access - /// token to associate the access token with a user account at that point. - /// </para> - /// </remarks> - public void ExpireRequestTokenAndStoreNewAccessToken(string consumerKey, string requestToken, string accessToken, string accessTokenSecret) - { - _tokensAndSecrets.Remove(requestToken); - _tokensAndSecrets[accessToken] = accessTokenSecret; - } + /// <summary> + /// Deletes a request token and its associated secret and stores a new access token and secret. + /// </summary> + /// <param name="consumerKey">The Consumer that is exchanging its request token for an access token.</param> + /// <param name="requestToken">The Consumer's request token that should be deleted/expired.</param> + /// <param name="accessToken">The new access token that is being issued to the Consumer.</param> + /// <param name="accessTokenSecret">The secret associated with the newly issued access token.</param> + /// <remarks> + /// <para> + /// Any scope of granted privileges associated with the request token from the + /// original call to <see cref="StoreNewRequestToken"/> should be carried over + /// to the new Access Token. + /// </para> + /// <para> + /// To associate a user account with the new access token, + /// <see cref="System.Web.HttpContext.User">HttpContext.Current.User</see> may be + /// useful in an ASP.NET web application within the implementation of this method. + /// Alternatively you may store the access token here without associating with a user account, + /// and wait until <see cref="WebConsumer.ProcessUserAuthorization()"/> or + /// <see cref="DesktopConsumer.ProcessUserAuthorization(string, string)"/> return the access + /// token to associate the access token with a user account at that point. + /// </para> + /// </remarks> + public void ExpireRequestTokenAndStoreNewAccessToken(string consumerKey, string requestToken, string accessToken, string accessTokenSecret) { + _tokensAndSecrets.Remove(requestToken); + _tokensAndSecrets[accessToken] = accessTokenSecret; + } - /// <summary> - /// Classifies a token as a request token or an access token. - /// </summary> - /// <param name="token">The token to classify.</param> - /// <returns>Request or Access token, or invalid if the token is not recognized.</returns> - public TokenType GetTokenType(string token) - { - throw new NotImplementedException(); - } + /// <summary> + /// Classifies a token as a request token or an access token. + /// </summary> + /// <param name="token">The token to classify.</param> + /// <returns>Request or Access token, or invalid if the token is not recognized.</returns> + public TokenType GetTokenType(string token) { + throw new NotImplementedException(); + } - #endregion - } + #endregion + } }
\ No newline at end of file diff --git a/src/DotNetOpenAuth.AspNet/Clients/OAuth/LinkedInClient.cs b/src/DotNetOpenAuth.AspNet/Clients/OAuth/LinkedInClient.cs index 2c83e30..53578ab 100644 --- a/src/DotNetOpenAuth.AspNet/Clients/OAuth/LinkedInClient.cs +++ b/src/DotNetOpenAuth.AspNet/Clients/OAuth/LinkedInClient.cs @@ -1,95 +1,85 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Net; -using System.Xml.Linq; -using DotNetOpenAuth.Messaging; -using DotNetOpenAuth.OAuth; -using DotNetOpenAuth.OAuth.ChannelElements; -using DotNetOpenAuth.OAuth.Messages; +namespace DotNetOpenAuth.AspNet.Clients { + using System; + using System.Collections.Generic; + using System.IO; + using System.Net; + using System.Xml.Linq; + using DotNetOpenAuth.Messaging; + using DotNetOpenAuth.OAuth; + using DotNetOpenAuth.OAuth.ChannelElements; + using DotNetOpenAuth.OAuth.Messages; -namespace DotNetOpenAuth.AspNet.Clients -{ - /// <summary> - /// Represents LinkedIn authentication client. - /// </summary> - public sealed class LinkedInClient : OAuthClient - { - public static readonly ServiceProviderDescription LinkedInServiceDescription = new ServiceProviderDescription - { - RequestTokenEndpoint = new MessageReceivingEndpoint("https://api.linkedin.com/uas/oauth/requestToken", HttpDeliveryMethods.GetRequest | HttpDeliveryMethods.AuthorizationHeaderRequest), - UserAuthorizationEndpoint = new MessageReceivingEndpoint("https://www.linkedin.com/uas/oauth/authenticate", HttpDeliveryMethods.GetRequest | HttpDeliveryMethods.AuthorizationHeaderRequest), - AccessTokenEndpoint = new MessageReceivingEndpoint("https://api.linkedin.com/uas/oauth/accessToken", HttpDeliveryMethods.GetRequest | HttpDeliveryMethods.AuthorizationHeaderRequest), - TamperProtectionElements = new ITamperProtectionChannelBindingElement[] { new HmacSha1SigningBindingElement() }, - }; + /// <summary> + /// Represents LinkedIn authentication client. + /// </summary> + public sealed class LinkedInClient : OAuthClient { + public static readonly ServiceProviderDescription LinkedInServiceDescription = new ServiceProviderDescription { + RequestTokenEndpoint = new MessageReceivingEndpoint("https://api.linkedin.com/uas/oauth/requestToken", HttpDeliveryMethods.GetRequest | HttpDeliveryMethods.AuthorizationHeaderRequest), + UserAuthorizationEndpoint = new MessageReceivingEndpoint("https://www.linkedin.com/uas/oauth/authenticate", HttpDeliveryMethods.GetRequest | HttpDeliveryMethods.AuthorizationHeaderRequest), + AccessTokenEndpoint = new MessageReceivingEndpoint("https://api.linkedin.com/uas/oauth/accessToken", HttpDeliveryMethods.GetRequest | HttpDeliveryMethods.AuthorizationHeaderRequest), + TamperProtectionElements = new ITamperProtectionChannelBindingElement[] { new HmacSha1SigningBindingElement() }, + }; - /// <summary> - /// Initializes a new instance of the <see cref="LinkedInClient"/> class. - /// </summary> - /// <param name="consumerKey">The LinkedIn app's consumer key.</param> - /// <param name="consumerSecret">The LinkedIn app's consumer secret.</param> - [System.Diagnostics.CodeAnalysis.SuppressMessage( - "Microsoft.Reliability", - "CA2000:Dispose objects before losing scope", - Justification = "We can't dispose the object because we still need it through the app lifetime.")] - public LinkedInClient(string consumerKey, string consumerSecret) : - base("linkedIn", LinkedInServiceDescription, consumerKey, consumerSecret) - { - } + /// <summary> + /// Initializes a new instance of the <see cref="LinkedInClient"/> class. + /// </summary> + /// <param name="consumerKey">The LinkedIn app's consumer key.</param> + /// <param name="consumerSecret">The LinkedIn app's consumer secret.</param> + [System.Diagnostics.CodeAnalysis.SuppressMessage( + "Microsoft.Reliability", + "CA2000:Dispose objects before losing scope", + Justification = "We can't dispose the object because we still need it through the app lifetime.")] + public LinkedInClient(string consumerKey, string consumerSecret) : + base("linkedIn", LinkedInServiceDescription, consumerKey, consumerSecret) { + } - /// <summary> - /// Check if authentication succeeded after user is redirected back from the service provider. - /// </summary> - /// <param name="response">The response token returned from service provider</param> - /// <returns> - /// Authentication result. - /// </returns> - [System.Diagnostics.CodeAnalysis.SuppressMessage( - "Microsoft.Design", - "CA1031:DoNotCatchGeneralExceptionTypes", - Justification = "We don't care if the request fails.")] - protected override AuthenticationResult VerifyAuthenticationCore(AuthorizedTokenResponse response) - { - // See here for Field Selectors API http://developer.linkedin.com/docs/DOC-1014 - const string profileRequestUrl = "http://api.linkedin.com/v1/people/~:(id,first-name,last-name,headline,industry,summary)"; + /// <summary> + /// Check if authentication succeeded after user is redirected back from the service provider. + /// </summary> + /// <param name="response">The response token returned from service provider</param> + /// <returns> + /// Authentication result. + /// </returns> + [System.Diagnostics.CodeAnalysis.SuppressMessage( + "Microsoft.Design", + "CA1031:DoNotCatchGeneralExceptionTypes", + Justification = "We don't care if the request fails.")] + protected override AuthenticationResult VerifyAuthenticationCore(AuthorizedTokenResponse response) { + // See here for Field Selectors API http://developer.linkedin.com/docs/DOC-1014 + const string profileRequestUrl = "http://api.linkedin.com/v1/people/~:(id,first-name,last-name,headline,industry,summary)"; - string accessToken = response.AccessToken; + string accessToken = response.AccessToken; - var profileEndpoint = new MessageReceivingEndpoint(profileRequestUrl, HttpDeliveryMethods.GetRequest); - HttpWebRequest request = WebWorker.PrepareAuthorizedRequest(profileEndpoint, accessToken); + var profileEndpoint = new MessageReceivingEndpoint(profileRequestUrl, HttpDeliveryMethods.GetRequest); + HttpWebRequest request = WebWorker.PrepareAuthorizedRequest(profileEndpoint, accessToken); - try - { - using (WebResponse profileResponse = request.GetResponse()) - { - using (Stream responseStream = profileResponse.GetResponseStream()) - { - XDocument document = XDocument.Load(responseStream); - string userId = document.Root.Element("id").Value; + try { + using (WebResponse profileResponse = request.GetResponse()) { + using (Stream responseStream = profileResponse.GetResponseStream()) { + XDocument document = XDocument.Load(responseStream); + string userId = document.Root.Element("id").Value; - string firstName = document.Root.Element("first-name").Value; - string lastName = document.Root.Element("last-name").Value; - string userName = firstName + " " + lastName; + string firstName = document.Root.Element("first-name").Value; + string lastName = document.Root.Element("last-name").Value; + string userName = firstName + " " + lastName; - var extraData = new Dictionary<string, string>(); - extraData.Add("name", userName); - extraData.AddDataIfNotEmpty(document, "headline"); - extraData.AddDataIfNotEmpty(document, "summary"); - extraData.AddDataIfNotEmpty(document, "industry"); + var extraData = new Dictionary<string, string>(); + extraData.Add("name", userName); + extraData.AddDataIfNotEmpty(document, "headline"); + extraData.AddDataIfNotEmpty(document, "summary"); + extraData.AddDataIfNotEmpty(document, "industry"); - return new AuthenticationResult( - isSuccessful: true, - provider: ProviderName, - providerUserId: userId, - userName: userName, - extraData: extraData); - } - } - } - catch (Exception exception) - { - return new AuthenticationResult(exception); - } - } - } + return new AuthenticationResult( + isSuccessful: true, + provider: ProviderName, + providerUserId: userId, + userName: userName, + extraData: extraData); + } + } + } catch (Exception exception) { + return new AuthenticationResult(exception); + } + } + } }
\ No newline at end of file diff --git a/src/DotNetOpenAuth.AspNet/Clients/OAuth/OAuthClient.cs b/src/DotNetOpenAuth.AspNet/Clients/OAuth/OAuthClient.cs index e50c536..0bc8ed9 100644 --- a/src/DotNetOpenAuth.AspNet/Clients/OAuth/OAuthClient.cs +++ b/src/DotNetOpenAuth.AspNet/Clients/OAuth/OAuthClient.cs @@ -1,116 +1,102 @@ -using System; -using System.Web; -using DotNetOpenAuth.Messaging; -using DotNetOpenAuth.OAuth; -using DotNetOpenAuth.OAuth.ChannelElements; -using DotNetOpenAuth.OAuth.Messages; +namespace DotNetOpenAuth.AspNet.Clients { + using System; + using System.Web; + using DotNetOpenAuth.Messaging; + using DotNetOpenAuth.OAuth; + using DotNetOpenAuth.OAuth.ChannelElements; + using DotNetOpenAuth.OAuth.Messages; -namespace DotNetOpenAuth.AspNet.Clients -{ - /// <summary> - /// Represents base class for OAuth 1.0 clients - /// </summary> - public abstract class OAuthClient : IAuthenticationClient - { - /// <summary> - /// Initializes a new instance of the <see cref="OAuthClient"/> class. - /// </summary> - /// <param name="providerName">Name of the provider.</param> - /// <param name="serviceDescription">The service description.</param> - /// <param name="consumerKey">The consumer key.</param> - /// <param name="consumerSecret">The consumer secret.</param> - protected OAuthClient(string providerName, ServiceProviderDescription serviceDescription, string consumerKey, string consumerSecret) : - this(providerName, serviceDescription, new InMemoryOAuthTokenManager(consumerKey, consumerSecret)) - { - } + /// <summary> + /// Represents base class for OAuth 1.0 clients + /// </summary> + public abstract class OAuthClient : IAuthenticationClient { + /// <summary> + /// Initializes a new instance of the <see cref="OAuthClient"/> class. + /// </summary> + /// <param name="providerName">Name of the provider.</param> + /// <param name="serviceDescription">The service description.</param> + /// <param name="consumerKey">The consumer key.</param> + /// <param name="consumerSecret">The consumer secret.</param> + protected OAuthClient(string providerName, ServiceProviderDescription serviceDescription, string consumerKey, string consumerSecret) : + this(providerName, serviceDescription, new InMemoryOAuthTokenManager(consumerKey, consumerSecret)) { + } - /// <summary> - /// Initializes a new instance of the <see cref="OAuthClient"/> class. - /// </summary> - /// <param name="providerName">Name of the provider.</param> - protected OAuthClient(string providerName, ServiceProviderDescription serviceDescription, IConsumerTokenManager tokenManager) : - this(providerName, new DotNetOpenAuthWebConsumer(serviceDescription, tokenManager)) - { - } + /// <summary> + /// Initializes a new instance of the <see cref="OAuthClient"/> class. + /// </summary> + /// <param name="providerName">Name of the provider.</param> + protected OAuthClient(string providerName, ServiceProviderDescription serviceDescription, IConsumerTokenManager tokenManager) : + this(providerName, new DotNetOpenAuthWebConsumer(serviceDescription, tokenManager)) { + } - protected OAuthClient(string providerName, IOAuthWebWorker webWorker) - { - if (providerName == null) - { - throw new ArgumentNullException("providerName"); - } + protected OAuthClient(string providerName, IOAuthWebWorker webWorker) { + if (providerName == null) { + throw new ArgumentNullException("providerName"); + } - if (webWorker == null) - { - throw new ArgumentNullException("webWorker"); - } + if (webWorker == null) { + throw new ArgumentNullException("webWorker"); + } - ProviderName = providerName; - WebWorker = webWorker; - } + ProviderName = providerName; + WebWorker = webWorker; + } - /// <summary> - /// Gets the name of the provider which provides authentication service. - /// </summary> - public string ProviderName - { - get; - private set; - } + /// <summary> + /// Gets the name of the provider which provides authentication service. + /// </summary> + public string ProviderName { + get; + private set; + } - /// <summary> - /// Gets the <see cref="OAuthWebConsumer"/> instance which handles constructing requests - /// to the OAuth providers. - /// </summary> - protected IOAuthWebWorker WebWorker - { - get; - private set; - } + /// <summary> + /// Gets the <see cref="OAuthWebConsumer"/> instance which handles constructing requests + /// to the OAuth providers. + /// </summary> + protected IOAuthWebWorker WebWorker { + get; + private set; + } - /// <summary> - /// Attempts to authenticate users by forwarding them to an external website, and - /// upon succcess or failure, redirect users back to the specified url. - /// </summary> - /// <param name="returnUrl">The return url after users have completed authenticating against external website.</param> - public virtual void RequestAuthentication(HttpContextBase context, Uri returnUrl) - { - if (returnUrl == null) - { - throw new ArgumentNullException("returnUrl"); - } + /// <summary> + /// Attempts to authenticate users by forwarding them to an external website, and + /// upon succcess or failure, redirect users back to the specified url. + /// </summary> + /// <param name="returnUrl">The return url after users have completed authenticating against external website.</param> + public virtual void RequestAuthentication(HttpContextBase context, Uri returnUrl) { + if (returnUrl == null) { + throw new ArgumentNullException("returnUrl"); + } - if (context == null) - { - throw new ArgumentNullException("context"); - } + if (context == null) { + throw new ArgumentNullException("context"); + } - Uri callback = returnUrl.StripQueryArgumentsWithPrefix("oauth_"); - WebWorker.RequestAuthentication(callback); - } + Uri callback = returnUrl.StripQueryArgumentsWithPrefix("oauth_"); + WebWorker.RequestAuthentication(callback); + } - /// <summary> - /// Check if authentication succeeded after user is redirected back from the service provider. - /// </summary> - /// <returns> - /// An instance of <see cref="AuthenticationResult"/> containing authentication result. - /// </returns> - public virtual AuthenticationResult VerifyAuthentication(HttpContextBase context) - { - AuthorizedTokenResponse response = WebWorker.ProcessUserAuthorization(); - if (response == null) - { - return AuthenticationResult.Failed; - } + /// <summary> + /// Check if authentication succeeded after user is redirected back from the service provider. + /// </summary> + /// <returns> + /// An instance of <see cref="AuthenticationResult"/> containing authentication result. + /// </returns> + public virtual AuthenticationResult VerifyAuthentication(HttpContextBase context) { + AuthorizedTokenResponse response = WebWorker.ProcessUserAuthorization(); + if (response == null) { + return AuthenticationResult.Failed; + } - return VerifyAuthenticationCore(response); - } + return VerifyAuthenticationCore(response); + } - /// <summary> - /// Check if authentication succeeded after user is redirected back from the service provider. - /// </summary> - /// <param name="response">The response token returned from service provider</param> - /// <returns>Authentication result</returns> - protected abstract AuthenticationResult VerifyAuthenticationCore(AuthorizedTokenResponse response); - } + /// <summary> + /// Check if authentication succeeded after user is redirected back from the service provider. + /// </summary> + /// <param name="response">The response token returned from service provider</param> + /// <returns>Authentication result</returns> + protected abstract AuthenticationResult VerifyAuthenticationCore(AuthorizedTokenResponse response); + } }
\ No newline at end of file diff --git a/src/DotNetOpenAuth.AspNet/Clients/OAuth/TwitterClient.cs b/src/DotNetOpenAuth.AspNet/Clients/OAuth/TwitterClient.cs index 497a5c9..c73deed 100644 --- a/src/DotNetOpenAuth.AspNet/Clients/OAuth/TwitterClient.cs +++ b/src/DotNetOpenAuth.AspNet/Clients/OAuth/TwitterClient.cs @@ -1,94 +1,84 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Net; -using System.Xml.Linq; -using DotNetOpenAuth.Messaging; -using DotNetOpenAuth.OAuth; -using DotNetOpenAuth.OAuth.ChannelElements; -using DotNetOpenAuth.OAuth.Messages; +namespace DotNetOpenAuth.AspNet.Clients { + using System; + using System.Collections.Generic; + using System.IO; + using System.Net; + using System.Xml.Linq; + using DotNetOpenAuth.Messaging; + using DotNetOpenAuth.OAuth; + using DotNetOpenAuth.OAuth.ChannelElements; + using DotNetOpenAuth.OAuth.Messages; -namespace DotNetOpenAuth.AspNet.Clients -{ - /// <summary> - /// Represents a Twitter client - /// </summary> - public class TwitterClient : OAuthClient - { - /// <summary> - /// The description of Twitter's OAuth protocol URIs for use with their "Sign in with Twitter" feature. - /// </summary> - public static readonly ServiceProviderDescription TwitterServiceDescription = new ServiceProviderDescription - { - RequestTokenEndpoint = new MessageReceivingEndpoint("http://twitter.com/oauth/request_token", HttpDeliveryMethods.GetRequest | HttpDeliveryMethods.AuthorizationHeaderRequest), - UserAuthorizationEndpoint = new MessageReceivingEndpoint("http://twitter.com/oauth/authenticate", HttpDeliveryMethods.GetRequest | HttpDeliveryMethods.AuthorizationHeaderRequest), - AccessTokenEndpoint = new MessageReceivingEndpoint("http://twitter.com/oauth/access_token", HttpDeliveryMethods.GetRequest | HttpDeliveryMethods.AuthorizationHeaderRequest), - TamperProtectionElements = new ITamperProtectionChannelBindingElement[] { new HmacSha1SigningBindingElement() }, - }; + /// <summary> + /// Represents a Twitter client + /// </summary> + public class TwitterClient : OAuthClient { + /// <summary> + /// The description of Twitter's OAuth protocol URIs for use with their "Sign in with Twitter" feature. + /// </summary> + public static readonly ServiceProviderDescription TwitterServiceDescription = new ServiceProviderDescription { + RequestTokenEndpoint = new MessageReceivingEndpoint("http://twitter.com/oauth/request_token", HttpDeliveryMethods.GetRequest | HttpDeliveryMethods.AuthorizationHeaderRequest), + UserAuthorizationEndpoint = new MessageReceivingEndpoint("http://twitter.com/oauth/authenticate", HttpDeliveryMethods.GetRequest | HttpDeliveryMethods.AuthorizationHeaderRequest), + AccessTokenEndpoint = new MessageReceivingEndpoint("http://twitter.com/oauth/access_token", HttpDeliveryMethods.GetRequest | HttpDeliveryMethods.AuthorizationHeaderRequest), + TamperProtectionElements = new ITamperProtectionChannelBindingElement[] { new HmacSha1SigningBindingElement() }, + }; - /// <summary> - /// Initializes a new instance of the <see cref="TwitterClient"/> class with the specified consumer key and consumer secret. - /// </summary> - /// <param name="consumerKey">The consumer key.</param> - /// <param name="consumerSecret">The consumer secret.</param> - [System.Diagnostics.CodeAnalysis.SuppressMessage( - "Microsoft.Reliability", - "CA2000:Dispose objects before losing scope", - Justification = "We can't dispose the object because we still need it through the app lifetime.")] - public TwitterClient(string consumerKey, string consumerSecret) : - base("twitter", TwitterServiceDescription, consumerKey, consumerSecret) - { - } + /// <summary> + /// Initializes a new instance of the <see cref="TwitterClient"/> class with the specified consumer key and consumer secret. + /// </summary> + /// <param name="consumerKey">The consumer key.</param> + /// <param name="consumerSecret">The consumer secret.</param> + [System.Diagnostics.CodeAnalysis.SuppressMessage( + "Microsoft.Reliability", + "CA2000:Dispose objects before losing scope", + Justification = "We can't dispose the object because we still need it through the app lifetime.")] + public TwitterClient(string consumerKey, string consumerSecret) : + base("twitter", TwitterServiceDescription, consumerKey, consumerSecret) { + } - /// <summary> - /// Check if authentication succeeded after user is redirected back from the service provider. - /// </summary> - /// <param name="response">The response token returned from service provider</param> - /// <returns> - /// Authentication result - /// </returns> - [System.Diagnostics.CodeAnalysis.SuppressMessage( - "Microsoft.Design", - "CA1031:DoNotCatchGeneralExceptionTypes", - Justification = "We don't care if the request for additional data fails.")] - protected override AuthenticationResult VerifyAuthenticationCore(AuthorizedTokenResponse response) - { - string accessToken = response.AccessToken; - string userId = response.ExtraData["user_id"]; - string userName = response.ExtraData["screen_name"]; + /// <summary> + /// Check if authentication succeeded after user is redirected back from the service provider. + /// </summary> + /// <param name="response">The response token returned from service provider</param> + /// <returns> + /// Authentication result + /// </returns> + [System.Diagnostics.CodeAnalysis.SuppressMessage( + "Microsoft.Design", + "CA1031:DoNotCatchGeneralExceptionTypes", + Justification = "We don't care if the request for additional data fails.")] + protected override AuthenticationResult VerifyAuthenticationCore(AuthorizedTokenResponse response) { + string accessToken = response.AccessToken; + string userId = response.ExtraData["user_id"]; + string userName = response.ExtraData["screen_name"]; - string profileRequestUrl = "http://api.twitter.com/1/users/show.xml?user_id=" + Uri.EscapeDataString(userId); - var profileEndpoint = new MessageReceivingEndpoint(profileRequestUrl, HttpDeliveryMethods.GetRequest); - HttpWebRequest request = WebWorker.PrepareAuthorizedRequest(profileEndpoint, accessToken); + string profileRequestUrl = "http://api.twitter.com/1/users/show.xml?user_id=" + Uri.EscapeDataString(userId); + var profileEndpoint = new MessageReceivingEndpoint(profileRequestUrl, HttpDeliveryMethods.GetRequest); + HttpWebRequest request = WebWorker.PrepareAuthorizedRequest(profileEndpoint, accessToken); - var extraData = new Dictionary<string, string>(); - try - { - using (WebResponse profileResponse = request.GetResponse()) - { - using (Stream responseStream = profileResponse.GetResponseStream()) - { - XDocument document = XDocument.Load(responseStream); - extraData.AddDataIfNotEmpty(document, "name"); - extraData.AddDataIfNotEmpty(document, "location"); - extraData.AddDataIfNotEmpty(document, "description"); - extraData.AddDataIfNotEmpty(document, "url"); - } - } - } - catch (Exception) - { - // At this point, the authentication is already successful. - // Here we are just trying to get additional data if we can. - // If it fails, no problem. - } + var extraData = new Dictionary<string, string>(); + try { + using (WebResponse profileResponse = request.GetResponse()) { + using (Stream responseStream = profileResponse.GetResponseStream()) { + XDocument document = XDocument.Load(responseStream); + extraData.AddDataIfNotEmpty(document, "name"); + extraData.AddDataIfNotEmpty(document, "location"); + extraData.AddDataIfNotEmpty(document, "description"); + extraData.AddDataIfNotEmpty(document, "url"); + } + } + } catch (Exception) { + // At this point, the authentication is already successful. + // Here we are just trying to get additional data if we can. + // If it fails, no problem. + } - return new AuthenticationResult( - isSuccessful: true, - provider: ProviderName, - providerUserId: userId, - userName: userName, - extraData: extraData); - } - } + return new AuthenticationResult( + isSuccessful: true, + provider: ProviderName, + providerUserId: userId, + userName: userName, + extraData: extraData); + } + } }
\ No newline at end of file diff --git a/src/DotNetOpenAuth.AspNet/Clients/OAuth2/FacebookClient.cs b/src/DotNetOpenAuth.AspNet/Clients/OAuth2/FacebookClient.cs index 073223d..623d595 100644 --- a/src/DotNetOpenAuth.AspNet/Clients/OAuth2/FacebookClient.cs +++ b/src/DotNetOpenAuth.AspNet/Clients/OAuth2/FacebookClient.cs @@ -1,104 +1,91 @@ -using System; -using System.Collections.Generic; -using System.Globalization; -using System.Net; -using System.Web; -using DotNetOpenAuth.AspNet.Resources; -using DotNetOpenAuth.Messaging; +namespace DotNetOpenAuth.AspNet.Clients { + using System; + using System.Collections.Generic; + using System.Globalization; + using System.Net; + using System.Web; + using DotNetOpenAuth.AspNet.Resources; + using DotNetOpenAuth.Messaging; -namespace DotNetOpenAuth.AspNet.Clients -{ - public sealed class FacebookClient : OAuth2Client - { - private const string AuthorizationEndpoint = "https://www.facebook.com/dialog/oauth"; - private const string TokenEndpoint = "https://graph.facebook.com/oauth/access_token"; + public sealed class FacebookClient : OAuth2Client { + private const string AuthorizationEndpoint = "https://www.facebook.com/dialog/oauth"; + private const string TokenEndpoint = "https://graph.facebook.com/oauth/access_token"; - private readonly string _appId; - private readonly string _appSecret; + private readonly string _appId; + private readonly string _appSecret; - public FacebookClient(string appId, string appSecret) - : base("facebook") - { - if (String.IsNullOrEmpty(appId)) - { - throw new ArgumentException( - String.Format(CultureInfo.CurrentCulture, WebResources.Argument_Cannot_Be_Null_Or_Empty, "appId"), - "appId"); - } + public FacebookClient(string appId, string appSecret) + : base("facebook") { + if (String.IsNullOrEmpty(appId)) { + throw new ArgumentException( + String.Format(CultureInfo.CurrentCulture, WebResources.Argument_Cannot_Be_Null_Or_Empty, "appId"), + "appId"); + } - if (String.IsNullOrEmpty("appSecret")) - { - throw new ArgumentException( - String.Format(CultureInfo.CurrentCulture, WebResources.Argument_Cannot_Be_Null_Or_Empty, "appSecret"), - "appSecret"); - } + if (String.IsNullOrEmpty("appSecret")) { + throw new ArgumentException( + String.Format(CultureInfo.CurrentCulture, WebResources.Argument_Cannot_Be_Null_Or_Empty, "appSecret"), + "appSecret"); + } - _appId = appId; - _appSecret = appSecret; - } + _appId = appId; + _appSecret = appSecret; + } - protected override Uri GetServiceLoginUrl(Uri returnUrl) - { - // Note: Facebook doesn't like us to url-encode the redirect_uri value - var builder = new UriBuilder(AuthorizationEndpoint); - MessagingUtilities.AppendQueryArgs(builder, - new KeyValuePair<string, string>[] { + protected override Uri GetServiceLoginUrl(Uri returnUrl) { + // Note: Facebook doesn't like us to url-encode the redirect_uri value + var builder = new UriBuilder(AuthorizationEndpoint); + MessagingUtilities.AppendQueryArgs(builder, + new KeyValuePair<string, string>[] { new KeyValuePair<string, string>("client_id", _appId), new KeyValuePair<string, string>("redirect_uri", returnUrl.ToString()) }); - return builder.Uri; - } + return builder.Uri; + } - protected override string QueryAccessToken(Uri returnUrl, string authorizationCode) - { - // Note: Facebook doesn't like us to url-encode the redirect_uri value - var builder = new UriBuilder(TokenEndpoint); - MessagingUtilities.AppendQueryArgs(builder, - new KeyValuePair<string, string>[] { + protected override string QueryAccessToken(Uri returnUrl, string authorizationCode) { + // Note: Facebook doesn't like us to url-encode the redirect_uri value + var builder = new UriBuilder(TokenEndpoint); + MessagingUtilities.AppendQueryArgs(builder, + new KeyValuePair<string, string>[] { new KeyValuePair<string, string>("client_id", _appId), new KeyValuePair<string, string>("redirect_uri", returnUrl.ToString()), new KeyValuePair<string, string>("client_secret", _appSecret), new KeyValuePair<string, string>("code", authorizationCode) }); - using (WebClient client = new WebClient()) - { - string data = client.DownloadString(builder.Uri); - if (String.IsNullOrEmpty(data)) - { - return null; - } + using (WebClient client = new WebClient()) { + string data = client.DownloadString(builder.Uri); + if (String.IsNullOrEmpty(data)) { + return null; + } - var parsedQueryString = HttpUtility.ParseQueryString(data); - if (parsedQueryString != null) - { - return parsedQueryString["access_token"]; - } - } - return null; - } + var parsedQueryString = HttpUtility.ParseQueryString(data); + if (parsedQueryString != null) { + return parsedQueryString["access_token"]; + } + } + return null; + } - protected override IDictionary<string, string> GetUserData(string accessToken) - { - FacebookGraphData graphData; - var request = WebRequest.Create("https://graph.facebook.com/me?access_token=" + Uri.EscapeDataString(accessToken)); - using (var response = request.GetResponse()) - { - using (var responseStream = response.GetResponseStream()) - { - graphData = JsonHelper.Deserialize<FacebookGraphData>(responseStream); - } - } + protected override IDictionary<string, string> GetUserData(string accessToken) { + FacebookGraphData graphData; + var request = WebRequest.Create("https://graph.facebook.com/me?access_token=" + Uri.EscapeDataString(accessToken)); + using (var response = request.GetResponse()) { + using (var responseStream = response.GetResponseStream()) { + graphData = JsonHelper.Deserialize<FacebookGraphData>(responseStream); + } + } - // this dictionary must contains - var userData = new Dictionary<string, string>(); - userData.AddItemIfNotEmpty("id", graphData.Id); - userData.AddItemIfNotEmpty("username", graphData.Email); - userData.AddItemIfNotEmpty("name", graphData.Name); - userData.AddItemIfNotEmpty("link", graphData.Link == null ? null : graphData.Link.ToString()); - userData.AddItemIfNotEmpty("gender", graphData.Gender); - userData.AddItemIfNotEmpty("birthday", graphData.Birthday); - return userData; - } - } + // this dictionary must contains + var userData = new Dictionary<string, string>(); + userData.AddItemIfNotEmpty("id", graphData.Id); + userData.AddItemIfNotEmpty("username", graphData.Email); + userData.AddItemIfNotEmpty("name", graphData.Name); + userData.AddItemIfNotEmpty("link", graphData.Link == null ? null : graphData.Link.ToString()); + userData.AddItemIfNotEmpty("gender", graphData.Gender); + userData.AddItemIfNotEmpty("birthday", graphData.Birthday); + return userData; + } + } } diff --git a/src/DotNetOpenAuth.AspNet/Clients/OAuth2/FacebookGraphData.cs b/src/DotNetOpenAuth.AspNet/Clients/OAuth2/FacebookGraphData.cs index 0f23907..a2605bf 100644 --- a/src/DotNetOpenAuth.AspNet/Clients/OAuth2/FacebookGraphData.cs +++ b/src/DotNetOpenAuth.AspNet/Clients/OAuth2/FacebookGraphData.cs @@ -1,36 +1,34 @@ -using System; -using System.Runtime.Serialization; -using System.ComponentModel; +namespace DotNetOpenAuth.AspNet.Clients { + using System; + using System.Runtime.Serialization; + using System.ComponentModel; -namespace DotNetOpenAuth.AspNet.Clients -{ - /// <summary> - /// Contains data of a Facebook user. - /// </summary> - /// <remarks> - /// Technically, this class doesn't need to be public, but because we want to make it serializable - /// in medium trust, it has to be public. - /// </remarks> - [DataContract] - [EditorBrowsable(EditorBrowsableState.Never)] - public class FacebookGraphData - { - [DataMember(Name = "id")] - public string Id { get; set; } + /// <summary> + /// Contains data of a Facebook user. + /// </summary> + /// <remarks> + /// Technically, this class doesn't need to be public, but because we want to make it serializable + /// in medium trust, it has to be public. + /// </remarks> + [DataContract] + [EditorBrowsable(EditorBrowsableState.Never)] + public class FacebookGraphData { + [DataMember(Name = "id")] + public string Id { get; set; } - [DataMember(Name = "email")] - public string Email { get; set; } + [DataMember(Name = "email")] + public string Email { get; set; } - [DataMember(Name = "name")] - public string Name { get; set; } + [DataMember(Name = "name")] + public string Name { get; set; } - [DataMember(Name = "link")] - public Uri Link { get; set; } + [DataMember(Name = "link")] + public Uri Link { get; set; } - [DataMember(Name = "gender")] - public string Gender { get; set; } + [DataMember(Name = "gender")] + public string Gender { get; set; } - [DataMember(Name = "birthday")] - public string Birthday { get; set; } - } + [DataMember(Name = "birthday")] + public string Birthday { get; set; } + } } diff --git a/src/DotNetOpenAuth.AspNet/Clients/OAuth2/JsonHelper.cs b/src/DotNetOpenAuth.AspNet/Clients/OAuth2/JsonHelper.cs index 8bc6f7c..bc8af46 100644 --- a/src/DotNetOpenAuth.AspNet/Clients/OAuth2/JsonHelper.cs +++ b/src/DotNetOpenAuth.AspNet/Clients/OAuth2/JsonHelper.cs @@ -1,20 +1,16 @@ -using System; -using System.IO; -using System.Runtime.Serialization.Json; +namespace DotNetOpenAuth.AspNet.Clients { + using System; + using System.IO; + using System.Runtime.Serialization.Json; -namespace DotNetOpenAuth.AspNet.Clients -{ - internal static class JsonHelper - { - public static T Deserialize<T>(Stream stream) where T : class - { - if (stream == null) - { - throw new ArgumentNullException("stream"); - } + internal static class JsonHelper { + public static T Deserialize<T>(Stream stream) where T : class { + if (stream == null) { + throw new ArgumentNullException("stream"); + } - var serializer = new DataContractJsonSerializer(typeof(T)); - return (T)serializer.ReadObject(stream); - } - } + var serializer = new DataContractJsonSerializer(typeof(T)); + return (T)serializer.ReadObject(stream); + } + } } diff --git a/src/DotNetOpenAuth.AspNet/Clients/OAuth2/OAuth2AccessTokenData.cs b/src/DotNetOpenAuth.AspNet/Clients/OAuth2/OAuth2AccessTokenData.cs index a2ecb30..7cb902e 100644 --- a/src/DotNetOpenAuth.AspNet/Clients/OAuth2/OAuth2AccessTokenData.cs +++ b/src/DotNetOpenAuth.AspNet/Clients/OAuth2/OAuth2AccessTokenData.cs @@ -1,20 +1,18 @@ -using System.Runtime.Serialization; +namespace DotNetOpenAuth.AspNet.Clients { + using System.Runtime.Serialization; -namespace DotNetOpenAuth.AspNet.Clients -{ - [DataContract] - public class OAuth2AccessTokenData - { - [DataMember(Name = "access_token")] - public string AccessToken { get; set; } + [DataContract] + public class OAuth2AccessTokenData { + [DataMember(Name = "access_token")] + public string AccessToken { get; set; } - [DataMember(Name = "refresh_token")] - public string RefreshToken { get; set; } + [DataMember(Name = "refresh_token")] + public string RefreshToken { get; set; } - [DataMember(Name = "scope")] - public string Scope { get; set; } + [DataMember(Name = "scope")] + public string Scope { get; set; } - [DataMember(Name = "token_type")] - public string TokenType { get; set; } - } + [DataMember(Name = "token_type")] + public string TokenType { get; set; } + } } diff --git a/src/DotNetOpenAuth.AspNet/Clients/OAuth2/OAuth2Client.cs b/src/DotNetOpenAuth.AspNet/Clients/OAuth2/OAuth2Client.cs index 859b3be..276f5f4 100644 --- a/src/DotNetOpenAuth.AspNet/Clients/OAuth2/OAuth2Client.cs +++ b/src/DotNetOpenAuth.AspNet/Clients/OAuth2/OAuth2Client.cs @@ -1,133 +1,119 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; -using System.Web; - -namespace DotNetOpenAuth.AspNet.Clients -{ - /// <summary> - /// Represents the base class for OAuth 2.0 clients - /// </summary> - public abstract class OAuth2Client : IAuthenticationClient - { - private readonly string _providerName; - private Uri _returnUrl; - - /// <summary> - /// Initializes a new instance of the <see cref="OAuth2Client"/> class with the specified provider name. - /// </summary> - /// <param name="providerName">Name of the provider.</param> - protected OAuth2Client(string providerName) - { - if (providerName == null) - { - throw new ArgumentNullException("providerName"); - } - - _providerName = providerName; - } - - /// <summary> - /// Gets the name of the provider which provides authentication service. - /// </summary> - public string ProviderName - { - get { return _providerName; } - } - - /// <summary> - /// Attempts to authenticate users by forwarding them to an external website, and - /// upon succcess or failure, redirect users back to the specified url. - /// </summary> - /// <param name="returnUrl">The return url after users have completed authenticating against external website.</param> - public virtual void RequestAuthentication(HttpContextBase context, Uri returnUrl) - { - if (context == null) - { - throw new ArgumentNullException("context"); - } - - if (returnUrl == null) - { - throw new ArgumentNullException("returnUrl"); - } - - _returnUrl = returnUrl; - - string redirectUrl = GetServiceLoginUrl(returnUrl).ToString(); - context.Response.Redirect(redirectUrl, endResponse: true); - } - - /// <summary> - /// Check if authentication succeeded after user is redirected back from the service provider. - /// </summary> - /// <returns> - /// An instance of <see cref="AuthenticationResult"/> containing authentication result. - /// </returns> - public virtual AuthenticationResult VerifyAuthentication(HttpContextBase context) - { - if (context == null) - { - throw new ArgumentNullException("context"); - } - - string code = context.Request.QueryString["code"]; - if (String.IsNullOrEmpty(code)) - { - return AuthenticationResult.Failed; - } - - string accessToken = QueryAccessToken(_returnUrl, code); - if (accessToken == null) - { - return AuthenticationResult.Failed; - } - - IDictionary<string, string> userData = GetUserData(accessToken); - if (userData == null) - { - return AuthenticationResult.Failed; - } - string id = userData["id"]; - string name; - // Some oAuth providers do not return value for the 'username' attribute. - // In that case, try the 'name' attribute. If it's still unavailable, fall back to 'id' - if (!userData.TryGetValue("username", out name) && !userData.TryGetValue("name", out name)) - { - name = id; - } - - return new AuthenticationResult( - isSuccessful: true, - provider: ProviderName, - providerUserId: id, - userName: name, - extraData: userData); - } - - /// <summary> - /// Gets the full url pointing to the login page for this client. The url should include the - /// specified return url so that when the login completes, user is redirected back to that url. - /// </summary> - /// <param name="returnUrl">The return URL.</param> - /// <returns></returns> - [SuppressMessage("Microsoft.Naming", "CA1726:UsePreferredTerms", MessageId = "Login", Justification = "Login is used more consistently in ASP.Net")] - protected abstract Uri GetServiceLoginUrl(Uri returnUrl); - - /// <summary> - /// Queries the access token from the specified authorization code. - /// </summary> - /// <param name="returnUrl">The return URL.</param> - /// <param name="authorizationCode">The authorization code.</param> - /// <returns></returns> - protected abstract string QueryAccessToken(Uri returnUrl, string authorizationCode); - - /// <summary> - /// Given the access token, gets the logged-in user's data. The returned dictionary must include - /// two keys 'id', and 'username'. - /// </summary> - /// <param name="accessToken">The access token of the current user.</param> - /// <returns>A dictionary contains key-value pairs of user data</returns> - protected abstract IDictionary<string, string> GetUserData(string accessToken); - } +namespace DotNetOpenAuth.AspNet.Clients { + using System; + using System.Collections.Generic; + using System.Diagnostics.CodeAnalysis; + using System.Web; + + /// <summary> + /// Represents the base class for OAuth 2.0 clients + /// </summary> + public abstract class OAuth2Client : IAuthenticationClient { + private readonly string _providerName; + private Uri _returnUrl; + + /// <summary> + /// Initializes a new instance of the <see cref="OAuth2Client"/> class with the specified provider name. + /// </summary> + /// <param name="providerName">Name of the provider.</param> + protected OAuth2Client(string providerName) { + if (providerName == null) { + throw new ArgumentNullException("providerName"); + } + + _providerName = providerName; + } + + /// <summary> + /// Gets the name of the provider which provides authentication service. + /// </summary> + public string ProviderName { + get { return _providerName; } + } + + /// <summary> + /// Attempts to authenticate users by forwarding them to an external website, and + /// upon succcess or failure, redirect users back to the specified url. + /// </summary> + /// <param name="returnUrl">The return url after users have completed authenticating against external website.</param> + public virtual void RequestAuthentication(HttpContextBase context, Uri returnUrl) { + if (context == null) { + throw new ArgumentNullException("context"); + } + + if (returnUrl == null) { + throw new ArgumentNullException("returnUrl"); + } + + _returnUrl = returnUrl; + + string redirectUrl = GetServiceLoginUrl(returnUrl).ToString(); + context.Response.Redirect(redirectUrl, endResponse: true); + } + + /// <summary> + /// Check if authentication succeeded after user is redirected back from the service provider. + /// </summary> + /// <returns> + /// An instance of <see cref="AuthenticationResult"/> containing authentication result. + /// </returns> + public virtual AuthenticationResult VerifyAuthentication(HttpContextBase context) { + if (context == null) { + throw new ArgumentNullException("context"); + } + + string code = context.Request.QueryString["code"]; + if (String.IsNullOrEmpty(code)) { + return AuthenticationResult.Failed; + } + + string accessToken = QueryAccessToken(_returnUrl, code); + if (accessToken == null) { + return AuthenticationResult.Failed; + } + + IDictionary<string, string> userData = GetUserData(accessToken); + if (userData == null) { + return AuthenticationResult.Failed; + } + string id = userData["id"]; + string name; + // Some oAuth providers do not return value for the 'username' attribute. + // In that case, try the 'name' attribute. If it's still unavailable, fall back to 'id' + if (!userData.TryGetValue("username", out name) && !userData.TryGetValue("name", out name)) { + name = id; + } + + return new AuthenticationResult( + isSuccessful: true, + provider: ProviderName, + providerUserId: id, + userName: name, + extraData: userData); + } + + /// <summary> + /// Gets the full url pointing to the login page for this client. The url should include the + /// specified return url so that when the login completes, user is redirected back to that url. + /// </summary> + /// <param name="returnUrl">The return URL.</param> + /// <returns></returns> + [SuppressMessage("Microsoft.Naming", "CA1726:UsePreferredTerms", MessageId = "Login", Justification = "Login is used more consistently in ASP.Net")] + protected abstract Uri GetServiceLoginUrl(Uri returnUrl); + + /// <summary> + /// Queries the access token from the specified authorization code. + /// </summary> + /// <param name="returnUrl">The return URL.</param> + /// <param name="authorizationCode">The authorization code.</param> + /// <returns></returns> + protected abstract string QueryAccessToken(Uri returnUrl, string authorizationCode); + + /// <summary> + /// Given the access token, gets the logged-in user's data. The returned dictionary must include + /// two keys 'id', and 'username'. + /// </summary> + /// <param name="accessToken">The access token of the current user.</param> + /// <returns>A dictionary contains key-value pairs of user data</returns> + protected abstract IDictionary<string, string> GetUserData(string accessToken); + } }
\ No newline at end of file diff --git a/src/DotNetOpenAuth.AspNet/Clients/OAuth2/WindowsLiveClient.cs b/src/DotNetOpenAuth.AspNet/Clients/OAuth2/WindowsLiveClient.cs index 8d81c02..bddb801 100644 --- a/src/DotNetOpenAuth.AspNet/Clients/OAuth2/WindowsLiveClient.cs +++ b/src/DotNetOpenAuth.AspNet/Clients/OAuth2/WindowsLiveClient.cs @@ -1,41 +1,35 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Net; -using System.Text; -using DotNetOpenAuth.Messaging; +namespace DotNetOpenAuth.AspNet.Clients { + using System; + using System.Collections.Generic; + using System.IO; + using System.Net; + using System.Text; + using DotNetOpenAuth.Messaging; -namespace DotNetOpenAuth.AspNet.Clients -{ - public sealed class WindowsLiveClient : OAuth2Client - { - private const string TokenEndpoint = "https://oauth.live.com/token"; - private const string AuthorizationEndpoint = "https://oauth.live.com/authorize"; - private readonly string _appId; - private readonly string _appSecret; + public sealed class WindowsLiveClient : OAuth2Client { + private const string TokenEndpoint = "https://oauth.live.com/token"; + private const string AuthorizationEndpoint = "https://oauth.live.com/authorize"; + private readonly string _appId; + private readonly string _appSecret; - public WindowsLiveClient(string appId, string appSecret) - : base("windowslive") - { - if (String.IsNullOrEmpty(appId)) - { - throw new ArgumentNullException("appId"); - } + public WindowsLiveClient(string appId, string appSecret) + : base("windowslive") { + if (String.IsNullOrEmpty(appId)) { + throw new ArgumentNullException("appId"); + } - if (String.IsNullOrEmpty("appSecret")) - { - throw new ArgumentNullException("appSecret"); - } + if (String.IsNullOrEmpty("appSecret")) { + throw new ArgumentNullException("appSecret"); + } - _appId = appId; - _appSecret = appSecret; - } + _appId = appId; + _appSecret = appSecret; + } - protected override Uri GetServiceLoginUrl(Uri returnUrl) - { - var builder = new UriBuilder(AuthorizationEndpoint); - MessagingUtilities.AppendQueryArgs(builder, - new KeyValuePair<string, string>[] + protected override Uri GetServiceLoginUrl(Uri returnUrl) { + var builder = new UriBuilder(AuthorizationEndpoint); + MessagingUtilities.AppendQueryArgs(builder, + new KeyValuePair<string, string>[] { new KeyValuePair<string, string>("client_id", _appId), new KeyValuePair<string, string>("scope", "wl.basic"), @@ -43,67 +37,59 @@ namespace DotNetOpenAuth.AspNet.Clients new KeyValuePair<string, string>("redirect_uri", returnUrl.ToString()) }); - return builder.Uri; - } + return builder.Uri; + } - protected override string QueryAccessToken(Uri returnUrl, string authorizationCode) - { - var builder = new StringBuilder(); - builder.AppendFormat("client_id={0}", _appId); - builder.AppendFormat("&redirect_uri={0}", Uri.EscapeDataString(returnUrl.ToString())); - builder.AppendFormat("&client_secret={0}", _appSecret); - builder.AppendFormat("&code={0}", authorizationCode); - builder.Append("&grant_type=authorization_code"); + protected override string QueryAccessToken(Uri returnUrl, string authorizationCode) { + var builder = new StringBuilder(); + builder.AppendFormat("client_id={0}", _appId); + builder.AppendFormat("&redirect_uri={0}", Uri.EscapeDataString(returnUrl.ToString())); + builder.AppendFormat("&client_secret={0}", _appSecret); + builder.AppendFormat("&code={0}", authorizationCode); + builder.Append("&grant_type=authorization_code"); - WebRequest tokenRequest = WebRequest.Create(TokenEndpoint); - tokenRequest.ContentType = "application/x-www-form-urlencoded"; - tokenRequest.ContentLength = builder.Length; - tokenRequest.Method = "POST"; + WebRequest tokenRequest = WebRequest.Create(TokenEndpoint); + tokenRequest.ContentType = "application/x-www-form-urlencoded"; + tokenRequest.ContentLength = builder.Length; + tokenRequest.Method = "POST"; - using (Stream requestStream = tokenRequest.GetRequestStream()) - { - var writer = new StreamWriter(requestStream); - writer.Write(builder.ToString()); - writer.Flush(); - } + using (Stream requestStream = tokenRequest.GetRequestStream()) { + var writer = new StreamWriter(requestStream); + writer.Write(builder.ToString()); + writer.Flush(); + } - HttpWebResponse tokenResponse = (HttpWebResponse)tokenRequest.GetResponse(); - if (tokenResponse.StatusCode == HttpStatusCode.OK) - { - using (Stream responseStream = tokenResponse.GetResponseStream()) - { - var tokenData = JsonHelper.Deserialize<OAuth2AccessTokenData>(responseStream); - if (tokenData != null) - { - return tokenData.AccessToken; - } - } - } + HttpWebResponse tokenResponse = (HttpWebResponse)tokenRequest.GetResponse(); + if (tokenResponse.StatusCode == HttpStatusCode.OK) { + using (Stream responseStream = tokenResponse.GetResponseStream()) { + var tokenData = JsonHelper.Deserialize<OAuth2AccessTokenData>(responseStream); + if (tokenData != null) { + return tokenData.AccessToken; + } + } + } - return null; - } + return null; + } - protected override IDictionary<string, string> GetUserData(string accessToken) - { - WindowsLiveUserData graph; - var request = WebRequest.Create("https://apis.live.net/v5.0/me?access_token=" + Uri.EscapeDataString(accessToken)); - using (var response = request.GetResponse()) - { - using (var responseStream = response.GetResponseStream()) - { - graph = JsonHelper.Deserialize<WindowsLiveUserData>(responseStream); - } - } + protected override IDictionary<string, string> GetUserData(string accessToken) { + WindowsLiveUserData graph; + var request = WebRequest.Create("https://apis.live.net/v5.0/me?access_token=" + Uri.EscapeDataString(accessToken)); + using (var response = request.GetResponse()) { + using (var responseStream = response.GetResponseStream()) { + graph = JsonHelper.Deserialize<WindowsLiveUserData>(responseStream); + } + } - var userData = new Dictionary<string, string>(); - userData.AddItemIfNotEmpty("id", graph.Id); - userData.AddItemIfNotEmpty("username", graph.Name); - userData.AddItemIfNotEmpty("name", graph.Name); - userData.AddItemIfNotEmpty("link", graph.Link == null ? null : graph.Link.ToString()); - userData.AddItemIfNotEmpty("gender", graph.Gender); - userData.AddItemIfNotEmpty("firstname", graph.FirstName); - userData.AddItemIfNotEmpty("lastname", graph.LastName); - return userData; - } - } + var userData = new Dictionary<string, string>(); + userData.AddItemIfNotEmpty("id", graph.Id); + userData.AddItemIfNotEmpty("username", graph.Name); + userData.AddItemIfNotEmpty("name", graph.Name); + userData.AddItemIfNotEmpty("link", graph.Link == null ? null : graph.Link.ToString()); + userData.AddItemIfNotEmpty("gender", graph.Gender); + userData.AddItemIfNotEmpty("firstname", graph.FirstName); + userData.AddItemIfNotEmpty("lastname", graph.LastName); + return userData; + } + } } diff --git a/src/DotNetOpenAuth.AspNet/Clients/OAuth2/WindowsLiveUserData.cs b/src/DotNetOpenAuth.AspNet/Clients/OAuth2/WindowsLiveUserData.cs index 7371250..8147e2f 100644 --- a/src/DotNetOpenAuth.AspNet/Clients/OAuth2/WindowsLiveUserData.cs +++ b/src/DotNetOpenAuth.AspNet/Clients/OAuth2/WindowsLiveUserData.cs @@ -1,36 +1,34 @@ -using System; -using System.Runtime.Serialization; -using System.ComponentModel; +namespace DotNetOpenAuth.AspNet.Clients { + using System; + using System.Runtime.Serialization; + using System.ComponentModel; -namespace DotNetOpenAuth.AspNet.Clients -{ - /// <summary> - /// Contains data of a Windows Live user. - /// </summary> - /// <remarks> - /// Technically, this class doesn't need to be public, but because we want to make it serializable - /// in medium trust, it has to be public. - /// </remarks> - [DataContract] - [EditorBrowsable(EditorBrowsableState.Never)] - public class WindowsLiveUserData - { - [DataMember(Name = "id")] - public string Id { get; set; } + /// <summary> + /// Contains data of a Windows Live user. + /// </summary> + /// <remarks> + /// Technically, this class doesn't need to be public, but because we want to make it serializable + /// in medium trust, it has to be public. + /// </remarks> + [DataContract] + [EditorBrowsable(EditorBrowsableState.Never)] + public class WindowsLiveUserData { + [DataMember(Name = "id")] + public string Id { get; set; } - [DataMember(Name = "name")] - public string Name { get; set; } + [DataMember(Name = "name")] + public string Name { get; set; } - [DataMember(Name = "link")] - public Uri Link { get; set; } + [DataMember(Name = "link")] + public Uri Link { get; set; } - [DataMember(Name = "gender")] - public string Gender { get; set; } + [DataMember(Name = "gender")] + public string Gender { get; set; } - [DataMember(Name = "first_name")] - public string FirstName { get; set; } + [DataMember(Name = "first_name")] + public string FirstName { get; set; } - [DataMember(Name = "last_name")] - public string LastName { get; set; } - } + [DataMember(Name = "last_name")] + public string LastName { get; set; } + } } diff --git a/src/DotNetOpenAuth.AspNet/Clients/OpenID/GoogleOpenIdClient.cs b/src/DotNetOpenAuth.AspNet/Clients/OpenID/GoogleOpenIdClient.cs index c9fa6a7..654fff6 100644 --- a/src/DotNetOpenAuth.AspNet/Clients/OpenID/GoogleOpenIdClient.cs +++ b/src/DotNetOpenAuth.AspNet/Clients/OpenID/GoogleOpenIdClient.cs @@ -1,55 +1,49 @@ -using System.Collections.Generic; -using DotNetOpenAuth.OpenId.Extensions.AttributeExchange; -using DotNetOpenAuth.OpenId.RelyingParty; +namespace DotNetOpenAuth.AspNet.Clients { + using System.Collections.Generic; + using DotNetOpenAuth.OpenId.Extensions.AttributeExchange; + using DotNetOpenAuth.OpenId.RelyingParty; -namespace DotNetOpenAuth.AspNet.Clients -{ - /// <summary> - /// Represents Google OpenID client. - /// </summary> - public sealed class GoogleOpenIdClient : OpenIDClient - { - public GoogleOpenIdClient() : - base("google", "https://www.google.com/accounts/o8/id") - { - } + /// <summary> + /// Represents Google OpenID client. + /// </summary> + public sealed class GoogleOpenIdClient : OpenIDClient { + public GoogleOpenIdClient() : + base("google", "https://www.google.com/accounts/o8/id") { + } - /// <summary> - /// Called just before the authentication request is sent to service provider. - /// </summary> - /// <param name="request">The request.</param> - protected override void OnBeforeSendingAuthenticationRequest(IAuthenticationRequest request) - { - // Attribute Exchange extensions - var fetchRequest = new FetchRequest(); - fetchRequest.Attributes.Add(new AttributeRequest(WellKnownAttributes.Contact.Email, isRequired: true)); - fetchRequest.Attributes.Add(new AttributeRequest(WellKnownAttributes.Contact.HomeAddress.Country, isRequired: false)); - fetchRequest.Attributes.Add(new AttributeRequest(WellKnownAttributes.Name.First, isRequired: false)); - fetchRequest.Attributes.Add(new AttributeRequest(WellKnownAttributes.Name.Last, isRequired: false)); + /// <summary> + /// Called just before the authentication request is sent to service provider. + /// </summary> + /// <param name="request">The request.</param> + protected override void OnBeforeSendingAuthenticationRequest(IAuthenticationRequest request) { + // Attribute Exchange extensions + var fetchRequest = new FetchRequest(); + fetchRequest.Attributes.Add(new AttributeRequest(WellKnownAttributes.Contact.Email, isRequired: true)); + fetchRequest.Attributes.Add(new AttributeRequest(WellKnownAttributes.Contact.HomeAddress.Country, isRequired: false)); + fetchRequest.Attributes.Add(new AttributeRequest(WellKnownAttributes.Name.First, isRequired: false)); + fetchRequest.Attributes.Add(new AttributeRequest(WellKnownAttributes.Name.Last, isRequired: false)); - request.AddExtension(fetchRequest); - } + request.AddExtension(fetchRequest); + } - /// <summary> - /// Gets the extra data obtained from the response message when authentication is successful. - /// </summary> - /// <param name="response">The response message.</param> - /// <returns></returns> - protected override Dictionary<string, string> GetExtraData(IAuthenticationResponse response) - { - FetchResponse fetchResponse = response.GetExtension<FetchResponse>(); - if (fetchResponse != null) - { - var extraData = new Dictionary<string, string>(); - extraData.AddItemIfNotEmpty("email", fetchResponse.GetAttributeValue(WellKnownAttributes.Contact.Email)); - extraData.AddItemIfNotEmpty("country", fetchResponse.GetAttributeValue(WellKnownAttributes.Contact.HomeAddress.Country)); - extraData.AddItemIfNotEmpty("firstName", fetchResponse.GetAttributeValue(WellKnownAttributes.Name.First)); - extraData.AddItemIfNotEmpty("lastName", fetchResponse.GetAttributeValue(WellKnownAttributes.Name.Last)); + /// <summary> + /// Gets the extra data obtained from the response message when authentication is successful. + /// </summary> + /// <param name="response">The response message.</param> + /// <returns></returns> + protected override Dictionary<string, string> GetExtraData(IAuthenticationResponse response) { + FetchResponse fetchResponse = response.GetExtension<FetchResponse>(); + if (fetchResponse != null) { + var extraData = new Dictionary<string, string>(); + extraData.AddItemIfNotEmpty("email", fetchResponse.GetAttributeValue(WellKnownAttributes.Contact.Email)); + extraData.AddItemIfNotEmpty("country", fetchResponse.GetAttributeValue(WellKnownAttributes.Contact.HomeAddress.Country)); + extraData.AddItemIfNotEmpty("firstName", fetchResponse.GetAttributeValue(WellKnownAttributes.Name.First)); + extraData.AddItemIfNotEmpty("lastName", fetchResponse.GetAttributeValue(WellKnownAttributes.Name.Last)); - return extraData; - } + return extraData; + } - return null; - } - } + return null; + } + } }
\ No newline at end of file diff --git a/src/DotNetOpenAuth.AspNet/Clients/OpenID/OpenIDClient.cs b/src/DotNetOpenAuth.AspNet/Clients/OpenID/OpenIDClient.cs index d426d7d..4bfb87e 100644 --- a/src/DotNetOpenAuth.AspNet/Clients/OpenID/OpenIDClient.cs +++ b/src/DotNetOpenAuth.AspNet/Clients/OpenID/OpenIDClient.cs @@ -1,143 +1,127 @@ -using System; -using System.Collections.Generic; -using System.Globalization; -using System.Web; -using DotNetOpenAuth.OpenId; -using DotNetOpenAuth.OpenId.RelyingParty; -using DotNetOpenAuth.AspNet.Resources; - -namespace DotNetOpenAuth.AspNet.Clients -{ - /// <summary> - /// Base classes for OpenID clients. - /// </summary> - public class OpenIDClient : IAuthenticationClient - { - private readonly Identifier _providerIdentifier; - private readonly string _providerName; - - private static OpenIdRelyingParty _openidRelayingParty = - new OpenIdRelyingParty(new StandardRelyingPartyApplicationStore()); - - /// <summary> - /// Initializes a new instance of the <see cref="OpenIDClient"/> class. - /// </summary> - /// <param name="providerName">Name of the provider.</param> - /// <param name="providerIdentifier">The provider identifier, which is the usually the login url of the specified provider.</param> - public OpenIDClient(string providerName, string providerIdentifier) - { - if (String.IsNullOrEmpty(providerIdentifier)) - { - throw new ArgumentException( - String.Format(CultureInfo.CurrentCulture, WebResources.Argument_Cannot_Be_Null_Or_Empty, "providerIdentifier"), - "providerIdentifier"); - } - - if (String.IsNullOrEmpty(providerName)) - { - throw new ArgumentException( - String.Format(CultureInfo.CurrentCulture, WebResources.Argument_Cannot_Be_Null_Or_Empty, "providerName"), - "providerName"); - } - - _providerName = providerName; - if (!Identifier.TryParse(providerIdentifier, out _providerIdentifier) || _providerIdentifier == null) - { - throw new ArgumentException(WebResources.OpenIDInvalidIdentifier, "providerIdentifier"); - } - } - - /// <summary> - /// Gets the name of the provider which provides authentication service. - /// </summary> - public string ProviderName - { - get - { - return _providerName; - } - } - - /// <summary> - /// Attempts to authenticate users by forwarding them to an external website, and - /// upon succcess or failure, redirect users back to the specified url. - /// </summary> - /// <param name="context">The context of the current request.</param> - /// <param name="returnUrl">The return url after users have completed authenticating against external website.</param> - [System.Diagnostics.CodeAnalysis.SuppressMessage( - "Microsoft.Usage", - "CA2234:PassSystemUriObjectsInsteadOfStrings", - Justification = "We don't have a Uri object handy.")] - public virtual void RequestAuthentication(HttpContextBase context, Uri returnUrl) - { - if (returnUrl == null) - { - throw new ArgumentNullException("returnUrl"); - } - - var realm = new Realm(returnUrl.GetComponents(UriComponents.SchemeAndServer, UriFormat.Unescaped)); - IAuthenticationRequest request = _openidRelayingParty.CreateRequest(_providerIdentifier, realm, returnUrl); - - // give subclasses a chance to modify request message, e.g. add extension attributes, etc. - OnBeforeSendingAuthenticationRequest(request); - - request.RedirectToProvider(); - } - - /// <summary> - /// Called just before the authentication request is sent to service provider. - /// </summary> - /// <param name="request">The request.</param> - protected virtual void OnBeforeSendingAuthenticationRequest(IAuthenticationRequest request) - { - } - - /// <summary> - /// Check if authentication succeeded after user is redirected back from the service provider. - /// </summary> - /// <param name="context">The context of the current request.</param> - /// <returns> - /// An instance of <see cref="AuthenticationResult"/> containing authentication result. - /// </returns> - public virtual AuthenticationResult VerifyAuthentication(HttpContextBase context) - { - IAuthenticationResponse response = _openidRelayingParty.GetResponse(); - if (response == null) - { - throw new InvalidOperationException(WebResources.OpenIDFailedToGetResponse); - } - - if (response.Status == AuthenticationStatus.Authenticated) - { - string id = response.ClaimedIdentifier; - string username; - - Dictionary<string, string> extraData = GetExtraData(response) ?? new Dictionary<string, string>(); - // try to look up username from the 'username' or 'email' property. If not found, fall back to 'friendly id' - if (!extraData.TryGetValue("username", out username) && !extraData.TryGetValue("email", out username)) - { - username = response.FriendlyIdentifierForDisplay; - } - - return new AuthenticationResult( - true, - ProviderName, - id, - username, - extraData); - } - - return AuthenticationResult.Failed; - } - - /// <summary> - /// Gets the extra data obtained from the response message when authentication is successful. - /// </summary> - /// <param name="response">The response message.</param> - /// <returns></returns> - protected virtual Dictionary<string, string> GetExtraData(IAuthenticationResponse response) - { - return null; - } - } +namespace DotNetOpenAuth.AspNet.Clients { + using System; + using System.Collections.Generic; + using System.Globalization; + using System.Web; + using DotNetOpenAuth.OpenId; + using DotNetOpenAuth.OpenId.RelyingParty; + using DotNetOpenAuth.AspNet.Resources; + + /// <summary> + /// Base classes for OpenID clients. + /// </summary> + public class OpenIDClient : IAuthenticationClient { + private readonly Identifier _providerIdentifier; + private readonly string _providerName; + + private static OpenIdRelyingParty _openidRelayingParty = + new OpenIdRelyingParty(new StandardRelyingPartyApplicationStore()); + + /// <summary> + /// Initializes a new instance of the <see cref="OpenIDClient"/> class. + /// </summary> + /// <param name="providerName">Name of the provider.</param> + /// <param name="providerIdentifier">The provider identifier, which is the usually the login url of the specified provider.</param> + public OpenIDClient(string providerName, string providerIdentifier) { + if (String.IsNullOrEmpty(providerIdentifier)) { + throw new ArgumentException( + String.Format(CultureInfo.CurrentCulture, WebResources.Argument_Cannot_Be_Null_Or_Empty, "providerIdentifier"), + "providerIdentifier"); + } + + if (String.IsNullOrEmpty(providerName)) { + throw new ArgumentException( + String.Format(CultureInfo.CurrentCulture, WebResources.Argument_Cannot_Be_Null_Or_Empty, "providerName"), + "providerName"); + } + + _providerName = providerName; + if (!Identifier.TryParse(providerIdentifier, out _providerIdentifier) || _providerIdentifier == null) { + throw new ArgumentException(WebResources.OpenIDInvalidIdentifier, "providerIdentifier"); + } + } + + /// <summary> + /// Gets the name of the provider which provides authentication service. + /// </summary> + public string ProviderName { + get { + return _providerName; + } + } + + /// <summary> + /// Attempts to authenticate users by forwarding them to an external website, and + /// upon succcess or failure, redirect users back to the specified url. + /// </summary> + /// <param name="context">The context of the current request.</param> + /// <param name="returnUrl">The return url after users have completed authenticating against external website.</param> + [System.Diagnostics.CodeAnalysis.SuppressMessage( + "Microsoft.Usage", + "CA2234:PassSystemUriObjectsInsteadOfStrings", + Justification = "We don't have a Uri object handy.")] + public virtual void RequestAuthentication(HttpContextBase context, Uri returnUrl) { + if (returnUrl == null) { + throw new ArgumentNullException("returnUrl"); + } + + var realm = new Realm(returnUrl.GetComponents(UriComponents.SchemeAndServer, UriFormat.Unescaped)); + IAuthenticationRequest request = _openidRelayingParty.CreateRequest(_providerIdentifier, realm, returnUrl); + + // give subclasses a chance to modify request message, e.g. add extension attributes, etc. + OnBeforeSendingAuthenticationRequest(request); + + request.RedirectToProvider(); + } + + /// <summary> + /// Called just before the authentication request is sent to service provider. + /// </summary> + /// <param name="request">The request.</param> + protected virtual void OnBeforeSendingAuthenticationRequest(IAuthenticationRequest request) { + } + + /// <summary> + /// Check if authentication succeeded after user is redirected back from the service provider. + /// </summary> + /// <param name="context">The context of the current request.</param> + /// <returns> + /// An instance of <see cref="AuthenticationResult"/> containing authentication result. + /// </returns> + public virtual AuthenticationResult VerifyAuthentication(HttpContextBase context) { + IAuthenticationResponse response = _openidRelayingParty.GetResponse(); + if (response == null) { + throw new InvalidOperationException(WebResources.OpenIDFailedToGetResponse); + } + + if (response.Status == AuthenticationStatus.Authenticated) { + string id = response.ClaimedIdentifier; + string username; + + Dictionary<string, string> extraData = GetExtraData(response) ?? new Dictionary<string, string>(); + // try to look up username from the 'username' or 'email' property. If not found, fall back to 'friendly id' + if (!extraData.TryGetValue("username", out username) && !extraData.TryGetValue("email", out username)) { + username = response.FriendlyIdentifierForDisplay; + } + + return new AuthenticationResult( + true, + ProviderName, + id, + username, + extraData); + } + + return AuthenticationResult.Failed; + } + + /// <summary> + /// Gets the extra data obtained from the response message when authentication is successful. + /// </summary> + /// <param name="response">The response message.</param> + /// <returns></returns> + protected virtual Dictionary<string, string> GetExtraData(IAuthenticationResponse response) { + return null; + } + } }
\ No newline at end of file diff --git a/src/DotNetOpenAuth.AspNet/Clients/OpenID/YahooOpenIdClient.cs b/src/DotNetOpenAuth.AspNet/Clients/OpenID/YahooOpenIdClient.cs index 4a29111..dcf6a13 100644 --- a/src/DotNetOpenAuth.AspNet/Clients/OpenID/YahooOpenIdClient.cs +++ b/src/DotNetOpenAuth.AspNet/Clients/OpenID/YahooOpenIdClient.cs @@ -1,48 +1,42 @@ -using System.Collections.Generic; -using DotNetOpenAuth.OpenId.Extensions.AttributeExchange; -using DotNetOpenAuth.OpenId.RelyingParty; +namespace DotNetOpenAuth.AspNet.Clients { + using System.Collections.Generic; + using DotNetOpenAuth.OpenId.Extensions.AttributeExchange; + using DotNetOpenAuth.OpenId.RelyingParty; -namespace DotNetOpenAuth.AspNet.Clients -{ - public sealed class YahooOpenIdClient : OpenIDClient - { - public YahooOpenIdClient() : - base("yahoo", "http://me.yahoo.com") - { - } + public sealed class YahooOpenIdClient : OpenIDClient { + public YahooOpenIdClient() : + base("yahoo", "http://me.yahoo.com") { + } - /// <summary> - /// Called just before the authentication request is sent to service provider. - /// </summary> - /// <param name="request">The request.</param> - protected override void OnBeforeSendingAuthenticationRequest(IAuthenticationRequest request) - { - // Attribute Exchange extensions - var fetchRequest = new FetchRequest(); - fetchRequest.Attributes.Add(new AttributeRequest(WellKnownAttributes.Contact.Email, isRequired: true)); - fetchRequest.Attributes.Add(new AttributeRequest(WellKnownAttributes.Name.FullName, isRequired: false)); + /// <summary> + /// Called just before the authentication request is sent to service provider. + /// </summary> + /// <param name="request">The request.</param> + protected override void OnBeforeSendingAuthenticationRequest(IAuthenticationRequest request) { + // Attribute Exchange extensions + var fetchRequest = new FetchRequest(); + fetchRequest.Attributes.Add(new AttributeRequest(WellKnownAttributes.Contact.Email, isRequired: true)); + fetchRequest.Attributes.Add(new AttributeRequest(WellKnownAttributes.Name.FullName, isRequired: false)); - request.AddExtension(fetchRequest); - } + request.AddExtension(fetchRequest); + } - /// <summary> - /// Gets the extra data obtained from the response message when authentication is successful. - /// </summary> - /// <param name="response">The response message.</param> - /// <returns></returns> - protected override Dictionary<string, string> GetExtraData(IAuthenticationResponse response) - { - FetchResponse fetchResponse = response.GetExtension<FetchResponse>(); - if (fetchResponse != null) - { - var extraData = new Dictionary<string, string>(); - extraData.AddItemIfNotEmpty("email", fetchResponse.GetAttributeValue(WellKnownAttributes.Contact.Email)); - extraData.AddItemIfNotEmpty("fullName", fetchResponse.GetAttributeValue(WellKnownAttributes.Name.FullName)); + /// <summary> + /// Gets the extra data obtained from the response message when authentication is successful. + /// </summary> + /// <param name="response">The response message.</param> + /// <returns></returns> + protected override Dictionary<string, string> GetExtraData(IAuthenticationResponse response) { + FetchResponse fetchResponse = response.GetExtension<FetchResponse>(); + if (fetchResponse != null) { + var extraData = new Dictionary<string, string>(); + extraData.AddItemIfNotEmpty("email", fetchResponse.GetAttributeValue(WellKnownAttributes.Contact.Email)); + extraData.AddItemIfNotEmpty("fullName", fetchResponse.GetAttributeValue(WellKnownAttributes.Name.FullName)); - return extraData; - } + return extraData; + } - return null; - } - } + return null; + } + } } diff --git a/src/DotNetOpenAuth.AspNet/IAuthenticationClient.cs b/src/DotNetOpenAuth.AspNet/IAuthenticationClient.cs index 2f4f938..b5745c3 100644 --- a/src/DotNetOpenAuth.AspNet/IAuthenticationClient.cs +++ b/src/DotNetOpenAuth.AspNet/IAuthenticationClient.cs @@ -1,33 +1,31 @@ -using System; -using System.Web; +namespace DotNetOpenAuth.AspNet { + using System; + using System.Web; -namespace DotNetOpenAuth.AspNet -{ - /// <summary> - /// Represents a client which can authenticate users via an external website/provider. - /// </summary> - public interface IAuthenticationClient - { - /// <summary> - /// Gets the name of the provider which provides authentication service. - /// </summary> - string ProviderName { get; } + /// <summary> + /// Represents a client which can authenticate users via an external website/provider. + /// </summary> + public interface IAuthenticationClient { + /// <summary> + /// Gets the name of the provider which provides authentication service. + /// </summary> + string ProviderName { get; } - /// <summary> - /// Attempts to authenticate users by forwarding them to an external website, and - /// upon succcess or failure, redirect users back to the specified url. - /// </summary> - /// <param name="context">The context of the current request.</param> - /// <param name="returnUrl">The return url after users have completed authenticating against external website.</param> - void RequestAuthentication(HttpContextBase context, Uri returnUrl); + /// <summary> + /// Attempts to authenticate users by forwarding them to an external website, and + /// upon succcess or failure, redirect users back to the specified url. + /// </summary> + /// <param name="context">The context of the current request.</param> + /// <param name="returnUrl">The return url after users have completed authenticating against external website.</param> + void RequestAuthentication(HttpContextBase context, Uri returnUrl); - /// <summary> - /// Check if authentication succeeded after user is redirected back from the service provider. - /// </summary> - /// <param name="context">The context of the current request.</param> - /// <returns> - /// An instance of <see cref="AuthenticationResult"/> containing authentication result. - /// </returns> - AuthenticationResult VerifyAuthentication(HttpContextBase context); - } + /// <summary> + /// Check if authentication succeeded after user is redirected back from the service provider. + /// </summary> + /// <param name="context">The context of the current request.</param> + /// <returns> + /// An instance of <see cref="AuthenticationResult"/> containing authentication result. + /// </returns> + AuthenticationResult VerifyAuthentication(HttpContextBase context); + } } diff --git a/src/DotNetOpenAuth.AspNet/IOpenAuthDataProvider.cs b/src/DotNetOpenAuth.AspNet/IOpenAuthDataProvider.cs index b6930e3..5eb19a5 100644 --- a/src/DotNetOpenAuth.AspNet/IOpenAuthDataProvider.cs +++ b/src/DotNetOpenAuth.AspNet/IOpenAuthDataProvider.cs @@ -1,8 +1,5 @@ - -namespace DotNetOpenAuth.AspNet -{ - public interface IOpenAuthDataProvider - { - string GetUserNameFromOpenAuth(string openAuthProvider, string openAuthId); - } +namespace DotNetOpenAuth.AspNet { + public interface IOpenAuthDataProvider { + string GetUserNameFromOpenAuth(string openAuthProvider, string openAuthId); + } }
\ No newline at end of file diff --git a/src/DotNetOpenAuth.AspNet/OpenAuthAuthenticationTicketHelper.cs b/src/DotNetOpenAuth.AspNet/OpenAuthAuthenticationTicketHelper.cs index ec6fd8f..22c1556 100644 --- a/src/DotNetOpenAuth.AspNet/OpenAuthAuthenticationTicketHelper.cs +++ b/src/DotNetOpenAuth.AspNet/OpenAuthAuthenticationTicketHelper.cs @@ -1,88 +1,73 @@ -using System; -using System.Diagnostics; -using System.Web; -using System.Web.Security; -using DotNetOpenAuth.AspNet.Resources; +namespace DotNetOpenAuth.AspNet { + using System; + using System.Diagnostics; + using System.Web; + using System.Web.Security; + using DotNetOpenAuth.AspNet.Resources; -namespace DotNetOpenAuth.AspNet -{ - internal static class OpenAuthAuthenticationTicketHelper - { - private const string OpenAuthCookieToken = "OpenAuth"; + internal static class OpenAuthAuthenticationTicketHelper { + private const string OpenAuthCookieToken = "OpenAuth"; - public static void SetAuthenticationTicket(HttpContextBase context, string userName, bool createPersistentCookie) - { - if (!context.Request.IsSecureConnection && FormsAuthentication.RequireSSL) - { - throw new HttpException(WebResources.ConnectionNotSecure); - } + public static void SetAuthenticationTicket(HttpContextBase context, string userName, bool createPersistentCookie) { + if (!context.Request.IsSecureConnection && FormsAuthentication.RequireSSL) { + throw new HttpException(WebResources.ConnectionNotSecure); + } - HttpCookie cookie = GetAuthCookie(userName, createPersistentCookie); - context.Response.Cookies.Add(cookie); - } + HttpCookie cookie = GetAuthCookie(userName, createPersistentCookie); + context.Response.Cookies.Add(cookie); + } - public static bool IsValidAuthenticationTicket(HttpContextBase context) - { - HttpCookie cookie = context.Request.Cookies[FormsAuthentication.FormsCookieName]; - if (cookie == null) - { - return false; - } + public static bool IsValidAuthenticationTicket(HttpContextBase context) { + HttpCookie cookie = context.Request.Cookies[FormsAuthentication.FormsCookieName]; + if (cookie == null) { + return false; + } - string encryptedCookieData = cookie.Value; - if (String.IsNullOrEmpty(encryptedCookieData)) - { - return false; - } + string encryptedCookieData = cookie.Value; + if (String.IsNullOrEmpty(encryptedCookieData)) { + return false; + } - try - { - FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(encryptedCookieData); - return authTicket != null && !authTicket.Expired && authTicket.UserData == OpenAuthCookieToken; - } - catch (ArgumentException) - { - return false; - } - } + try { + FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(encryptedCookieData); + return authTicket != null && !authTicket.Expired && authTicket.UserData == OpenAuthCookieToken; + } catch (ArgumentException) { + return false; + } + } - private static HttpCookie GetAuthCookie(string userName, bool createPersistentCookie) - { - Debug.Assert(!String.IsNullOrEmpty(userName)); + private static HttpCookie GetAuthCookie(string userName, bool createPersistentCookie) { + Debug.Assert(!String.IsNullOrEmpty(userName)); - var ticket = new FormsAuthenticationTicket( - /* version */ 2, - userName, - DateTime.Now, - DateTime.Now.Add(FormsAuthentication.Timeout), - createPersistentCookie, - OpenAuthCookieToken, - FormsAuthentication.FormsCookiePath); + var ticket = new FormsAuthenticationTicket( + /* version */ 2, + userName, + DateTime.Now, + DateTime.Now.Add(FormsAuthentication.Timeout), + createPersistentCookie, + OpenAuthCookieToken, + FormsAuthentication.FormsCookiePath); - string encryptedTicket = FormsAuthentication.Encrypt(ticket); - if (encryptedTicket == null || encryptedTicket.Length < 1) - { - throw new HttpException(WebResources.FailedToEncryptTicket); - } + string encryptedTicket = FormsAuthentication.Encrypt(ticket); + if (encryptedTicket == null || encryptedTicket.Length < 1) { + throw new HttpException(WebResources.FailedToEncryptTicket); + } - var cookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket) - { - HttpOnly = true, - Path = FormsAuthentication.FormsCookiePath, - Secure = FormsAuthentication.RequireSSL - }; + var cookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket) { + HttpOnly = true, + Path = FormsAuthentication.FormsCookiePath, + Secure = FormsAuthentication.RequireSSL + }; - if (FormsAuthentication.CookieDomain != null) - { - cookie.Domain = FormsAuthentication.CookieDomain; - } + if (FormsAuthentication.CookieDomain != null) { + cookie.Domain = FormsAuthentication.CookieDomain; + } - if (ticket.IsPersistent) - { - cookie.Expires = ticket.Expiration; - } + if (ticket.IsPersistent) { + cookie.Expires = ticket.Expiration; + } - return cookie; - } - } + return cookie; + } + } }
\ No newline at end of file diff --git a/src/DotNetOpenAuth.AspNet/OpenAuthSecurityManager.cs b/src/DotNetOpenAuth.AspNet/OpenAuthSecurityManager.cs index 98a3da1..188307f 100644 --- a/src/DotNetOpenAuth.AspNet/OpenAuthSecurityManager.cs +++ b/src/DotNetOpenAuth.AspNet/OpenAuthSecurityManager.cs @@ -1,114 +1,112 @@ -using System; -using System.Diagnostics.CodeAnalysis; -using System.Diagnostics.Contracts; -using System.Web; -using DotNetOpenAuth.Messaging; +namespace DotNetOpenAuth.AspNet { + using System; + using System.Diagnostics.CodeAnalysis; + using System.Diagnostics.Contracts; + using System.Web; + using DotNetOpenAuth.Messaging; -namespace DotNetOpenAuth.AspNet { - /// <summary> - /// Manage authenticating with an external OAuth or OpenID provider - /// </summary> - public class OpenAuthSecurityManager { - private const string ProviderQueryStringName = "__provider__"; + /// <summary> + /// Manage authenticating with an external OAuth or OpenID provider + /// </summary> + public class OpenAuthSecurityManager { + private const string ProviderQueryStringName = "__provider__"; - private readonly HttpContextBase _requestContext; - private readonly IOpenAuthDataProvider _dataProvider; - private readonly IAuthenticationClient _authenticationProvider; + private readonly HttpContextBase _requestContext; + private readonly IOpenAuthDataProvider _dataProvider; + private readonly IAuthenticationClient _authenticationProvider; - /// <summary> - /// Initializes a new instance of the <see cref="OpenAuthSecurityManager"/> class. - /// </summary> - /// <param name="requestContext">The request context.</param> - public OpenAuthSecurityManager(HttpContextBase requestContext) : - this(requestContext, provider: null, dataProvider: null) { - } + /// <summary> + /// Initializes a new instance of the <see cref="OpenAuthSecurityManager"/> class. + /// </summary> + /// <param name="requestContext">The request context.</param> + public OpenAuthSecurityManager(HttpContextBase requestContext) : + this(requestContext, provider: null, dataProvider: null) { + } - /// <summary> - /// Initializes a new instance of the <see cref="OpenAuthSecurityManager"/> class. - /// </summary> - /// <param name="requestContext">The request context.</param> - /// <param name="provider">The provider.</param> - /// <param name="dataProvider">The data provider.</param> - public OpenAuthSecurityManager(HttpContextBase requestContext, IAuthenticationClient provider, IOpenAuthDataProvider dataProvider) { - if (requestContext == null) - { - throw new ArgumentNullException("requestContext"); - } + /// <summary> + /// Initializes a new instance of the <see cref="OpenAuthSecurityManager"/> class. + /// </summary> + /// <param name="requestContext">The request context.</param> + /// <param name="provider">The provider.</param> + /// <param name="dataProvider">The data provider.</param> + public OpenAuthSecurityManager(HttpContextBase requestContext, IAuthenticationClient provider, IOpenAuthDataProvider dataProvider) { + if (requestContext == null) { + throw new ArgumentNullException("requestContext"); + } - _requestContext = requestContext; - _dataProvider = dataProvider; - _authenticationProvider = provider; - } + _requestContext = requestContext; + _dataProvider = dataProvider; + _authenticationProvider = provider; + } - /// <summary> - /// Requests the specified provider to start the authentication by directing users to an external website - /// </summary> - /// <param name="returnUrl">The return url after user is authenticated.</param> - public void RequestAuthentication(string returnUrl) { - // convert returnUrl to an absolute path - Uri uri; - if (!String.IsNullOrEmpty(returnUrl)) { - uri = UriHelper.ConvertToAbsoluteUri(returnUrl, _requestContext); - } - else { - uri = HttpRequestInfo.GetPublicFacingUrl(_requestContext.Request, _requestContext.Request.ServerVariables); - } - // attach the provider parameter so that we know which provider initiated - // the login when user is redirected back to this page - uri = uri.AttachQueryStringParameter(ProviderQueryStringName, _authenticationProvider.ProviderName); - _authenticationProvider.RequestAuthentication(_requestContext, uri); - } + /// <summary> + /// Requests the specified provider to start the authentication by directing users to an external website + /// </summary> + /// <param name="returnUrl">The return url after user is authenticated.</param> + public void RequestAuthentication(string returnUrl) { + // convert returnUrl to an absolute path + Uri uri; + if (!String.IsNullOrEmpty(returnUrl)) { + uri = UriHelper.ConvertToAbsoluteUri(returnUrl, _requestContext); + } else { + uri = HttpRequestInfo.GetPublicFacingUrl(_requestContext.Request, _requestContext.Request.ServerVariables); + } + // attach the provider parameter so that we know which provider initiated + // the login when user is redirected back to this page + uri = uri.AttachQueryStringParameter(ProviderQueryStringName, _authenticationProvider.ProviderName); + _authenticationProvider.RequestAuthentication(_requestContext, uri); + } - public static string GetProviderName(HttpContextBase context) { - return context.Request.QueryString[ProviderQueryStringName]; - } + public static string GetProviderName(HttpContextBase context) { + return context.Request.QueryString[ProviderQueryStringName]; + } - /// <summary> - /// Checks if user is successfully authenticated when user is redirected back to this user. - /// </summary> - /// <returns></returns> - public AuthenticationResult VerifyAuthentication() { - AuthenticationResult result = _authenticationProvider.VerifyAuthentication(_requestContext); - if (!result.IsSuccessful) { - // if the result is a Failed result, creates a new Failed response which has providerName info. - result = new AuthenticationResult(isSuccessful: false, - provider: _authenticationProvider.ProviderName, - providerUserId: null, - userName: null, - extraData: null); - } + /// <summary> + /// Checks if user is successfully authenticated when user is redirected back to this user. + /// </summary> + /// <returns></returns> + public AuthenticationResult VerifyAuthentication() { + AuthenticationResult result = _authenticationProvider.VerifyAuthentication(_requestContext); + if (!result.IsSuccessful) { + // if the result is a Failed result, creates a new Failed response which has providerName info. + result = new AuthenticationResult(isSuccessful: false, + provider: _authenticationProvider.ProviderName, + providerUserId: null, + userName: null, + extraData: null); + } - return result; - } + return result; + } - /// <summary> - /// Checks if the specified provider user id represents a valid account. - /// If it does, log user in. - /// </summary> - /// <param name="providerUserId">The provider user id.</param> - /// <param name="createPersistentCookie">if set to <c>true</c> create persistent cookie.</param> - /// <returns> - /// <c>true</c> if the login is successful. - /// </returns> - [SuppressMessage("Microsoft.Naming", "CA1726:UsePreferredTerms", MessageId = "Login", Justification = "Login is used more consistently in ASP.Net")] - public bool Login(string providerUserId, bool createPersistentCookie) { - string userName = _dataProvider.GetUserNameFromOpenAuth(_authenticationProvider.ProviderName, providerUserId); - if (String.IsNullOrEmpty(userName)) { - return false; - } + /// <summary> + /// Checks if the specified provider user id represents a valid account. + /// If it does, log user in. + /// </summary> + /// <param name="providerUserId">The provider user id.</param> + /// <param name="createPersistentCookie">if set to <c>true</c> create persistent cookie.</param> + /// <returns> + /// <c>true</c> if the login is successful. + /// </returns> + [SuppressMessage("Microsoft.Naming", "CA1726:UsePreferredTerms", MessageId = "Login", Justification = "Login is used more consistently in ASP.Net")] + public bool Login(string providerUserId, bool createPersistentCookie) { + string userName = _dataProvider.GetUserNameFromOpenAuth(_authenticationProvider.ProviderName, providerUserId); + if (String.IsNullOrEmpty(userName)) { + return false; + } - OpenAuthAuthenticationTicketHelper.SetAuthenticationTicket(_requestContext, userName, createPersistentCookie); - return true; - } + OpenAuthAuthenticationTicketHelper.SetAuthenticationTicket(_requestContext, userName, createPersistentCookie); + return true; + } - /// <summary> - /// Gets a value indicating whether the current user is authenticated by an OAuth & OpenID provider. - /// </summary> - public bool IsAuthenticatedWithOpenAuth { - get { - return _requestContext.Request.IsAuthenticated && - OpenAuthAuthenticationTicketHelper.IsValidAuthenticationTicket(_requestContext); - } - } - } + /// <summary> + /// Gets a value indicating whether the current user is authenticated by an OAuth & OpenID provider. + /// </summary> + public bool IsAuthenticatedWithOpenAuth { + get { + return _requestContext.Request.IsAuthenticated && + OpenAuthAuthenticationTicketHelper.IsValidAuthenticationTicket(_requestContext); + } + } + } }
\ No newline at end of file diff --git a/src/DotNetOpenAuth.AspNet/UriHelper.cs b/src/DotNetOpenAuth.AspNet/UriHelper.cs index ad4cc8a..83e0ade 100644 --- a/src/DotNetOpenAuth.AspNet/UriHelper.cs +++ b/src/DotNetOpenAuth.AspNet/UriHelper.cs @@ -1,75 +1,66 @@ -using System; -using System.Text.RegularExpressions; -using System.Web; -using DotNetOpenAuth.Messaging; +namespace DotNetOpenAuth.AspNet { + using System; + using System.Text.RegularExpressions; + using System.Web; + using DotNetOpenAuth.Messaging; -namespace DotNetOpenAuth.AspNet -{ - internal static class UriHelper - { - /// <summary> - /// Attaches the query string '__provider' to an existing url. If the url already - /// contains the __provider query string, it overrides it with the specified provider name. - /// </summary> - /// <param name="url">The original url.</param> - /// <param name="providerName">Name of the provider.</param> - /// <returns>The new url with the provider name query string attached</returns> - /// <example> - /// If the url is: http://contoso.com, and providerName='facebook', the returned value is: http://contoso.com?__provider=facebook - /// If the url is: http://contoso.com?a=1, and providerName='twitter', the returned value is: http://contoso.com?a=1&__provider=twitter - /// If the url is: http://contoso.com?a=1&__provider=twitter, and providerName='linkedin', the returned value is: http://contoso.com?a=1&__provider=linkedin - /// </example> - /// <remarks> - /// The reason we have to do this is so that when the external service provider forwards user - /// back to our site, we know which provider it comes back from. - /// </remarks> - public static Uri AttachQueryStringParameter(this Uri url, string parameterName, string parameterValue) - { - UriBuilder builder = new UriBuilder(url); - string query = builder.Query; - if (query.Length > 1) - { - // remove the '?' character in front of the query string - query = query.Substring(1); - } + internal static class UriHelper { + /// <summary> + /// Attaches the query string '__provider' to an existing url. If the url already + /// contains the __provider query string, it overrides it with the specified provider name. + /// </summary> + /// <param name="url">The original url.</param> + /// <param name="providerName">Name of the provider.</param> + /// <returns>The new url with the provider name query string attached</returns> + /// <example> + /// If the url is: http://contoso.com, and providerName='facebook', the returned value is: http://contoso.com?__provider=facebook + /// If the url is: http://contoso.com?a=1, and providerName='twitter', the returned value is: http://contoso.com?a=1&__provider=twitter + /// If the url is: http://contoso.com?a=1&__provider=twitter, and providerName='linkedin', the returned value is: http://contoso.com?a=1&__provider=linkedin + /// </example> + /// <remarks> + /// The reason we have to do this is so that when the external service provider forwards user + /// back to our site, we know which provider it comes back from. + /// </remarks> + public static Uri AttachQueryStringParameter(this Uri url, string parameterName, string parameterValue) { + UriBuilder builder = new UriBuilder(url); + string query = builder.Query; + if (query.Length > 1) { + // remove the '?' character in front of the query string + query = query.Substring(1); + } - string parameterPrefix = parameterName + "="; + string parameterPrefix = parameterName + "="; - string encodedParameterValue = Uri.EscapeDataString(parameterValue); + string encodedParameterValue = Uri.EscapeDataString(parameterValue); - string newQuery = Regex.Replace(query, parameterPrefix + "[^\\&]*", parameterPrefix + encodedParameterValue); - if (newQuery == query) - { - if (newQuery.Length > 0) - { - newQuery += "&"; - } - newQuery = newQuery + parameterPrefix + encodedParameterValue; - } - builder.Query = newQuery; + string newQuery = Regex.Replace(query, parameterPrefix + "[^\\&]*", parameterPrefix + encodedParameterValue); + if (newQuery == query) { + if (newQuery.Length > 0) { + newQuery += "&"; + } + newQuery = newQuery + parameterPrefix + encodedParameterValue; + } + builder.Query = newQuery; - return builder.Uri; - } + return builder.Uri; + } - /// <summary> - /// Converts an app-relative url, e.g. ~/Content/Return.cshtml, to a full-blown url, e.g. http://mysite.com/Content/Return.cshtml - /// </summary> - /// <param name="returnUrl">The return URL.</param> - /// <returns></returns> - public static Uri ConvertToAbsoluteUri(string returnUrl, HttpContextBase context) - { - if (Uri.IsWellFormedUriString(returnUrl, UriKind.Absolute)) - { - return new Uri(returnUrl, UriKind.Absolute); - } + /// <summary> + /// Converts an app-relative url, e.g. ~/Content/Return.cshtml, to a full-blown url, e.g. http://mysite.com/Content/Return.cshtml + /// </summary> + /// <param name="returnUrl">The return URL.</param> + /// <returns></returns> + public static Uri ConvertToAbsoluteUri(string returnUrl, HttpContextBase context) { + if (Uri.IsWellFormedUriString(returnUrl, UriKind.Absolute)) { + return new Uri(returnUrl, UriKind.Absolute); + } - if (!VirtualPathUtility.IsAbsolute(returnUrl)) - { - returnUrl = VirtualPathUtility.ToAbsolute(returnUrl); - } + if (!VirtualPathUtility.IsAbsolute(returnUrl)) { + returnUrl = VirtualPathUtility.ToAbsolute(returnUrl); + } - Uri publicUrl = HttpRequestInfo.GetPublicFacingUrl(context.Request, context.Request.ServerVariables); - return new Uri(publicUrl, returnUrl); - } - } + Uri publicUrl = HttpRequestInfo.GetPublicFacingUrl(context.Request, context.Request.ServerVariables); + return new Uri(publicUrl, returnUrl); + } + } }
\ No newline at end of file |