React to options / DI / startup changes

This commit is contained in:
Hao Kung 2014-10-08 13:11:49 -07:00
parent 665780b18f
commit ffa226dfa9
25 changed files with 295 additions and 393 deletions

View File

@ -28,6 +28,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
global.json = global.json global.json = global.json
EndProjectSection EndProjectSection
EndProject EndProject
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Hosting", "..\Hosting\src\Microsoft.AspNet.Hosting\Microsoft.AspNet.Hosting.kproj", "{3944F036-7E75-47E8-AA52-C4B89A64EC3A}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU Debug|Any CPU = Debug|Any CPU
@ -108,6 +110,16 @@ Global
{E1BFA023-CFFD-49CE-8466-1C28DD2EC1F6}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU {E1BFA023-CFFD-49CE-8466-1C28DD2EC1F6}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{E1BFA023-CFFD-49CE-8466-1C28DD2EC1F6}.Release|Mixed Platforms.Build.0 = Release|Any CPU {E1BFA023-CFFD-49CE-8466-1C28DD2EC1F6}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{E1BFA023-CFFD-49CE-8466-1C28DD2EC1F6}.Release|x86.ActiveCfg = Release|Any CPU {E1BFA023-CFFD-49CE-8466-1C28DD2EC1F6}.Release|x86.ActiveCfg = Release|Any CPU
{3944F036-7E75-47E8-AA52-C4B89A64EC3A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3944F036-7E75-47E8-AA52-C4B89A64EC3A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3944F036-7E75-47E8-AA52-C4B89A64EC3A}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{3944F036-7E75-47E8-AA52-C4B89A64EC3A}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{3944F036-7E75-47E8-AA52-C4B89A64EC3A}.Debug|x86.ActiveCfg = Debug|Any CPU
{3944F036-7E75-47E8-AA52-C4B89A64EC3A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3944F036-7E75-47E8-AA52-C4B89A64EC3A}.Release|Any CPU.Build.0 = Release|Any CPU
{3944F036-7E75-47E8-AA52-C4B89A64EC3A}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{3944F036-7E75-47E8-AA52-C4B89A64EC3A}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{3944F036-7E75-47E8-AA52-C4B89A64EC3A}.Release|x86.ActiveCfg = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE

View File

