[Identity] Guard against null user security stamps (#8300)
Also fix up some UI issues
This commit is contained in:
parent
3657a429eb
commit
79beaea734
|
|
@ -94,8 +94,9 @@ namespace Microsoft.AspNetCore.Identity
|
||||||
}
|
}
|
||||||
public partial class SecurityStampValidator<TUser> : Microsoft.AspNetCore.Identity.ISecurityStampValidator where TUser : class
|
public partial class SecurityStampValidator<TUser> : Microsoft.AspNetCore.Identity.ISecurityStampValidator where TUser : class
|
||||||
{
|
{
|
||||||
public SecurityStampValidator(Microsoft.Extensions.Options.IOptions<Microsoft.AspNetCore.Identity.SecurityStampValidatorOptions> options, Microsoft.AspNetCore.Identity.SignInManager<TUser> signInManager, Microsoft.AspNetCore.Authentication.ISystemClock clock) { }
|
public SecurityStampValidator(Microsoft.Extensions.Options.IOptions<Microsoft.AspNetCore.Identity.SecurityStampValidatorOptions> options, Microsoft.AspNetCore.Identity.SignInManager<TUser> signInManager, Microsoft.AspNetCore.Authentication.ISystemClock clock, Microsoft.Extensions.Logging.ILoggerFactory logger) { }
|
||||||
public Microsoft.AspNetCore.Authentication.ISystemClock Clock { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } }
|
public Microsoft.AspNetCore.Authentication.ISystemClock Clock { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } }
|
||||||
|
public Microsoft.Extensions.Logging.ILogger Logger { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
|
||||||
public Microsoft.AspNetCore.Identity.SecurityStampValidatorOptions Options { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } }
|
public Microsoft.AspNetCore.Identity.SecurityStampValidatorOptions Options { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } }
|
||||||
public Microsoft.AspNetCore.Identity.SignInManager<TUser> SignInManager { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } }
|
public Microsoft.AspNetCore.Identity.SignInManager<TUser> SignInManager { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } }
|
||||||
[System.Diagnostics.DebuggerStepThroughAttribute]
|
[System.Diagnostics.DebuggerStepThroughAttribute]
|
||||||
|
|
@ -171,7 +172,7 @@ namespace Microsoft.AspNetCore.Identity
|
||||||
}
|
}
|
||||||
public partial class TwoFactorSecurityStampValidator<TUser> : Microsoft.AspNetCore.Identity.SecurityStampValidator<TUser>, Microsoft.AspNetCore.Identity.ISecurityStampValidator, Microsoft.AspNetCore.Identity.ITwoFactorSecurityStampValidator where TUser : class
|
public partial class TwoFactorSecurityStampValidator<TUser> : Microsoft.AspNetCore.Identity.SecurityStampValidator<TUser>, Microsoft.AspNetCore.Identity.ISecurityStampValidator, Microsoft.AspNetCore.Identity.ITwoFactorSecurityStampValidator where TUser : class
|
||||||
{
|
{
|
||||||
public TwoFactorSecurityStampValidator(Microsoft.Extensions.Options.IOptions<Microsoft.AspNetCore.Identity.SecurityStampValidatorOptions> options, Microsoft.AspNetCore.Identity.SignInManager<TUser> signInManager, Microsoft.AspNetCore.Authentication.ISystemClock clock) : base (default(Microsoft.Extensions.Options.IOptions<Microsoft.AspNetCore.Identity.SecurityStampValidatorOptions>), default(Microsoft.AspNetCore.Identity.SignInManager<TUser>), default(Microsoft.AspNetCore.Authentication.ISystemClock)) { }
|
public TwoFactorSecurityStampValidator(Microsoft.Extensions.Options.IOptions<Microsoft.AspNetCore.Identity.SecurityStampValidatorOptions> options, Microsoft.AspNetCore.Identity.SignInManager<TUser> signInManager, Microsoft.AspNetCore.Authentication.ISystemClock clock, Microsoft.Extensions.Logging.ILoggerFactory logger) : base (default(Microsoft.Extensions.Options.IOptions<Microsoft.AspNetCore.Identity.SecurityStampValidatorOptions>), default(Microsoft.AspNetCore.Identity.SignInManager<TUser>), default(Microsoft.AspNetCore.Authentication.ISystemClock), default(Microsoft.Extensions.Logging.ILoggerFactory)) { }
|
||||||
protected override System.Threading.Tasks.Task SecurityStampVerified(TUser user, Microsoft.AspNetCore.Authentication.Cookies.CookieValidatePrincipalContext context) { throw null; }
|
protected override System.Threading.Tasks.Task SecurityStampVerified(TUser user, Microsoft.AspNetCore.Authentication.Cookies.CookieValidatePrincipalContext context) { throw null; }
|
||||||
protected override System.Threading.Tasks.Task<TUser> VerifySecurityStamp(System.Security.Claims.ClaimsPrincipal principal) { throw null; }
|
protected override System.Threading.Tasks.Task<TUser> VerifySecurityStamp(System.Security.Claims.ClaimsPrincipal principal) { throw null; }
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ using System.Threading.Tasks;
|
||||||
using Microsoft.AspNetCore.Authentication;
|
using Microsoft.AspNetCore.Authentication;
|
||||||
using Microsoft.AspNetCore.Authentication.Cookies;
|
using Microsoft.AspNetCore.Authentication.Cookies;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Identity
|
namespace Microsoft.AspNetCore.Identity
|
||||||
|
|
@ -23,7 +24,8 @@ namespace Microsoft.AspNetCore.Identity
|
||||||
/// <param name="options">Used to access the <see cref="IdentityOptions"/>.</param>
|
/// <param name="options">Used to access the <see cref="IdentityOptions"/>.</param>
|
||||||
/// <param name="signInManager">The <see cref="SignInManager{TUser}"/>.</param>
|
/// <param name="signInManager">The <see cref="SignInManager{TUser}"/>.</param>
|
||||||
/// <param name="clock">The system clock.</param>
|
/// <param name="clock">The system clock.</param>
|
||||||
public SecurityStampValidator(IOptions<SecurityStampValidatorOptions> options, SignInManager<TUser> signInManager, ISystemClock clock)
|
/// <param name="logger">The logger.</param>
|
||||||
|
public SecurityStampValidator(IOptions<SecurityStampValidatorOptions> options, SignInManager<TUser> signInManager, ISystemClock clock, ILoggerFactory logger)
|
||||||
{
|
{
|
||||||
if (options == null)
|
if (options == null)
|
||||||
{
|
{
|
||||||
|
|
@ -36,6 +38,7 @@ namespace Microsoft.AspNetCore.Identity
|
||||||
SignInManager = signInManager;
|
SignInManager = signInManager;
|
||||||
Options = options.Value;
|
Options = options.Value;
|
||||||
Clock = clock;
|
Clock = clock;
|
||||||
|
Logger = logger.CreateLogger(this.GetType().FullName);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -53,6 +56,14 @@ namespace Microsoft.AspNetCore.Identity
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public ISystemClock Clock { get; }
|
public ISystemClock Clock { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the <see cref="ILogger"/> used to log messages.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>
|
||||||
|
/// The <see cref="ILogger"/> used to log messages.
|
||||||
|
/// </value>
|
||||||
|
public ILogger Logger { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Called when the security stamp has been verified.
|
/// Called when the security stamp has been verified.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -121,6 +132,7 @@ namespace Microsoft.AspNetCore.Identity
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
Logger.LogDebug(0, "Security stamp validation failed, rejecting cookie.");
|
||||||
context.RejectPrincipal();
|
context.RejectPrincipal();
|
||||||
await SignInManager.SignOutAsync();
|
await SignInManager.SignOutAsync();
|
||||||
}
|
}
|
||||||
|
|
@ -163,4 +175,4 @@ namespace Microsoft.AspNetCore.Identity
|
||||||
return validator.ValidateAsync(context);
|
return validator.ValidateAsync(context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -233,6 +233,7 @@ namespace Microsoft.AspNetCore.Identity
|
||||||
{
|
{
|
||||||
return user;
|
return user;
|
||||||
}
|
}
|
||||||
|
Logger.LogDebug(4, "Failed to validate a security stamp.");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -255,6 +256,7 @@ namespace Microsoft.AspNetCore.Identity
|
||||||
{
|
{
|
||||||
return user;
|
return user;
|
||||||
}
|
}
|
||||||
|
Logger.LogDebug(5, "Failed to validate a security stamp.");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ using System.Security.Claims;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNetCore.Authentication;
|
using Microsoft.AspNetCore.Authentication;
|
||||||
using Microsoft.AspNetCore.Authentication.Cookies;
|
using Microsoft.AspNetCore.Authentication.Cookies;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Identity
|
namespace Microsoft.AspNetCore.Identity
|
||||||
|
|
@ -21,7 +22,8 @@ namespace Microsoft.AspNetCore.Identity
|
||||||
/// <param name="options">Used to access the <see cref="IdentityOptions"/>.</param>
|
/// <param name="options">Used to access the <see cref="IdentityOptions"/>.</param>
|
||||||
/// <param name="signInManager">The <see cref="SignInManager{TUser}"/>.</param>
|
/// <param name="signInManager">The <see cref="SignInManager{TUser}"/>.</param>
|
||||||
/// <param name="clock">The system clock.</param>
|
/// <param name="clock">The system clock.</param>
|
||||||
public TwoFactorSecurityStampValidator(IOptions<SecurityStampValidatorOptions> options, SignInManager<TUser> signInManager, ISystemClock clock) : base(options, signInManager, clock)
|
/// <param name="logger">The logger.</param>
|
||||||
|
public TwoFactorSecurityStampValidator(IOptions<SecurityStampValidatorOptions> options, SignInManager<TUser> signInManager, ISystemClock clock, ILoggerFactory logger) : base(options, signInManager, clock, logger)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -41,4 +43,4 @@ namespace Microsoft.AspNetCore.Identity
|
||||||
protected override Task SecurityStampVerified(TUser user, CookieValidatePrincipalContext context)
|
protected override Task SecurityStampVerified(TUser user, CookieValidatePrincipalContext context)
|
||||||
=> Task.CompletedTask;
|
=> Task.CompletedTask;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -339,6 +339,20 @@ namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore.Test
|
||||||
Assert.Equal(2, (await manager.GetRolesAsync(userByLogin)).Count);
|
Assert.Equal(2, (await manager.GetRolesAsync(userByLogin)).Count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[ConditionalFact]
|
||||||
|
[FrameworkSkipCondition(RuntimeFrameworks.Mono)]
|
||||||
|
[OSSkipCondition(OperatingSystems.Linux)]
|
||||||
|
[OSSkipCondition(OperatingSystems.MacOSX)]
|
||||||
|
public async Task GetSecurityStampThrowsIfNull()
|
||||||
|
{
|
||||||
|
var manager = CreateManager();
|
||||||
|
var user = CreateTestUser();
|
||||||
|
var result = await manager.CreateAsync(user);
|
||||||
|
Assert.NotNull(user);
|
||||||
|
user.SecurityStamp = null;
|
||||||
|
await Assert.ThrowsAsync<InvalidOperationException>(async () => await manager.GetSecurityStampAsync(user));
|
||||||
|
}
|
||||||
|
|
||||||
[ConditionalFact]
|
[ConditionalFact]
|
||||||
[FrameworkSkipCondition(RuntimeFrameworks.Mono)]
|
[FrameworkSkipCondition(RuntimeFrameworks.Mono)]
|
||||||
[OSSkipCondition(OperatingSystems.Linux)]
|
[OSSkipCondition(OperatingSystems.Linux)]
|
||||||
|
|
|
||||||
|
|
@ -860,7 +860,13 @@ namespace Microsoft.AspNetCore.Identity
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException(nameof(user));
|
throw new ArgumentNullException(nameof(user));
|
||||||
}
|
}
|
||||||
return await securityStore.GetSecurityStampAsync(user, CancellationToken);
|
var stamp = await securityStore.GetSecurityStampAsync(user, CancellationToken);
|
||||||
|
if (stamp == null)
|
||||||
|
{
|
||||||
|
Logger.LogWarning(15, "GetSecurityStampAsync for user {userId} failed because stamp was null.", await GetUserIdAsync(user));
|
||||||
|
throw new InvalidOperationException(Resources.NullSecurityStamp);
|
||||||
|
}
|
||||||
|
return stamp;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@ namespace Microsoft.AspNetCore.Identity
|
||||||
public IdentityUser()
|
public IdentityUser()
|
||||||
{
|
{
|
||||||
Id = Guid.NewGuid().ToString();
|
Id = Guid.NewGuid().ToString();
|
||||||
|
SecurityStamp = Guid.NewGuid().ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
||||||
|
|
@ -274,25 +274,6 @@ namespace Microsoft.AspNetCore.Identity.Test
|
||||||
Assert.NotEqual(stamp, await manager.GetSecurityStampAsync(user));
|
Assert.NotEqual(stamp, await manager.GetSecurityStampAsync(user));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Test.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>Task</returns>
|
|
||||||
[Fact]
|
|
||||||
public async Task CreateUpdatesSecurityStamp()
|
|
||||||
{
|
|
||||||
if (ShouldSkipDbTests())
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var manager = CreateManager();
|
|
||||||
var username = "Create" + Guid.NewGuid().ToString();
|
|
||||||
var user = CreateTestUser(username, useNamePrefixAsUserName: true);
|
|
||||||
var stamp = await manager.GetSecurityStampAsync(user);
|
|
||||||
IdentityResultAssert.IsSuccess(await manager.CreateAsync(user));
|
|
||||||
Assert.NotEqual(stamp, await manager.GetSecurityStampAsync(user));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Test.
|
/// Test.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -965,10 +946,8 @@ namespace Microsoft.AspNetCore.Identity.Test
|
||||||
}
|
}
|
||||||
var manager = CreateManager();
|
var manager = CreateManager();
|
||||||
var user = CreateTestUser();
|
var user = CreateTestUser();
|
||||||
Assert.Null(await manager.GetSecurityStampAsync(user));
|
|
||||||
IdentityResultAssert.IsSuccess(await manager.CreateAsync(user));
|
IdentityResultAssert.IsSuccess(await manager.CreateAsync(user));
|
||||||
var stamp = await manager.GetSecurityStampAsync(user);
|
var stamp = await manager.GetSecurityStampAsync(user);
|
||||||
Assert.NotNull(stamp);
|
|
||||||
IdentityResultAssert.IsSuccess(await manager.UpdateSecurityStampAsync(user));
|
IdentityResultAssert.IsSuccess(await manager.UpdateSecurityStampAsync(user));
|
||||||
Assert.NotEqual(stamp, await manager.GetSecurityStampAsync(user));
|
Assert.NotEqual(stamp, await manager.GetSecurityStampAsync(user));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,11 +4,9 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Hosting;
|
|
||||||
using Microsoft.AspNetCore.Identity.UI.Services;
|
using Microsoft.AspNetCore.Identity.UI.Services;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.AspNetCore.Mvc.RazorPages;
|
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||||
using Microsoft.Extensions.Hosting;
|
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Identity.UI.V3.Pages.Account.Internal
|
namespace Microsoft.AspNetCore.Identity.UI.V3.Pages.Account.Internal
|
||||||
|
|
||||||
|
|
@ -49,13 +47,11 @@ namespace Microsoft.AspNetCore.Identity.UI.V3.Pages.Account.Internal
|
||||||
internal class RegisterConfirmationModel<TUser> : RegisterConfirmationModel where TUser : class
|
internal class RegisterConfirmationModel<TUser> : RegisterConfirmationModel where TUser : class
|
||||||
{
|
{
|
||||||
private readonly UserManager<TUser> _userManager;
|
private readonly UserManager<TUser> _userManager;
|
||||||
private readonly IWebHostEnvironment _hostingEnv;
|
|
||||||
private readonly IEmailSender _sender;
|
private readonly IEmailSender _sender;
|
||||||
|
|
||||||
public RegisterConfirmationModel(UserManager<TUser> userManager, IWebHostEnvironment hostingEnv, IEmailSender sender)
|
public RegisterConfirmationModel(UserManager<TUser> userManager, IEmailSender sender)
|
||||||
{
|
{
|
||||||
_userManager = userManager;
|
_userManager = userManager;
|
||||||
_hostingEnv = hostingEnv;
|
|
||||||
_sender = sender;
|
_sender = sender;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,7 @@
|
||||||
<input asp-for="Input.NewEmail" class="form-control" />
|
<input asp-for="Input.NewEmail" class="form-control" />
|
||||||
<span asp-validation-for="Input.NewEmail" class="text-danger"></span>
|
<span asp-validation-for="Input.NewEmail" class="text-danger"></span>
|
||||||
</div>
|
</div>
|
||||||
<button id="change-email-button" type="submit" class="btn btn-default">Change email</button>
|
<button id="change-email-button" type="submit" class="btn btn-primary">Change email</button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
ViewData["Title"] = "Register confirmation";
|
ViewData["Title"] = "Register confirmation";
|
||||||
}
|
}
|
||||||
|
|
||||||
<h2>@ViewData["Title"]</h2>
|
<h1>@ViewData["Title"]</h1>
|
||||||
@{
|
@{
|
||||||
if (@Model.DisplayConfirmAccountLink)
|
if (@Model.DisplayConfirmAccountLink)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -4,11 +4,9 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Hosting;
|
|
||||||
using Microsoft.AspNetCore.Identity.UI.Services;
|
using Microsoft.AspNetCore.Identity.UI.Services;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.AspNetCore.Mvc.RazorPages;
|
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||||
using Microsoft.Extensions.Hosting;
|
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Identity.UI.V4.Pages.Account.Internal
|
namespace Microsoft.AspNetCore.Identity.UI.V4.Pages.Account.Internal
|
||||||
|
|
||||||
|
|
@ -49,13 +47,11 @@ namespace Microsoft.AspNetCore.Identity.UI.V4.Pages.Account.Internal
|
||||||
internal class RegisterConfirmationModel<TUser> : RegisterConfirmationModel where TUser : class
|
internal class RegisterConfirmationModel<TUser> : RegisterConfirmationModel where TUser : class
|
||||||
{
|
{
|
||||||
private readonly UserManager<TUser> _userManager;
|
private readonly UserManager<TUser> _userManager;
|
||||||
private readonly IWebHostEnvironment _hostingEnv;
|
|
||||||
private readonly IEmailSender _sender;
|
private readonly IEmailSender _sender;
|
||||||
|
|
||||||
public RegisterConfirmationModel(UserManager<TUser> userManager, IWebHostEnvironment hostingEnv, IEmailSender sender)
|
public RegisterConfirmationModel(UserManager<TUser> userManager, IEmailSender sender)
|
||||||
{
|
{
|
||||||
_userManager = userManager;
|
_userManager = userManager;
|
||||||
_hostingEnv = hostingEnv;
|
|
||||||
_sender = sender;
|
_sender = sender;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -73,7 +69,7 @@ namespace Microsoft.AspNetCore.Identity.UI.V4.Pages.Account.Internal
|
||||||
}
|
}
|
||||||
|
|
||||||
Email = email;
|
Email = email;
|
||||||
// This sender is a no-op, so we should auto confirm the account
|
// If the email sender is a no-op, display the confirm link in the page
|
||||||
DisplayConfirmAccountLink = _sender is EmailSender;
|
DisplayConfirmAccountLink = _sender is EmailSender;
|
||||||
if (DisplayConfirmAccountLink)
|
if (DisplayConfirmAccountLink)
|
||||||
{
|
{
|
||||||
|
|
@ -84,7 +80,6 @@ namespace Microsoft.AspNetCore.Identity.UI.V4.Pages.Account.Internal
|
||||||
pageHandler: null,
|
pageHandler: null,
|
||||||
values: new { userId = userId, code = code },
|
values: new { userId = userId, code = code },
|
||||||
protocol: Request.Scheme);
|
protocol: Request.Scheme);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return Page();
|
return Page();
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ using Microsoft.AspNetCore.Authentication;
|
||||||
using Microsoft.AspNetCore.Authentication.Cookies;
|
using Microsoft.AspNetCore.Authentication.Cookies;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
using Moq;
|
using Moq;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
@ -117,7 +118,7 @@ namespace Microsoft.AspNetCore.Identity.Test
|
||||||
var services = new ServiceCollection();
|
var services = new ServiceCollection();
|
||||||
services.AddSingleton(options.Object);
|
services.AddSingleton(options.Object);
|
||||||
services.AddSingleton(signInManager.Object);
|
services.AddSingleton(signInManager.Object);
|
||||||
services.AddSingleton<ISecurityStampValidator>(new SecurityStampValidator<PocoUser>(options.Object, signInManager.Object, new SystemClock()));
|
services.AddSingleton<ISecurityStampValidator>(new SecurityStampValidator<PocoUser>(options.Object, signInManager.Object, new SystemClock(), new LoggerFactory()));
|
||||||
httpContext.Setup(c => c.RequestServices).Returns(services.BuildServiceProvider());
|
httpContext.Setup(c => c.RequestServices).Returns(services.BuildServiceProvider());
|
||||||
|
|
||||||
await testCode.Invoke();
|
await testCode.Invoke();
|
||||||
|
|
@ -171,7 +172,7 @@ namespace Microsoft.AspNetCore.Identity.Test
|
||||||
var services = new ServiceCollection();
|
var services = new ServiceCollection();
|
||||||
services.AddSingleton(options.Object);
|
services.AddSingleton(options.Object);
|
||||||
services.AddSingleton(signInManager);
|
services.AddSingleton(signInManager);
|
||||||
services.AddSingleton<ISecurityStampValidator>(new SecurityStampValidator<PocoUser>(options.Object, signInManager, new SystemClock()));
|
services.AddSingleton<ISecurityStampValidator>(new SecurityStampValidator<PocoUser>(options.Object, signInManager, new SystemClock(), new LoggerFactory()));
|
||||||
httpContext.Setup(c => c.RequestServices).Returns(services.BuildServiceProvider());
|
httpContext.Setup(c => c.RequestServices).Returns(services.BuildServiceProvider());
|
||||||
|
|
||||||
var tid = new ClaimsIdentity(IdentityConstants.ApplicationScheme);
|
var tid = new ClaimsIdentity(IdentityConstants.ApplicationScheme);
|
||||||
|
|
@ -210,7 +211,7 @@ namespace Microsoft.AspNetCore.Identity.Test
|
||||||
var services = new ServiceCollection();
|
var services = new ServiceCollection();
|
||||||
services.AddSingleton(options.Object);
|
services.AddSingleton(options.Object);
|
||||||
services.AddSingleton(signInManager.Object);
|
services.AddSingleton(signInManager.Object);
|
||||||
services.AddSingleton<ISecurityStampValidator>(new SecurityStampValidator<PocoUser>(options.Object, signInManager.Object, new SystemClock()));
|
services.AddSingleton<ISecurityStampValidator>(new SecurityStampValidator<PocoUser>(options.Object, signInManager.Object, new SystemClock(), new LoggerFactory()));
|
||||||
httpContext.Setup(c => c.RequestServices).Returns(services.BuildServiceProvider());
|
httpContext.Setup(c => c.RequestServices).Returns(services.BuildServiceProvider());
|
||||||
var id = new ClaimsIdentity(IdentityConstants.ApplicationScheme);
|
var id = new ClaimsIdentity(IdentityConstants.ApplicationScheme);
|
||||||
id.AddClaim(new Claim(ClaimTypes.NameIdentifier, user.Id));
|
id.AddClaim(new Claim(ClaimTypes.NameIdentifier, user.Id));
|
||||||
|
|
@ -247,7 +248,7 @@ namespace Microsoft.AspNetCore.Identity.Test
|
||||||
var services = new ServiceCollection();
|
var services = new ServiceCollection();
|
||||||
services.AddSingleton(options.Object);
|
services.AddSingleton(options.Object);
|
||||||
services.AddSingleton(signInManager.Object);
|
services.AddSingleton(signInManager.Object);
|
||||||
services.AddSingleton<ISecurityStampValidator>(new SecurityStampValidator<PocoUser>(options.Object, signInManager.Object, new SystemClock()));
|
services.AddSingleton<ISecurityStampValidator>(new SecurityStampValidator<PocoUser>(options.Object, signInManager.Object, new SystemClock(), new LoggerFactory()));
|
||||||
httpContext.Setup(c => c.RequestServices).Returns(services.BuildServiceProvider());
|
httpContext.Setup(c => c.RequestServices).Returns(services.BuildServiceProvider());
|
||||||
var id = new ClaimsIdentity(IdentityConstants.ApplicationScheme);
|
var id = new ClaimsIdentity(IdentityConstants.ApplicationScheme);
|
||||||
id.AddClaim(new Claim(ClaimTypes.NameIdentifier, user.Id));
|
id.AddClaim(new Claim(ClaimTypes.NameIdentifier, user.Id));
|
||||||
|
|
@ -283,7 +284,7 @@ namespace Microsoft.AspNetCore.Identity.Test
|
||||||
var services = new ServiceCollection();
|
var services = new ServiceCollection();
|
||||||
services.AddSingleton(options.Object);
|
services.AddSingleton(options.Object);
|
||||||
services.AddSingleton(signInManager.Object);
|
services.AddSingleton(signInManager.Object);
|
||||||
services.AddSingleton<ITwoFactorSecurityStampValidator>(new TwoFactorSecurityStampValidator<PocoUser>(options.Object, signInManager.Object, new SystemClock()));
|
services.AddSingleton<ITwoFactorSecurityStampValidator>(new TwoFactorSecurityStampValidator<PocoUser>(options.Object, signInManager.Object, new SystemClock(), new LoggerFactory()));
|
||||||
httpContext.Setup(c => c.RequestServices).Returns(services.BuildServiceProvider());
|
httpContext.Setup(c => c.RequestServices).Returns(services.BuildServiceProvider());
|
||||||
|
|
||||||
var principal = await signInManager.Object.StoreRememberClient(user);
|
var principal = await signInManager.Object.StoreRememberClient(user);
|
||||||
|
|
|
||||||
|
|
@ -84,6 +84,25 @@ namespace Microsoft.AspNetCore.Identity.Test
|
||||||
store.VerifyAll();
|
store.VerifyAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task CreateUpdatesSecurityStampStore()
|
||||||
|
{
|
||||||
|
// Setup
|
||||||
|
var store = new Mock<IUserSecurityStampStore<PocoUser>>();
|
||||||
|
var user = new PocoUser { UserName = "Foo", SecurityStamp = "sssss" };
|
||||||
|
store.Setup(s => s.CreateAsync(user, CancellationToken.None)).ReturnsAsync(IdentityResult.Success).Verifiable();
|
||||||
|
store.Setup(s => s.GetSecurityStampAsync(user, CancellationToken.None)).Returns(Task.FromResult(user.SecurityStamp)).Verifiable();
|
||||||
|
store.Setup(s => s.SetSecurityStampAsync(user, It.IsAny<string>(), CancellationToken.None)).Returns(Task.FromResult(0)).Verifiable();
|
||||||
|
var userManager = MockHelpers.TestUserManager<PocoUser>(store.Object);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = await userManager.CreateAsync(user);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.True(result.Succeeded);
|
||||||
|
store.VerifyAll();
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task CreateCallsUpdateEmailStore()
|
public async Task CreateCallsUpdateEmailStore()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue