save wordpress token to identity

This commit is contained in:
Tommy Parnell
2016-10-03 17:20:56 -04:00
parent 688ee2ab4a
commit 287b22455d
8 changed files with 149 additions and 56 deletions

View File

@@ -1,16 +1,16 @@
using System;
using GetWordpressOAuthToken.Models;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.EntityFramework;
using Microsoft.AspNet.Identity.Owin;
using Microsoft.Owin;
using Microsoft.Owin.Security;
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
using System.Web;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.EntityFramework;
using Microsoft.AspNet.Identity.Owin;
using Microsoft.Owin;
using Microsoft.Owin.Security;
using GetWordpressOAuthToken.Models;
namespace GetWordpressOAuthToken
{
@@ -40,7 +40,7 @@ namespace GetWordpressOAuthToken
{
}
public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context)
public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context)
{
var manager = new ApplicationUserManager(new UserStore<ApplicationUser>(context.Get<ApplicationDbContext>()));
// Configure validation logic for usernames
@@ -81,7 +81,7 @@ namespace GetWordpressOAuthToken
var dataProtectionProvider = options.DataProtectionProvider;
if (dataProtectionProvider != null)
{
manager.UserTokenProvider =
manager.UserTokenProvider =
new DataProtectorTokenProvider<ApplicationUser>(dataProtectionProvider.Create("ASP.NET Identity"));
}
return manager;
@@ -106,4 +106,4 @@ namespace GetWordpressOAuthToken
return new ApplicationSignInManager(context.GetUserManager<ApplicationUserManager>(), context.Authentication);
}
}
}
}

View File

@@ -1,11 +1,13 @@
using System;
using GetWordpressOAuthToken.Models;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.Owin;
using Microsoft.Owin;
using Microsoft.Owin.Security.Cookies;
using Microsoft.Owin.Security.Google;
using Owin;
using GetWordpressOAuthToken.Models;
using Owin.Security.Providers.WordPress;
using System;
using System.Threading.Tasks;
namespace GetWordpressOAuthToken
{
@@ -29,12 +31,13 @@ namespace GetWordpressOAuthToken
Provider = new CookieAuthenticationProvider
{
// Enables the application to validate the security stamp when the user logs in.
// This is a security feature which is used when you change a password or add an external login to your account.
// This is a security feature which is used when you change a password or add an external login to your account.
OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>(
validateInterval: TimeSpan.FromMinutes(30),
regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager))
}
});
});
app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
// Enables the application to temporarily store user information when they are verifying the second factor in the two-factor authentication process.
@@ -63,6 +66,19 @@ namespace GetWordpressOAuthToken
// ClientId = "",
// ClientSecret = ""
//});
app.UseWordPressAuthentication(new WordPressAuthenticationOptions()
{
ClientId = "YOURCLIENTTOKENHERE",
ClientSecret = "YOURCLIENTSECRETHERE",
Provider = new WordPressAuthenticationProvider()
{
OnAuthenticated = context =>
{
context.Identity.AddClaim(new System.Security.Claims.Claim("urn:wordpress:access_token", context.AccessToken));
return Task.FromResult(0);
}
}
});
}
}
}

View File

@@ -1,14 +1,14 @@
using System;
using GetWordpressOAuthToken.Models;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.Owin;
using Microsoft.Owin.Security;
using System;
using System.Globalization;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
using System.Web;
using System.Web.Mvc;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.Owin;
using Microsoft.Owin.Security;
using GetWordpressOAuthToken.Models;
namespace GetWordpressOAuthToken.Controllers
{
@@ -22,7 +22,7 @@ namespace GetWordpressOAuthToken.Controllers
{
}
public AccountController(ApplicationUserManager userManager, ApplicationSignInManager signInManager )
public AccountController(ApplicationUserManager userManager, ApplicationSignInManager signInManager)
{
UserManager = userManager;
SignInManager = signInManager;
@@ -34,9 +34,9 @@ namespace GetWordpressOAuthToken.Controllers
{
return _signInManager ?? HttpContext.GetOwinContext().Get<ApplicationSignInManager>();
}
private set
{
_signInManager = value;
private set
{
_signInManager = value;
}
}
@@ -80,10 +80,13 @@ namespace GetWordpressOAuthToken.Controllers
{
case SignInStatus.Success:
return RedirectToLocal(returnUrl);
case SignInStatus.LockedOut:
return View("Lockout");
case SignInStatus.RequiresVerification:
return RedirectToAction("SendCode", new { ReturnUrl = returnUrl, RememberMe = model.RememberMe });
case SignInStatus.Failure:
default:
ModelState.AddModelError("", "Invalid login attempt.");
@@ -116,17 +119,19 @@ namespace GetWordpressOAuthToken.Controllers
return View(model);
}
// The following code protects for brute force attacks against the two factor codes.
// If a user enters incorrect codes for a specified amount of time then the user account
// will be locked out for a specified amount of time.
// The following code protects for brute force attacks against the two factor codes.
// If a user enters incorrect codes for a specified amount of time then the user account
// will be locked out for a specified amount of time.
// You can configure the account lockout settings in IdentityConfig
var result = await SignInManager.TwoFactorSignInAsync(model.Provider, model.Code, isPersistent: model.RememberMe, rememberBrowser: model.RememberBrowser);
var result = await SignInManager.TwoFactorSignInAsync(model.Provider, model.Code, isPersistent: model.RememberMe, rememberBrowser: model.RememberBrowser);
switch (result)
{
case SignInStatus.Success:
return RedirectToLocal(model.ReturnUrl);
case SignInStatus.LockedOut:
return View("Lockout");
case SignInStatus.Failure:
default:
ModelState.AddModelError("", "Invalid code.");
@@ -155,8 +160,8 @@ namespace GetWordpressOAuthToken.Controllers
var result = await UserManager.CreateAsync(user, model.Password);
if (result.Succeeded)
{
await SignInManager.SignInAsync(user, isPersistent:false, rememberBrowser:false);
await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false);
// For more information on how to enable account confirmation and password reset please visit http://go.microsoft.com/fwlink/?LinkID=320771
// Send an email with this link
// string code = await UserManager.GenerateEmailConfirmationTokenAsync(user.Id);
@@ -212,7 +217,7 @@ namespace GetWordpressOAuthToken.Controllers
// For more information on how to enable account confirmation and password reset please visit http://go.microsoft.com/fwlink/?LinkID=320771
// Send an email with this link
// string code = await UserManager.GeneratePasswordResetTokenAsync(user.Id);
// var callbackUrl = Url.Action("ResetPassword", "Account", new { userId = user.Id, code = code }, protocol: Request.Url.Scheme);
// var callbackUrl = Url.Action("ResetPassword", "Account", new { userId = user.Id, code = code }, protocol: Request.Url.Scheme);
// await UserManager.SendEmailAsync(user.Id, "Reset Password", "Please reset your password by clicking <a href=\"" + callbackUrl + "\">here</a>");
// return RedirectToAction("ForgotPasswordConfirmation", "Account");
}
@@ -333,11 +338,15 @@ namespace GetWordpressOAuthToken.Controllers
switch (result)
{
case SignInStatus.Success:
await StoreWordpressToken(await UserManager.FindAsync(loginInfo.Login));
return RedirectToLocal(returnUrl);
case SignInStatus.LockedOut:
return View("Lockout");
case SignInStatus.RequiresVerification:
return RedirectToAction("SendCode", new { ReturnUrl = returnUrl, RememberMe = false });
case SignInStatus.Failure:
default:
// If the user does not have an account, then prompt the user to create an account
@@ -347,6 +356,16 @@ namespace GetWordpressOAuthToken.Controllers
}
}
private async Task ProcessExternalClaims(ExternalLoginInfo loginInfo)
{
var currentIdentity = await UserManager.FindByIdAsync(loginInfo.ExternalIdentity.GetUserId());
var userId = this.AuthenticationManager.User.Identity.GetUserId();
foreach (var claim in loginInfo.ExternalIdentity.Claims.Where(a => a.Type.StartsWith("urn:wordpress", StringComparison.Ordinal)))
{
await UserManager.AddClaimAsync(userId, claim);
}
}
//
// POST: /Account/ExternalLoginConfirmation
[HttpPost]
@@ -374,6 +393,7 @@ namespace GetWordpressOAuthToken.Controllers
result = await UserManager.AddLoginAsync(user.Id, info.Login);
if (result.Succeeded)
{
await StoreWordpressToken(user);
await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false);
return RedirectToLocal(returnUrl);
}
@@ -385,6 +405,25 @@ namespace GetWordpressOAuthToken.Controllers
return View(model);
}
private async Task StoreWordpressToken(ApplicationUser user)
{
var claimsIdentity = await AuthenticationManager.GetExternalIdentityAsync(DefaultAuthenticationTypes.ExternalCookie);
if (claimsIdentity != null)
{
// Retrieve the existing claims for the user and add the FacebookAccessTokenClaim
var currentClaims = await UserManager.GetClaimsAsync(user.Id);
var wordpressToken = claimsIdentity.Claims.Where(a => a.Type.Contains("wordpress:access_token")).FirstOrDefault();
if (wordpressToken != null)
{
if (currentClaims.Count(a => a.Type.Contains("wordpress:access_token")) > 0)
{
await UserManager.RemoveClaimAsync(user.Id, wordpressToken);
}
await UserManager.AddClaimAsync(user.Id, wordpressToken);
}
}
}
//
// POST: /Account/LogOff
[HttpPost]
@@ -424,6 +463,7 @@ namespace GetWordpressOAuthToken.Controllers
}
#region Helpers
// Used for XSRF protection when adding external logins
private const string XsrfKey = "XsrfId";
@@ -480,6 +520,7 @@ namespace GetWordpressOAuthToken.Controllers
context.HttpContext.GetOwinContext().Authentication.Challenge(properties, LoginProvider);
}
}
#endregion
#endregion Helpers
}
}