@ -22,7 +22,6 @@ namespace IdentitySample.Models
public SignInManager<ApplicationUser> SignInManager { get; private set; } public SignInManager<ApplicationUser> SignInManager { get; private set; }
// //
// GET: /Account/Login // GET: /Account/Login
[HttpGet] [HttpGet]
@ -30,7 +29,7 @@ namespace IdentitySample.Models
public IActionResult Login(string returnUrl = null) public IActionResult Login(string returnUrl = null)
{ {
ViewBag.ReturnUrl = returnUrl; ViewBag.ReturnUrl = returnUrl;
ViewBag.LoginProviders = Context.GetExternalAuthenticationTypes().ToList(); ViewBag.LoginProviders = SignInManager.GetExternalAuthenticationTypes().ToList();
return View(); return View();
} }
@ -118,7 +117,7 @@ namespace IdentitySample.Models
{ {
// Request a redirect to the external login provider // Request a redirect to the external login provider
var redirectUrl = Url.Action("ExternalLoginCallback", "Account", new { ReturnUrl = returnUrl }); var redirectUrl = Url.Action("ExternalLoginCallback", "Account", new { ReturnUrl = returnUrl });
var properties = Context.ConfigureExternalAuthenticationProperties(provider, redirectUrl); var properties = SignInManager.ConfigureExternalAuthenticationProperties(provider, redirectUrl);
return new ChallengeResult(provider, properties); return new ChallengeResult(provider, properties);
} }
@ -128,7 +127,7 @@ namespace IdentitySample.Models
[AllowAnonymous] [AllowAnonymous]
public async Task<IActionResult> ExternalLoginCallback(string returnUrl = null) public async Task<IActionResult> ExternalLoginCallback(string returnUrl = null)
{ {
var info = await Context.GetExternalLoginInfo(); var info = await SignInManager.GetExternalLoginInfoAsync();
if (info == null) if (info == null)
{ {
return RedirectToAction("Login"); return RedirectToAction("Login");
@ -171,7 +170,7 @@ namespace IdentitySample.Models
if (ModelState.IsValid) if (ModelState.IsValid)
{ {
// Get the information about the user from the external login provider // Get the information about the user from the external login provider
var info = await Context.GetExternalLoginInfo(); var info = await SignInManager.GetExternalLoginInfoAsync();
if (info == null) if (info == null)
{ {
return View("ExternalLoginFailure"); return View("ExternalLoginFailure");

View File

@ -302,7 +302,7 @@ namespace IdentitySample
return View("Error"); return View("Error");
} }
var userLogins = await UserManager.GetLoginsAsync(user); var userLogins = await UserManager.GetLoginsAsync(user);
var otherLogins = Context.GetExternalAuthenticationTypes().Where(auth => userLogins.All(ul => auth.AuthenticationType != ul.LoginProvider)).ToList(); var otherLogins = SignInManager.GetExternalAuthenticationTypes().Where(auth => userLogins.All(ul => auth.AuthenticationType != ul.LoginProvider)).ToList();
ViewBag.ShowRemoveButton = user.PasswordHash != null || userLogins.Count > 1; ViewBag.ShowRemoveButton = user.PasswordHash != null || userLogins.Count > 1;
return View(new ManageLoginsViewModel return View(new ManageLoginsViewModel
{ {
@ -319,7 +319,7 @@ namespace IdentitySample
{ {
// Request a redirect to the external login provider to link a login for the current user // Request a redirect to the external login provider to link a login for the current user
var redirectUrl = Url.Action("LinkLoginCallback", "Manage"); var redirectUrl = Url.Action("LinkLoginCallback", "Manage");
var properties = Context.ConfigureExternalAuthenticationProperties(provider, redirectUrl, User.Identity.GetUserId()); var properties = SignInManager.ConfigureExternalAuthenticationProperties(provider, redirectUrl, User.Identity.GetUserId());
return new ChallengeResult(provider, properties); return new ChallengeResult(provider, properties);
} }
@ -333,7 +333,7 @@ namespace IdentitySample
{ {
return View("Error"); return View("Error");
} }
var info = await Context.GetExternalLoginInfo(User.Identity.GetUserId()); var info = await SignInManager.GetExternalLoginInfoAsync(User.Identity.GetUserId());
if (info == null) if (info == null)
{ {
return RedirectToAction("ManageLogins", new { Message = ManageMessageId.Error }); return RedirectToAction("ManageLogins", new { Message = ManageMessageId.Error });

View File

@ -1,79 +1,15 @@
using System; using IdentitySample.Models;
using Microsoft.AspNet.Builder; using Microsoft.AspNet.Builder;
using Microsoft.AspNet.Diagnostics; using Microsoft.AspNet.Diagnostics;
using Microsoft.AspNet.Identity; using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Routing; using Microsoft.AspNet.Routing;
using Microsoft.AspNet.Security.Facebook;
using Microsoft.AspNet.Security.Google;
using Microsoft.AspNet.Security.Twitter;
using Microsoft.Data.Entity; using Microsoft.Data.Entity;
using Microsoft.Framework.ConfigurationModel; using Microsoft.Framework.ConfigurationModel;
using Microsoft.Framework.DependencyInjection; using Microsoft.Framework.DependencyInjection;
using Microsoft.Framework.DependencyInjection.Fallback; using System;
using Microsoft.Framework.OptionsModel;
using IdentitySample.Models;
namespace IdentitySamples namespace IdentitySamples
{ {
public static class UseExt
{
/**
* TODO: Middleware constructors need to take IOptionsAccessor<TOptions>
* Move options setup into a different method?
* Cookie options need to be different, named service/option instances? i.e. Singleton Named Options
SetupNamedOption("ApplicationCookie", options => { })
UseCookieAuthentication("ApplicationCookie")
SetupNamedOption("ExternalCookie", options => { })
UseCookieAuthentication("ApplicationCookie")
// Overloads which use default/no name
SetupOption(options => { })
UseGoogleAuthentication()
*/
public static IApplicationBuilder UseGoogleAuthentication(this IApplicationBuilder builder)
{
return builder.UseMiddleware<GoogleAuthenticationMiddleware>();
//return builder.UseGoogleAuthentication(b =>
// b.ApplicationServices.GetService<IOptionsAccessor<GoogleAuthenticationOptions>>().Options);
}
public static IApplicationBuilder UseGoogleAuthentication(this IApplicationBuilder builder, Func<IApplicationBuilder, GoogleAuthenticationOptions> func)
{
return builder.UseGoogleAuthentication(func(builder));
}
public static IApplicationBuilder UseFacebookAuthentication(this IApplicationBuilder builder)
{
// This should go inside of the middleware delegate
return builder.UseFacebookAuthentication(b =>
b.ApplicationServices.GetService<IOptionsAccessor<FacebookAuthenticationOptions>>().Options);
}
public static IApplicationBuilder UseFacebookAuthentication(this IApplicationBuilder builder, Func<IApplicationBuilder, FacebookAuthenticationOptions> func)
{
return builder.UseFacebookAuthentication(func(builder));
}
public static IApplicationBuilder UseTwitterAuthentication(this IApplicationBuilder builder)
{
return builder.UseTwitterAuthentication(b =>
b.ApplicationServices.GetService<IOptionsAccessor<TwitterAuthenticationOptions>>().Options);
}
public static IApplicationBuilder UseTwitterAuthentication(this IApplicationBuilder builder, Func<IApplicationBuilder, TwitterAuthenticationOptions> func)
{
return builder.UseTwitterAuthentication(func(builder));
}
}
public partial class Startup public partial class Startup
{ {
public Startup() public Startup()
@ -89,102 +25,63 @@ namespace IdentitySamples
public IConfiguration Configuration { get; private set; } public IConfiguration Configuration { get; private set; }
public void ConfigureServices(IServiceCollection services)
{
services.AddEntityFramework().AddSqlServer();
services.AddScoped<ApplicationDbContext>();
services.ConfigureOptions<IdentityDbContextOptions>(options =>
{
options.DefaultAdminUserName = Configuration.Get("DefaultAdminUsername");
options.DefaultAdminPassword = Configuration.Get("DefaultAdminPassword");
options.UseSqlServer(Configuration.Get("Data:IdentityConnection:ConnectionString"));
});
services.AddDefaultIdentity<ApplicationDbContext, ApplicationUser, IdentityRole>(Configuration, options =>
{
options.Password.RequireDigit = false;
options.Password.RequireLowercase = false;
options.Password.RequireUppercase = false;
options.Password.RequireNonLetterOrDigit = false;
options.SecurityStampValidationInterval = TimeSpan.FromMinutes(20);
});
services.ConfigureFacebookAuthentication(options =>
{
options.AppId = "901611409868059";
options.AppSecret = "4aa3c530297b1dcebc8860334b39668b";
});
services.ConfigureGoogleAuthentication(options =>
{
options.ClientId = "514485782433-fr3ml6sq0imvhi8a7qir0nb46oumtgn9.apps.googleusercontent.com";
options.ClientSecret = "V2nDD9SkFbvLTqAUBWBBxYAL";
});
services.ConfigureTwitterAuthentication(options =>
{
options.ConsumerKey = "BSdJJ0CrDuvEhpkchnukXZBUv";
options.ConsumerSecret = "xKUNuKhsRdHD03eLn67xhPAyE1wFFEndFo1X2UJaK2m1jdAxf4";
});
services.AddMvc();
}
public void Configure(IApplicationBuilder app) public void Configure(IApplicationBuilder app)
{ {
app.UseServices(services => app.UseErrorPage(ErrorPageOptions.ShowAll)
{ .UseServices()
// Add EF services to the services container .UseStaticFiles()
services.AddEntityFramework() .UseIdentity()
.AddSqlServer(); .UseFacebookAuthentication()
.UseGoogleAuthentication()
// Configure DbContext .UseTwitterAuthentication()
services.SetupOptions<IdentityDbContextOptions>(options => .UseMvc(routes =>
{ {
options.DefaultAdminUserName = Configuration.Get("DefaultAdminUsername"); routes.MapRoute(
options.DefaultAdminPassword = Configuration.Get("DefaultAdminPassword"); name: "default",
options.UseSqlServer(Configuration.Get("Data:IdentityConnection:ConnectionString")); template: "{controller}/{action}/{id?}",
defaults: new { controller = "Home", action = "Index" });
}); });
// Add Identity services to the services container //Populates the Admin user and role
services.AddDefaultIdentity<ApplicationDbContext, ApplicationUser, IdentityRole>(Configuration);
// move this into add identity along with the
//service.SetupOptions<ExternalAuthenticationOptions>(options => options.SignInAsAuthenticationType = "External")
services.SetupOptions<IdentityOptions>(options =>
{
options.Password.RequireDigit = false;
options.Password.RequireLowercase = false;
options.Password.RequireUppercase = false;
options.Password.RequireNonLetterOrDigit = false;
options.SecurityStampValidationInterval = TimeSpan.Zero;
});
services.SetupOptions<GoogleAuthenticationOptions>(options =>
{
options.ClientId = "514485782433-fr3ml6sq0imvhi8a7qir0nb46oumtgn9.apps.googleusercontent.com";
options.ClientSecret = "V2nDD9SkFbvLTqAUBWBBxYAL";
});
services.AddInstance(new GoogleAuthenticationOptions
{
ClientId = "514485782433-fr3ml6sq0imvhi8a7qir0nb46oumtgn9.apps.googleusercontent.com",
ClientSecret = "V2nDD9SkFbvLTqAUBWBBxYAL"
});
services.SetupOptions<FacebookAuthenticationOptions>(options =>
{
options.AppId = "901611409868059";
options.AppSecret = "4aa3c530297b1dcebc8860334b39668b";
});
services.SetupOptions<FacebookAuthenticationOptions>(options =>
{
options.AppId = "901611409868059";
options.AppSecret = "4aa3c530297b1dcebc8860334b39668b";
});
services.SetupOptions<TwitterAuthenticationOptions>(options =>
{
options.ConsumerKey = "BSdJJ0CrDuvEhpkchnukXZBUv";
options.ConsumerSecret = "xKUNuKhsRdHD03eLn67xhPAyE1wFFEndFo1X2UJaK2m1jdAxf4";
});
// Add MVC services to the services container
services.AddMvc();
});
/* Error page middleware displays a nice formatted HTML page for any unhandled exceptions in the request pipeline.
* Note: ErrorPageOptions.ShowAll to be used only at development time. Not recommended for production.
*/
app.UseErrorPage(ErrorPageOptions.ShowAll);
// Add static files to the request pipeline
app.UseStaticFiles();
// Setup identity cookie middleware
// Add cookie-based authentication to the request pipeline
app.UseIdentity();
app.UseGoogleAuthentication();
app.UseFacebookAuthentication();
app.UseTwitterAuthentication();
// Add MVC to the request pipeline
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller}/{action}/{id?}",
defaults: new { controller = "Home", action = "Index" });
});
//Populates the Admin user and role
SampleData.InitializeIdentityDatabaseAsync(app.ApplicationServices).Wait(); SampleData.InitializeIdentityDatabaseAsync(app.ApplicationServices).Wait();
} }
// TODO: Move services here
public IServiceProvider ConfigureServices(ServiceCollection services)
{
return services.BuildServiceProvider();
}
} }
} }

View File

@ -1,6 +1,7 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.AspNet.Builder;
using Microsoft.AspNet.Identity; using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.SqlServer; using Microsoft.AspNet.Identity.SqlServer;
using Microsoft.Data.Entity; using Microsoft.Data.Entity;
@ -11,6 +12,7 @@ namespace Microsoft.Framework.DependencyInjection
{ {
public static class IdentityEntityFrameworkServiceCollectionExtensions public static class IdentityEntityFrameworkServiceCollectionExtensions
{ {
// MOVE to builder extension
public static IdentityBuilder<IdentityUser, IdentityRole> AddIdentitySqlServer(this IServiceCollection services) public static IdentityBuilder<IdentityUser, IdentityRole> AddIdentitySqlServer(this IServiceCollection services)
{ {
return services.AddIdentitySqlServer<IdentityDbContext, IdentityUser, IdentityRole>(); return services.AddIdentitySqlServer<IdentityDbContext, IdentityUser, IdentityRole>();
@ -22,54 +24,42 @@ namespace Microsoft.Framework.DependencyInjection
return services.AddIdentitySqlServer<TContext, IdentityUser, IdentityRole>(); return services.AddIdentitySqlServer<TContext, IdentityUser, IdentityRole>();
} }
public static IdentityBuilder<TUser, TRole> AddDefaultIdentity<TContext, TUser, TRole>(this IServiceCollection services, IConfiguration config) public static IdentityBuilder<TUser, TRole> AddDefaultIdentity<TContext, TUser, TRole>(this IServiceCollection services, IConfiguration config = null,
Action<IdentityOptions> configureOptions = null)
where TUser : IdentityUser, new() where TUser : IdentityUser, new()
where TRole : IdentityRole, new() where TRole : IdentityRole, new()
where TContext : DbContext where TContext : DbContext
{ {
return services.AddDefaultIdentity<TUser, TRole>(config) return services.AddDefaultIdentity<TUser, TRole>(config, configureOptions)
.AddEntityFramework<TContext, TUser, TRole>(); .AddEntityFramework<TContext, TUser, TRole>();
} }
public static IdentityBuilder<TUser, IdentityRole> AddIdentitySqlServer<TContext, TUser>(this IServiceCollection services, Action<IdentityOptions> configureOptions = null)
public static IdentityBuilder<TUser, IdentityRole> AddIdentitySqlServer<TContext, TUser>(this IServiceCollection services)
where TUser : IdentityUser, new() where TUser : IdentityUser, new()
where TContext : DbContext where TContext : DbContext
{ {
return services.AddIdentitySqlServer<TContext, TUser, IdentityRole>(); return services.AddIdentitySqlServer<TContext, TUser, IdentityRole>(null, configureOptions);
} }
public static IdentityBuilder<TUser, TRole> AddSqlServer<TContext, TUser, TRole>(this IServiceCollection services) public static IdentityBuilder<TUser, TRole> AddIdentitySqlServer<TContext, TUser, TRole>(this IServiceCollection services, IConfiguration config = null, Action<IdentityOptions> configureOptions = null)
where TUser : IdentityUser, new() where TUser : IdentityUser, new()
where TRole : IdentityRole, new() where TRole : IdentityRole, new()
where TContext : DbContext where TContext : DbContext
{ {
var builder = services.AddIdentity<TUser, TRole>(); var builder = services.AddIdentity<TUser, TRole>(config, configureOptions);
services.AddScoped<IUserStore<TUser>, UserStore<TUser, TRole, TContext>>(); services.AddScoped<IUserStore<TUser>, UserStore<TUser, TRole, TContext>>();
services.AddScoped<IRoleStore<TRole>, RoleStore<TRole, TContext>>(); services.AddScoped<IRoleStore<TRole>, RoleStore<TRole, TContext>>();
services.AddScoped<TContext>(); services.AddScoped<TContext>();
return builder; return builder;
} }
public static IdentityBuilder<TUser, TRole> AddIdentitySqlServer<TContext, TUser, TRole>(this IServiceCollection services) public static IdentityBuilder<TUser, TRole> AddIdentitySqlServer<TContext, TUser, TRole, TKey>(this IServiceCollection services, IConfiguration config = null, Action<IdentityOptions> configureOptions = null)
where TUser : IdentityUser, new()
where TRole : IdentityRole, new()
where TContext : DbContext
{
var builder = services.AddIdentity<TUser, TRole>();
services.AddScoped<IUserStore<TUser>, UserStore<TUser, TRole, TContext>>();
services.AddScoped<IRoleStore<TRole>, RoleStore<TRole, TContext>>();
services.AddScoped<TContext>();
return builder;
}
public static IdentityBuilder<TUser, TRole> AddIdentitySqlServer<TContext, TUser, TRole, TKey>(this IServiceCollection services)
where TUser : IdentityUser<TKey>, new() where TUser : IdentityUser<TKey>, new()
where TRole : IdentityRole<TKey>, new() where TRole : IdentityRole<TKey>, new()
where TContext : DbContext where TContext : DbContext
where TKey : IEquatable<TKey> where TKey : IEquatable<TKey>
{ {
var builder = services.AddIdentity<TUser, TRole>(); var builder = services.AddIdentity<TUser, TRole>(config, configureOptions);
services.AddScoped<IUserStore<TUser>, UserStore<TUser, TRole, TContext, TKey>>(); services.AddScoped<IUserStore<TUser>, UserStore<TUser, TRole, TContext, TKey>>();
services.AddScoped<IRoleStore<TRole>, RoleStore<TRole, TContext, TKey>>(); services.AddScoped<IRoleStore<TRole>, RoleStore<TRole, TContext, TKey>>();
services.AddScoped<TContext>(); services.AddScoped<TContext>();

View File

@ -5,6 +5,8 @@ using System;
using Microsoft.AspNet.Identity; using Microsoft.AspNet.Identity;
using Microsoft.Framework.OptionsModel; using Microsoft.Framework.OptionsModel;
using Microsoft.Framework.DependencyInjection; using Microsoft.Framework.DependencyInjection;
using Microsoft.AspNet.Security.Cookies;
using Microsoft.Framework.ConfigurationModel;
namespace Microsoft.AspNet.Builder namespace Microsoft.AspNet.Builder
{ {
@ -19,12 +21,11 @@ namespace Microsoft.AspNet.Builder
{ {
throw new ArgumentNullException("app"); throw new ArgumentNullException("app");
} }
var options = app.ApplicationServices.GetService<IOptionsAccessor<IdentityOptions>>().Options; app.UseCookieAuthentication(null, IdentityOptions.ExternalCookieAuthenticationType);
app.SetDefaultSignInAsAuthenticationType(options.DefaultSignInAsAuthenticationType); app.UseCookieAuthentication(null, IdentityOptions.ApplicationCookieAuthenticationType);
app.UseCookieAuthentication(options.ExternalCookie); app.UseCookieAuthentication(null, IdentityOptions.TwoFactorRememberMeCookieAuthenticationType);
app.UseCookieAuthentication(options.ApplicationCookie); app.UseCookieAuthentication(null, IdentityOptions.TwoFactorUserIdCookieAuthenticationType);
app.UseCookieAuthentication(options.TwoFactorRememberMeCookie); app.UseCookieAuthentication(null, IdentityOptions.ApplicationCookieAuthenticationType);
app.UseCookieAuthentication(options.TwoFactorUserIdCookie);
return app; return app;
} }
} }

View File

@ -58,7 +58,7 @@ namespace Microsoft.AspNet.Identity
} }
var userId = await UserManager.GetUserIdAsync(user, cancellationToken); var userId = await UserManager.GetUserIdAsync(user, cancellationToken);
var userName = await UserManager.GetUserNameAsync(user, cancellationToken); var userName = await UserManager.GetUserNameAsync(user, cancellationToken);
var id = new ClaimsIdentity(Options.ApplicationCookie.AuthenticationType, Options.ClaimsIdentity.UserNameClaimType, var id = new ClaimsIdentity(IdentityOptions.ApplicationCookieAuthenticationType, Options.ClaimsIdentity.UserNameClaimType,
Options.ClaimsIdentity.RoleClaimType); Options.ClaimsIdentity.RoleClaimType);
id.AddClaim(new Claim(Options.ClaimsIdentity.UserIdClaimType, userId)); id.AddClaim(new Claim(Options.ClaimsIdentity.UserIdClaimType, userId));
id.AddClaim(new Claim(Options.ClaimsIdentity.UserNameClaimType, userName, ClaimValueTypes.String)); id.AddClaim(new Claim(Options.ClaimsIdentity.UserNameClaimType, userName, ClaimValueTypes.String));

View File

@ -8,10 +8,6 @@ namespace Microsoft.AspNet.Identity
public class ClaimsIdentityOptions public class ClaimsIdentityOptions
{ {
public static readonly string DefaultSecurityStampClaimType = "AspNet.Identity.SecurityStamp"; public static readonly string DefaultSecurityStampClaimType = "AspNet.Identity.SecurityStamp";
public static readonly string DefaultAuthenticationType = typeof(ClaimsIdentityOptions).Namespace + ".Application";
public static readonly string DefaultExternalLoginAuthenticationType = typeof(ClaimsIdentityOptions).Namespace + ".ExternalLogin";
public static readonly string DefaultTwoFactorRememberMeAuthenticationType = typeof(ClaimsIdentityOptions).Namespace + ".TwoFactorRememberMe";
public static readonly string DefaultTwoFactorUserIdAuthenticationType = typeof(ClaimsIdentityOptions).Namespace + ".TwoFactorUserId";
/// <summary> /// <summary>
/// Claim type used for role claims /// Claim type used for role claims

View File

@ -1,75 +0,0 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Collections.Generic;
using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Http.Security;
using System.Linq;
using System;
using System.Security.Principal;
namespace Microsoft.AspNet.Http
{
public static class HttpContextExtensions
{
private const string LoginProviderKey = "LoginProvider";
private const string XsrfKey = "XsrfId";
public static IEnumerable<AuthenticationDescription> GetExternalAuthenticationTypes(this HttpContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
return context.GetAuthenticationTypes().Where(d => !string.IsNullOrEmpty(d.Caption));
}
public static async Task<ExternalLoginInfo> GetExternalLoginInfo(this HttpContext context, string expectedXsrf = null)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
// REVIEW: should we consider taking the external authentication type as an argument?
var auth = await context.AuthenticateAsync(ClaimsIdentityOptions.DefaultExternalLoginAuthenticationType);
if (auth == null || auth.Identity == null || auth.Properties.Dictionary == null || !auth.Properties.Dictionary.ContainsKey(LoginProviderKey))
{
return null;
}
if (expectedXsrf != null)
{
if (!auth.Properties.Dictionary.ContainsKey(XsrfKey))
{
return null;
}
var userId = auth.Properties.Dictionary[XsrfKey] as string;
if (userId != expectedXsrf)
{
return null;
}
}
var providerKey = auth.Identity.FindFirstValue(ClaimTypes.NameIdentifier);
var provider = auth.Properties.Dictionary[LoginProviderKey] as string;
if (providerKey == null || provider == null)
{
return null;
}
return new ExternalLoginInfo(auth.Identity, provider, providerKey, auth.Description.Caption);
}
public static AuthenticationProperties ConfigureExternalAuthenticationProperties(this HttpContext context, string provider, string redirectUrl, string userId = null)
{
var properties = new AuthenticationProperties { RedirectUri = redirectUrl };
properties.Dictionary[LoginProviderKey] = provider;
if (userId != null)
{
properties.Dictionary[XsrfKey] = userId;
}
return properties;
}
}
}

View File

@ -16,8 +16,6 @@ namespace Microsoft.AspNet.Identity
Services = services; Services = services;
} }
// Rename to Add
public IdentityBuilder<TUser, TRole> AddInstance<T>(T obj) public IdentityBuilder<TUser, TRole> AddInstance<T>(T obj)
{ {
Services.AddInstance(obj); Services.AddInstance(obj);
@ -49,17 +47,12 @@ namespace Microsoft.AspNet.Identity
return AddInstance(tokenProvider); return AddInstance(tokenProvider);
} }
public IdentityBuilder<TUser, TRole> SetupOptions(Action<IdentityOptions> action, int order) public IdentityBuilder<TUser, TRole> ConfigureIdentity(Action<IdentityOptions> action, int order = 0)
{ {
Services.AddSetup(new OptionsSetup<IdentityOptions>(action) { Order = order }); Services.AddOptionsAction(new OptionsAction<IdentityOptions>(action) { Order = order });
return this; return this;
} }
public IdentityBuilder<TUser, TRole> SetupOptions(Action<IdentityOptions> action)
{
return SetupOptions(action, 0);
}
public IdentityBuilder<TUser, TRole> AddUserManager<TManager>() where TManager : UserManager<TUser> public IdentityBuilder<TUser, TRole> AddUserManager<TManager>() where TManager : UserManager<TUser>
{ {
Services.AddScoped<TManager>(); Services.AddScoped<TManager>();

View File

@ -29,47 +29,9 @@ namespace Microsoft.AspNet.Identity
public string PasswordResetTokenProvider { get; set; } = Resources.DefaultTokenProvider; public string PasswordResetTokenProvider { get; set; } = Resources.DefaultTokenProvider;
//public string ApplicationCookieAuthenticationType { get; set; } public static string ApplicationCookieAuthenticationType { get; set; } = typeof(IdentityOptions).Namespace + ".Application";
//public string ExternalCookieAuthenticationType { get; set; } public static string ExternalCookieAuthenticationType { get; set; } = typeof(IdentityOptions).Namespace + ".External";
//public string TwoFactorCookieAuthenticationType { get; set; } public static string TwoFactorUserIdCookieAuthenticationType { get; set; } = typeof(IdentityOptions).Namespace + ".TwoFactorUserId";
//public string TwoFactorFactorCookieAuthenticationType { get; set; } public static string TwoFactorRememberMeCookieAuthenticationType { get; set; } = typeof(IdentityOptions).Namespace + ".TwoFactorRemeberMe";
public CookieAuthenticationOptions ApplicationCookie { get; set; } = new CookieAuthenticationOptions
{
AuthenticationType = ClaimsIdentityOptions.DefaultAuthenticationType,
//CookieName = ".AspNet.Identity." + ClaimsIdentityOptions.DefaultAuthenticationType,
LoginPath = new PathString("/Account/Login"),
Notifications = new CookieAuthenticationNotifications
{
OnValidateIdentity = SecurityStampValidator.ValidateIdentityAsync
}
};
// Move to setups for named per cookie option
public string DefaultSignInAsAuthenticationType { get; set; } = ClaimsIdentityOptions.DefaultExternalLoginAuthenticationType;
public CookieAuthenticationOptions ExternalCookie { get; set; } = new CookieAuthenticationOptions
{
AuthenticationType = ClaimsIdentityOptions.DefaultExternalLoginAuthenticationType,
AuthenticationMode = AuthenticationMode.Passive,
CookieName = ClaimsIdentityOptions.DefaultExternalLoginAuthenticationType,
ExpireTimeSpan = TimeSpan.FromMinutes(5),
};
public CookieAuthenticationOptions TwoFactorRememberMeCookie { get; set; } = new CookieAuthenticationOptions
{
AuthenticationType = ClaimsIdentityOptions.DefaultTwoFactorRememberMeAuthenticationType,
AuthenticationMode = AuthenticationMode.Passive,
CookieName = ClaimsIdentityOptions.DefaultTwoFactorRememberMeAuthenticationType
};
public CookieAuthenticationOptions TwoFactorUserIdCookie { get; set; } = new CookieAuthenticationOptions
{
AuthenticationType = ClaimsIdentityOptions.DefaultTwoFactorUserIdAuthenticationType,
AuthenticationMode = AuthenticationMode.Passive,
CookieName = ClaimsIdentityOptions.DefaultTwoFactorUserIdAuthenticationType,
ExpireTimeSpan = TimeSpan.FromMinutes(5),
};
} }
} }

View File

@ -5,16 +5,23 @@ using System;
using Microsoft.AspNet.Identity; using Microsoft.AspNet.Identity;
using Microsoft.Framework.ConfigurationModel; using Microsoft.Framework.ConfigurationModel;
using Microsoft.AspNet.Security.DataProtection; using Microsoft.AspNet.Security.DataProtection;
using Microsoft.AspNet.Security.Cookies;
using Microsoft.AspNet.Http;
using Microsoft.AspNet.Security;
namespace Microsoft.Framework.DependencyInjection namespace Microsoft.Framework.DependencyInjection
{ {
public static class IdentityServiceCollectionExtensions public static class IdentityServiceCollectionExtensions
{ {
public static IdentityBuilder<IdentityUser, IdentityRole> AddIdentity(this IServiceCollection services, public static IServiceCollection ConfigureIdentity(this IServiceCollection services, Action<IdentityOptions> configure)
IConfiguration identityConfig)
{ {
services.SetupOptions<IdentityOptions>(identityConfig); return services.ConfigureOptions(configure);
return services.AddIdentity<IdentityUser, IdentityRole>(); }
public static IdentityBuilder<IdentityUser, IdentityRole> AddIdentity(this IServiceCollection services,
IConfiguration identityConfig = null, Action<IdentityOptions> configureOptions = null)
{
return services.AddIdentity<IdentityUser, IdentityRole>(identityConfig, configureOptions);
} }
public static IdentityBuilder<IdentityUser, IdentityRole> AddIdentity(this IServiceCollection services) public static IdentityBuilder<IdentityUser, IdentityRole> AddIdentity(this IServiceCollection services)
@ -23,28 +30,73 @@ namespace Microsoft.Framework.DependencyInjection
} }
public static IdentityBuilder<TUser, TRole> AddIdentity<TUser, TRole>(this IServiceCollection services, public static IdentityBuilder<TUser, TRole> AddIdentity<TUser, TRole>(this IServiceCollection services,
IConfiguration identityConfig = null) IConfiguration identityConfig = null, Action<IdentityOptions> configureOptions = null)
where TUser : class where TUser : class
where TRole : class where TRole : class
{ {
if (identityConfig != null) if (identityConfig != null)
{ {
services.SetupOptions<IdentityOptions>(identityConfig); services.ConfigureOptions<IdentityOptions>(identityConfig);
} }
if (configureOptions != null)
{
services.ConfigureIdentity(configureOptions);
}
services.Add(IdentityServices.GetDefaultServices<TUser, TRole>(identityConfig)); services.Add(IdentityServices.GetDefaultServices<TUser, TRole>(identityConfig));
services.AddScoped<UserManager<TUser>>(); services.AddScoped<UserManager<TUser>>();
services.AddScoped<SignInManager<TUser>>(); services.AddScoped<SignInManager<TUser>>();
services.AddScoped<ISecurityStampValidator, SecurityStampValidator<TUser>>(); services.AddScoped<ISecurityStampValidator, SecurityStampValidator<TUser>>();
services.AddScoped<RoleManager<TRole>>(); services.AddScoped<RoleManager<TRole>>();
services.AddScoped<IClaimsIdentityFactory<TUser>, ClaimsIdentityFactory<TUser, TRole>>(); services.AddScoped<IClaimsIdentityFactory<TUser>, ClaimsIdentityFactory<TUser, TRole>>();
services.ConfigureOptions<ExternalAuthenticationOptions>(options =>
{
options.SignInAsAuthenticationType = IdentityOptions.ExternalCookieAuthenticationType;
});
services.ConfigureOptions<CookieAuthenticationOptions>(options =>
{
options.AuthenticationType = IdentityOptions.ApplicationCookieAuthenticationType;
//CookieName = ".AspNet.Identity." + ClaimsIdentityOptions.DefaultAuthenticationType,
options.LoginPath = new PathString("/Account/Login");
options.Notifications = new CookieAuthenticationNotifications
{
OnValidateIdentity = SecurityStampValidator.ValidateIdentityAsync
};
}, IdentityOptions.ApplicationCookieAuthenticationType);
services.ConfigureOptions<CookieAuthenticationOptions>(options =>
{
options.AuthenticationType = IdentityOptions.ExternalCookieAuthenticationType;
options.AuthenticationMode = AuthenticationMode.Passive;
options.CookieName = IdentityOptions.ExternalCookieAuthenticationType;
options.ExpireTimeSpan = TimeSpan.FromMinutes(5);
}, IdentityOptions.ExternalCookieAuthenticationType);
services.ConfigureOptions<CookieAuthenticationOptions>(options =>
{
options.AuthenticationType = IdentityOptions.TwoFactorRememberMeCookieAuthenticationType;
options.AuthenticationMode = AuthenticationMode.Passive;
options.CookieName = IdentityOptions.TwoFactorRememberMeCookieAuthenticationType;
}, IdentityOptions.TwoFactorRememberMeCookieAuthenticationType);
services.ConfigureOptions<CookieAuthenticationOptions>(options =>
{
options.AuthenticationType = IdentityOptions.TwoFactorUserIdCookieAuthenticationType;
options.AuthenticationMode = AuthenticationMode.Passive;
options.CookieName = IdentityOptions.TwoFactorUserIdCookieAuthenticationType;
options.ExpireTimeSpan = TimeSpan.FromMinutes(5);
}, IdentityOptions.TwoFactorUserIdCookieAuthenticationType);
return new IdentityBuilder<TUser, TRole>(services); return new IdentityBuilder<TUser, TRole>(services);
} }
public static IdentityBuilder<TUser, TRole> AddDefaultIdentity<TUser, TRole>(this IServiceCollection services, IConfiguration config = null) public static IdentityBuilder<TUser, TRole> AddDefaultIdentity<TUser, TRole>(this IServiceCollection services, IConfiguration config = null, Action<IdentityOptions> configureOptions = null)
where TUser : class where TUser : class
where TRole : class where TRole : class
{ {
return services.AddIdentity<TUser, TRole>(config) return services.AddIdentity<TUser, TRole>(config, configureOptions)
.AddTokenProvider(new DataProtectorTokenProvider<TUser>( .AddTokenProvider(new DataProtectorTokenProvider<TUser>(
new DataProtectionTokenProviderOptions new DataProtectionTokenProviderOptions
{ {

View File

@ -10,6 +10,8 @@ using Microsoft.AspNet.Http;
using Microsoft.AspNet.Http.Security; using Microsoft.AspNet.Http.Security;
using Microsoft.Framework.DependencyInjection; using Microsoft.Framework.DependencyInjection;
using Microsoft.Framework.OptionsModel; using Microsoft.Framework.OptionsModel;
using System.Collections.Generic;
using System.Linq;
namespace Microsoft.AspNet.Identity namespace Microsoft.AspNet.Identity
{ {
@ -74,8 +76,6 @@ namespace Microsoft.AspNet.Identity
CancellationToken cancellationToken = default(CancellationToken)) CancellationToken cancellationToken = default(CancellationToken))
{ {
var userIdentity = await CreateUserIdentityAsync(user); var userIdentity = await CreateUserIdentityAsync(user);
// Should always clear any external login cookies when signing in for real
Context.Response.SignOut(Options.ExternalCookie.AuthenticationType);
if (authenticationMethod != null) if (authenticationMethod != null)
{ {
userIdentity.AddClaim(new Claim(ClaimTypes.AuthenticationMethod, authenticationMethod)); userIdentity.AddClaim(new Claim(ClaimTypes.AuthenticationMethod, authenticationMethod));
@ -86,7 +86,7 @@ namespace Microsoft.AspNet.Identity
// TODO: Should this be async? // TODO: Should this be async?
public virtual void SignOut() public virtual void SignOut()
{ {
Context.Response.SignOut(Options.ApplicationCookie.AuthenticationType); Context.Response.SignOut(IdentityOptions.ApplicationCookieAuthenticationType);
} }
private async Task<bool> IsLockedOut(TUser user, CancellationToken token) private async Task<bool> IsLockedOut(TUser user, CancellationToken token)
@ -151,7 +151,7 @@ namespace Microsoft.AspNet.Identity
{ {
return null; return null;
} }
var identity = new ClaimsIdentity(ClaimsIdentityOptions.DefaultTwoFactorUserIdAuthenticationType); var identity = new ClaimsIdentity(IdentityOptions.TwoFactorUserIdCookieAuthenticationType);
identity.AddClaim(new Claim(ClaimTypes.Name, info.UserId)); identity.AddClaim(new Claim(ClaimTypes.Name, info.UserId));
if (info.LoginProvider != null) if (info.LoginProvider != null)
{ {
@ -185,7 +185,7 @@ namespace Microsoft.AspNet.Identity
{ {
var userId = await UserManager.GetUserIdAsync(user, cancellationToken); var userId = await UserManager.GetUserIdAsync(user, cancellationToken);
var result = var result =
await Context.AuthenticateAsync(Options.TwoFactorRememberMeCookie.AuthenticationType); await Context.AuthenticateAsync(IdentityOptions.TwoFactorRememberMeCookieAuthenticationType);
return (result != null && result.Identity != null && result.Identity.Name == userId); return (result != null && result.Identity != null && result.Identity.Name == userId);
} }
@ -193,14 +193,14 @@ namespace Microsoft.AspNet.Identity
CancellationToken cancellationToken = default(CancellationToken)) CancellationToken cancellationToken = default(CancellationToken))
{ {
var userId = await UserManager.GetUserIdAsync(user, cancellationToken); var userId = await UserManager.GetUserIdAsync(user, cancellationToken);
var rememberBrowserIdentity = new ClaimsIdentity(ClaimsIdentityOptions.DefaultTwoFactorRememberMeAuthenticationType); var rememberBrowserIdentity = new ClaimsIdentity(IdentityOptions.TwoFactorRememberMeCookieAuthenticationType);
rememberBrowserIdentity.AddClaim(new Claim(ClaimTypes.Name, userId)); rememberBrowserIdentity.AddClaim(new Claim(ClaimTypes.Name, userId));
Context.Response.SignIn(new AuthenticationProperties { IsPersistent = true }, rememberBrowserIdentity); Context.Response.SignIn(new AuthenticationProperties { IsPersistent = true }, rememberBrowserIdentity);
} }
public virtual Task ForgetTwoFactorClientAsync() public virtual Task ForgetTwoFactorClientAsync()
{ {
Context.Response.SignOut(Options.TwoFactorRememberMeCookie.AuthenticationType); Context.Response.SignOut(IdentityOptions.TwoFactorRememberMeCookieAuthenticationType);
return Task.FromResult(0); return Task.FromResult(0);
} }
@ -225,6 +225,11 @@ namespace Microsoft.AspNet.Identity
{ {
// When token is verified correctly, clear the access failed count used for lockout // When token is verified correctly, clear the access failed count used for lockout
await UserManager.ResetAccessFailedCountAsync(user, cancellationToken); await UserManager.ResetAccessFailedCountAsync(user, cancellationToken);
// Cleanup external cookie
if (twoFactorInfo.LoginProvider != null)
{
Context.Response.SignOut(IdentityOptions.ExternalCookieAuthenticationType);
}
await SignInAsync(user, isPersistent, twoFactorInfo.LoginProvider, cancellationToken); await SignInAsync(user, isPersistent, twoFactorInfo.LoginProvider, cancellationToken);
if (rememberClient) if (rememberClient)
{ {
@ -254,7 +259,7 @@ namespace Microsoft.AspNet.Identity
return await UserManager.FindByIdAsync(info.UserId, cancellationToken); return await UserManager.FindByIdAsync(info.UserId, cancellationToken);
} }
public async Task<SignInStatus> ExternalLoginSignInAsync(string loginProvider, string providerKey, bool isPersistent, public virtual async Task<SignInStatus> ExternalLoginSignInAsync(string loginProvider, string providerKey, bool isPersistent,
CancellationToken cancellationToken = default(CancellationToken)) CancellationToken cancellationToken = default(CancellationToken))
{ {
var user = await UserManager.FindByLoginAsync(loginProvider, providerKey, cancellationToken); var user = await UserManager.FindByLoginAsync(loginProvider, providerKey, cancellationToken);
@ -269,6 +274,56 @@ namespace Microsoft.AspNet.Identity
return await SignInOrTwoFactorAsync(user, isPersistent, cancellationToken, loginProvider); return await SignInOrTwoFactorAsync(user, isPersistent, cancellationToken, loginProvider);
} }
private const string LoginProviderKey = "LoginProvider";
private const string XsrfKey = "XsrfId";
public virtual IEnumerable<AuthenticationDescription> GetExternalAuthenticationTypes()
{
return Context.GetAuthenticationTypes().Where(d => !string.IsNullOrEmpty(d.Caption));
}
public virtual async Task<ExternalLoginInfo> GetExternalLoginInfoAsync(string expectedXsrf = null,
CancellationToken cancellationToken = default(CancellationToken))
{
var auth = await Context.AuthenticateAsync(IdentityOptions.ExternalCookieAuthenticationType);
if (auth == null || auth.Identity == null || auth.Properties.Dictionary == null || !auth.Properties.Dictionary.ContainsKey(LoginProviderKey))
{
return null;
}
if (expectedXsrf != null)
{
if (!auth.Properties.Dictionary.ContainsKey(XsrfKey))
{
return null;
}
var userId = auth.Properties.Dictionary[XsrfKey] as string;
if (userId != expectedXsrf)
{
return null;
}
}
var providerKey = auth.Identity.FindFirstValue(ClaimTypes.NameIdentifier);
var provider = auth.Properties.Dictionary[LoginProviderKey] as string;
if (providerKey == null || provider == null)
{
return null;
}
return new ExternalLoginInfo(auth.Identity, provider, providerKey, auth.Description.Caption);
}
public AuthenticationProperties ConfigureExternalAuthenticationProperties(string provider, string redirectUrl, string userId = null)
{
var properties = new AuthenticationProperties { RedirectUri = redirectUrl };
properties.Dictionary[LoginProviderKey] = provider;
if (userId != null)
{
properties.Dictionary[XsrfKey] = userId;
}
return properties;
}
private async Task<SignInStatus> SignInOrTwoFactorAsync(TUser user, bool isPersistent, private async Task<SignInStatus> SignInOrTwoFactorAsync(TUser user, bool isPersistent,
CancellationToken cancellationToken, string loginProvider = null) CancellationToken cancellationToken, string loginProvider = null)
{ {
@ -284,13 +339,18 @@ namespace Microsoft.AspNet.Identity
return SignInStatus.RequiresVerification; return SignInStatus.RequiresVerification;
} }
} }
// Cleanup external cookie
if (loginProvider != null)
{
Context.Response.SignOut(IdentityOptions.ExternalCookieAuthenticationType);
}
await SignInAsync(user, isPersistent, loginProvider, cancellationToken); await SignInAsync(user, isPersistent, loginProvider, cancellationToken);
return SignInStatus.Success; return SignInStatus.Success;
} }
private async Task<TwoFactorAuthenticationInfo> RetrieveTwoFactorInfoAsync(CancellationToken cancellationToken) private async Task<TwoFactorAuthenticationInfo> RetrieveTwoFactorInfoAsync(CancellationToken cancellationToken)
{ {
var result = await Context.AuthenticateAsync(ClaimsIdentityOptions.DefaultTwoFactorUserIdAuthenticationType); var result = await Context.AuthenticateAsync(IdentityOptions.TwoFactorUserIdCookieAuthenticationType);
if (result != null && result.Identity != null) if (result != null && result.Identity != null)
{ {
return new TwoFactorAuthenticationInfo return new TwoFactorAuthenticationInfo
@ -304,7 +364,7 @@ namespace Microsoft.AspNet.Identity
internal static ClaimsIdentity StoreTwoFactorInfo(string userId, string loginProvider) internal static ClaimsIdentity StoreTwoFactorInfo(string userId, string loginProvider)
{ {
var identity = new ClaimsIdentity(ClaimsIdentityOptions.DefaultTwoFactorUserIdAuthenticationType); var identity = new ClaimsIdentity(IdentityOptions.TwoFactorUserIdCookieAuthenticationType);
identity.AddClaim(new Claim(ClaimTypes.Name, userId)); identity.AddClaim(new Claim(ClaimTypes.Name, userId));
if (loginProvider != null) if (loginProvider != null)
{ {

View File

@ -19,17 +19,20 @@ namespace Microsoft.AspNet.Identity.InMemory.Test
public class HttpSignInTest public class HttpSignInTest
{ {
#if ASPNET50
[Theory] [Theory]
[InlineData(true)] [InlineData(true)]
[InlineData(false)] [InlineData(false)]
public async Task VerifyAccountControllerSignIn(bool isPersistent) public async Task VerifyAccountControllerSignIn(bool isPersistent)
{ {
var app = new ApplicationBuilder(new ServiceCollection().BuildServiceProvider()); var app = new ApplicationBuilder(new ServiceCollection().BuildServiceProvider());
app.UseCookieAuthentication(new CookieAuthenticationOptions //app.UseServices(services =>
{ //{
AuthenticationType = ClaimsIdentityOptions.DefaultAuthenticationType // services.SetupOptions<CookieAuthenticationOptions>(options =>
}); // {
// options.AuthenticationType = IdentityOptions.ApplicationCookieAuthenticationType;
// });
//});
app.UseCookieAuthentication();
var context = new Mock<HttpContext>(); var context = new Mock<HttpContext>();
var response = new Mock<HttpResponse>(); var response = new Mock<HttpResponse>();
@ -61,6 +64,5 @@ namespace Microsoft.AspNet.Identity.InMemory.Test
response.VerifyAll(); response.VerifyAll();
contextAccessor.VerifyAll(); contextAccessor.VerifyAll();
} }
#endif
} }
} }

View File

@ -21,7 +21,7 @@ namespace Microsoft.AspNet.Identity.InMemory.Test
var services = new ServiceCollection(); var services = new ServiceCollection();
services.Add(OptionsServices.GetDefaultServices()); services.Add(OptionsServices.GetDefaultServices());
services.AddIdentity().AddInMemory(); services.AddIdentity().AddInMemory();
services.SetupOptions<IdentityOptions>(options => services.ConfigureIdentity(options =>
{ {
options.Password.RequireDigit = false; options.Password.RequireDigit = false;
options.Password.RequireLowercase = false; options.Password.RequireLowercase = false;

View File

@ -25,7 +25,7 @@ namespace Microsoft.AspNet.Identity.SqlServer.InMemory.Test
services.Add(OptionsServices.GetDefaultServices()); services.Add(OptionsServices.GetDefaultServices());
services.AddEntityFramework().AddInMemoryStore(); services.AddEntityFramework().AddInMemoryStore();
services.AddIdentityInMemory((InMemoryContext)context); services.AddIdentityInMemory((InMemoryContext)context);
services.SetupOptions<IdentityOptions>(options => services.ConfigureIdentity(options =>
{ {
options.Password.RequireDigit = false; options.Password.RequireDigit = false;
options.Password.RequireLowercase = false; options.Password.RequireLowercase = false;

View File

@ -52,7 +52,7 @@ namespace Microsoft.AspNet.Identity.SqlServer.Test
services.Add(OptionsServices.GetDefaultServices()); services.Add(OptionsServices.GetDefaultServices());
services.AddInstance<ILoggerFactory>(new NullLoggerFactory()); services.AddInstance<ILoggerFactory>(new NullLoggerFactory());
services.AddEntityFramework().AddSqlServer(); services.AddEntityFramework().AddSqlServer();
services.SetupOptions<DbContextOptions>(options => options.UseSqlServer(ConnectionString)); services.ConfigureOptions<DbContextOptions>(options => options.UseSqlServer(ConnectionString));
var serviceProvider = services.BuildServiceProvider(); var serviceProvider = services.BuildServiceProvider();
return new CustomDbContext<TKey>(serviceProvider); return new CustomDbContext<TKey>(serviceProvider);
} }

View File

@ -25,7 +25,7 @@ namespace Microsoft.AspNet.Identity.SqlServer.Test
services.Add(OptionsServices.GetDefaultServices()); services.Add(OptionsServices.GetDefaultServices());
services.AddInstance<ILoggerFactory>(new NullLoggerFactory()); services.AddInstance<ILoggerFactory>(new NullLoggerFactory());
services.AddEntityFramework().AddSqlServer(); services.AddEntityFramework().AddSqlServer();
services.SetupOptions<DbContextOptions>(options => options.UseSqlServer(ConnectionString)); services.ConfigureOptions<DbContextOptions>(options => options.UseSqlServer(ConnectionString));
var serviceProvider = services.BuildServiceProvider(); var serviceProvider = services.BuildServiceProvider();
var db = new IdentityDbContext(serviceProvider, var db = new IdentityDbContext(serviceProvider,
serviceProvider.GetService<IOptionsAccessor<DbContextOptions>>().Options); serviceProvider.GetService<IOptionsAccessor<DbContextOptions>>().Options);
@ -59,7 +59,7 @@ namespace Microsoft.AspNet.Identity.SqlServer.Test
{ {
services.AddEntityFramework().AddSqlServer(); services.AddEntityFramework().AddSqlServer();
services.AddIdentitySqlServer(); services.AddIdentitySqlServer();
services.SetupOptions<DbContextOptions>(options => services.ConfigureOptions<DbContextOptions>(options =>
options.UseSqlServer(ConnectionString)); options.UseSqlServer(ConnectionString));
// todo: constructor resolution doesn't work well with IdentityDbContext since it has 4 constructors // todo: constructor resolution doesn't work well with IdentityDbContext since it has 4 constructors
services.AddInstance(context); services.AddInstance(context);

View File

@ -50,7 +50,7 @@ namespace Microsoft.AspNet.Identity.SqlServer.Test
services.AddEntityFramework().AddSqlServer(); services.AddEntityFramework().AddSqlServer();
services.Add(OptionsServices.GetDefaultServices()); services.Add(OptionsServices.GetDefaultServices());
services.AddInstance<ILoggerFactory>(new NullLoggerFactory()); services.AddInstance<ILoggerFactory>(new NullLoggerFactory());
services.SetupOptions<DbContextOptions>(options => services.ConfigureOptions<DbContextOptions>(options =>
options.UseSqlServer(ConnectionString)); options.UseSqlServer(ConnectionString));
var serviceProvider = services.BuildServiceProvider(); var serviceProvider = services.BuildServiceProvider();
var db = new ApplicationDbContext(serviceProvider, var db = new ApplicationDbContext(serviceProvider,
@ -64,8 +64,7 @@ namespace Microsoft.AspNet.Identity.SqlServer.Test
services.AddEntityFramework().AddSqlServer(); services.AddEntityFramework().AddSqlServer();
services.Add(OptionsServices.GetDefaultServices()); services.Add(OptionsServices.GetDefaultServices());
services.AddInstance<ILoggerFactory>(new NullLoggerFactory()); services.AddInstance<ILoggerFactory>(new NullLoggerFactory());
services.SetupOptions<DbContextOptions>(options => services.ConfigureOptions<DbContextOptions>(options => options.UseSqlServer(ConnectionString));
options.UseSqlServer(ConnectionString));
var serviceProvider = services.BuildServiceProvider(); var serviceProvider = services.BuildServiceProvider();
var db = new ApplicationDbContext(serviceProvider, var db = new ApplicationDbContext(serviceProvider,
serviceProvider.GetService<IOptionsAccessor<DbContextOptions>>()); serviceProvider.GetService<IOptionsAccessor<DbContextOptions>>());
@ -118,7 +117,7 @@ namespace Microsoft.AspNet.Identity.SqlServer.Test
services.AddInstance<ILoggerFactory>(new NullLoggerFactory()); services.AddInstance<ILoggerFactory>(new NullLoggerFactory());
services.AddEntityFramework().AddSqlServer(); services.AddEntityFramework().AddSqlServer();
services.AddIdentitySqlServer<ApplicationDbContext, TUser, TRole, TKey>(); services.AddIdentitySqlServer<ApplicationDbContext, TUser, TRole, TKey>();
services.SetupOptions<DbContextOptions>(options => services.ConfigureOptions<DbContextOptions>(options =>
options.UseSqlServer(ConnectionString)); options.UseSqlServer(ConnectionString));
}); });
@ -145,7 +144,8 @@ namespace Microsoft.AspNet.Identity.SqlServer.Test
{ {
services.AddInstance<ILoggerFactory>(new NullLoggerFactory()); services.AddInstance<ILoggerFactory>(new NullLoggerFactory());
services.AddEntityFramework().AddSqlServer(); services.AddEntityFramework().AddSqlServer();
services.AddIdentitySqlServer<ApplicationDbContext, TUser, TRole, TKey>().SetupOptions(options => services.AddIdentitySqlServer<ApplicationDbContext, TUser, TRole, TKey>();
services.ConfigureIdentity(options =>
{ {
options.Password.RequiredLength = 1; options.Password.RequiredLength = 1;
options.Password.RequireLowercase = false; options.Password.RequireLowercase = false;
@ -154,7 +154,7 @@ namespace Microsoft.AspNet.Identity.SqlServer.Test
options.Password.RequireDigit = false; options.Password.RequireDigit = false;
options.User.UserNameValidationRegex = null; options.User.UserNameValidationRegex = null;
}); });
services.SetupOptions<DbContextOptions>(options => services.ConfigureOptions<DbContextOptions>(options =>
options.UseSqlServer(ConnectionString)); options.UseSqlServer(ConnectionString));
}); });

View File

@ -49,7 +49,7 @@ namespace Microsoft.AspNet.Identity.SqlServer.Test
services.AddInstance<ILoggerFactory>(new NullLoggerFactory()); services.AddInstance<ILoggerFactory>(new NullLoggerFactory());
services.AddEntityFramework().AddSqlServer(); services.AddEntityFramework().AddSqlServer();
services.Add(OptionsServices.GetDefaultServices()); services.Add(OptionsServices.GetDefaultServices());
services.SetupOptions<DbContextOptions>(options => services.ConfigureOptions<DbContextOptions>(options =>
options.UseSqlServer(ConnectionString)); options.UseSqlServer(ConnectionString));
var serviceProvider = services.BuildServiceProvider(); var serviceProvider = services.BuildServiceProvider();
var db = new ApplicationDbContext(serviceProvider, var db = new ApplicationDbContext(serviceProvider,
@ -67,8 +67,8 @@ namespace Microsoft.AspNet.Identity.SqlServer.Test
{ {
services.AddInstance<ILoggerFactory>(new NullLoggerFactory()); services.AddInstance<ILoggerFactory>(new NullLoggerFactory());
services.AddEntityFramework().AddSqlServer(); services.AddEntityFramework().AddSqlServer();
services.AddIdentitySqlServer<ApplicationDbContext, ApplicationUser>(); services.AddDefaultIdentity<ApplicationDbContext, ApplicationUser, IdentityRole>();
services.SetupOptions<DbContextOptions>(options => services.ConfigureOptions<DbContextOptions>(options =>
options.UseSqlServer(ConnectionString)); options.UseSqlServer(ConnectionString));
}); });
@ -95,7 +95,7 @@ namespace Microsoft.AspNet.Identity.SqlServer.Test
{ {
services.AddInstance<ILoggerFactory>(new NullLoggerFactory()); services.AddInstance<ILoggerFactory>(new NullLoggerFactory());
services.AddEntityFramework().AddSqlServer(); services.AddEntityFramework().AddSqlServer();
services.AddIdentitySqlServer<ApplicationDbContext, ApplicationUser>().SetupOptions(options => services.AddIdentitySqlServer<ApplicationDbContext, ApplicationUser>(options =>
{ {
options.Password.RequiredLength = 1; options.Password.RequiredLength = 1;
options.Password.RequireLowercase = false; options.Password.RequireLowercase = false;
@ -103,7 +103,7 @@ namespace Microsoft.AspNet.Identity.SqlServer.Test
options.Password.RequireUppercase = false; options.Password.RequireUppercase = false;
options.Password.RequireDigit = false; options.Password.RequireDigit = false;
}); });
services.SetupOptions<DbContextOptions>(options => services.ConfigureOptions<DbContextOptions>(options =>
options.UseSqlServer(ConnectionString)); options.UseSqlServer(ConnectionString));
}); });

View File

@ -82,8 +82,7 @@ namespace Microsoft.AspNet.Identity.Test
// Assert // Assert
var manager = userManager.Object; var manager = userManager.Object;
Assert.NotNull(identity); Assert.NotNull(identity);
Assert.Equal(ClaimsIdentityOptions.DefaultAuthenticationType, identity.AuthenticationType); Assert.Equal(IdentityOptions.ApplicationCookieAuthenticationType, identity.AuthenticationType);
Assert.Equal(identityOptions.ApplicationCookie.AuthenticationType, identity.AuthenticationType);
var claims = identity.Claims.ToList(); var claims = identity.Claims.ToList();
Assert.NotNull(claims); Assert.NotNull(claims);
Assert.True( Assert.True(

View File

@ -84,14 +84,30 @@ namespace Microsoft.AspNet.Identity.Test
Assert.Equal(1000, options.Lockout.MaxFailedAccessAttempts); Assert.Equal(1000, options.Lockout.MaxFailedAccessAttempts);
} }
public class PasswordsNegativeLengthSetup : IOptionsSetup<IdentityOptions> [Fact]
public void IdentityOptionsActionOverridesConfig()
{ {
public int Order { get { return 0; } } var dic = new Dictionary<string, string>
public string Name { get; set; }
public void Setup(IdentityOptions options)
{ {
options.Password.RequiredLength = -1; {"identity:user:requireUniqueEmail", "true"},
} {"identity:lockout:MaxFailedAccessAttempts", "1000"}
};
var config = new Configuration { new MemoryConfigurationSource(dic) };
var services = new ServiceCollection { OptionsServices.GetDefaultServices() };
services.AddIdentity(config.GetSubKey("identity"),
o => { o.User.RequireUniqueEmail = false; o.Lockout.MaxFailedAccessAttempts++; });
var accessor = services.BuildServiceProvider().GetService<IOptionsAccessor<IdentityOptions>>();
Assert.NotNull(accessor);
var options = accessor.Options;
Assert.False(options.User.RequireUniqueEmail);
Assert.Equal(1001, options.Lockout.MaxFailedAccessAttempts);
}
public class PasswordsNegativeLengthSetup : OptionsAction<IdentityOptions>
{
public PasswordsNegativeLengthSetup()
: base(options => options.Password.RequiredLength = -1)
{ }
} }
[Fact] [Fact]
@ -101,15 +117,13 @@ namespace Microsoft.AspNet.Identity.Test
builder.UseServices(services => builder.UseServices(services =>
{ {
services.AddIdentity<IdentityUser>(); services.AddIdentity<IdentityUser>();
services.AddSetup<PasswordsNegativeLengthSetup>(); services.AddOptionsAction<PasswordsNegativeLengthSetup>();
}); });
var setup = builder.ApplicationServices.GetService<IOptionsSetup<IdentityOptions>>(); var setup = builder.ApplicationServices.GetService<IOptionsAction<IdentityOptions>>();
Assert.IsType(typeof(PasswordsNegativeLengthSetup), setup); Assert.IsType(typeof(PasswordsNegativeLengthSetup), setup);
var optionsGetter = builder.ApplicationServices.GetService<IOptionsAccessor<IdentityOptions>>(); var optionsGetter = builder.ApplicationServices.GetService<IOptionsAccessor<IdentityOptions>>();
Assert.NotNull(optionsGetter); Assert.NotNull(optionsGetter);
setup.Setup(optionsGetter.Options);
var myOptions = optionsGetter.Options; var myOptions = optionsGetter.Options;
Assert.True(myOptions.Password.RequireLowercase); Assert.True(myOptions.Password.RequireLowercase);
Assert.True(myOptions.Password.RequireDigit); Assert.True(myOptions.Password.RequireDigit);
@ -124,7 +138,7 @@ namespace Microsoft.AspNet.Identity.Test
var app = new ApplicationBuilder(new ServiceCollection().BuildServiceProvider()); var app = new ApplicationBuilder(new ServiceCollection().BuildServiceProvider());
app.UseServices(services => app.UseServices(services =>
{ {
services.AddIdentity<IdentityUser>().SetupOptions(options => options.User.RequireUniqueEmail = true); services.AddIdentity<IdentityUser>().ConfigureIdentity(options => options.User.RequireUniqueEmail = true);
}); });
var optionsGetter = app.ApplicationServices.GetService<IOptionsAccessor<IdentityOptions>>(); var optionsGetter = app.ApplicationServices.GetService<IOptionsAccessor<IdentityOptions>>();

View File

@ -24,7 +24,7 @@ namespace Microsoft.AspNet.Identity.Test
{ {
var httpContext = new Mock<HttpContext>(); var httpContext = new Mock<HttpContext>();
httpContext.Setup(c => c.RequestServices).Returns(new ServiceCollection().BuildServiceProvider()); httpContext.Setup(c => c.RequestServices).Returns(new ServiceCollection().BuildServiceProvider());
var id = new ClaimsIdentity(ClaimsIdentityOptions.DefaultAuthenticationType); var id = new ClaimsIdentity(IdentityOptions.ApplicationCookieAuthenticationType);
var ticket = new AuthenticationTicket(id, new AuthenticationProperties { IssuedUtc = DateTimeOffset.UtcNow }); var ticket = new AuthenticationTicket(id, new AuthenticationProperties { IssuedUtc = DateTimeOffset.UtcNow });
var context = new CookieValidateIdentityContext(httpContext.Object, ticket, new CookieAuthenticationOptions()); var context = new CookieValidateIdentityContext(httpContext.Object, ticket, new CookieAuthenticationOptions());
await Assert.ThrowsAsync<Exception>(() => SecurityStampValidator.ValidateIdentityAsync(context)); await Assert.ThrowsAsync<Exception>(() => SecurityStampValidator.ValidateIdentityAsync(context));
@ -53,7 +53,7 @@ namespace Microsoft.AspNet.Identity.Test
services.AddInstance(signInManager.Object); services.AddInstance(signInManager.Object);
services.AddInstance<ISecurityStampValidator>(new SecurityStampValidator<IdentityUser>()); services.AddInstance<ISecurityStampValidator>(new SecurityStampValidator<IdentityUser>());
httpContext.Setup(c => c.RequestServices).Returns(services.BuildServiceProvider()); httpContext.Setup(c => c.RequestServices).Returns(services.BuildServiceProvider());
var id = new ClaimsIdentity(ClaimsIdentityOptions.DefaultAuthenticationType); var id = new ClaimsIdentity(IdentityOptions.ApplicationCookieAuthenticationType);
id.AddClaim(new Claim(ClaimTypes.NameIdentifier, user.Id)); id.AddClaim(new Claim(ClaimTypes.NameIdentifier, user.Id));
var ticket = new AuthenticationTicket(id, new AuthenticationProperties { IssuedUtc = DateTimeOffset.UtcNow, IsPersistent = isPersistent }); var ticket = new AuthenticationTicket(id, new AuthenticationProperties { IssuedUtc = DateTimeOffset.UtcNow, IsPersistent = isPersistent });
@ -87,7 +87,7 @@ namespace Microsoft.AspNet.Identity.Test
services.AddInstance(signInManager.Object); services.AddInstance(signInManager.Object);
services.AddInstance<ISecurityStampValidator>(new SecurityStampValidator<IdentityUser>()); services.AddInstance<ISecurityStampValidator>(new SecurityStampValidator<IdentityUser>());
httpContext.Setup(c => c.RequestServices).Returns(services.BuildServiceProvider()); httpContext.Setup(c => c.RequestServices).Returns(services.BuildServiceProvider());
var id = new ClaimsIdentity(ClaimsIdentityOptions.DefaultAuthenticationType); var id = new ClaimsIdentity(IdentityOptions.ApplicationCookieAuthenticationType);
id.AddClaim(new Claim(ClaimTypes.NameIdentifier, user.Id)); id.AddClaim(new Claim(ClaimTypes.NameIdentifier, user.Id));
var ticket = new AuthenticationTicket(id, new AuthenticationProperties { IssuedUtc = DateTimeOffset.UtcNow }); var ticket = new AuthenticationTicket(id, new AuthenticationProperties { IssuedUtc = DateTimeOffset.UtcNow });
@ -121,7 +121,7 @@ namespace Microsoft.AspNet.Identity.Test
services.AddInstance(signInManager.Object); services.AddInstance(signInManager.Object);
services.AddInstance<ISecurityStampValidator>(new SecurityStampValidator<IdentityUser>()); services.AddInstance<ISecurityStampValidator>(new SecurityStampValidator<IdentityUser>());
httpContext.Setup(c => c.RequestServices).Returns(services.BuildServiceProvider()); httpContext.Setup(c => c.RequestServices).Returns(services.BuildServiceProvider());
var id = new ClaimsIdentity(ClaimsIdentityOptions.DefaultAuthenticationType); var id = new ClaimsIdentity(IdentityOptions.ApplicationCookieAuthenticationType);
id.AddClaim(new Claim(ClaimTypes.NameIdentifier, user.Id)); id.AddClaim(new Claim(ClaimTypes.NameIdentifier, user.Id));
var ticket = new AuthenticationTicket(id, new AuthenticationProperties()); var ticket = new AuthenticationTicket(id, new AuthenticationProperties());
@ -156,7 +156,7 @@ namespace Microsoft.AspNet.Identity.Test
services.AddInstance(signInManager.Object); services.AddInstance(signInManager.Object);
services.AddInstance<ISecurityStampValidator>(new SecurityStampValidator<IdentityUser>()); services.AddInstance<ISecurityStampValidator>(new SecurityStampValidator<IdentityUser>());
httpContext.Setup(c => c.RequestServices).Returns(services.BuildServiceProvider()); httpContext.Setup(c => c.RequestServices).Returns(services.BuildServiceProvider());
var id = new ClaimsIdentity(ClaimsIdentityOptions.DefaultAuthenticationType); var id = new ClaimsIdentity(IdentityOptions.ApplicationCookieAuthenticationType);
id.AddClaim(new Claim(ClaimTypes.NameIdentifier, user.Id)); id.AddClaim(new Claim(ClaimTypes.NameIdentifier, user.Id));
var ticket = new AuthenticationTicket(id, new AuthenticationProperties { IssuedUtc = DateTimeOffset.UtcNow }); var ticket = new AuthenticationTicket(id, new AuthenticationProperties { IssuedUtc = DateTimeOffset.UtcNow });

View File

@ -280,7 +280,7 @@ namespace Microsoft.AspNet.Identity.Test
contextAccessor.Setup(a => a.Value).Returns(context.Object); contextAccessor.Setup(a => a.Value).Returns(context.Object);
var roleManager = MockHelpers.MockRoleManager<TestRole>(); var roleManager = MockHelpers.MockRoleManager<TestRole>();
var identityOptions = new IdentityOptions(); var identityOptions = new IdentityOptions();
response.Setup(r => r.SignOut(identityOptions.ExternalCookie.AuthenticationType)).Verifiable(); response.Setup(r => r.SignOut(IdentityOptions.ExternalCookieAuthenticationType)).Verifiable();
var options = new Mock<IOptionsAccessor<IdentityOptions>>(); var options = new Mock<IOptionsAccessor<IdentityOptions>>();
options.Setup(a => a.Options).Returns(identityOptions); options.Setup(a => a.Options).Returns(identityOptions);
var claimsFactory = new Mock<ClaimsIdentityFactory<TestUser, TestRole>>(manager.Object, roleManager.Object, options.Object); var claimsFactory = new Mock<ClaimsIdentityFactory<TestUser, TestRole>>(manager.Object, roleManager.Object, options.Object);
@ -351,6 +351,7 @@ namespace Microsoft.AspNet.Identity.Test
It.Is<AuthenticationProperties>(v => v.IsPersistent == isPersistent), It.Is<AuthenticationProperties>(v => v.IsPersistent == isPersistent),
It.Is<ClaimsIdentity>(i => i.FindFirstValue(ClaimTypes.NameIdentifier) == user.Id It.Is<ClaimsIdentity>(i => i.FindFirstValue(ClaimTypes.NameIdentifier) == user.Id
&& i.FindFirstValue(ClaimTypes.AuthenticationMethod) == loginProvider))).Verifiable(); && i.FindFirstValue(ClaimTypes.AuthenticationMethod) == loginProvider))).Verifiable();
response.Setup(r => r.SignOut(IdentityOptions.ExternalCookieAuthenticationType)).Verifiable();
} }
else else
{ {
@ -363,11 +364,10 @@ namespace Microsoft.AspNet.Identity.Test
response.Setup(r => r.SignIn( response.Setup(r => r.SignIn(
It.Is<AuthenticationProperties>(v => v.IsPersistent == true), It.Is<AuthenticationProperties>(v => v.IsPersistent == true),
It.Is<ClaimsIdentity>(i => i.FindFirstValue(ClaimTypes.Name) == user.Id It.Is<ClaimsIdentity>(i => i.FindFirstValue(ClaimTypes.Name) == user.Id
&& i.AuthenticationType == ClaimsIdentityOptions.DefaultTwoFactorRememberMeAuthenticationType))).Verifiable(); && i.AuthenticationType == IdentityOptions.TwoFactorRememberMeCookieAuthenticationType))).Verifiable();
} }
response.Setup(r => r.SignOut(identityOptions.ExternalCookie.AuthenticationType)).Verifiable();
context.Setup(c => c.Response).Returns(response.Object).Verifiable(); context.Setup(c => c.Response).Returns(response.Object).Verifiable();
context.Setup(c => c.AuthenticateAsync(ClaimsIdentityOptions.DefaultTwoFactorUserIdAuthenticationType)).ReturnsAsync(authResult).Verifiable(); context.Setup(c => c.AuthenticateAsync(IdentityOptions.TwoFactorUserIdCookieAuthenticationType)).ReturnsAsync(authResult).Verifiable();
contextAccessor.Setup(a => a.Value).Returns(context.Object); contextAccessor.Setup(a => a.Value).Returns(context.Object);
var helper = new SignInManager<TestUser>(manager.Object, contextAccessor.Object, claimsFactory, options.Object); var helper = new SignInManager<TestUser>(manager.Object, contextAccessor.Object, claimsFactory, options.Object);
@ -402,7 +402,7 @@ namespace Microsoft.AspNet.Identity.Test
response.Setup(r => r.SignIn( response.Setup(r => r.SignIn(
It.Is<AuthenticationProperties>(v => v.IsPersistent == true), It.Is<AuthenticationProperties>(v => v.IsPersistent == true),
It.Is<ClaimsIdentity>(i => i.FindFirstValue(ClaimTypes.Name) == user.Id It.Is<ClaimsIdentity>(i => i.FindFirstValue(ClaimTypes.Name) == user.Id
&& i.AuthenticationType == ClaimsIdentityOptions.DefaultTwoFactorRememberMeAuthenticationType))).Verifiable(); && i.AuthenticationType == IdentityOptions.TwoFactorRememberMeCookieAuthenticationType))).Verifiable();
contextAccessor.Setup(a => a.Value).Returns(context.Object).Verifiable(); contextAccessor.Setup(a => a.Value).Returns(context.Object).Verifiable();
options.Setup(a => a.Options).Returns(identityOptions).Verifiable(); options.Setup(a => a.Options).Returns(identityOptions).Verifiable();
@ -440,20 +440,19 @@ namespace Microsoft.AspNet.Identity.Test
var context = new Mock<HttpContext>(); var context = new Mock<HttpContext>();
var response = new Mock<HttpResponse>(); var response = new Mock<HttpResponse>();
context.Setup(c => c.Response).Returns(response.Object).Verifiable(); context.Setup(c => c.Response).Returns(response.Object).Verifiable();
response.Setup(r => r.SignIn(It.Is<AuthenticationProperties>(v => v.IsPersistent == isPersistent), It.Is<ClaimsIdentity>(i => i.AuthenticationType == ClaimsIdentityOptions.DefaultAuthenticationType))).Verifiable(); response.Setup(r => r.SignIn(It.Is<AuthenticationProperties>(v => v.IsPersistent == isPersistent), It.Is<ClaimsIdentity>(i => i.AuthenticationType == IdentityOptions.ApplicationCookieAuthenticationType))).Verifiable();
var id = new ClaimsIdentity(ClaimsIdentityOptions.DefaultTwoFactorRememberMeAuthenticationType); var id = new ClaimsIdentity(IdentityOptions.TwoFactorRememberMeCookieAuthenticationType);
id.AddClaim(new Claim(ClaimTypes.Name, user.Id)); id.AddClaim(new Claim(ClaimTypes.Name, user.Id));
var authResult = new AuthenticationResult(id, new AuthenticationProperties(), new AuthenticationDescription()); var authResult = new AuthenticationResult(id, new AuthenticationProperties(), new AuthenticationDescription());
context.Setup(c => c.AuthenticateAsync(ClaimsIdentityOptions.DefaultTwoFactorRememberMeAuthenticationType)).ReturnsAsync(authResult).Verifiable(); context.Setup(c => c.AuthenticateAsync(IdentityOptions.TwoFactorRememberMeCookieAuthenticationType)).ReturnsAsync(authResult).Verifiable();
var contextAccessor = new Mock<IContextAccessor<HttpContext>>(); var contextAccessor = new Mock<IContextAccessor<HttpContext>>();
contextAccessor.Setup(a => a.Value).Returns(context.Object); contextAccessor.Setup(a => a.Value).Returns(context.Object);
var roleManager = MockHelpers.MockRoleManager<TestRole>(); var roleManager = MockHelpers.MockRoleManager<TestRole>();
var identityOptions = new IdentityOptions(); var identityOptions = new IdentityOptions();
response.Setup(r => r.SignOut(identityOptions.ExternalCookie.AuthenticationType)).Verifiable();
var options = new Mock<IOptionsAccessor<IdentityOptions>>(); var options = new Mock<IOptionsAccessor<IdentityOptions>>();
options.Setup(a => a.Options).Returns(identityOptions); options.Setup(a => a.Options).Returns(identityOptions);
var claimsFactory = new Mock<ClaimsIdentityFactory<TestUser, TestRole>>(manager.Object, roleManager.Object, options.Object); var claimsFactory = new Mock<ClaimsIdentityFactory<TestUser, TestRole>>(manager.Object, roleManager.Object, options.Object);
claimsFactory.Setup(m => m.CreateAsync(user, CancellationToken.None)).ReturnsAsync(new ClaimsIdentity(identityOptions.ApplicationCookie.AuthenticationType)).Verifiable(); claimsFactory.Setup(m => m.CreateAsync(user, CancellationToken.None)).ReturnsAsync(new ClaimsIdentity(IdentityOptions.ApplicationCookieAuthenticationType)).Verifiable();
var helper = new SignInManager<TestUser>(manager.Object, contextAccessor.Object, claimsFactory.Object, options.Object); var helper = new SignInManager<TestUser>(manager.Object, contextAccessor.Object, claimsFactory.Object, options.Object);
// Act // Act
@ -485,7 +484,7 @@ namespace Microsoft.AspNet.Identity.Test
var identityOptions = new IdentityOptions(); var identityOptions = new IdentityOptions();
var options = new Mock<IOptionsAccessor<IdentityOptions>>(); var options = new Mock<IOptionsAccessor<IdentityOptions>>();
options.Setup(a => a.Options).Returns(identityOptions); options.Setup(a => a.Options).Returns(identityOptions);
identityOptions.ApplicationCookie.AuthenticationType = authenticationType; IdentityOptions.ApplicationCookieAuthenticationType = authenticationType;
var claimsFactory = new Mock<ClaimsIdentityFactory<TestUser, TestRole>>(manager.Object, roleManager.Object, options.Object); var claimsFactory = new Mock<ClaimsIdentityFactory<TestUser, TestRole>>(manager.Object, roleManager.Object, options.Object);
var helper = new SignInManager<TestUser>(manager.Object, contextAccessor.Object, claimsFactory.Object, options.Object); var helper = new SignInManager<TestUser>(manager.Object, contextAccessor.Object, claimsFactory.Object, options.Object);

View File

@ -8,6 +8,7 @@ using Microsoft.Framework.DependencyInjection.Fallback;
using Microsoft.Framework.OptionsModel; using Microsoft.Framework.OptionsModel;
using Moq; using Moq;
using System; using System;
using System.Collections.Generic;
namespace Microsoft.AspNet.Identity.Test namespace Microsoft.AspNet.Identity.Test
{ {
@ -18,7 +19,7 @@ namespace Microsoft.AspNet.Identity.Test
var services = new ServiceCollection(); var services = new ServiceCollection();
services.Add(OptionsServices.GetDefaultServices()); services.Add(OptionsServices.GetDefaultServices());
services.AddIdentity<TUser>().AddUserStore(store); services.AddIdentity<TUser>().AddUserStore(store);
services.SetupOptions<IdentityOptions>(options => services.ConfigureIdentity(options =>
{ {
options.Password.RequireDigit = false; options.Password.RequireDigit = false;
options.Password.RequireLowercase = false; options.Password.RequireLowercase = false;
@ -40,7 +41,7 @@ namespace Microsoft.AspNet.Identity.Test
new UserValidator<TUser>(), new UserValidator<TUser>(),
new PasswordValidator<TUser>(), new PasswordValidator<TUser>(),
new UpperInvariantUserNameNormalizer(), new UpperInvariantUserNameNormalizer(),
null); new List<IUserTokenProvider<TUser>>());
} }
public static Mock<RoleManager<TRole>> MockRoleManager<TRole>() where TRole : class public static Mock<RoleManager<TRole>> MockRoleManager<TRole>() where TRole : class