Guard against null security stamps

This commit is contained in:
Hao Kung 2016-11-21 12:17:09 -08:00
parent 82893848dd
commit 4dd38e8ca8
6 changed files with 69 additions and 1 deletions

View File

@ -1247,6 +1247,10 @@ namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore
{
throw new ArgumentNullException(nameof(user));
}
if (stamp == null)
{
throw new ArgumentNullException(nameof(stamp));
}
user.SecurityStamp = stamp;
return TaskCache.CompletedTask;
}

View File

@ -14,7 +14,7 @@ namespace Microsoft.AspNetCore.Identity
/// <summary>
/// Returns the default <see cref="IdentityError"/>.
/// </summary>
/// <returns>The default <see cref="IdentityError"/>,</returns>
/// <returns>The default <see cref="IdentityError"/>.</returns>
public virtual IdentityError DefaultError()
{
return new IdentityError

View File

@ -250,6 +250,22 @@ namespace Microsoft.AspNetCore.Identity
return string.Format(CultureInfo.CurrentCulture, GetString("NoTokenProvider"), p0);
}
/// <summary>
/// User security stamp cannot be null.
/// </summary>
internal static string NullSecurityStamp
{
get { return GetString("NullSecurityStamp"); }
}
/// <summary>
/// User security stamp cannot be null.
/// </summary>
internal static string FormatNullSecurityStamp()
{
return GetString("NullSecurityStamp");
}
/// <summary>
/// Incorrect password.
/// </summary>

View File

@ -177,6 +177,10 @@
<value>No IUserTokenProvider named '{0}' is registered.</value>
<comment>Error when there is no IUserTokenProvider</comment>
</data>
<data name="NullSecurityStamp" xml:space="preserve">
<value>User security stamp cannot be null.</value>
<comment>Error when a user's security stamp is null.</comment>
</data>
<data name="PasswordMismatch" xml:space="preserve">
<value>Incorrect password.</value>
<comment>Error when a password doesn't match</comment>

View File

@ -2236,6 +2236,14 @@ namespace Microsoft.AspNetCore.Identity
private async Task<IdentityResult> ValidateUserInternal(TUser user)
{
if (SupportsUserSecurityStamp)
{
var stamp = await GetSecurityStampAsync(user);
if (stamp == null)
{
throw new InvalidOperationException(Resources.NullSecurityStamp);
}
}
var errors = new List<IdentityError>();
foreach (var v in UserValidators)
{

View File

@ -483,6 +483,42 @@ namespace Microsoft.AspNetCore.Identity.Test
hasher.VerifyAll();
}
[Fact]
public async Task CreateFailsWithNullSecurityStamp()
{
// Setup
var store = new Mock<IUserSecurityStampStore<TestUser>>();
var manager = MockHelpers.TestUserManager(store.Object);
var user = new TestUser { UserName = "nulldude" };
store.Setup(s => s.GetSecurityStampAsync(user, It.IsAny<CancellationToken>())).ReturnsAsync(null).Verifiable();
// Act
// Assert
var ex = await Assert.ThrowsAsync<InvalidOperationException>(() => manager.CreateAsync(user));
Assert.Contains(Resources.NullSecurityStamp, ex.Message);
store.VerifyAll();
}
[Fact]
public async Task UpdateFailsWithNullSecurityStamp()
{
// Setup
var store = new Mock<IUserSecurityStampStore<TestUser>>();
var manager = MockHelpers.TestUserManager(store.Object);
var user = new TestUser { UserName = "nulldude" };
store.Setup(s => s.GetSecurityStampAsync(user, It.IsAny<CancellationToken>())).ReturnsAsync(null).Verifiable();
// Act
// Assert
var ex = await Assert.ThrowsAsync<InvalidOperationException>(() => manager.UpdateAsync(user));
Assert.Contains(Resources.NullSecurityStamp, ex.Message);
store.VerifyAll();
}
[Fact]
public async Task RemoveClaimsCallsStore()
{