View File

@@ -1,12 +1,12 @@
using System;
using GetWordpressOAuthToken.Models;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.Owin;
using Microsoft.Owin.Security;
using System;
using System.Linq;
using System.Threading.Tasks;
using System.Web;
using System.Web.Mvc;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.Owin;
using Microsoft.Owin.Security;
using GetWordpressOAuthToken.Models;
namespace GetWordpressOAuthToken.Controllers
{
@@ -20,6 +20,12 @@ namespace GetWordpressOAuthToken.Controllers
{
}
public string WhatIsMyWordpressToken()
{
//this shouldnt really exist, but this is a way to view the actual users wordpress token claim
return UserManager.GetClaims(this.User.Identity.GetUserId()).Where(a => a.Type.Contains("wordpress:access_token")).Select(a => a.Value).FirstOrDefault() ?? string.Empty;
}
public ManageController(ApplicationUserManager userManager, ApplicationSignInManager signInManager)
{
UserManager = userManager;
@@ -32,9 +38,9 @@ namespace GetWordpressOAuthToken.Controllers
{
return _signInManager ?? HttpContext.GetOwinContext().Get<ApplicationSignInManager>();
}
private set
{
_signInManager = value;
private set
{
_signInManager = value;
}
}
@@ -309,6 +315,25 @@ namespace GetWordpressOAuthToken.Controllers
return new AccountController.ChallengeResult(provider, Url.Action("LinkLoginCallback", "Manage"), User.Identity.GetUserId());
}
private async Task StoreWordpressToken(ApplicationUser user)
{
var claimsIdentity = await AuthenticationManager.GetExternalIdentityAsync(DefaultAuthenticationTypes.ExternalCookie);
if (claimsIdentity != null)
{
// Retrieve the existing claims for the user and add the FacebookAccessTokenClaim
var currentClaims = await UserManager.GetClaimsAsync(user.Id);
var wordpressToken = claimsIdentity.Claims.Where(a => a.Type.Contains("wordpress:access_token")).FirstOrDefault();
if (wordpressToken != null)
{
if (currentClaims.Count(a => a.Type.Contains("wordpress:access_token")) > 0)
{
await UserManager.RemoveClaimAsync(user.Id, wordpressToken);
}
await UserManager.AddClaimAsync(user.Id, wordpressToken);
}
}
}
//
// GET: /Manage/LinkLoginCallback
public async Task<ActionResult> LinkLoginCallback()
@@ -319,6 +344,11 @@ namespace GetWordpressOAuthToken.Controllers
return RedirectToAction("ManageLogins", new { Message = ManageMessageId.Error });
}
var result = await UserManager.AddLoginAsync(User.Identity.GetUserId(), loginInfo.Login);
if (result.Succeeded)
{
var currentUser = await UserManager.FindByIdAsync(User.Identity.GetUserId());
await StoreWordpressToken(currentUser);
}
return result.Succeeded ? RedirectToAction("ManageLogins") : RedirectToAction("ManageLogins", new { Message = ManageMessageId.Error });
}
@@ -333,7 +363,8 @@ namespace GetWordpressOAuthToken.Controllers
base.Dispose(disposing);
}
#region Helpers
#region Helpers
// Used for XSRF protection when adding external logins
private const string XsrfKey = "XsrfId";
@@ -384,6 +415,6 @@ namespace GetWordpressOAuthToken.Controllers
Error
}
#endregion
#endregion Helpers
}
}

