From 596282e597fda3bf83a5cc2c6c6707c4fc6a5c63 Mon Sep 17 00:00:00 2001 From: Ricardo Peres Date: Wed, 18 Mar 2015 18:21:00 +0000 Subject: [PATCH] - Added v=version with the current date in YYYYMMdd format; - Added m=foursquare so as to use the Foursquare format (https://developer.foursquare.com/overview/versioning); - Formatted code so as to match guidelines; - Added claims to authenticated user identity; - Added reference and commented code to demo project. --- .../Foursquare/Constants.cs | 9 +-- .../FoursquareAuthenticationExtensions.cs | 3 +- .../FoursquareAuthenticationHandler.cs | 58 ++++++++++--------- .../FoursquareAuthenticationMiddleware.cs | 10 ++-- .../FoursquareAuthenticationOptions.cs | 15 ++--- .../FoursquareAuthenticatedContext.cs | 46 +++++++-------- .../FoursquareAuthenticationProvider.cs | 4 +- .../App_Start/Startup.Auth.cs | 5 ++ 8 files changed, 76 insertions(+), 74 deletions(-) diff --git a/Owin.Security.Providers/Foursquare/Constants.cs b/Owin.Security.Providers/Foursquare/Constants.cs index e40a196..d724320 100644 --- a/Owin.Security.Providers/Foursquare/Constants.cs +++ b/Owin.Security.Providers/Foursquare/Constants.cs @@ -1,13 +1,8 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - + namespace Owin.Security.Providers.Foursquare { internal static class Constants { - internal const String DefaultAuthenticationType = "Foursquare"; + internal const string DefaultAuthenticationType = "Foursquare"; } } diff --git a/Owin.Security.Providers/Foursquare/FoursquareAuthenticationExtensions.cs b/Owin.Security.Providers/Foursquare/FoursquareAuthenticationExtensions.cs index f098035..be32e54 100644 --- a/Owin.Security.Providers/Foursquare/FoursquareAuthenticationExtensions.cs +++ b/Owin.Security.Providers/Foursquare/FoursquareAuthenticationExtensions.cs @@ -1,5 +1,4 @@ using System; -using Owin; namespace Owin.Security.Providers.Foursquare { @@ -20,7 +19,7 @@ namespace Owin.Security.Providers.Foursquare return app.Use(typeof(FoursquareAuthenticationMiddleware), app, options); } - public static IAppBuilder UseFoursquareAuthentication(this IAppBuilder app, String clientId, String clientSecret) + public static IAppBuilder UseFoursquareAuthentication(this IAppBuilder app, string clientId, string clientSecret) { return app.UseFoursquareAuthentication(new FoursquareAuthenticationOptions { diff --git a/Owin.Security.Providers/Foursquare/FoursquareAuthenticationHandler.cs b/Owin.Security.Providers/Foursquare/FoursquareAuthenticationHandler.cs index c25a748..e1dee5b 100644 --- a/Owin.Security.Providers/Foursquare/FoursquareAuthenticationHandler.cs +++ b/Owin.Security.Providers/Foursquare/FoursquareAuthenticationHandler.cs @@ -15,10 +15,10 @@ namespace Owin.Security.Providers.Foursquare { public class FoursquareAuthenticationHandler : AuthenticationHandler { - private const String AuthorizationEndpoint = "https://foursquare.com/oauth2/authenticate"; - private const String TokenEndpoint = "https://foursquare.com/oauth2/access_token"; - private const String GraphApiEndpoint = "https://api.foursquare.com/v2/users/self"; - private const String XmlSchemaString = "http://www.w3.org/2001/XMLSchema#string"; + private const string AuthorizationEndpoint = "https://foursquare.com/oauth2/authenticate"; + private const string TokenEndpoint = "https://foursquare.com/oauth2/access_token"; + private const string GraphApiEndpoint = "https://api.foursquare.com/v2/users/self"; + private const string XmlSchemaString = "http://www.w3.org/2001/XMLSchema#string"; private readonly ILogger _logger; private readonly HttpClient _httpClient; @@ -29,9 +29,9 @@ namespace Owin.Security.Providers.Foursquare this._logger = logger; } - public override async Task InvokeAsync() + public override async Task InvokeAsync() { - if ((String.IsNullOrEmpty(this.Options.CallbackPath) == false) && (this.Options.CallbackPath == this.Request.Path.ToString())) + if ((string.IsNullOrEmpty(this.Options.CallbackPath) == false) && (this.Options.CallbackPath == this.Request.Path.ToString())) { return await this.InvokeReturnPathAsync(); } @@ -47,8 +47,8 @@ namespace Owin.Security.Providers.Foursquare try { - String code = null; - String state = null; + string code = null; + string state = null; var query = this.Request.Query; var values = query.GetValues("code"); @@ -78,13 +78,13 @@ namespace Owin.Security.Providers.Foursquare return new AuthenticationTicket(null, properties); } - var tokenRequestParameters = new List>() + var tokenRequestParameters = new List>() { - new KeyValuePair("client_id", this.Options.ClientId), - new KeyValuePair("client_secret", this.Options.ClientSecret), - new KeyValuePair("grant_type", "authorization_code"), - new KeyValuePair("redirect_uri", this.GenerateRedirectUri()), - new KeyValuePair("code", code), + new KeyValuePair("client_id", this.Options.ClientId), + new KeyValuePair("client_secret", this.Options.ClientSecret), + new KeyValuePair("grant_type", "authorization_code"), + new KeyValuePair("redirect_uri", this.GenerateRedirectUri()), + new KeyValuePair("code", code), }; var requestContent = new FormUrlEncodedContent(tokenRequestParameters); @@ -95,19 +95,19 @@ namespace Owin.Security.Providers.Foursquare var oauthTokenResponse = await response.Content.ReadAsStringAsync(); var oauth2Token = JObject.Parse(oauthTokenResponse); - var accessToken = oauth2Token["access_token"].Value(); + var accessToken = oauth2Token["access_token"].Value(); - if (String.IsNullOrWhiteSpace(accessToken) == true) + if (string.IsNullOrWhiteSpace(accessToken) == true) { this._logger.WriteWarning("Access token was not found"); return new AuthenticationTicket(null, properties); } - var graphResponse = await this._httpClient.GetAsync(GraphApiEndpoint + "?oauth_token=" + Uri.EscapeDataString(accessToken), Request.CallCancelled); + var graphResponse = await this._httpClient.GetAsync(GraphApiEndpoint + "?oauth_token=" + Uri.EscapeDataString(accessToken) + "&m=foursquare&v=" + DateTime.Today.ToString("yyyyyMMdd"), this.Request.CallCancelled); graphResponse.EnsureSuccessStatusCode(); - var accountString = await graphResponse.Content.ReadAsStringAsync(); - var accountInformation = JObject.Parse(accountString); + var accountstring = await graphResponse.Content.ReadAsStringAsync(); + var accountInformation = JObject.Parse(accountstring); var user = (JObject) accountInformation["response"]["user"]; var context = new FoursquareAuthenticatedContext(this.Context, user, accessToken); @@ -118,13 +118,15 @@ namespace Owin.Security.Providers.Foursquare new Claim(ClaimTypes.NameIdentifier, context.Id, XmlSchemaString, this.Options.AuthenticationType), new Claim(ClaimTypes.Name, context.Name, XmlSchemaString, this.Options.AuthenticationType), new Claim("urn:foursquare:id", context.Id, XmlSchemaString, this.Options.AuthenticationType), - new Claim("urn:foursquare:name", context.Name, XmlSchemaString, this.Options.AuthenticationType) + new Claim("urn:foursquare:name", context.Name, XmlSchemaString, this.Options.AuthenticationType), + new Claim("urn:foursquare:email", context.Email, XmlSchemaString, this.Options.AuthenticationType), + new Claim("urn:foursquare:twitter", context.Twitter, XmlSchemaString, this.Options.AuthenticationType) }, this.Options.AuthenticationType, ClaimsIdentity.DefaultNameClaimType, ClaimsIdentity.DefaultRoleClaimType); - if (String.IsNullOrWhiteSpace(context.Email) == false) + if (string.IsNullOrWhiteSpace(context.Email) == false) { context.Identity.AddClaim(new Claim(ClaimTypes.Email, context.Email, XmlSchemaString, this.Options.AuthenticationType)); } @@ -146,7 +148,7 @@ namespace Owin.Security.Providers.Foursquare { this._logger.WriteVerbose("ApplyResponseChallenge"); - if (this.Response.StatusCode != (Int32) HttpStatusCode.Unauthorized) + if (this.Response.StatusCode != (int) HttpStatusCode.Unauthorized) { return Task.FromResult(null); } @@ -161,7 +163,7 @@ namespace Owin.Security.Providers.Foursquare var extra = challenge.Properties; - if (String.IsNullOrEmpty(extra.RedirectUri) == true) + if (string.IsNullOrEmpty(extra.RedirectUri) == true) { extra.RedirectUri = currentUri; } @@ -170,7 +172,7 @@ namespace Owin.Security.Providers.Foursquare this.GenerateCorrelationId(extra); // OAuth2 3.3 space separated - var scope = String.Join(" ", this.Options.Scope); + var scope = string.Join(" ", this.Options.Scope); var state = this.Options.StateDataFormat.Protect(extra); @@ -180,14 +182,14 @@ namespace Owin.Security.Providers.Foursquare "&redirect_uri=" + Uri.EscapeDataString(redirectUri) + "&state=" + Uri.EscapeDataString(state); - this.Response.StatusCode = (Int32) HttpStatusCode.Moved; + this.Response.StatusCode = (int) HttpStatusCode.Moved; this.Response.Headers.Set("Location", authorizationEndpoint); } return Task.FromResult(null); } - public async Task InvokeReturnPathAsync() + public async Task InvokeReturnPathAsync() { this._logger.WriteVerbose("InvokeReturnPath"); @@ -205,7 +207,7 @@ namespace Owin.Security.Providers.Foursquare { var signInIdentity = context.Identity; - if (String.Equals(signInIdentity.AuthenticationType, context.SignInAsAuthenticationType, StringComparison.Ordinal) == false) + if (string.Equals(signInIdentity.AuthenticationType, context.SignInAsAuthenticationType, StringComparison.Ordinal) == false) { signInIdentity = new ClaimsIdentity(signInIdentity.Claims, context.SignInAsAuthenticationType, signInIdentity.NameClaimType, signInIdentity.RoleClaimType); } @@ -228,7 +230,7 @@ namespace Owin.Security.Providers.Foursquare return context.IsRequestCompleted; } - private String GenerateRedirectUri() + private string GenerateRedirectUri() { var requestPrefix = this.Request.Scheme + "://" + this.Request.Host; var redirectUri = requestPrefix + this.RequestPathBase + this.Options.CallbackPath; diff --git a/Owin.Security.Providers/Foursquare/FoursquareAuthenticationMiddleware.cs b/Owin.Security.Providers/Foursquare/FoursquareAuthenticationMiddleware.cs index 33c8350..6980598 100644 --- a/Owin.Security.Providers/Foursquare/FoursquareAuthenticationMiddleware.cs +++ b/Owin.Security.Providers/Foursquare/FoursquareAuthenticationMiddleware.cs @@ -6,7 +6,6 @@ using Microsoft.Owin.Security; using Microsoft.Owin.Security.DataHandler; using Microsoft.Owin.Security.DataProtection; using Microsoft.Owin.Security.Infrastructure; -using Owin; using Owin.Security.Providers.Foursquare.Provider; namespace Owin.Security.Providers.Foursquare @@ -16,14 +15,15 @@ namespace Owin.Security.Providers.Foursquare private readonly ILogger _logger; private readonly HttpClient _httpClient; - public FoursquareAuthenticationMiddleware(OwinMiddleware next, IAppBuilder app, FoursquareAuthenticationOptions options) : base(next, options) + public FoursquareAuthenticationMiddleware(OwinMiddleware next, IAppBuilder app, FoursquareAuthenticationOptions options) + : base(next, options) { - if (String.IsNullOrWhiteSpace(this.Options.ClientId) == true) + if (string.IsNullOrWhiteSpace(this.Options.ClientId) == true) { throw new ArgumentException("The 'ClientId' must be provided."); } - if (String.IsNullOrWhiteSpace(this.Options.ClientSecret) == true) + if (string.IsNullOrWhiteSpace(this.Options.ClientSecret) == true) { throw new ArgumentException("The 'ClientSecret' option must be provided."); } @@ -41,7 +41,7 @@ namespace Owin.Security.Providers.Foursquare this.Options.StateDataFormat = new PropertiesDataFormat(dataProtector); } - if (String.IsNullOrEmpty(this.Options.SignInAsAuthenticationType) == true) + if (string.IsNullOrEmpty(this.Options.SignInAsAuthenticationType) == true) { this.Options.SignInAsAuthenticationType = app.GetDefaultSignInAsAuthenticationType(); } diff --git a/Owin.Security.Providers/Foursquare/FoursquareAuthenticationOptions.cs b/Owin.Security.Providers/Foursquare/FoursquareAuthenticationOptions.cs index 1aa5863..defcec3 100644 --- a/Owin.Security.Providers/Foursquare/FoursquareAuthenticationOptions.cs +++ b/Owin.Security.Providers/Foursquare/FoursquareAuthenticationOptions.cs @@ -11,7 +11,8 @@ namespace Owin.Security.Providers.Foursquare /// /// Initializes a new /// - public FoursquareAuthenticationOptions() : base(Constants.DefaultAuthenticationType) + public FoursquareAuthenticationOptions() + : base(Constants.DefaultAuthenticationType) { this.Caption = Constants.DefaultAuthenticationType; this.CallbackPath = "/signin-foursquare"; @@ -23,12 +24,12 @@ namespace Owin.Security.Providers.Foursquare /// /// Gets or sets the Foursquare supplied Client ID /// - public String ClientId { get; set; } + public string ClientId { get; set; } /// /// Gets or sets the Foursquare supplied Client Secret /// - public String ClientSecret { get; set; } + public string ClientSecret { get; set; } /// /// Gets or sets the a pinned certificate validator to use to validate the endpoints used @@ -63,13 +64,13 @@ namespace Owin.Security.Providers.Foursquare /// The middleware will process this request when it arrives. /// Default value is "/signin-foursquare". /// - public String CallbackPath { get; set; } + public string CallbackPath { get; set; } /// /// Gets or sets the name of another authentication middleware which will be responsible for actually issuing a user /// . /// - public String SignInAsAuthenticationType { get; set; } + public string SignInAsAuthenticationType { get; set; } /// /// Gets or sets the used in the authentication events @@ -84,12 +85,12 @@ namespace Owin.Security.Providers.Foursquare /// /// A list of permissions to request. /// - public IList Scope { get; private set; } + public IList Scope { get; private set; } /// /// Get or sets the text that the user can display on a sign in user interface. /// - public String Caption + public string Caption { get { return this.Description.Caption; } set { this.Description.Caption = value; } diff --git a/Owin.Security.Providers/Foursquare/Provider/FoursquareAuthenticatedContext.cs b/Owin.Security.Providers/Foursquare/Provider/FoursquareAuthenticatedContext.cs index 35d39d8..df29592 100644 --- a/Owin.Security.Providers/Foursquare/Provider/FoursquareAuthenticatedContext.cs +++ b/Owin.Security.Providers/Foursquare/Provider/FoursquareAuthenticatedContext.cs @@ -9,7 +9,7 @@ namespace Owin.Security.Providers.Foursquare.Provider { public class FoursquareAuthenticatedContext : BaseContext { - public FoursquareAuthenticatedContext(IOwinContext context, JObject user, String accessToken) : base(context) + public FoursquareAuthenticatedContext(IOwinContext context, JObject user, string accessToken) : base(context) { if (user == null) { @@ -49,31 +49,31 @@ namespace Owin.Security.Providers.Foursquare.Provider } public JObject User { get; private set; } - public String AccessToken { get; private set; } - public String Id { get; private set; } - public String FirstName { get; private set; } - public String LastName { get; private set; } - public String Name { get; private set; } - public String Gender { get; private set; } - public String Photo { get; private set; } - public String Friends { get; private set; } - public String HomeCity { get; private set; } - public String Bio { get; private set; } - public String Contact { get; private set; } - public String Phone { get; private set; } - public String Email { get; private set; } - public String Twitter { get; private set; } - public String Facebook { get; private set; } - public String Badges { get; private set; } - public String Mayorships { get; private set; } - public String Checkins { get; private set; } - public String Photos { get; private set; } - public String Scores { get; private set; } - public String Link { get; private set; } + public string AccessToken { get; private set; } + public string Id { get; private set; } + public string FirstName { get; private set; } + public string LastName { get; private set; } + public string Name { get; private set; } + public string Gender { get; private set; } + public string Photo { get; private set; } + public string Friends { get; private set; } + public string HomeCity { get; private set; } + public string Bio { get; private set; } + public string Contact { get; private set; } + public string Phone { get; private set; } + public string Email { get; private set; } + public string Twitter { get; private set; } + public string Facebook { get; private set; } + public string Badges { get; private set; } + public string Mayorships { get; private set; } + public string Checkins { get; private set; } + public string Photos { get; private set; } + public string Scores { get; private set; } + public string Link { get; private set; } public ClaimsIdentity Identity { get; set; } public AuthenticationProperties Properties { get; set; } - private static String TryGetValue(JObject user, String propertyName) + private static string TryGetValue(JObject user, string propertyName) { JToken value; return user.TryGetValue(propertyName, out value) ? value.ToString() : null; diff --git a/Owin.Security.Providers/Foursquare/Provider/FoursquareAuthenticationProvider.cs b/Owin.Security.Providers/Foursquare/Provider/FoursquareAuthenticationProvider.cs index fb3a062..ebe5746 100644 --- a/Owin.Security.Providers/Foursquare/Provider/FoursquareAuthenticationProvider.cs +++ b/Owin.Security.Providers/Foursquare/Provider/FoursquareAuthenticationProvider.cs @@ -7,8 +7,8 @@ namespace Owin.Security.Providers.Foursquare.Provider { public FoursquareAuthenticationProvider() { - this.OnAuthenticated = context => Task.FromResult(null); - this.OnReturnEndpoint = context => Task.FromResult(null); + this.OnAuthenticated = context => Task.FromResult(null); + this.OnReturnEndpoint = context => Task.FromResult(null); } public Func OnAuthenticated { get; set; } diff --git a/OwinOAuthProvidersDemo/App_Start/Startup.Auth.cs b/OwinOAuthProvidersDemo/App_Start/Startup.Auth.cs index a24f345..bf04d4a 100755 --- a/OwinOAuthProvidersDemo/App_Start/Startup.Auth.cs +++ b/OwinOAuthProvidersDemo/App_Start/Startup.Auth.cs @@ -10,6 +10,7 @@ using Owin.Security.Providers.BattleNet; using Owin.Security.Providers.Buffer; using Owin.Security.Providers.Dropbox; using Owin.Security.Providers.EveOnline; +using Owin.Security.Providers.Foursquare; using Owin.Security.Providers.GitHub; using Owin.Security.Providers.GooglePlus; using Owin.Security.Providers.GooglePlus.Provider; @@ -204,6 +205,10 @@ namespace OwinOAuthProvidersDemo //app.UseEveOnlineAuthentication("", ""); //app.UseSoundCloudAuthentication("", ""); + + //app.UseFoursquareAuthentication( + // clientId: "", + // clientSecret: ""); } } } \ No newline at end of file