The ASP.NET Identity 2.0 alpha ships with new middleware to manage getting an instance of the UserManager
(app.UseUserManagerFactory
to set this up) and getting an instance of the DbContext
(app.UseDbContextFactory
to set this up). There is an example showing how to get this working with an MVC app, but there is no documentation on how to get this working from the SPA template which uses OAuthBearerTokens
, unlike the sample.
I currently am stuck with:
UserManagerFactory = () => new DerivedUserManager(new CustomUserStore(new CustomDbContext()));
OAuthOptions = new Microsoft.Owin.Security.OAuth.OAuthAuthorizationServerOptions
{
TokenEndpointPath = new PathString("/Token"),
Provider = new MyApp.Web.Api.Providers.ApplicationOAuthProvider(PublicClientId, UserManagerFactory),
AuthorizeEndpointPath = new PathString("/api/Account/ExternalLogin"),
AccessTokenExpireTimeSpan = TimeSpan.FromDays(14),
AllowInsecureHttp = true
};
app.UseOAuthBearerTokens(OAuthOptions);
and have no idea how to replace the UserManagerFactory
above with calls like these from the 2.0 alpha samples while still working with the OAuthBearerTokens
objects used in the SPA template:
app.UseDbContextFactory(ApplicationDbContext.Create);
// Configure the UserManager
app.UseUserManagerFactory(new IdentityFactoryOptions<ApplicationUserManager>()
{
DataProtectionProvider = app.GetDataProtectionProvider(),
Provider = new IdentityFactoryProvider<ApplicationUserManager>()
{
OnCreate = ApplicationUserManager.Create
}
});
Thanks... -Ben
I am adding stubs here which show you how you can use OAuthBearerTokens... You do not have to use the UserManagerFactory that you were using in SPA. You can switch that to use the PerOWINContext pattern.
Startup.Auth.cs
app.CreatePerOwinContext(ApplicationDbContext.Create);
app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
OAuthOptions = new OAuthAuthorizationServerOptions
{
TokenEndpointPath = new PathString("/Token"),
Provider = new ApplicationOAuthProvider(PublicClientId),
AuthorizeEndpointPath = new PathString("/api/Account/ExternalLogin"),
AccessTokenExpireTimeSpan = TimeSpan.FromDays(14),
AllowInsecureHttp = true
};
ApplicationOAuthProvider.cs
public ApplicationOAuthProvider(string publicClientId)
{
if (publicClientId == null)
{
throw new ArgumentNullException("publicClientId");
}
_publicClientId = publicClientId;
}
public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
{
var userManager = context.OwinContext.GetUserManager<ApplicationUserManager>();
ApplicationUser user = await userManager.FindAsync(context.UserName, context.Password);
if (user == null)
{
context.SetError("invalid_grant", "The user name or password is incorrect.");
return;
}
ClaimsIdentity oAuthIdentity = await user.GenerateUserIdentityAsync(userManager,
OAuthDefaults.AuthenticationType);
ClaimsIdentity cookiesIdentity = await user.GenerateUserIdentityAsync(userManager,
DefaultAuthenticationTypes.ApplicationCookie);
AuthenticationProperties properties = CreateProperties(user.UserName);
AuthenticationTicket ticket = new AuthenticationTicket(oAuthIdentity, properties);
context.Validated(ticket);
context.Request.Context.Authentication.SignIn(cookiesIdentity);
}
// namespace below needed to enable GetUserManager extension of the OwinContext
using Microsoft.AspNet.Identity.Owin;
The ASP.NET Identity includes support for creating a single instance of a the UserManager
and the identity DBContext
per application request. To support this pattern use the following extension methods per the IAppBuilder
object:
app.CreatePerOwinContext<AppUserIdentityDbContext>(AppUserIdentityDbContext.Create);
app.CreatePerOwinContext<AppUserManager>(AppUserManager.Create);
You can find a great example implementing this very pattern below:
Here is the AppManager Class:
public class AppUserManager : UserManager<AppUserIdentity>
{
public AppUserManager(IUserStore<AppUserIdentity> store)
: base(store) { }
public static AppUserManager Create(IdentityFactoryOptions<AppUserManager> options, IOwinContext context)
{
var manager = new AppUserManager(new UserStore<AppUserIdentity>(context.Get<AppUserIdentityDbContext>()));
return manager;
}
}
This acticle uses the OWIN Middleware components UseOAuthBearerAuthentication
and UseCookieAuthentication
to support browser based authentication along with single Owin context IdentityDb Objects and a single AppManager.
OAuthBearerOptions = new OAuthBearerAuthenticationOptions();
//This will used the HTTP header: "Authorization" Value: "Bearer 1234123412341234asdfasdfasdfasdf"
app.UseOAuthBearerAuthentication(OAuthBearerOptions);
// Enable the application to use a cookie to store information for the signed in user
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString("/Account/Login")
});
HostAuthenticationFilter represents an authentication filter that authenticates via OWIN middleware:
config.SuppressDefaultHostAuthentication();
//This will used the HTTP header: "Authorization" Value: "Bearer 1234123412341234asdfasdfasdfasdf"
config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));
var identity = new ClaimsIdentity(Startup.OAuthBearerOptions.AuthenticationType);
identity.AddClaim(new Claim(ClaimTypes.Name, user));
identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, userIdentity.Id));
AuthenticationTicket ticket = new AuthenticationTicket(identity, new AuthenticationProperties());
var currentUtc = new SystemClock().UtcNow;
ticket.Properties.IssuedUtc = currentUtc;
ticket.Properties.ExpiresUtc = currentUtc.Add(TimeSpan.FromMinutes(30));
string AccessToken = Startup.OAuthBearerOptions.AccessTokenFormat.Protect(ticket);
return AccessToken;
Ben, some of these things have changed from the alpha1 to beta1 builds (currently available on the ASP.NET Nightly NuGet Repo at https://aspnetwebstack.codeplex.com/wikipage?title=Use%20Nightly%20Builds). If you upgrade to the latest beta bits, you will not be using this syntax anymore but this instead:
// Configure the db context and user manager to use per request
app.CreatePerOwinContext(ApplicationIdentityContext.Create);
app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
Also, notice that HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>
is now moved to Microsoft.AspNet.Identity.Owin
.
You can install the `Microsoft.AspNet.Identity.Samples' package (preferably in a new MVC project because it might overwrite files). It helped me learn how they do certain things considering documentation for 2.0 is non-existent at the moment besides a few blog posts (all of which written for the alpha1 builds).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With