View File

@@ -49,6 +49,14 @@
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.CSharp" />
<Reference Include="Newtonsoft.Json, Version=8.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Newtonsoft.Json.8.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Owin.Security.Providers.WordPress, Version=2.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Owin.Security.Providers.WordPress.2.8.0\lib\net45\Owin.Security.Providers.WordPress.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.Drawing" />
@@ -112,9 +120,6 @@
</Reference>
</ItemGroup>
<ItemGroup>
<Reference Include="Newtonsoft.Json">
<HintPath>..\packages\Newtonsoft.Json.6.0.4\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="EntityFramework">
<HintPath>..\packages\EntityFramework.6.1.3\lib\net45\EntityFramework.dll</HintPath>
</Reference>

View File

@@ -1,8 +1,8 @@
using System.Data.Entity;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.EntityFramework;
using System.Data.Entity;
using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.EntityFramework;
namespace GetWordpressOAuthToken.Models
{

View File

@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<!--
For more information on how to configure your ASP.NET application, please visit
http://go.microsoft.com/fwlink/?LinkId=301880
@@ -9,8 +9,7 @@
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</configSections>
<connectionStrings>
<add name="DefaultConnection" connectionString="Data Source=(LocalDb)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\aspnet-GetWordpressOAuthToken-20161003034300.mdf;Initial Catalog=aspnet-GetWordpressOAuthToken-20161003034300;Integrated Security=True"
providerName="System.Data.SqlClient" />
<add name="DefaultConnection" connectionString="Data Source=(LocalDb)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\aspnet-GetWordpressOAuthToken-20161003034300.mdf;Initial Catalog=aspnet-GetWordpressOAuthToken-20161003034300;Integrated Security=True" providerName="System.Data.SqlClient" />
</connectionStrings>
<appSettings>
<add key="webpages:Version" value="3.0.0.0" />
@@ -32,23 +31,23 @@
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Microsoft.Owin.Security" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0-3.0.1.0" newVersion="3.0.1.0" />
<bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Owin.Security.OAuth" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0-3.0.1.0" newVersion="3.0.1.0" />
<bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Owin.Security.Cookies" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0-3.0.1.0" newVersion="3.0.1.0" />
<bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Owin" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0-3.0.1.0" newVersion="3.0.1.0" />
<bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" culture="neutral" publicKeyToken="30ad4fe6b2a6aeed" />
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
<bindingRedirect oldVersion="0.0.0.0-8.0.0.0" newVersion="8.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Optimization" publicKeyToken="31bf3856ad364e35" />

View File

@@ -26,8 +26,9 @@
<package id="Microsoft.Owin.Security.Twitter" version="3.0.1" targetFramework="net45" />
<package id="Microsoft.Web.Infrastructure" version="1.0.0.0" targetFramework="net45" />
<package id="Modernizr" version="2.6.2" targetFramework="net45" />
<package id="Newtonsoft.Json" version="6.0.4" targetFramework="net45" />
<package id="Newtonsoft.Json" version="8.0.3" targetFramework="net45" />
<package id="Owin" version="1.0" targetFramework="net45" />
<package id="Owin.Security.Providers.WordPress" version="2.8.0" targetFramework="net45" />
<package id="Respond" version="1.2.0" targetFramework="net45" />
<package id="WebGrease" version="1.5.2" targetFramework="net45" />
</packages>