Identity => Auth 2.0
This commit is contained in:
parent
d4669453ba
commit
14b4bea964
|
|
@ -10,6 +10,7 @@ using Microsoft.Extensions.Logging;
|
|||
using IdentitySample.Models;
|
||||
using IdentitySample.Models.ManageViewModels;
|
||||
using IdentitySample.Services;
|
||||
using Microsoft.AspNetCore.Authentication;
|
||||
|
||||
namespace IdentitySamples.Controllers
|
||||
{
|
||||
|
|
@ -19,6 +20,7 @@ namespace IdentitySamples.Controllers
|
|||
{
|
||||
private readonly UserManager<ApplicationUser> _userManager;
|
||||
private readonly SignInManager<ApplicationUser> _signInManager;
|
||||
private readonly IAuthenticationSchemeProvider _schemes;
|
||||
private readonly IEmailSender _emailSender;
|
||||
private readonly ISmsSender _smsSender;
|
||||
private readonly ILogger _logger;
|
||||
|
|
@ -26,12 +28,14 @@ namespace IdentitySamples.Controllers
|
|||
public ManageController(
|
||||
UserManager<ApplicationUser> userManager,
|
||||
SignInManager<ApplicationUser> signInManager,
|
||||
IAuthenticationSchemeProvider schemes,
|
||||
IEmailSender emailSender,
|
||||
ISmsSender smsSender,
|
||||
ILoggerFactory loggerFactory)
|
||||
{
|
||||
_userManager = userManager;
|
||||
_signInManager = signInManager;
|
||||
_schemes = schemes;
|
||||
_emailSender = emailSender;
|
||||
_smsSender = smsSender;
|
||||
_logger = loggerFactory.CreateLogger<ManageController>();
|
||||
|
|
@ -308,7 +312,8 @@ namespace IdentitySamples.Controllers
|
|||
return View("Error");
|
||||
}
|
||||
var userLogins = await _userManager.GetLoginsAsync(user);
|
||||
var otherLogins = _signInManager.GetExternalAuthenticationSchemes().Where(auth => userLogins.All(ul => auth.AuthenticationScheme != ul.LoginProvider)).ToList();
|
||||
var schemes = await _schemes.GetAllSchemesAsync();
|
||||
var otherLogins = schemes.Where(auth => userLogins.All(ul => auth.Name != ul.LoginProvider)).ToList();
|
||||
ViewData["ShowRemoveButton"] = user.PasswordHash != null || userLogins.Count > 1;
|
||||
return View(new ManageLoginsViewModel
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,8 +1,5 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Http.Authentication;
|
||||
using Microsoft.AspNetCore.Authentication;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
|
||||
namespace IdentitySample.Models.ManageViewModels
|
||||
|
|
@ -11,6 +8,6 @@ namespace IdentitySample.Models.ManageViewModels
|
|||
{
|
||||
public IList<UserLoginInfo> CurrentLogins { get; set; }
|
||||
|
||||
public IList<AuthenticationDescription> OtherLogins { get; set; }
|
||||
public IList<AuthenticationScheme> OtherLogins { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -68,7 +68,6 @@ namespace IdentitySample
|
|||
|
||||
app.UseStaticFiles();
|
||||
|
||||
app.UseIdentity();
|
||||
// To configure external authentication please see http://go.microsoft.com/fwlink/?LinkID=532715
|
||||
|
||||
app.UseMvc(routes =>
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
@using System.Collections.Generic
|
||||
@using Microsoft.AspNetCore.Http
|
||||
@using Microsoft.AspNetCore.Http.Authentication
|
||||
@using Microsoft.AspNetCore.Authentication
|
||||
@model LoginViewModel
|
||||
@inject SignInManager<ApplicationUser> SignInManager
|
||||
@inject IAuthenticationSchemeProvider SchemeProvider
|
||||
|
||||
@{
|
||||
ViewData["Title"] = "Log in";
|
||||
|
|
@ -59,7 +60,8 @@
|
|||
<h4>Use another service to log in.</h4>
|
||||
<hr />
|
||||
@{
|
||||
var loginProviders = SignInManager.GetExternalAuthenticationSchemes().ToList();
|
||||
var schemes = await SchemeProvider.GetAllSchemesAsync();
|
||||
var loginProviders = schemes.ToList();
|
||||
if (loginProviders.Count == 0)
|
||||
{
|
||||
<div>
|
||||
|
|
@ -76,7 +78,7 @@
|
|||
<p>
|
||||
@foreach (var provider in loginProviders)
|
||||
{
|
||||
<button type="submit" class="btn btn-default" name="provider" value="@provider.AuthenticationScheme" title="Log in using your @provider.DisplayName account">@provider.AuthenticationScheme</button>
|
||||
<button type="submit" class="btn btn-default" name="provider" value="@provider.AuthenticationScheme" title="Log in using your @provider.Name account">@provider.Name</button>
|
||||
}
|
||||
</p>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@
|
|||
<p>
|
||||
@foreach (var provider in Model.OtherLogins)
|
||||
{
|
||||
<button type="submit" class="btn btn-default" name="provider" value="@provider.AuthenticationScheme" title="Log in using your @provider.DisplayName account">@provider.AuthenticationScheme</button>
|
||||
<button type="submit" class="btn btn-default" name="provider" value="@provider.Name" title="Log in using your @provider.Name account">@provider.Name</button>
|
||||
}
|
||||
</p>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ using System.Text;
|
|||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
|
@ -58,6 +59,7 @@ namespace Microsoft.AspNetCore.Identity.Test
|
|||
/// <param name="context"></param>
|
||||
protected virtual void SetupIdentityServices(IServiceCollection services, object context = null)
|
||||
{
|
||||
services.AddSingleton<IConfiguration>(new ConfigurationBuilder().Build());
|
||||
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
|
||||
services.AddIdentity<TUser, TRole>(options =>
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,12 +1,8 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace Microsoft.AspNetCore.Builder
|
||||
{
|
||||
/// <summary>
|
||||
|
|
@ -19,25 +15,7 @@ namespace Microsoft.AspNetCore.Builder
|
|||
/// </summary>
|
||||
/// <param name="app">The <see cref="IApplicationBuilder"/> instance this method extends.</param>
|
||||
/// <returns>The <see cref="IApplicationBuilder"/> instance this method extends.</returns>
|
||||
public static IApplicationBuilder UseIdentity(this IApplicationBuilder app)
|
||||
{
|
||||
if (app == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(app));
|
||||
}
|
||||
|
||||
var marker = app.ApplicationServices.GetService<IdentityMarkerService>();
|
||||
if (marker == null)
|
||||
{
|
||||
throw new InvalidOperationException(Resources.MustCallAddIdentity);
|
||||
}
|
||||
|
||||
var options = app.ApplicationServices.GetRequiredService<IOptions<IdentityOptions>>().Value;
|
||||
app.UseCookieAuthentication(options.Cookies.ExternalCookie);
|
||||
app.UseCookieAuthentication(options.Cookies.TwoFactorRememberMeCookie);
|
||||
app.UseCookieAuthentication(options.Cookies.TwoFactorUserIdCookie);
|
||||
app.UseCookieAuthentication(options.Cookies.ApplicationCookie);
|
||||
return app;
|
||||
}
|
||||
[Obsolete("See https://go.microsoft.com/fwlink/?linkid=845470", error: true)]
|
||||
public static IApplicationBuilder UseIdentity(this IApplicationBuilder app) => app;
|
||||
}
|
||||
}
|
||||
|
|
@ -3,8 +3,6 @@
|
|||
|
||||
using System;
|
||||
using Microsoft.AspNetCore.Authentication.Cookies;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
|
||||
namespace Microsoft.AspNetCore.Identity
|
||||
{
|
||||
|
|
@ -14,95 +12,72 @@ namespace Microsoft.AspNetCore.Identity
|
|||
public class IdentityCookieOptions
|
||||
{
|
||||
private static readonly string CookiePrefix = "Identity";
|
||||
private static readonly string DefaultApplicationScheme = CookiePrefix + ".Application";
|
||||
private static readonly string DefaultExternalScheme = CookiePrefix + ".External";
|
||||
private static readonly string DefaultTwoFactorRememberMeScheme = CookiePrefix + ".TwoFactorRememberMe";
|
||||
private static readonly string DefaultTwoFactorUserIdScheme = CookiePrefix + ".TwoFactorUserId";
|
||||
/// <summary>
|
||||
/// The scheme used to identify application authentication cookies.
|
||||
/// </summary>
|
||||
public static readonly string ApplicationScheme = CookiePrefix + ".Application";
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a new instance of <see cref="IdentityCookieOptions"/>.
|
||||
/// The scheme used to identify external authentication cookies.
|
||||
/// </summary>
|
||||
public IdentityCookieOptions()
|
||||
{
|
||||
// Configure all of the cookie middlewares
|
||||
ApplicationCookie = new CookieAuthenticationOptions
|
||||
{
|
||||
AuthenticationScheme = DefaultApplicationScheme,
|
||||
AutomaticAuthenticate = true,
|
||||
AutomaticChallenge = true,
|
||||
LoginPath = new PathString("/Account/Login"),
|
||||
Events = new CookieAuthenticationEvents
|
||||
{
|
||||
OnValidatePrincipal = SecurityStampValidator.ValidatePrincipalAsync
|
||||
}
|
||||
};
|
||||
public static readonly string ExternalScheme = CookiePrefix + ".External";
|
||||
|
||||
ExternalCookie = new CookieAuthenticationOptions
|
||||
{
|
||||
AutomaticAuthenticate = false,
|
||||
AuthenticationScheme = DefaultExternalScheme,
|
||||
CookieName = DefaultExternalScheme,
|
||||
ExpireTimeSpan = TimeSpan.FromMinutes(5)
|
||||
};
|
||||
/// <summary>
|
||||
/// The scheme used to identify Two Factor authentication cookies for saving the Remember Me state.
|
||||
/// </summary>
|
||||
public static readonly string TwoFactorRememberMeScheme = CookiePrefix + ".TwoFactorRememberMe";
|
||||
|
||||
TwoFactorRememberMeCookie = new CookieAuthenticationOptions
|
||||
{
|
||||
AutomaticAuthenticate = false,
|
||||
AuthenticationScheme = DefaultTwoFactorRememberMeScheme,
|
||||
CookieName = DefaultTwoFactorRememberMeScheme
|
||||
};
|
||||
|
||||
TwoFactorUserIdCookie = new CookieAuthenticationOptions
|
||||
{
|
||||
AutomaticAuthenticate = false,
|
||||
AuthenticationScheme = DefaultTwoFactorUserIdScheme,
|
||||
CookieName = DefaultTwoFactorUserIdScheme,
|
||||
ExpireTimeSpan = TimeSpan.FromMinutes(5)
|
||||
};
|
||||
}
|
||||
/// <summary>
|
||||
/// The scheme used to identify Two Factor authentication cookies for round tripping user identities.
|
||||
/// </summary>
|
||||
public static readonly string TwoFactorUserIdScheme = CookiePrefix + ".TwoFactorUserId";
|
||||
|
||||
/// <summary>
|
||||
/// The options for the application cookie.
|
||||
/// </summary>
|
||||
[Obsolete("See https://go.microsoft.com/fwlink/?linkid=845470", error: true)]
|
||||
public CookieAuthenticationOptions ApplicationCookie { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The options for the external cookie.
|
||||
/// </summary>
|
||||
[Obsolete("See https://go.microsoft.com/fwlink/?linkid=845470", error: true)]
|
||||
public CookieAuthenticationOptions ExternalCookie { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The options for the two factor remember me cookie.
|
||||
/// </summary>
|
||||
[Obsolete("See https://go.microsoft.com/fwlink/?linkid=845470", error: true)]
|
||||
public CookieAuthenticationOptions TwoFactorRememberMeCookie { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The options for the two factor user id cookie.
|
||||
/// </summary>
|
||||
[Obsolete("See https://go.microsoft.com/fwlink/?linkid=845470", error: true)]
|
||||
public CookieAuthenticationOptions TwoFactorUserIdCookie { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the scheme used to identify application authentication cookies.
|
||||
/// </summary>
|
||||
/// <value>The scheme used to identify application authentication cookies.</value>
|
||||
public string ApplicationCookieAuthenticationScheme => ApplicationCookie?.AuthenticationScheme;
|
||||
public string ApplicationCookieAuthenticationScheme { get; set; } = ApplicationScheme;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the scheme used to identify external authentication cookies.
|
||||
/// </summary>
|
||||
/// <value>The scheme used to identify external authentication cookies.</value>
|
||||
public string ExternalCookieAuthenticationScheme => ExternalCookie?.AuthenticationScheme;
|
||||
public string ExternalCookieAuthenticationScheme { get; set; } = ExternalScheme;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the scheme used to identify Two Factor authentication cookies for round tripping user identities.
|
||||
/// </summary>
|
||||
/// <value>The scheme used to identify user identity 2fa authentication cookies.</value>
|
||||
public string TwoFactorUserIdCookieAuthenticationScheme => TwoFactorUserIdCookie?.AuthenticationScheme;
|
||||
public string TwoFactorUserIdCookieAuthenticationScheme { get; set; } = TwoFactorUserIdScheme;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the scheme used to identify Two Factor authentication cookies for saving the Remember Me state.
|
||||
/// </summary>
|
||||
/// <value>The scheme used to identify remember me application authentication cookies.</value>
|
||||
public string TwoFactorRememberMeCookieAuthenticationScheme => TwoFactorRememberMeCookie?.AuthenticationScheme;
|
||||
public string TwoFactorRememberMeCookieAuthenticationScheme { get; set; } = TwoFactorRememberMeScheme;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
namespace Microsoft.AspNetCore.Identity
|
||||
{
|
||||
/// <summary>
|
||||
/// Used to verify AddIdentity was called on a ServiceCollection
|
||||
/// </summary>
|
||||
public class IdentityMarkerService { }
|
||||
}
|
||||
|
|
@ -2,10 +2,13 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using Microsoft.AspNetCore.Authentication.Cookies;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection.Extensions;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace Microsoft.Extensions.DependencyInjection
|
||||
{
|
||||
|
|
@ -14,6 +17,13 @@ namespace Microsoft.Extensions.DependencyInjection
|
|||
/// </summary>
|
||||
public static class IdentityServiceCollectionExtensions
|
||||
{
|
||||
internal class IdentityConfigureOptions : ConfigureOptions<IdentityOptions>
|
||||
{
|
||||
public IdentityConfigureOptions(IConfiguration config) :
|
||||
base(options => config.GetSection("Identity").Bind(options))
|
||||
{ }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds the default identity system configuration for the specified User and Role types.
|
||||
/// </summary>
|
||||
|
|
@ -29,6 +39,24 @@ namespace Microsoft.Extensions.DependencyInjection
|
|||
return services.AddIdentity<TUser, TRole>(setupAction: null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Configures the application cookie.
|
||||
/// </summary>
|
||||
/// <param name="services">The services available in the application.</param>
|
||||
/// <param name="configure">An action to configure the <see cref="CookieAuthenticationOptions"/>.</param>
|
||||
/// <returns>The services.</returns>
|
||||
public static IServiceCollection ConfigureApplicationCookie(this IServiceCollection services, Action<CookieAuthenticationOptions> configure)
|
||||
=> services.Configure(IdentityCookieOptions.ApplicationScheme, configure);
|
||||
|
||||
/// <summary>
|
||||
/// Configure the external cookie.
|
||||
/// </summary>
|
||||
/// <param name="services">The services available in the application.</param>
|
||||
/// <param name="configure">An action to configure the <see cref="CookieAuthenticationOptions"/>.</param>
|
||||
/// <returns>The services.</returns>
|
||||
public static IServiceCollection ConfigureExternalCookie(this IServiceCollection services, Action<CookieAuthenticationOptions> configure)
|
||||
=> services.Configure(IdentityCookieOptions.ExternalScheme, configure);
|
||||
|
||||
/// <summary>
|
||||
/// Adds and configures the identity system for the specified User and Role types.
|
||||
/// </summary>
|
||||
|
|
@ -44,16 +72,40 @@ namespace Microsoft.Extensions.DependencyInjection
|
|||
where TRole : class
|
||||
{
|
||||
// Services used by identity
|
||||
services.AddAuthentication(options =>
|
||||
services.AddAuthenticationCore(options =>
|
||||
{
|
||||
// This is the Default value for ExternalCookieAuthenticationScheme
|
||||
options.SignInScheme = new IdentityCookieOptions().ExternalCookieAuthenticationScheme;
|
||||
options.DefaultAuthenticateScheme = IdentityCookieOptions.ApplicationScheme;
|
||||
options.DefaultChallengeScheme = IdentityCookieOptions.ApplicationScheme;
|
||||
options.DefaultSignInScheme = IdentityCookieOptions.ExternalScheme;
|
||||
});
|
||||
|
||||
services.AddCookieAuthentication(IdentityCookieOptions.ApplicationScheme, o =>
|
||||
{
|
||||
o.LoginPath = new PathString("/Account/Login");
|
||||
o.Events = new CookieAuthenticationEvents
|
||||
{
|
||||
OnValidatePrincipal = SecurityStampValidator.ValidatePrincipalAsync
|
||||
};
|
||||
});
|
||||
|
||||
services.AddCookieAuthentication(IdentityCookieOptions.ExternalScheme, o =>
|
||||
{
|
||||
o.CookieName = IdentityCookieOptions.ExternalScheme;
|
||||
o.ExpireTimeSpan = TimeSpan.FromMinutes(5);
|
||||
});
|
||||
|
||||
services.AddCookieAuthentication(IdentityCookieOptions.TwoFactorRememberMeScheme,
|
||||
o => o.CookieName = IdentityCookieOptions.TwoFactorRememberMeScheme);
|
||||
|
||||
services.AddCookieAuthentication(IdentityCookieOptions.TwoFactorUserIdScheme, o =>
|
||||
{
|
||||
o.CookieName = IdentityCookieOptions.TwoFactorUserIdScheme;
|
||||
o.ExpireTimeSpan = TimeSpan.FromMinutes(5);
|
||||
});
|
||||
|
||||
// Hosting doesn't add IHttpContextAccessor by default
|
||||
services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>();
|
||||
// Identity services
|
||||
services.TryAddSingleton<IdentityMarkerService>();
|
||||
services.TryAddScoped<IUserValidator<TUser>, UserValidator<TUser>>();
|
||||
services.TryAddScoped<IPasswordValidator<TUser>, PasswordValidator<TUser>>();
|
||||
services.TryAddScoped<IPasswordHasher<TUser>, PasswordHasher<TUser>>();
|
||||
|
|
@ -67,6 +119,7 @@ namespace Microsoft.Extensions.DependencyInjection
|
|||
services.TryAddScoped<SignInManager<TUser>, SignInManager<TUser>>();
|
||||
services.TryAddScoped<RoleManager<TRole>, RoleManager<TRole>>();
|
||||
|
||||
services.AddSingleton<IConfigureOptions<IdentityOptions>, IdentityConfigureOptions>();
|
||||
if (setupAction != null)
|
||||
{
|
||||
services.Configure(setupAction);
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
<PackageReference Include="Microsoft.AspNetCore.Authentication.Cookies" Version="$(AspNetCoreVersion)" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Cryptography.KeyDerivation" Version="$(AspNetCoreVersion)" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Hosting.Abstractions" Version="$(AspNetCoreVersion)" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="$(AspNetCoreVersion)" />
|
||||
<PackageReference Include="Microsoft.Extensions.TaskCache.Sources" Version="$(AspNetCoreVersion)" PrivateAssets="All" />
|
||||
<PackageReference Include="System.ComponentModel.Annotations" Version="$(CoreFxVersion)" />
|
||||
</ItemGroup>
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Authentication;
|
||||
using Microsoft.AspNetCore.Authentication.Cookies;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
|
@ -18,13 +19,15 @@ namespace Microsoft.AspNetCore.Identity
|
|||
{
|
||||
private readonly SignInManager<TUser> _signInManager;
|
||||
private readonly IdentityOptions _options;
|
||||
private ISystemClock _clock;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of <see cref="SecurityStampValidator{TUser}"/>.
|
||||
/// </summary>
|
||||
/// <param name="options">Used to access the <see cref="IdentityOptions"/>.</param>
|
||||
/// <param name="signInManager">The <see cref="SignInManager{TUser}"/>.</param>
|
||||
public SecurityStampValidator(IOptions<IdentityOptions> options, SignInManager<TUser> signInManager)
|
||||
/// <param name="clock">The system clock.</param>
|
||||
public SecurityStampValidator(IOptions<IdentityOptions> options, SignInManager<TUser> signInManager, ISystemClock clock)
|
||||
{
|
||||
if (options == null)
|
||||
{
|
||||
|
|
@ -36,6 +39,7 @@ namespace Microsoft.AspNetCore.Identity
|
|||
}
|
||||
_signInManager = signInManager;
|
||||
_options = options.Value;
|
||||
_clock = clock;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -48,9 +52,9 @@ namespace Microsoft.AspNetCore.Identity
|
|||
public virtual async Task ValidateAsync(CookieValidatePrincipalContext context)
|
||||
{
|
||||
var currentUtc = DateTimeOffset.UtcNow;
|
||||
if (context.Options != null && context.Options.SystemClock != null)
|
||||
if (context.Options != null && _clock != null)
|
||||
{
|
||||
currentUtc = context.Options.SystemClock.UtcNow;
|
||||
currentUtc = _clock.UtcNow;
|
||||
}
|
||||
var issuedUtc = context.Properties.IssuedUtc;
|
||||
|
||||
|
|
|
|||
|
|
@ -2,15 +2,12 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Security.Claims;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Authentication;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Http.Authentication;
|
||||
using Microsoft.AspNetCore.Http.Features.Authentication;
|
||||
using Microsoft.Extensions.Internal;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
|
@ -159,10 +156,9 @@ namespace Microsoft.AspNetCore.Identity
|
|||
/// <returns>The task object representing the asynchronous operation.</returns>
|
||||
public virtual async Task RefreshSignInAsync(TUser user)
|
||||
{
|
||||
var auth = new AuthenticateContext(Options.Cookies.ApplicationCookieAuthenticationScheme);
|
||||
await Context.Authentication.AuthenticateAsync(auth);
|
||||
var authenticationMethod = auth.Principal?.FindFirstValue(ClaimTypes.AuthenticationMethod);
|
||||
await SignInAsync(user, new AuthenticationProperties(auth.Properties), authenticationMethod);
|
||||
var auth = await Context.AuthenticateAsync(Options.Cookies.ApplicationCookieAuthenticationScheme);
|
||||
var authenticationMethod = auth?.Principal?.FindFirstValue(ClaimTypes.AuthenticationMethod);
|
||||
await SignInAsync(user, auth?.Properties, authenticationMethod);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -192,7 +188,7 @@ namespace Microsoft.AspNetCore.Identity
|
|||
{
|
||||
userPrincipal.Identities.First().AddClaim(new Claim(ClaimTypes.AuthenticationMethod, authenticationMethod));
|
||||
}
|
||||
await Context.Authentication.SignInAsync(Options.Cookies.ApplicationCookieAuthenticationScheme,
|
||||
await Context.SignInAsync(Options.Cookies.ApplicationCookieAuthenticationScheme,
|
||||
userPrincipal,
|
||||
authenticationProperties ?? new AuthenticationProperties());
|
||||
}
|
||||
|
|
@ -202,9 +198,9 @@ namespace Microsoft.AspNetCore.Identity
|
|||
/// </summary>
|
||||
public virtual async Task SignOutAsync()
|
||||
{
|
||||
await Context.Authentication.SignOutAsync(Options.Cookies.ApplicationCookieAuthenticationScheme);
|
||||
await Context.Authentication.SignOutAsync(Options.Cookies.ExternalCookieAuthenticationScheme);
|
||||
await Context.Authentication.SignOutAsync(Options.Cookies.TwoFactorUserIdCookieAuthenticationScheme);
|
||||
await Context.SignOutAsync(Options.Cookies.ApplicationCookieAuthenticationScheme);
|
||||
await Context.SignOutAsync(Options.Cookies.ExternalCookieAuthenticationScheme);
|
||||
await Context.SignOutAsync(Options.Cookies.TwoFactorUserIdCookieAuthenticationScheme);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -333,8 +329,8 @@ namespace Microsoft.AspNetCore.Identity
|
|||
public virtual async Task<bool> IsTwoFactorClientRememberedAsync(TUser user)
|
||||
{
|
||||
var userId = await UserManager.GetUserIdAsync(user);
|
||||
var result = await Context.Authentication.AuthenticateAsync(Options.Cookies.TwoFactorRememberMeCookieAuthenticationScheme);
|
||||
return (result != null && result.FindFirstValue(ClaimTypes.Name) == userId);
|
||||
var result = await Context.AuthenticateAsync(Options.Cookies.TwoFactorRememberMeCookieAuthenticationScheme);
|
||||
return (result?.Principal != null && result.Principal.FindFirstValue(ClaimTypes.Name) == userId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -348,7 +344,7 @@ namespace Microsoft.AspNetCore.Identity
|
|||
var userId = await UserManager.GetUserIdAsync(user);
|
||||
var rememberBrowserIdentity = new ClaimsIdentity(Options.Cookies.TwoFactorRememberMeCookieAuthenticationScheme);
|
||||
rememberBrowserIdentity.AddClaim(new Claim(ClaimTypes.Name, userId));
|
||||
await Context.Authentication.SignInAsync(Options.Cookies.TwoFactorRememberMeCookieAuthenticationScheme,
|
||||
await Context.SignInAsync(Options.Cookies.TwoFactorRememberMeCookieAuthenticationScheme,
|
||||
new ClaimsPrincipal(rememberBrowserIdentity),
|
||||
new AuthenticationProperties { IsPersistent = true });
|
||||
}
|
||||
|
|
@ -359,7 +355,7 @@ namespace Microsoft.AspNetCore.Identity
|
|||
/// <returns>The task object representing the asynchronous operation.</returns>
|
||||
public virtual Task ForgetTwoFactorClientAsync()
|
||||
{
|
||||
return Context.Authentication.SignOutAsync(Options.Cookies.TwoFactorRememberMeCookieAuthenticationScheme);
|
||||
return Context.SignOutAsync(Options.Cookies.TwoFactorRememberMeCookieAuthenticationScheme);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -399,10 +395,10 @@ namespace Microsoft.AspNetCore.Identity
|
|||
// Cleanup external cookie
|
||||
if (twoFactorInfo.LoginProvider != null)
|
||||
{
|
||||
await Context.Authentication.SignOutAsync(Options.Cookies.ExternalCookieAuthenticationScheme);
|
||||
await Context.SignOutAsync(Options.Cookies.ExternalCookieAuthenticationScheme);
|
||||
}
|
||||
// Cleanup two factor user id cookie
|
||||
await Context.Authentication.SignOutAsync(Options.Cookies.TwoFactorUserIdCookieAuthenticationScheme);
|
||||
await Context.SignOutAsync(Options.Cookies.TwoFactorUserIdCookieAuthenticationScheme);
|
||||
if (rememberClient)
|
||||
{
|
||||
await RememberTwoFactorClientAsync(user);
|
||||
|
|
@ -539,15 +535,6 @@ namespace Microsoft.AspNetCore.Identity
|
|||
return await SignInOrTwoFactorAsync(user, isPersistent, loginProvider, bypassTwoFactor);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a collection of <see cref="AuthenticationDescription"/>s for the known external login providers.
|
||||
/// </summary>
|
||||
/// <returns>A collection of <see cref="AuthenticationDescription"/>s for the known external login providers.</returns>
|
||||
public virtual IEnumerable<AuthenticationDescription> GetExternalAuthenticationSchemes()
|
||||
{
|
||||
return Context.Authentication.GetAuthenticationSchemes().Where(d => !string.IsNullOrEmpty(d.DisplayName));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the external login information for the current login, as an asynchronous operation.
|
||||
/// </summary>
|
||||
|
|
@ -556,20 +543,20 @@ namespace Microsoft.AspNetCore.Identity
|
|||
/// for the sign-in attempt.</returns>
|
||||
public virtual async Task<ExternalLoginInfo> GetExternalLoginInfoAsync(string expectedXsrf = null)
|
||||
{
|
||||
var auth = new AuthenticateContext(Options.Cookies.ExternalCookieAuthenticationScheme);
|
||||
await Context.Authentication.AuthenticateAsync(auth);
|
||||
if (auth.Principal == null || auth.Properties == null || !auth.Properties.ContainsKey(LoginProviderKey))
|
||||
var auth = await Context.AuthenticateAsync(Options.Cookies.ExternalCookieAuthenticationScheme);
|
||||
var items = auth?.Properties?.Items;
|
||||
if (auth?.Principal == null || items == null || !items.ContainsKey(LoginProviderKey))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (expectedXsrf != null)
|
||||
{
|
||||
if (!auth.Properties.ContainsKey(XsrfKey))
|
||||
if (!items.ContainsKey(XsrfKey))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
var userId = auth.Properties[XsrfKey] as string;
|
||||
var userId = items[XsrfKey] as string;
|
||||
if (userId != expectedXsrf)
|
||||
{
|
||||
return null;
|
||||
|
|
@ -577,14 +564,15 @@ namespace Microsoft.AspNetCore.Identity
|
|||
}
|
||||
|
||||
var providerKey = auth.Principal.FindFirstValue(ClaimTypes.NameIdentifier);
|
||||
var provider = auth.Properties[LoginProviderKey] as string;
|
||||
var provider = items[LoginProviderKey] as string;
|
||||
if (providerKey == null || provider == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return new ExternalLoginInfo(auth.Principal, provider, providerKey, new AuthenticationDescription(auth.Description).DisplayName)
|
||||
// TODO: display name gone?. Add [] indexer for Authproperties
|
||||
return new ExternalLoginInfo(auth.Principal, provider, providerKey, provider)
|
||||
{
|
||||
AuthenticationTokens = new AuthenticationProperties(auth.Properties).GetTokens()
|
||||
AuthenticationTokens = auth.Properties.GetTokens()
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -682,14 +670,14 @@ namespace Microsoft.AspNetCore.Identity
|
|||
{
|
||||
// Store the userId for use after two factor check
|
||||
var userId = await UserManager.GetUserIdAsync(user);
|
||||
await Context.Authentication.SignInAsync(Options.Cookies.TwoFactorUserIdCookieAuthenticationScheme, StoreTwoFactorInfo(userId, loginProvider));
|
||||
await Context.SignInAsync(Options.Cookies.TwoFactorUserIdCookieAuthenticationScheme, StoreTwoFactorInfo(userId, loginProvider));
|
||||
return SignInResult.TwoFactorRequired;
|
||||
}
|
||||
}
|
||||
// Cleanup external cookie
|
||||
if (loginProvider != null)
|
||||
{
|
||||
await Context.Authentication.SignOutAsync(Options.Cookies.ExternalCookieAuthenticationScheme);
|
||||
await Context.SignOutAsync(Options.Cookies.ExternalCookieAuthenticationScheme);
|
||||
}
|
||||
await SignInAsync(user, isPersistent, loginProvider);
|
||||
return SignInResult.Success;
|
||||
|
|
@ -697,13 +685,13 @@ namespace Microsoft.AspNetCore.Identity
|
|||
|
||||
private async Task<TwoFactorAuthenticationInfo> RetrieveTwoFactorInfoAsync()
|
||||
{
|
||||
var result = await Context.Authentication.AuthenticateAsync(Options.Cookies.TwoFactorUserIdCookieAuthenticationScheme);
|
||||
if (result != null)
|
||||
var result = await Context.AuthenticateAsync(Options.Cookies.TwoFactorUserIdCookieAuthenticationScheme);
|
||||
if (result?.Principal != null)
|
||||
{
|
||||
return new TwoFactorAuthenticationInfo
|
||||
{
|
||||
UserId = result.FindFirstValue(ClaimTypes.Name),
|
||||
LoginProvider = result.FindFirstValue(ClaimTypes.AuthenticationMethod)
|
||||
UserId = result.Principal.FindFirstValue(ClaimTypes.Name),
|
||||
LoginProvider = result.Principal.FindFirstValue(ClaimTypes.AuthenticationMethod)
|
||||
};
|
||||
}
|
||||
return null;
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ using Microsoft.AspNetCore.Builder.Internal;
|
|||
using Microsoft.AspNetCore.Identity.Test;
|
||||
using Microsoft.AspNetCore.Testing.xunit;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Xunit;
|
||||
|
||||
|
|
@ -24,6 +25,7 @@ namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore.Test
|
|||
var services = new ServiceCollection();
|
||||
|
||||
services
|
||||
.AddSingleton<IConfiguration>(new ConfigurationBuilder().Build())
|
||||
.AddDbContext<IdentityDbContext>(o => o.UseSqlServer(fixture.ConnectionString))
|
||||
.AddIdentity<IdentityUser, IdentityRole>()
|
||||
.AddEntityFrameworkStores<IdentityDbContext>();
|
||||
|
|
|
|||
|
|
@ -1,21 +1,16 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Diagnostics;
|
||||
using System.Security.Claims;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Authentication;
|
||||
using Microsoft.AspNetCore.Builder.Internal;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Http.Authentication;
|
||||
using Microsoft.AspNetCore.Http.Features.Authentication;
|
||||
using Microsoft.AspNetCore.Authentication;
|
||||
using Microsoft.AspNetCore.Identity.Test;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Moq;
|
||||
using Xunit;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Microsoft.AspNetCore.Identity.InMemory.Test
|
||||
{
|
||||
|
|
@ -26,25 +21,25 @@ namespace Microsoft.AspNetCore.Identity.InMemory.Test
|
|||
[InlineData(false)]
|
||||
public async Task VerifyAccountControllerSignIn(bool isPersistent)
|
||||
{
|
||||
var context = new Mock<HttpContext>();
|
||||
var auth = new Mock<AuthenticationManager>();
|
||||
context.Setup(c => c.Authentication).Returns(auth.Object).Verifiable();
|
||||
auth.Setup(a => a.SignInAsync(new IdentityCookieOptions().ApplicationCookieAuthenticationScheme,
|
||||
var context = new DefaultHttpContext();
|
||||
var auth = MockAuth(context);
|
||||
auth.Setup(a => a.SignInAsync(context, new IdentityCookieOptions().ApplicationCookieAuthenticationScheme,
|
||||
It.IsAny<ClaimsPrincipal>(),
|
||||
It.IsAny<AuthenticationProperties>())).Returns(Task.FromResult(0)).Verifiable();
|
||||
// REVIEW: is persistant mocking broken
|
||||
//It.Is<AuthenticationProperties>(v => v.IsPersistent == isPersistent))).Returns(Task.FromResult(0)).Verifiable();
|
||||
var contextAccessor = new Mock<IHttpContextAccessor>();
|
||||
contextAccessor.Setup(a => a.HttpContext).Returns(context.Object);
|
||||
var services = new ServiceCollection();
|
||||
services.AddLogging();
|
||||
services.AddSingleton(contextAccessor.Object);
|
||||
contextAccessor.Setup(a => a.HttpContext).Returns(context);
|
||||
var services = new ServiceCollection()
|
||||
.AddSingleton<IConfiguration>(new ConfigurationBuilder().Build())
|
||||
.AddLogging()
|
||||
.AddSingleton(contextAccessor.Object);
|
||||
|
||||
services.AddIdentity<TestUser, TestRole>();
|
||||
services.AddSingleton<IUserStore<TestUser>, InMemoryStore<TestUser, TestRole>>();
|
||||
services.AddSingleton<IRoleStore<TestRole>, InMemoryStore<TestUser, TestRole>>();
|
||||
|
||||
var app = new ApplicationBuilder(services.BuildServiceProvider());
|
||||
app.UseCookieAuthentication();
|
||||
|
||||
// Act
|
||||
var user = new TestUser
|
||||
|
|
@ -61,7 +56,6 @@ namespace Microsoft.AspNetCore.Identity.InMemory.Test
|
|||
|
||||
// Assert
|
||||
Assert.True(result.Succeeded);
|
||||
context.VerifyAll();
|
||||
auth.VerifyAll();
|
||||
contextAccessor.VerifyAll();
|
||||
}
|
||||
|
|
@ -83,21 +77,20 @@ namespace Microsoft.AspNetCore.Identity.InMemory.Test
|
|||
}
|
||||
};
|
||||
|
||||
var auth = new Mock<AuthenticationManager>();
|
||||
auth.Setup(a => a.AuthenticateAsync(It.IsAny<AuthenticateContext>())).Returns(Task.FromResult(0));
|
||||
var context = new Mock<HttpContext>();
|
||||
context.Setup(c => c.Authentication).Returns(auth.Object).Verifiable();
|
||||
var context = new DefaultHttpContext();
|
||||
var auth = MockAuth(context);
|
||||
auth.Setup(a => a.AuthenticateAsync(context, It.IsAny<string>())).Returns(Task.FromResult(AuthenticateResult.None()));
|
||||
var contextAccessor = new Mock<IHttpContextAccessor>();
|
||||
contextAccessor.Setup(a => a.HttpContext).Returns(context.Object);
|
||||
var services = new ServiceCollection();
|
||||
services.AddLogging();
|
||||
services.AddSingleton(contextAccessor.Object);
|
||||
contextAccessor.Setup(a => a.HttpContext).Returns(context);
|
||||
var services = new ServiceCollection()
|
||||
.AddSingleton<IConfiguration>(new ConfigurationBuilder().Build())
|
||||
.AddLogging()
|
||||
.AddSingleton(contextAccessor.Object);
|
||||
services.AddIdentity<TestUser, TestRole>();
|
||||
services.AddSingleton<IUserStore<TestUser>, InMemoryStore<TestUser, TestRole>>();
|
||||
services.AddSingleton<IRoleStore<TestRole>, InMemoryStore<TestUser, TestRole>>();
|
||||
|
||||
var app = new ApplicationBuilder(services.BuildServiceProvider());
|
||||
app.UseCookieAuthentication();
|
||||
|
||||
// Act
|
||||
var user = new TestUser
|
||||
|
|
@ -113,5 +106,12 @@ namespace Microsoft.AspNetCore.Identity.InMemory.Test
|
|||
Assert.Equal("refresh", await userManager.GetAuthenticationTokenAsync(user, authScheme, "refresh_token"));
|
||||
Assert.Equal("access", await userManager.GetAuthenticationTokenAsync(user, authScheme, "access_token"));
|
||||
}
|
||||
|
||||
private Mock<IAuthenticationService> MockAuth(HttpContext context)
|
||||
{
|
||||
var auth = new Mock<IAuthenticationService>();
|
||||
context.RequestServices = new ServiceCollection().AddSingleton(auth.Object).BuildServiceProvider();
|
||||
return auth;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,11 +11,11 @@ using System.Text;
|
|||
using System.Threading.Tasks;
|
||||
using System.Xml;
|
||||
using System.Xml.Linq;
|
||||
using Microsoft.AspNetCore.Authentication;
|
||||
using Microsoft.AspNetCore.Authentication.Cookies;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Http.Authentication;
|
||||
using Microsoft.AspNetCore.Http.Features.Authentication;
|
||||
using Microsoft.AspNetCore.Identity.Test;
|
||||
using Microsoft.AspNetCore.TestHost;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
|
@ -27,14 +27,6 @@ namespace Microsoft.AspNetCore.Identity.InMemory
|
|||
{
|
||||
const string TestPassword = "1qaz!QAZ";
|
||||
|
||||
[Fact]
|
||||
public void UseIdentityThrowsWithoutAddIdentity()
|
||||
{
|
||||
var builder = new WebHostBuilder()
|
||||
.Configure(app => app.UseIdentity());
|
||||
Assert.Throws<InvalidOperationException>(() => new TestServer(builder));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task CanChangePasswordOptions()
|
||||
{
|
||||
|
|
@ -57,12 +49,15 @@ namespace Microsoft.AspNetCore.Identity.InMemory
|
|||
public async Task CanCreateMeLoginAndCookieStopsWorkingAfterExpiration()
|
||||
{
|
||||
var clock = new TestClock();
|
||||
var server = CreateServer(services => services.Configure<IdentityOptions>(options =>
|
||||
var server = CreateServer(services =>
|
||||
{
|
||||
options.Cookies.ApplicationCookie.SystemClock = clock;
|
||||
options.Cookies.ApplicationCookie.ExpireTimeSpan = TimeSpan.FromMinutes(10);
|
||||
options.Cookies.ApplicationCookie.SlidingExpiration = false;
|
||||
}));
|
||||
services.ConfigureApplicationCookie(options =>
|
||||
{
|
||||
options.ExpireTimeSpan = TimeSpan.FromMinutes(10);
|
||||
options.SlidingExpiration = false;
|
||||
});
|
||||
services.AddSingleton<ISystemClock>(clock);
|
||||
});
|
||||
|
||||
var transaction1 = await SendAsync(server, "http://example.com/createMe");
|
||||
Assert.Equal(HttpStatusCode.OK, transaction1.Response.StatusCode);
|
||||
|
|
@ -96,10 +91,7 @@ namespace Microsoft.AspNetCore.Identity.InMemory
|
|||
public async Task CanCreateMeLoginAndSecurityStampExtendsExpiration(bool rememberMe)
|
||||
{
|
||||
var clock = new TestClock();
|
||||
var server = CreateServer(services => services.Configure<IdentityOptions>(options =>
|
||||
{
|
||||
options.Cookies.ApplicationCookie.SystemClock = clock;
|
||||
}));
|
||||
var server = CreateServer(services => services.AddSingleton<ISystemClock>(clock));
|
||||
|
||||
var transaction1 = await SendAsync(server, "http://example.com/createMe");
|
||||
Assert.Equal(HttpStatusCode.OK, transaction1.Response.StatusCode);
|
||||
|
|
@ -143,17 +135,20 @@ namespace Microsoft.AspNetCore.Identity.InMemory
|
|||
public async Task CanAccessOldPrincipalDuringSecurityStampReplacement()
|
||||
{
|
||||
var clock = new TestClock();
|
||||
var server = CreateServer(services => services.Configure<IdentityOptions>(options =>
|
||||
var server = CreateServer(services =>
|
||||
{
|
||||
options.Cookies.ApplicationCookie.SystemClock = clock;
|
||||
options.OnSecurityStampRefreshingPrincipal = c =>
|
||||
services.Configure<IdentityOptions>(options =>
|
||||
{
|
||||
var newId = new ClaimsIdentity();
|
||||
newId.AddClaim(new Claim("PreviousName", c.CurrentPrincipal.Identity.Name));
|
||||
c.NewPrincipal.AddIdentity(newId);
|
||||
return Task.FromResult(0);
|
||||
};
|
||||
}));
|
||||
options.OnSecurityStampRefreshingPrincipal = c =>
|
||||
{
|
||||
var newId = new ClaimsIdentity();
|
||||
newId.AddClaim(new Claim("PreviousName", c.CurrentPrincipal.Identity.Name));
|
||||
c.NewPrincipal.AddIdentity(newId);
|
||||
return Task.FromResult(0);
|
||||
};
|
||||
});
|
||||
services.AddSingleton<ISystemClock>(clock);
|
||||
});
|
||||
|
||||
var transaction1 = await SendAsync(server, "http://example.com/createMe");
|
||||
Assert.Equal(HttpStatusCode.OK, transaction1.Response.StatusCode);
|
||||
|
|
@ -233,7 +228,7 @@ namespace Microsoft.AspNetCore.Identity.InMemory
|
|||
var builder = new WebHostBuilder()
|
||||
.Configure(app =>
|
||||
{
|
||||
app.UseIdentity();
|
||||
app.UseAuthentication();
|
||||
app.Use(async (context, next) =>
|
||||
{
|
||||
var req = context.Request;
|
||||
|
|
@ -282,14 +277,11 @@ namespace Microsoft.AspNetCore.Identity.InMemory
|
|||
}
|
||||
else if (req.Path == new PathString("/me"))
|
||||
{
|
||||
var auth = new AuthenticateContext("Application");
|
||||
auth.Authenticated(context.User, new AuthenticationProperties().Items, new AuthenticationDescription().Items);
|
||||
Describe(res, auth);
|
||||
Describe(res, AuthenticateResult.Success(new AuthenticationTicket(context.User, null, "Application")));
|
||||
}
|
||||
else if (req.Path.StartsWithSegments(new PathString("/me"), out remainder))
|
||||
{
|
||||
var auth = new AuthenticateContext(remainder.Value.Substring(1));
|
||||
await context.Authentication.AuthenticateAsync(auth);
|
||||
var auth = await context.AuthenticateAsync(remainder.Value.Substring(1));
|
||||
Describe(res, auth);
|
||||
}
|
||||
else if (req.Path == new PathString("/testpath") && testpath != null)
|
||||
|
|
@ -307,17 +299,14 @@ namespace Microsoft.AspNetCore.Identity.InMemory
|
|||
services.AddIdentity<TestUser, TestRole>();
|
||||
services.AddSingleton<IUserStore<TestUser>, InMemoryStore<TestUser, TestRole>>();
|
||||
services.AddSingleton<IRoleStore<TestRole>, InMemoryStore<TestUser, TestRole>>();
|
||||
if (configureServices != null)
|
||||
{
|
||||
configureServices(services);
|
||||
}
|
||||
configureServices?.Invoke(services);
|
||||
});
|
||||
var server = new TestServer(builder);
|
||||
server.BaseAddress = baseAddress;
|
||||
return server;
|
||||
}
|
||||
|
||||
private static void Describe(HttpResponse res, AuthenticateContext result)
|
||||
private static void Describe(HttpResponse res, AuthenticateResult result)
|
||||
{
|
||||
res.StatusCode = 200;
|
||||
res.ContentType = "text/xml";
|
||||
|
|
@ -328,7 +317,7 @@ namespace Microsoft.AspNetCore.Identity.InMemory
|
|||
}
|
||||
if (result != null && result.Properties != null)
|
||||
{
|
||||
xml.Add(result.Properties.Select(extra => new XElement("extra", new XAttribute("type", extra.Key), new XAttribute("value", extra.Value))));
|
||||
xml.Add(result.Properties.Items.Select(extra => new XElement("extra", new XAttribute("type", extra.Key), new XAttribute("value", extra.Value))));
|
||||
}
|
||||
using (var memory = new MemoryStream())
|
||||
{
|
||||
|
|
|
|||
|
|
@ -19,8 +19,6 @@
|
|||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Authentication" Version="$(AspNetCoreVersion)" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.Cookies" Version="$(AspNetCoreVersion)" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Hosting" Version="$(AspNetCoreVersion)" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Http" Version="$(AspNetCoreVersion)" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.TestHost" Version="$(AspNetCoreVersion)" />
|
||||
|
|
|
|||
|
|
@ -4,13 +4,12 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Security.Claims;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Xunit;
|
||||
|
||||
|
|
@ -22,7 +21,8 @@ namespace Microsoft.AspNetCore.Identity.Test
|
|||
[Fact]
|
||||
public void CanOverrideUserStore()
|
||||
{
|
||||
var services = new ServiceCollection();
|
||||
var services = new ServiceCollection()
|
||||
.AddSingleton<IConfiguration>(new ConfigurationBuilder().Build());
|
||||
services.AddIdentity<TestUser,TestRole>().AddUserStore<MyUberThingy>();
|
||||
var thingy = services.BuildServiceProvider().GetRequiredService<IUserStore<TestUser>>() as MyUberThingy;
|
||||
Assert.NotNull(thingy);
|
||||
|
|
@ -31,7 +31,8 @@ namespace Microsoft.AspNetCore.Identity.Test
|
|||
[Fact]
|
||||
public void CanOverrideRoleStore()
|
||||
{
|
||||
var services = new ServiceCollection();
|
||||
var services = new ServiceCollection()
|
||||
.AddSingleton<IConfiguration>(new ConfigurationBuilder().Build());
|
||||
services.AddIdentity<TestUser,TestRole>().AddRoleStore<MyUberThingy>();
|
||||
var thingy = services.BuildServiceProvider().GetRequiredService<IRoleStore<TestRole>>() as MyUberThingy;
|
||||
Assert.NotNull(thingy);
|
||||
|
|
@ -40,7 +41,9 @@ namespace Microsoft.AspNetCore.Identity.Test
|
|||
[Fact]
|
||||
public void CanOverridePrincipalFactory()
|
||||
{
|
||||
var services = new ServiceCollection().AddLogging();
|
||||
var services = new ServiceCollection()
|
||||
.AddLogging()
|
||||
.AddSingleton<IConfiguration>(new ConfigurationBuilder().Build());
|
||||
services.AddIdentity<TestUser, TestRole>()
|
||||
.AddClaimsPrincipalFactory<MyClaimsPrincipalFactory>()
|
||||
.AddUserManager<MyUserManager>()
|
||||
|
|
@ -53,7 +56,8 @@ namespace Microsoft.AspNetCore.Identity.Test
|
|||
[Fact]
|
||||
public void CanOverrideRoleValidator()
|
||||
{
|
||||
var services = new ServiceCollection();
|
||||
var services = new ServiceCollection()
|
||||
.AddSingleton<IConfiguration>(new ConfigurationBuilder().Build());
|
||||
services.AddIdentity<TestUser,TestRole>().AddRoleValidator<MyUberThingy>();
|
||||
var thingy = services.BuildServiceProvider().GetRequiredService<IRoleValidator<TestRole>>() as MyUberThingy;
|
||||
Assert.NotNull(thingy);
|
||||
|
|
@ -62,7 +66,8 @@ namespace Microsoft.AspNetCore.Identity.Test
|
|||
[Fact]
|
||||
public void CanOverrideUserValidator()
|
||||
{
|
||||
var services = new ServiceCollection();
|
||||
var services = new ServiceCollection()
|
||||
.AddSingleton<IConfiguration>(new ConfigurationBuilder().Build());
|
||||
services.AddIdentity<TestUser,TestRole>().AddUserValidator<MyUberThingy>();
|
||||
var thingy = services.BuildServiceProvider().GetRequiredService<IUserValidator<TestUser>>() as MyUberThingy;
|
||||
Assert.NotNull(thingy);
|
||||
|
|
@ -71,7 +76,8 @@ namespace Microsoft.AspNetCore.Identity.Test
|
|||
[Fact]
|
||||
public void CanOverridePasswordValidator()
|
||||
{
|
||||
var services = new ServiceCollection();
|
||||
var services = new ServiceCollection()
|
||||
.AddSingleton<IConfiguration>(new ConfigurationBuilder().Build());
|
||||
services.AddIdentity<TestUser,TestRole>().AddPasswordValidator<MyUberThingy>();
|
||||
var thingy = services.BuildServiceProvider().GetRequiredService<IPasswordValidator<TestUser>>() as MyUberThingy;
|
||||
Assert.NotNull(thingy);
|
||||
|
|
@ -80,7 +86,8 @@ namespace Microsoft.AspNetCore.Identity.Test
|
|||
[Fact]
|
||||
public void CanOverrideUserManager()
|
||||
{
|
||||
var services = new ServiceCollection();
|
||||
var services = new ServiceCollection()
|
||||
.AddSingleton<IConfiguration>(new ConfigurationBuilder().Build());
|
||||
services.AddIdentity<TestUser, TestRole>()
|
||||
.AddUserStore<NoopUserStore>()
|
||||
.AddUserManager<MyUserManager>();
|
||||
|
|
@ -91,7 +98,8 @@ namespace Microsoft.AspNetCore.Identity.Test
|
|||
[Fact]
|
||||
public void CanOverrideRoleManager()
|
||||
{
|
||||
var services = new ServiceCollection();
|
||||
var services = new ServiceCollection()
|
||||
.AddSingleton<IConfiguration>(new ConfigurationBuilder().Build());
|
||||
services.AddIdentity<TestUser, TestRole>()
|
||||
.AddRoleStore<NoopRoleStore>()
|
||||
.AddRoleManager<MyRoleManager>();
|
||||
|
|
@ -102,10 +110,11 @@ namespace Microsoft.AspNetCore.Identity.Test
|
|||
[Fact]
|
||||
public void CanOverrideSignInManager()
|
||||
{
|
||||
var services = new ServiceCollection();
|
||||
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>()
|
||||
.AddLogging()
|
||||
.AddIdentity<TestUser, TestRole>()
|
||||
var services = new ServiceCollection()
|
||||
.AddSingleton<IConfiguration>(new ConfigurationBuilder().Build())
|
||||
.AddSingleton<IHttpContextAccessor, HttpContextAccessor>()
|
||||
.AddLogging();
|
||||
services.AddIdentity<TestUser, TestRole>()
|
||||
.AddUserStore<NoopUserStore>()
|
||||
.AddRoleStore<NoopRoleStore>()
|
||||
.AddUserManager<MyUserManager>()
|
||||
|
|
@ -118,7 +127,8 @@ namespace Microsoft.AspNetCore.Identity.Test
|
|||
[Fact]
|
||||
public void EnsureDefaultServices()
|
||||
{
|
||||
var services = new ServiceCollection();
|
||||
var services = new ServiceCollection()
|
||||
.AddSingleton<IConfiguration>(new ConfigurationBuilder().Build());
|
||||
services.AddIdentity<TestUser,TestRole>();
|
||||
|
||||
var provider = services.BuildServiceProvider();
|
||||
|
|
@ -135,7 +145,8 @@ namespace Microsoft.AspNetCore.Identity.Test
|
|||
[Fact]
|
||||
public void EnsureDefaultTokenProviders()
|
||||
{
|
||||
var services = new ServiceCollection();
|
||||
var services = new ServiceCollection()
|
||||
.AddSingleton<IConfiguration>(new ConfigurationBuilder().Build());
|
||||
services.AddIdentity<TestUser,TestRole>().AddDefaultTokenProviders();
|
||||
|
||||
var provider = services.BuildServiceProvider();
|
||||
|
|
@ -146,7 +157,8 @@ namespace Microsoft.AspNetCore.Identity.Test
|
|||
[Fact]
|
||||
public void AddManagerWithWrongTypesThrows()
|
||||
{
|
||||
var services = new ServiceCollection();
|
||||
var services = new ServiceCollection()
|
||||
.AddSingleton<IConfiguration>(new ConfigurationBuilder().Build());
|
||||
var builder = services.AddIdentity<TestUser, TestRole>();
|
||||
Assert.Throws<InvalidOperationException>(() => builder.AddUserManager<UserManager<TestUser>>());
|
||||
Assert.Throws<InvalidOperationException>(() => builder.AddRoleManager<RoleManager<TestRole>>());
|
||||
|
|
@ -159,7 +171,8 @@ namespace Microsoft.AspNetCore.Identity.Test
|
|||
[Fact]
|
||||
public void AddTokenProviderWithWrongTypesThrows()
|
||||
{
|
||||
var services = new ServiceCollection();
|
||||
var services = new ServiceCollection()
|
||||
.AddSingleton<IConfiguration>(new ConfigurationBuilder().Build());
|
||||
var builder = services.AddIdentity<TestUser, TestRole>();
|
||||
Assert.Throws<InvalidOperationException>(() => builder.AddTokenProvider<object>("whatevs"));
|
||||
Assert.Throws<InvalidOperationException>(() => builder.AddTokenProvider("whatevs", typeof(object)));
|
||||
|
|
|
|||
|
|
@ -36,11 +36,6 @@ namespace Microsoft.AspNetCore.Identity.Test
|
|||
Assert.Equal(ClaimTypes.Name, options.ClaimsIdentity.UserNameClaimType);
|
||||
Assert.Equal(ClaimTypes.NameIdentifier, options.ClaimsIdentity.UserIdClaimType);
|
||||
Assert.Equal("AspNet.Identity.SecurityStamp", options.ClaimsIdentity.SecurityStampClaimType);
|
||||
|
||||
Assert.True(options.Cookies.ApplicationCookie.AutomaticAuthenticate);
|
||||
Assert.False(options.Cookies.ExternalCookie.AutomaticAuthenticate);
|
||||
Assert.False(options.Cookies.TwoFactorRememberMeCookie.AutomaticAuthenticate);
|
||||
Assert.False(options.Cookies.TwoFactorUserIdCookie.AutomaticAuthenticate);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -73,8 +68,8 @@ namespace Microsoft.AspNetCore.Identity.Test
|
|||
Assert.Equal(roleClaimType, config["identity:claimsidentity:roleclaimtype"]);
|
||||
|
||||
var services = new ServiceCollection();
|
||||
services.AddSingleton<IConfiguration>(config);
|
||||
services.AddIdentity<TestUser,TestRole>();
|
||||
services.Configure<IdentityOptions>(config.GetSection("identity"));
|
||||
var accessor = services.BuildServiceProvider().GetRequiredService<IOptions<IdentityOptions>>();
|
||||
Assert.NotNull(accessor);
|
||||
var options = accessor.Value;
|
||||
|
|
@ -106,7 +101,7 @@ namespace Microsoft.AspNetCore.Identity.Test
|
|||
builder.AddInMemoryCollection(dic);
|
||||
var config = builder.Build();
|
||||
var services = new ServiceCollection();
|
||||
services.Configure<IdentityOptions>(config.GetSection("identity"));
|
||||
services.AddSingleton<IConfiguration>(config);
|
||||
services.AddIdentity<TestUser, TestRole>(o => { o.User.RequireUniqueEmail = false; o.Lockout.MaxFailedAccessAttempts++; });
|
||||
var accessor = services.BuildServiceProvider().GetRequiredService<IOptions<IdentityOptions>>();
|
||||
Assert.NotNull(accessor);
|
||||
|
|
@ -119,6 +114,7 @@ namespace Microsoft.AspNetCore.Identity.Test
|
|||
public void CanCustomizeIdentityOptions()
|
||||
{
|
||||
var services = new ServiceCollection()
|
||||
.AddSingleton<IConfiguration>(new ConfigurationBuilder().Build())
|
||||
.Configure<IdentityOptions>(options => options.Password.RequiredLength = -1);
|
||||
services.AddIdentity<TestUser,TestRole>();
|
||||
var serviceProvider = services.BuildServiceProvider();
|
||||
|
|
@ -139,7 +135,8 @@ namespace Microsoft.AspNetCore.Identity.Test
|
|||
[Fact]
|
||||
public void CanSetupIdentityOptions()
|
||||
{
|
||||
var services = new ServiceCollection();
|
||||
var services = new ServiceCollection()
|
||||
.AddSingleton<IConfiguration>(new ConfigurationBuilder().Build());
|
||||
services.AddIdentity<TestUser,TestRole>(options => options.User.RequireUniqueEmail = true);
|
||||
var serviceProvider = services.BuildServiceProvider();
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ using Microsoft.AspNetCore.Authentication;
|
|||
using Microsoft.AspNetCore.Authentication.Cookies;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Http.Authentication;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Moq;
|
||||
|
|
@ -18,15 +17,47 @@ namespace Microsoft.AspNetCore.Identity.Test
|
|||
{
|
||||
public class SecurityStampTest
|
||||
{
|
||||
private class NoopHandler : IAuthenticationHandler
|
||||
{
|
||||
public Task<AuthenticateResult> AuthenticateAsync()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Task ChallengeAsync(ChallengeContext context)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Task<bool> HandleRequestAsync()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Task InitializeAsync(AuthenticationScheme scheme, HttpContext context)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Task SignInAsync(SignInContext context)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Task SignOutAsync(SignOutContext context)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task OnValidatePrincipalThrowsWithEmptyServiceCollection()
|
||||
{
|
||||
var scheme = new IdentityOptions().Cookies.ApplicationCookieAuthenticationScheme;
|
||||
var httpContext = new Mock<HttpContext>();
|
||||
httpContext.Setup(c => c.RequestServices).Returns(new ServiceCollection().BuildServiceProvider());
|
||||
var id = new ClaimsPrincipal(new ClaimsIdentity(scheme));
|
||||
var ticket = new AuthenticationTicket(id, new AuthenticationProperties { IssuedUtc = DateTimeOffset.UtcNow }, scheme);
|
||||
var context = new CookieValidatePrincipalContext(httpContext.Object, ticket, new CookieAuthenticationOptions());
|
||||
var id = new ClaimsPrincipal(new ClaimsIdentity(IdentityCookieOptions.ApplicationScheme));
|
||||
var ticket = new AuthenticationTicket(id, new AuthenticationProperties { IssuedUtc = DateTimeOffset.UtcNow }, IdentityCookieOptions.ApplicationScheme);
|
||||
var context = new CookieValidatePrincipalContext(httpContext.Object, new AuthenticationSchemeBuilder(IdentityCookieOptions.ApplicationScheme) { HandlerType = typeof(NoopHandler) }.Build(), ticket, new CookieAuthenticationOptions());
|
||||
var ex = await Assert.ThrowsAsync<InvalidOperationException>(() => SecurityStampValidator.ValidatePrincipalAsync(context));
|
||||
}
|
||||
|
||||
|
|
@ -56,13 +87,13 @@ namespace Microsoft.AspNetCore.Identity.Test
|
|||
var services = new ServiceCollection();
|
||||
services.AddSingleton(options.Object);
|
||||
services.AddSingleton(signInManager.Object);
|
||||
services.AddSingleton<ISecurityStampValidator>(new SecurityStampValidator<TestUser>(options.Object, signInManager.Object));
|
||||
services.AddSingleton<ISecurityStampValidator>(new SecurityStampValidator<TestUser>(options.Object, signInManager.Object, new SystemClock()));
|
||||
httpContext.Setup(c => c.RequestServices).Returns(services.BuildServiceProvider());
|
||||
|
||||
var ticket = new AuthenticationTicket(principal,
|
||||
properties,
|
||||
identityOptions.Cookies.ApplicationCookieAuthenticationScheme);
|
||||
var context = new CookieValidatePrincipalContext(httpContext.Object, ticket, new CookieAuthenticationOptions());
|
||||
var context = new CookieValidatePrincipalContext(httpContext.Object, new AuthenticationSchemeBuilder(identityOptions.Cookies.ApplicationCookieAuthenticationScheme) { HandlerType = typeof(NoopHandler) }.Build(), ticket, new CookieAuthenticationOptions());
|
||||
Assert.NotNull(context.Properties);
|
||||
Assert.NotNull(context.Options);
|
||||
Assert.NotNull(context.Principal);
|
||||
|
|
@ -90,7 +121,7 @@ namespace Microsoft.AspNetCore.Identity.Test
|
|||
var services = new ServiceCollection();
|
||||
services.AddSingleton(options.Object);
|
||||
services.AddSingleton(signInManager.Object);
|
||||
services.AddSingleton<ISecurityStampValidator>(new SecurityStampValidator<TestUser>(options.Object, signInManager.Object));
|
||||
services.AddSingleton<ISecurityStampValidator>(new SecurityStampValidator<TestUser>(options.Object, signInManager.Object, new SystemClock()));
|
||||
httpContext.Setup(c => c.RequestServices).Returns(services.BuildServiceProvider());
|
||||
var id = new ClaimsIdentity(identityOptions.Cookies.ApplicationCookieAuthenticationScheme);
|
||||
id.AddClaim(new Claim(ClaimTypes.NameIdentifier, user.Id));
|
||||
|
|
@ -98,7 +129,7 @@ namespace Microsoft.AspNetCore.Identity.Test
|
|||
var ticket = new AuthenticationTicket(new ClaimsPrincipal(id),
|
||||
new AuthenticationProperties { IssuedUtc = DateTimeOffset.UtcNow.AddSeconds(-1) },
|
||||
identityOptions.Cookies.ApplicationCookieAuthenticationScheme);
|
||||
var context = new CookieValidatePrincipalContext(httpContext.Object, ticket, new CookieAuthenticationOptions());
|
||||
var context = new CookieValidatePrincipalContext(httpContext.Object, new AuthenticationSchemeBuilder(identityOptions.Cookies.ApplicationCookieAuthenticationScheme) { HandlerType = typeof(NoopHandler) }.Build(), ticket, new CookieAuthenticationOptions());
|
||||
Assert.NotNull(context.Properties);
|
||||
Assert.NotNull(context.Options);
|
||||
Assert.NotNull(context.Principal);
|
||||
|
|
@ -125,7 +156,7 @@ namespace Microsoft.AspNetCore.Identity.Test
|
|||
var services = new ServiceCollection();
|
||||
services.AddSingleton(options.Object);
|
||||
services.AddSingleton(signInManager.Object);
|
||||
services.AddSingleton<ISecurityStampValidator>(new SecurityStampValidator<TestUser>(options.Object, signInManager.Object));
|
||||
services.AddSingleton<ISecurityStampValidator>(new SecurityStampValidator<TestUser>(options.Object, signInManager.Object, new SystemClock()));
|
||||
httpContext.Setup(c => c.RequestServices).Returns(services.BuildServiceProvider());
|
||||
var id = new ClaimsIdentity(identityOptions.Cookies.ApplicationCookieAuthenticationScheme);
|
||||
id.AddClaim(new Claim(ClaimTypes.NameIdentifier, user.Id));
|
||||
|
|
@ -133,7 +164,7 @@ namespace Microsoft.AspNetCore.Identity.Test
|
|||
var ticket = new AuthenticationTicket(new ClaimsPrincipal(id),
|
||||
new AuthenticationProperties(),
|
||||
identityOptions.Cookies.ApplicationCookieAuthenticationScheme);
|
||||
var context = new CookieValidatePrincipalContext(httpContext.Object, ticket, new CookieAuthenticationOptions());
|
||||
var context = new CookieValidatePrincipalContext(httpContext.Object, new AuthenticationSchemeBuilder(identityOptions.Cookies.ApplicationCookieAuthenticationScheme) { HandlerType = typeof(NoopHandler) }.Build(), ticket, new CookieAuthenticationOptions());
|
||||
Assert.NotNull(context.Properties);
|
||||
Assert.NotNull(context.Options);
|
||||
Assert.NotNull(context.Principal);
|
||||
|
|
@ -161,7 +192,7 @@ namespace Microsoft.AspNetCore.Identity.Test
|
|||
var services = new ServiceCollection();
|
||||
services.AddSingleton(options.Object);
|
||||
services.AddSingleton(signInManager.Object);
|
||||
services.AddSingleton<ISecurityStampValidator>(new SecurityStampValidator<TestUser>(options.Object, signInManager.Object));
|
||||
services.AddSingleton<ISecurityStampValidator>(new SecurityStampValidator<TestUser>(options.Object, signInManager.Object, new SystemClock()));
|
||||
httpContext.Setup(c => c.RequestServices).Returns(services.BuildServiceProvider());
|
||||
var id = new ClaimsIdentity(identityOptions.Cookies.ApplicationCookieAuthenticationScheme);
|
||||
id.AddClaim(new Claim(ClaimTypes.NameIdentifier, user.Id));
|
||||
|
|
@ -169,7 +200,7 @@ namespace Microsoft.AspNetCore.Identity.Test
|
|||
var ticket = new AuthenticationTicket(new ClaimsPrincipal(id),
|
||||
new AuthenticationProperties { IssuedUtc = DateTimeOffset.UtcNow },
|
||||
identityOptions.Cookies.ApplicationCookieAuthenticationScheme);
|
||||
var context = new CookieValidatePrincipalContext(httpContext.Object, ticket, new CookieAuthenticationOptions());
|
||||
var context = new CookieValidatePrincipalContext(httpContext.Object, new AuthenticationSchemeBuilder(identityOptions.Cookies.ApplicationCookieAuthenticationScheme) { HandlerType = typeof(NoopHandler) }.Build(), ticket, new CookieAuthenticationOptions());
|
||||
Assert.NotNull(context.Properties);
|
||||
Assert.NotNull(context.Options);
|
||||
Assert.NotNull(context.Principal);
|
||||
|
|
|
|||
|
|
@ -7,10 +7,10 @@ using System.Linq;
|
|||
using System.Security.Claims;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Authentication;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Http.Authentication;
|
||||
using Microsoft.AspNetCore.Http.Features.Authentication;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Moq;
|
||||
using Xunit;
|
||||
|
|
@ -203,11 +203,10 @@ namespace Microsoft.AspNetCore.Identity.Test
|
|||
manager.Setup(m => m.IsLockedOutAsync(user)).ReturnsAsync(false).Verifiable();
|
||||
manager.Setup(m => m.CheckPasswordAsync(user, "password")).ReturnsAsync(true).Verifiable();
|
||||
|
||||
var context = new Mock<HttpContext>();
|
||||
var auth = new Mock<AuthenticationManager>();
|
||||
context.Setup(c => c.Authentication).Returns(auth.Object).Verifiable();
|
||||
SetupSignIn(auth, user.Id, isPersistent);
|
||||
var helper = SetupSignInManager(manager.Object, context.Object);
|
||||
var context = new DefaultHttpContext();
|
||||
var auth = MockAuth(context);
|
||||
SetupSignIn(context, auth, user.Id, isPersistent);
|
||||
var helper = SetupSignInManager(manager.Object, context);
|
||||
|
||||
// Act
|
||||
var result = await helper.PasswordSignInAsync(user.UserName, "password", isPersistent, false);
|
||||
|
|
@ -215,7 +214,6 @@ namespace Microsoft.AspNetCore.Identity.Test
|
|||
// Assert
|
||||
Assert.True(result.Succeeded);
|
||||
manager.Verify();
|
||||
context.Verify();
|
||||
auth.Verify();
|
||||
}
|
||||
|
||||
|
|
@ -229,11 +227,10 @@ namespace Microsoft.AspNetCore.Identity.Test
|
|||
manager.Setup(m => m.IsLockedOutAsync(user)).ReturnsAsync(false).Verifiable();
|
||||
manager.Setup(m => m.CheckPasswordAsync(user, "password")).ReturnsAsync(true).Verifiable();
|
||||
|
||||
var context = new Mock<HttpContext>();
|
||||
var auth = new Mock<AuthenticationManager>();
|
||||
context.Setup(c => c.Authentication).Returns(auth.Object).Verifiable();
|
||||
SetupSignIn(auth, user.Id, false);
|
||||
var helper = SetupSignInManager(manager.Object, context.Object);
|
||||
var context = new DefaultHttpContext();
|
||||
var auth = MockAuth(context);
|
||||
SetupSignIn(context, auth, user.Id, false);
|
||||
var helper = SetupSignInManager(manager.Object, context);
|
||||
|
||||
// Act
|
||||
var result = await helper.PasswordSignInAsync(user.UserName, "password", false, false);
|
||||
|
|
@ -241,7 +238,6 @@ namespace Microsoft.AspNetCore.Identity.Test
|
|||
// Assert
|
||||
Assert.True(result.Succeeded);
|
||||
manager.Verify();
|
||||
context.Verify();
|
||||
auth.Verify();
|
||||
}
|
||||
|
||||
|
|
@ -257,11 +253,10 @@ namespace Microsoft.AspNetCore.Identity.Test
|
|||
manager.Setup(m => m.CheckPasswordAsync(user, "password")).ReturnsAsync(true).Verifiable();
|
||||
manager.Setup(m => m.ResetAccessFailedCountAsync(user)).ReturnsAsync(IdentityResult.Success).Verifiable();
|
||||
|
||||
var context = new Mock<HttpContext>();
|
||||
var auth = new Mock<AuthenticationManager>();
|
||||
SetupSignIn(auth);
|
||||
context.Setup(c => c.Authentication).Returns(auth.Object).Verifiable();
|
||||
var helper = SetupSignInManager(manager.Object, context.Object);
|
||||
var context = new DefaultHttpContext();
|
||||
var auth = MockAuth(context);
|
||||
SetupSignIn(context, auth);
|
||||
var helper = SetupSignInManager(manager.Object, context);
|
||||
|
||||
// Act
|
||||
var result = await helper.PasswordSignInAsync(user.UserName, "password", false, false);
|
||||
|
|
@ -269,7 +264,6 @@ namespace Microsoft.AspNetCore.Identity.Test
|
|||
// Assert
|
||||
Assert.True(result.Succeeded);
|
||||
manager.Verify();
|
||||
context.Verify();
|
||||
auth.Verify();
|
||||
}
|
||||
|
||||
|
|
@ -296,12 +290,12 @@ namespace Microsoft.AspNetCore.Identity.Test
|
|||
{
|
||||
manager.Setup(m => m.ResetAccessFailedCountAsync(user)).ReturnsAsync(IdentityResult.Success).Verifiable();
|
||||
}
|
||||
var context = new Mock<HttpContext>();
|
||||
var helper = SetupSignInManager(manager.Object, context.Object);
|
||||
var auth = new Mock<AuthenticationManager>();
|
||||
auth.Setup(a => a.SignInAsync(helper.Options.Cookies.TwoFactorUserIdCookieAuthenticationScheme,
|
||||
It.Is<ClaimsPrincipal>(id => id.FindFirstValue(ClaimTypes.Name) == user.Id))).Returns(Task.FromResult(0)).Verifiable();
|
||||
context.Setup(c => c.Authentication).Returns(auth.Object).Verifiable();
|
||||
var context = new DefaultHttpContext();
|
||||
var helper = SetupSignInManager(manager.Object, context);
|
||||
var auth = MockAuth(context);
|
||||
auth.Setup(a => a.SignInAsync(context, helper.Options.Cookies.TwoFactorUserIdCookieAuthenticationScheme,
|
||||
It.Is<ClaimsPrincipal>(id => id.FindFirstValue(ClaimTypes.Name) == user.Id),
|
||||
It.IsAny<AuthenticationProperties>())).Returns(Task.FromResult(0)).Verifiable();
|
||||
|
||||
// Act
|
||||
var result = await helper.PasswordSignInAsync(user.UserName, "password", false, false);
|
||||
|
|
@ -310,7 +304,6 @@ namespace Microsoft.AspNetCore.Identity.Test
|
|||
Assert.False(result.Succeeded);
|
||||
Assert.True(result.RequiresTwoFactor);
|
||||
manager.Verify();
|
||||
context.Verify();
|
||||
auth.Verify();
|
||||
}
|
||||
|
||||
|
|
@ -334,19 +327,19 @@ namespace Microsoft.AspNetCore.Identity.Test
|
|||
manager.Setup(m => m.SupportsUserTwoFactor).Returns(true).Verifiable();
|
||||
manager.Setup(m => m.GetTwoFactorEnabledAsync(user)).ReturnsAsync(true).Verifiable();
|
||||
}
|
||||
var context = new Mock<HttpContext>();
|
||||
var auth = new Mock<AuthenticationManager>();
|
||||
context.Setup(c => c.Authentication).Returns(auth.Object).Verifiable();
|
||||
var helper = SetupSignInManager(manager.Object, context.Object);
|
||||
var context = new DefaultHttpContext();
|
||||
var auth = MockAuth(context);
|
||||
var helper = SetupSignInManager(manager.Object, context);
|
||||
|
||||
if (bypass)
|
||||
{
|
||||
SetupSignIn(auth, user.Id, false, loginProvider);
|
||||
SetupSignIn(context, auth, user.Id, false, loginProvider);
|
||||
}
|
||||
else
|
||||
{
|
||||
auth.Setup(a => a.SignInAsync(helper.Options.Cookies.TwoFactorUserIdCookieAuthenticationScheme,
|
||||
It.Is<ClaimsPrincipal>(id => id.FindFirstValue(ClaimTypes.Name) == user.Id))).Returns(Task.FromResult(0)).Verifiable();
|
||||
auth.Setup(a => a.SignInAsync(context, helper.Options.Cookies.TwoFactorUserIdCookieAuthenticationScheme,
|
||||
It.Is<ClaimsPrincipal>(id => id.FindFirstValue(ClaimTypes.Name) == user.Id),
|
||||
It.IsAny<AuthenticationProperties>())).Returns(Task.FromResult(0)).Verifiable();
|
||||
}
|
||||
|
||||
// Act
|
||||
|
|
@ -356,7 +349,6 @@ namespace Microsoft.AspNetCore.Identity.Test
|
|||
Assert.Equal(bypass, result.Succeeded);
|
||||
Assert.Equal(!bypass, result.RequiresTwoFactor);
|
||||
manager.Verify();
|
||||
context.Verify();
|
||||
auth.Verify();
|
||||
}
|
||||
|
||||
|
|
@ -384,21 +376,21 @@ namespace Microsoft.AspNetCore.Identity.Test
|
|||
manager.Setup(m => m.VerifyTwoFactorTokenAsync(user, providerName ?? TokenOptions.DefaultAuthenticatorProvider, code)).ReturnsAsync(true).Verifiable();
|
||||
manager.Setup(m => m.ResetAccessFailedCountAsync(user)).ReturnsAsync(IdentityResult.Success).Verifiable();
|
||||
|
||||
var context = new Mock<HttpContext>();
|
||||
var auth = new Mock<AuthenticationManager>();
|
||||
var context = new DefaultHttpContext();
|
||||
var auth = MockAuth(context);
|
||||
var helper = SetupSignInManager(manager.Object, context);
|
||||
var twoFactorInfo = new SignInManager<TestUser>.TwoFactorAuthenticationInfo { UserId = user.Id };
|
||||
var helper = SetupSignInManager(manager.Object, context.Object);
|
||||
if (providerName != null)
|
||||
{
|
||||
helper.Options.Tokens.AuthenticatorTokenProvider = providerName;
|
||||
}
|
||||
var id = helper.StoreTwoFactorInfo(user.Id, null);
|
||||
SetupSignIn(auth, user.Id, isPersistent);
|
||||
auth.Setup(a => a.AuthenticateAsync(helper.Options.Cookies.TwoFactorUserIdCookieAuthenticationScheme)).ReturnsAsync(id).Verifiable();
|
||||
context.Setup(c => c.Authentication).Returns(auth.Object).Verifiable();
|
||||
SetupSignIn(context, auth, user.Id, isPersistent);
|
||||
auth.Setup(a => a.AuthenticateAsync(context, helper.Options.Cookies.TwoFactorUserIdCookieAuthenticationScheme))
|
||||
.ReturnsAsync(AuthenticateResult.Success(new AuthenticationTicket(id, null, helper.Options.Cookies.TwoFactorUserIdCookieAuthenticationScheme))).Verifiable();
|
||||
if (rememberClient)
|
||||
{
|
||||
auth.Setup(a => a.SignInAsync(
|
||||
auth.Setup(a => a.SignInAsync(context,
|
||||
helper.Options.Cookies.TwoFactorRememberMeCookieAuthenticationScheme,
|
||||
It.Is<ClaimsPrincipal>(i => i.FindFirstValue(ClaimTypes.Name) == user.Id
|
||||
&& i.Identities.First().AuthenticationType == helper.Options.Cookies.TwoFactorRememberMeCookieAuthenticationScheme),
|
||||
|
|
@ -411,7 +403,6 @@ namespace Microsoft.AspNetCore.Identity.Test
|
|||
// Assert
|
||||
Assert.True(result.Succeeded);
|
||||
manager.Verify();
|
||||
context.Verify();
|
||||
auth.Verify();
|
||||
}
|
||||
|
||||
|
|
@ -432,28 +423,28 @@ namespace Microsoft.AspNetCore.Identity.Test
|
|||
{
|
||||
manager.Setup(m => m.ResetAccessFailedCountAsync(user)).ReturnsAsync(IdentityResult.Success).Verifiable();
|
||||
}
|
||||
var context = new Mock<HttpContext>();
|
||||
var auth = new Mock<AuthenticationManager>();
|
||||
var context = new DefaultHttpContext();
|
||||
var auth = MockAuth(context);
|
||||
var helper = SetupSignInManager(manager.Object, context);
|
||||
var twoFactorInfo = new SignInManager<TestUser>.TwoFactorAuthenticationInfo { UserId = user.Id };
|
||||
var loginProvider = "loginprovider";
|
||||
var helper = SetupSignInManager(manager.Object, context.Object);
|
||||
var id = helper.StoreTwoFactorInfo(user.Id, externalLogin ? loginProvider : null);
|
||||
if (externalLogin)
|
||||
{
|
||||
auth.Setup(a => a.SignInAsync(
|
||||
auth.Setup(a => a.SignInAsync(context,
|
||||
helper.Options.Cookies.ApplicationCookieAuthenticationScheme,
|
||||
It.Is<ClaimsPrincipal>(i => i.FindFirstValue(ClaimTypes.AuthenticationMethod) == loginProvider
|
||||
&& i.FindFirstValue(ClaimTypes.NameIdentifier) == user.Id),
|
||||
It.IsAny<AuthenticationProperties>())).Returns(Task.FromResult(0)).Verifiable();
|
||||
auth.Setup(a => a.SignOutAsync(helper.Options.Cookies.ExternalCookieAuthenticationScheme)).Returns(Task.FromResult(0)).Verifiable();
|
||||
auth.Setup(a => a.SignOutAsync(helper.Options.Cookies.TwoFactorUserIdCookieAuthenticationScheme)).Returns(Task.FromResult(0)).Verifiable();
|
||||
auth.Setup(a => a.SignOutAsync(context, helper.Options.Cookies.ExternalCookieAuthenticationScheme, It.IsAny<AuthenticationProperties>())).Returns(Task.FromResult(0)).Verifiable();
|
||||
auth.Setup(a => a.SignOutAsync(context, helper.Options.Cookies.TwoFactorUserIdCookieAuthenticationScheme, It.IsAny<AuthenticationProperties>())).Returns(Task.FromResult(0)).Verifiable();
|
||||
}
|
||||
else
|
||||
{
|
||||
SetupSignIn(auth, user.Id);
|
||||
SetupSignIn(context, auth, user.Id);
|
||||
}
|
||||
auth.Setup(a => a.AuthenticateAsync(helper.Options.Cookies.TwoFactorUserIdCookieAuthenticationScheme)).ReturnsAsync(id).Verifiable();
|
||||
context.Setup(c => c.Authentication).Returns(auth.Object).Verifiable();
|
||||
auth.Setup(a => a.AuthenticateAsync(context, helper.Options.Cookies.TwoFactorUserIdCookieAuthenticationScheme))
|
||||
.ReturnsAsync(AuthenticateResult.Success(new AuthenticationTicket(id, null, helper.Options.Cookies.TwoFactorUserIdCookieAuthenticationScheme))).Verifiable();
|
||||
|
||||
// Act
|
||||
var result = await helper.TwoFactorRecoveryCodeSignInAsync(bypassCode);
|
||||
|
|
@ -461,7 +452,6 @@ namespace Microsoft.AspNetCore.Identity.Test
|
|||
// Assert
|
||||
Assert.True(result.Succeeded);
|
||||
manager.Verify();
|
||||
context.Verify();
|
||||
auth.Verify();
|
||||
}
|
||||
|
||||
|
|
@ -484,11 +474,10 @@ namespace Microsoft.AspNetCore.Identity.Test
|
|||
}
|
||||
manager.Setup(m => m.FindByLoginAsync(loginProvider, providerKey)).ReturnsAsync(user).Verifiable();
|
||||
|
||||
var context = new Mock<HttpContext>();
|
||||
var auth = new Mock<AuthenticationManager>();
|
||||
context.Setup(c => c.Authentication).Returns(auth.Object).Verifiable();
|
||||
SetupSignIn(auth, user.Id, isPersistent, loginProvider);
|
||||
var helper = SetupSignInManager(manager.Object, context.Object);
|
||||
var context = new DefaultHttpContext();
|
||||
var auth = MockAuth(context);
|
||||
var helper = SetupSignInManager(manager.Object, context);
|
||||
SetupSignIn(context, auth, user.Id, isPersistent, loginProvider);
|
||||
|
||||
// Act
|
||||
var result = await helper.ExternalLoginSignInAsync(loginProvider, providerKey, isPersistent);
|
||||
|
|
@ -496,7 +485,6 @@ namespace Microsoft.AspNetCore.Identity.Test
|
|||
// Assert
|
||||
Assert.True(result.Succeeded);
|
||||
manager.Verify();
|
||||
context.Verify();
|
||||
auth.Verify();
|
||||
}
|
||||
|
||||
|
|
@ -509,9 +497,8 @@ namespace Microsoft.AspNetCore.Identity.Test
|
|||
{
|
||||
// Setup
|
||||
var user = new TestUser { UserName = "Foo" };
|
||||
var context = new Mock<HttpContext>();
|
||||
var auth = new Mock<AuthenticationManager>();
|
||||
context.Setup(c => c.Authentication).Returns(auth.Object).Verifiable();
|
||||
var context = new DefaultHttpContext();
|
||||
var auth = MockAuth(context);
|
||||
var loginProvider = "loginprovider";
|
||||
var id = new ClaimsIdentity();
|
||||
if (externalLogin)
|
||||
|
|
@ -520,24 +507,24 @@ namespace Microsoft.AspNetCore.Identity.Test
|
|||
}
|
||||
// REVIEW: auth changes we lost the ability to mock is persistent
|
||||
//var properties = new AuthenticationProperties { IsPersistent = isPersistent };
|
||||
auth.Setup(a => a.AuthenticateAsync(It.Is<AuthenticateContext>(c => c.AuthenticationScheme == new IdentityCookieOptions().ApplicationCookieAuthenticationScheme)))
|
||||
.Returns(Task.FromResult(0)).Verifiable();
|
||||
var authResult = AuthenticateResult.None();
|
||||
auth.Setup(a => a.AuthenticateAsync(context, new IdentityCookieOptions().ApplicationCookieAuthenticationScheme))
|
||||
.Returns(Task.FromResult(authResult)).Verifiable();
|
||||
var manager = SetupUserManager(user);
|
||||
var signInManager = new Mock<SignInManager<TestUser>>(manager.Object,
|
||||
new HttpContextAccessor { HttpContext = context.Object },
|
||||
new HttpContextAccessor { HttpContext = context },
|
||||
new Mock<IUserClaimsPrincipalFactory<TestUser>>().Object,
|
||||
null, null)
|
||||
{ CallBase = true };
|
||||
//signInManager.Setup(s => s.SignInAsync(user, It.Is<AuthenticationProperties>(p => p.IsPersistent == isPersistent),
|
||||
//externalLogin? loginProvider : null)).Returns(Task.FromResult(0)).Verifiable();
|
||||
signInManager.Setup(s => s.SignInAsync(user, It.IsAny<AuthenticationProperties>(), null)).Returns(Task.FromResult(0)).Verifiable();
|
||||
signInManager.Object.Context = context.Object;
|
||||
signInManager.Object.Context = context;
|
||||
|
||||
// Act
|
||||
await signInManager.Object.RefreshSignInAsync(user);
|
||||
|
||||
// Assert
|
||||
context.Verify();
|
||||
auth.Verify();
|
||||
signInManager.Verify();
|
||||
}
|
||||
|
|
@ -573,39 +560,39 @@ namespace Microsoft.AspNetCore.Identity.Test
|
|||
manager.Setup(m => m.ResetAccessFailedCountAsync(user)).ReturnsAsync(IdentityResult.Success).Verifiable();
|
||||
}
|
||||
manager.Setup(m => m.VerifyTwoFactorTokenAsync(user, provider, code)).ReturnsAsync(true).Verifiable();
|
||||
var context = new Mock<HttpContext>();
|
||||
var auth = new Mock<AuthenticationManager>();
|
||||
var context = new DefaultHttpContext();
|
||||
var auth = MockAuth(context);
|
||||
var helper = SetupSignInManager(manager.Object, context);
|
||||
var twoFactorInfo = new SignInManager<TestUser>.TwoFactorAuthenticationInfo { UserId = user.Id };
|
||||
var loginProvider = "loginprovider";
|
||||
var helper = SetupSignInManager(manager.Object, context.Object);
|
||||
var id = helper.StoreTwoFactorInfo(user.Id, externalLogin ? loginProvider : null);
|
||||
if (externalLogin)
|
||||
{
|
||||
auth.Setup(a => a.SignInAsync(
|
||||
auth.Setup(a => a.SignInAsync(context,
|
||||
helper.Options.Cookies.ApplicationCookieAuthenticationScheme,
|
||||
It.Is<ClaimsPrincipal>(i => i.FindFirstValue(ClaimTypes.AuthenticationMethod) == loginProvider
|
||||
&& i.FindFirstValue(ClaimTypes.NameIdentifier) == user.Id),
|
||||
It.IsAny<AuthenticationProperties>())).Returns(Task.FromResult(0)).Verifiable();
|
||||
// REVIEW: restore ability to test is persistent
|
||||
//It.Is<AuthenticationProperties>(v => v.IsPersistent == isPersistent))).Verifiable();
|
||||
auth.Setup(a => a.SignOutAsync(helper.Options.Cookies.ExternalCookieAuthenticationScheme)).Returns(Task.FromResult(0)).Verifiable();
|
||||
auth.Setup(a => a.SignOutAsync(helper.Options.Cookies.TwoFactorUserIdCookieAuthenticationScheme)).Returns(Task.FromResult(0)).Verifiable();
|
||||
auth.Setup(a => a.SignOutAsync(context, helper.Options.Cookies.ExternalCookieAuthenticationScheme, It.IsAny<AuthenticationProperties>())).Returns(Task.FromResult(0)).Verifiable();
|
||||
auth.Setup(a => a.SignOutAsync(context, helper.Options.Cookies.TwoFactorUserIdCookieAuthenticationScheme, It.IsAny<AuthenticationProperties>())).Returns(Task.FromResult(0)).Verifiable();
|
||||
}
|
||||
else
|
||||
{
|
||||
SetupSignIn(auth, user.Id);
|
||||
SetupSignIn(context, auth, user.Id);
|
||||
}
|
||||
if (rememberClient)
|
||||
{
|
||||
auth.Setup(a => a.SignInAsync(
|
||||
auth.Setup(a => a.SignInAsync(context,
|
||||
helper.Options.Cookies.TwoFactorRememberMeCookieAuthenticationScheme,
|
||||
It.Is<ClaimsPrincipal>(i => i.FindFirstValue(ClaimTypes.Name) == user.Id
|
||||
&& i.Identities.First().AuthenticationType == helper.Options.Cookies.TwoFactorRememberMeCookieAuthenticationScheme),
|
||||
It.IsAny<AuthenticationProperties>())).Returns(Task.FromResult(0)).Verifiable();
|
||||
//It.Is<AuthenticationProperties>(v => v.IsPersistent == true))).Returns(Task.FromResult(0)).Verifiable();
|
||||
}
|
||||
auth.Setup(a => a.AuthenticateAsync(helper.Options.Cookies.TwoFactorUserIdCookieAuthenticationScheme)).ReturnsAsync(id).Verifiable();
|
||||
context.Setup(c => c.Authentication).Returns(auth.Object).Verifiable();
|
||||
auth.Setup(a => a.AuthenticateAsync(context, helper.Options.Cookies.TwoFactorUserIdCookieAuthenticationScheme))
|
||||
.ReturnsAsync(AuthenticateResult.Success(new AuthenticationTicket(id, null, helper.Options.Cookies.TwoFactorUserIdCookieAuthenticationScheme))).Verifiable();
|
||||
|
||||
// Act
|
||||
var result = await helper.TwoFactorSignInAsync(provider, code, isPersistent, rememberClient);
|
||||
|
|
@ -613,7 +600,6 @@ namespace Microsoft.AspNetCore.Identity.Test
|
|||
// Assert
|
||||
Assert.True(result.Succeeded);
|
||||
manager.Verify();
|
||||
context.Verify();
|
||||
auth.Verify();
|
||||
}
|
||||
|
||||
|
|
@ -623,23 +609,22 @@ namespace Microsoft.AspNetCore.Identity.Test
|
|||
// Setup
|
||||
var user = new TestUser { UserName = "Foo" };
|
||||
var manager = SetupUserManager(user);
|
||||
var context = new Mock<HttpContext>();
|
||||
var auth = new Mock<AuthenticationManager>();
|
||||
context.Setup(c => c.Authentication).Returns(auth.Object).Verifiable();
|
||||
var context = new DefaultHttpContext();
|
||||
var auth = MockAuth(context);
|
||||
var helper = SetupSignInManager(manager.Object, context);
|
||||
auth.Setup(a => a.SignInAsync(
|
||||
context,
|
||||
manager.Object.Options.Cookies.TwoFactorRememberMeCookieAuthenticationScheme,
|
||||
It.Is<ClaimsPrincipal>(i => i.FindFirstValue(ClaimTypes.Name) == user.Id
|
||||
&& i.Identities.First().AuthenticationType == manager.Object.Options.Cookies.TwoFactorRememberMeCookieAuthenticationScheme),
|
||||
It.Is<AuthenticationProperties>(v => v.IsPersistent == true))).Returns(Task.FromResult(0)).Verifiable();
|
||||
|
||||
var helper = SetupSignInManager(manager.Object, context.Object);
|
||||
|
||||
// Act
|
||||
await helper.RememberTwoFactorClientAsync(user);
|
||||
|
||||
// Assert
|
||||
manager.Verify();
|
||||
context.Verify();
|
||||
auth.Verify();
|
||||
}
|
||||
|
||||
|
|
@ -659,14 +644,14 @@ namespace Microsoft.AspNetCore.Identity.Test
|
|||
manager.Setup(m => m.SupportsUserTwoFactor).Returns(true).Verifiable();
|
||||
manager.Setup(m => m.IsLockedOutAsync(user)).ReturnsAsync(false).Verifiable();
|
||||
manager.Setup(m => m.CheckPasswordAsync(user, "password")).ReturnsAsync(true).Verifiable();
|
||||
var context = new Mock<HttpContext>();
|
||||
var auth = new Mock<AuthenticationManager>();
|
||||
context.Setup(c => c.Authentication).Returns(auth.Object).Verifiable();
|
||||
SetupSignIn(auth);
|
||||
var context = new DefaultHttpContext();
|
||||
var auth = MockAuth(context);
|
||||
SetupSignIn(context, auth);
|
||||
var id = new ClaimsIdentity(manager.Object.Options.Cookies.TwoFactorRememberMeCookieAuthenticationScheme);
|
||||
id.AddClaim(new Claim(ClaimTypes.Name, user.Id));
|
||||
auth.Setup(a => a.AuthenticateAsync(manager.Object.Options.Cookies.TwoFactorRememberMeCookieAuthenticationScheme)).ReturnsAsync(new ClaimsPrincipal(id)).Verifiable();
|
||||
var helper = SetupSignInManager(manager.Object, context.Object);
|
||||
auth.Setup(a => a.AuthenticateAsync(context, manager.Object.Options.Cookies.TwoFactorRememberMeCookieAuthenticationScheme))
|
||||
.ReturnsAsync(AuthenticateResult.Success(new AuthenticationTicket(new ClaimsPrincipal(id), null, manager.Object.Options.Cookies.TwoFactorRememberMeCookieAuthenticationScheme))).Verifiable();
|
||||
var helper = SetupSignInManager(manager.Object, context);
|
||||
|
||||
// Act
|
||||
var result = await helper.PasswordSignInAsync(user.UserName, "password", isPersistent, false);
|
||||
|
|
@ -674,10 +659,16 @@ namespace Microsoft.AspNetCore.Identity.Test
|
|||
// Assert
|
||||
Assert.True(result.Succeeded);
|
||||
manager.Verify();
|
||||
context.Verify();
|
||||
auth.Verify();
|
||||
}
|
||||
|
||||
private Mock<IAuthenticationService> MockAuth(HttpContext context)
|
||||
{
|
||||
var auth = new Mock<IAuthenticationService>();
|
||||
context.RequestServices = new ServiceCollection().AddSingleton(auth.Object).BuildServiceProvider();
|
||||
return auth;
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("Microsoft.AspNetCore.Identity.Authentication.Application")]
|
||||
[InlineData("Foo")]
|
||||
|
|
@ -685,20 +676,18 @@ namespace Microsoft.AspNetCore.Identity.Test
|
|||
{
|
||||
// Setup
|
||||
var manager = MockHelpers.TestUserManager<TestUser>();
|
||||
manager.Options.Cookies.ApplicationCookie.AuthenticationScheme = authenticationScheme;
|
||||
var context = new Mock<HttpContext>();
|
||||
var auth = new Mock<AuthenticationManager>();
|
||||
context.Setup(c => c.Authentication).Returns(auth.Object).Verifiable();
|
||||
auth.Setup(a => a.SignOutAsync(authenticationScheme)).Returns(Task.FromResult(0)).Verifiable();
|
||||
auth.Setup(a => a.SignOutAsync(manager.Options.Cookies.TwoFactorUserIdCookieAuthenticationScheme)).Returns(Task.FromResult(0)).Verifiable();
|
||||
auth.Setup(a => a.SignOutAsync(manager.Options.Cookies.ExternalCookieAuthenticationScheme)).Returns(Task.FromResult(0)).Verifiable();
|
||||
var helper = SetupSignInManager(manager, context.Object, null, manager.Options);
|
||||
manager.Options.Cookies.ApplicationCookieAuthenticationScheme = authenticationScheme;
|
||||
var context = new DefaultHttpContext();
|
||||
var auth = MockAuth(context);
|
||||
auth.Setup(a => a.SignOutAsync(context, authenticationScheme, It.IsAny<AuthenticationProperties>())).Returns(Task.FromResult(0)).Verifiable();
|
||||
auth.Setup(a => a.SignOutAsync(context, manager.Options.Cookies.TwoFactorUserIdCookieAuthenticationScheme, It.IsAny<AuthenticationProperties>())).Returns(Task.FromResult(0)).Verifiable();
|
||||
auth.Setup(a => a.SignOutAsync(context, manager.Options.Cookies.ExternalCookieAuthenticationScheme, It.IsAny<AuthenticationProperties>())).Returns(Task.FromResult(0)).Verifiable();
|
||||
var helper = SetupSignInManager(manager, context, null, manager.Options);
|
||||
|
||||
// Act
|
||||
await helper.SignOutAsync();
|
||||
|
||||
// Assert
|
||||
context.Verify();
|
||||
auth.Verify();
|
||||
}
|
||||
|
||||
|
|
@ -811,18 +800,17 @@ namespace Microsoft.AspNetCore.Identity.Test
|
|||
{
|
||||
manager.Setup(m => m.CheckPasswordAsync(user, "password")).ReturnsAsync(true).Verifiable();
|
||||
}
|
||||
var context = new Mock<HttpContext>();
|
||||
var auth = new Mock<AuthenticationManager>();
|
||||
var context = new DefaultHttpContext();
|
||||
var auth = MockAuth(context);
|
||||
if (confirmed)
|
||||
{
|
||||
manager.Setup(m => m.CheckPasswordAsync(user, "password")).ReturnsAsync(true).Verifiable();
|
||||
context.Setup(c => c.Authentication).Returns(auth.Object).Verifiable();
|
||||
SetupSignIn(auth);
|
||||
SetupSignIn(context, auth);
|
||||
}
|
||||
var identityOptions = new IdentityOptions();
|
||||
identityOptions.SignIn.RequireConfirmedEmail = true;
|
||||
var logStore = new StringBuilder();
|
||||
var helper = SetupSignInManager(manager.Object, context.Object, logStore, identityOptions);
|
||||
var helper = SetupSignInManager(manager.Object, context, logStore, identityOptions);
|
||||
|
||||
// Act
|
||||
var result = await helper.PasswordSignInAsync(user, "password", false, false);
|
||||
|
|
@ -834,13 +822,13 @@ namespace Microsoft.AspNetCore.Identity.Test
|
|||
Assert.Equal(confirmed, !logStore.ToString().Contains($"User {user.Id} cannot sign in without a confirmed email."));
|
||||
|
||||
manager.Verify();
|
||||
context.Verify();
|
||||
auth.Verify();
|
||||
}
|
||||
|
||||
private static void SetupSignIn(Mock<AuthenticationManager> auth, string userId = null, bool? isPersistent = null, string loginProvider = null)
|
||||
private static void SetupSignIn(HttpContext context, Mock<IAuthenticationService> auth, string userId = null, bool? isPersistent = null, string loginProvider = null)
|
||||
{
|
||||
auth.Setup(a => a.SignInAsync(new IdentityCookieOptions().ApplicationCookieAuthenticationScheme,
|
||||
auth.Setup(a => a.SignInAsync(context,
|
||||
new IdentityCookieOptions().ApplicationCookieAuthenticationScheme,
|
||||
It.Is<ClaimsPrincipal>(id =>
|
||||
(userId == null || id.FindFirstValue(ClaimTypes.NameIdentifier) == userId) &&
|
||||
(loginProvider == null || id.FindFirstValue(ClaimTypes.AuthenticationMethod) == loginProvider)),
|
||||
|
|
@ -856,19 +844,18 @@ namespace Microsoft.AspNetCore.Identity.Test
|
|||
var user = new TestUser { UserName = "Foo" };
|
||||
var manager = SetupUserManager(user);
|
||||
manager.Setup(m => m.IsPhoneNumberConfirmedAsync(user)).ReturnsAsync(confirmed).Verifiable();
|
||||
var context = new Mock<HttpContext>();
|
||||
var auth = new Mock<AuthenticationManager>();
|
||||
var context = new DefaultHttpContext();
|
||||
var auth = MockAuth(context);
|
||||
if (confirmed)
|
||||
{
|
||||
manager.Setup(m => m.CheckPasswordAsync(user, "password")).ReturnsAsync(true).Verifiable();
|
||||
context.Setup(c => c.Authentication).Returns(auth.Object).Verifiable();
|
||||
SetupSignIn(auth);
|
||||
SetupSignIn(context, auth);
|
||||
}
|
||||
|
||||
var identityOptions = new IdentityOptions();
|
||||
identityOptions.SignIn.RequireConfirmedPhoneNumber = true;
|
||||
var logStore = new StringBuilder();
|
||||
var helper = SetupSignInManager(manager.Object, context.Object, logStore, identityOptions);
|
||||
var helper = SetupSignInManager(manager.Object, context, logStore, identityOptions);
|
||||
|
||||
// Act
|
||||
var result = await helper.PasswordSignInAsync(user, "password", false, false);
|
||||
|
|
@ -878,7 +865,6 @@ namespace Microsoft.AspNetCore.Identity.Test
|
|||
Assert.NotEqual(confirmed, result.IsNotAllowed);
|
||||
Assert.Equal(confirmed, !logStore.ToString().Contains($"User {user.Id} cannot sign in without a confirmed phone number."));
|
||||
manager.Verify();
|
||||
context.Verify();
|
||||
auth.Verify();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ using System.Text;
|
|||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Moq;
|
||||
using Xunit;
|
||||
|
|
@ -21,7 +22,9 @@ namespace Microsoft.AspNetCore.Identity.Test
|
|||
[Fact]
|
||||
public void EnsureDefaultServicesDefaultsWithStoreWorks()
|
||||
{
|
||||
var config = new ConfigurationBuilder().Build();
|
||||
var services = new ServiceCollection()
|
||||
.AddSingleton<IConfiguration>(config)
|
||||
.AddTransient<IUserStore<TestUser>, NoopUserStore>();
|
||||
services.AddIdentity<TestUser, TestRole>();
|
||||
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
|
||||
|
|
@ -35,7 +38,9 @@ namespace Microsoft.AspNetCore.Identity.Test
|
|||
[Fact]
|
||||
public void AddUserManagerWithCustomManagerReturnsSameInstance()
|
||||
{
|
||||
var config = new ConfigurationBuilder().Build();
|
||||
var services = new ServiceCollection()
|
||||
.AddSingleton<IConfiguration>(config)
|
||||
.AddTransient<IUserStore<TestUser>, NoopUserStore>()
|
||||
.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
|
||||
|
||||
|
|
@ -682,10 +687,13 @@ namespace Microsoft.AspNetCore.Identity.Test
|
|||
[Fact]
|
||||
public void UserManagerWillUseTokenProviderInstance()
|
||||
{
|
||||
var services = new ServiceCollection();
|
||||
var provider = new ATokenProvider();
|
||||
services.AddLogging()
|
||||
.AddIdentity<TestUser, TestRole>(o => o.Tokens.ProviderMap.Add("A", new TokenProviderDescriptor(typeof(ATokenProvider))
|
||||
var config = new ConfigurationBuilder().Build();
|
||||
var services = new ServiceCollection()
|
||||
.AddSingleton<IConfiguration>(config)
|
||||
.AddLogging();
|
||||
|
||||
services.AddIdentity<TestUser, TestRole>(o => o.Tokens.ProviderMap.Add("A", new TokenProviderDescriptor(typeof(ATokenProvider))
|
||||
{
|
||||
ProviderInstance = provider
|
||||
})).AddUserStore<NoopUserStore>();
|
||||
|
|
@ -836,10 +844,13 @@ namespace Microsoft.AspNetCore.Identity.Test
|
|||
[Fact]
|
||||
public void UserManagerWillUseTokenProviderInstanceOverDefaults()
|
||||
{
|
||||
var services = new ServiceCollection();
|
||||
var provider = new ATokenProvider();
|
||||
services.AddLogging()
|
||||
.AddIdentity<TestUser, TestRole>(o => o.Tokens.ProviderMap.Add(TokenOptions.DefaultProvider, new TokenProviderDescriptor(typeof(ATokenProvider))
|
||||
var config = new ConfigurationBuilder().Build();
|
||||
var services = new ServiceCollection()
|
||||
.AddSingleton<IConfiguration>(config)
|
||||
.AddLogging();
|
||||
|
||||
services.AddIdentity<TestUser, TestRole>(o => o.Tokens.ProviderMap.Add(TokenOptions.DefaultProvider, new TokenProviderDescriptor(typeof(ATokenProvider))
|
||||
{
|
||||
ProviderInstance = provider
|
||||
})).AddUserStore<NoopUserStore>().AddDefaultTokenProviders();
|
||||
|
|
@ -1668,14 +1679,17 @@ namespace Microsoft.AspNetCore.Identity.Test
|
|||
[Fact]
|
||||
public async Task CanCustomizeUserValidatorErrors()
|
||||
{
|
||||
var services = new ServiceCollection();
|
||||
var store = new Mock<IUserEmailStore<TestUser>>();
|
||||
var describer = new TestErrorDescriber();
|
||||
services.AddSingleton<IdentityErrorDescriber>(describer)
|
||||
.AddSingleton<IUserStore<TestUser>>(store.Object)
|
||||
.AddIdentity<TestUser, TestRole>();
|
||||
services.AddLogging();
|
||||
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
|
||||
var config = new ConfigurationBuilder().Build();
|
||||
var services = new ServiceCollection()
|
||||
.AddSingleton<IConfiguration>(config)
|
||||
.AddLogging()
|
||||
.AddSingleton<IdentityErrorDescriber>(describer)
|
||||
.AddSingleton<IUserStore<TestUser>>(store.Object)
|
||||
.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
|
||||
|
||||
services.AddIdentity<TestUser, TestRole>();
|
||||
|
||||
var manager = services.BuildServiceProvider().GetRequiredService<UserManager<TestUser>>();
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue