Clean up sign in manager

- Add SignInOptions
- Also fix SecurityStampValidator issue resolving against wrong service
collection
This commit is contained in:
Hao Kung 2014-08-07 16:29:56 -07:00
parent 48ae50ab67
commit 7d4aed4e3b
11 changed files with 181 additions and 77 deletions

View File

@ -39,7 +39,7 @@ namespace IdentitySample
PhoneNumber = await UserManager.GetPhoneNumberAsync(user),
TwoFactor = await UserManager.GetTwoFactorEnabledAsync(user),
Logins = await UserManager.GetLoginsAsync(user),
BrowserRemembered = await SignInManager.IsTwoFactorClientRemembered(user)
BrowserRemembered = await SignInManager.IsTwoFactorClientRememberedAsync(user)
};
return View(model);
}

View File

@ -2,11 +2,11 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Security.Claims;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNet.Http;
using Microsoft.AspNet.Http.Security;
using Microsoft.Framework.DependencyInjection;
using System;
namespace Microsoft.AspNet.Identity.Authentication
{
@ -27,7 +27,7 @@ namespace Microsoft.AspNet.Identity.Authentication
Context.Response.SignOut(TwoFactorRememberedAuthenticationType);
}
public async Task<bool> IsClientRememeberedAsync(string userId)
public async Task<bool> IsClientRememeberedAsync(string userId, CancellationToken cancellationToken = default(CancellationToken))
{
var result =
await Context.AuthenticateAsync(TwoFactorRememberedAuthenticationType);

View File

@ -12,8 +12,7 @@ namespace Microsoft.Framework.DependencyInjection
where TUser : class
where TRole : class
{
// todo: review should this be scoped?
builder.Services.AddTransient<IAuthenticationManager, HttpAuthenticationManager>();
builder.Services.AddScoped<IAuthenticationManager, HttpAuthenticationManager>();
return builder;
}
}

View File

@ -68,9 +68,9 @@ namespace Microsoft.AspNet.Identity.Authentication
}
if (validate)
{
var manager = context.HttpContext.ApplicationServices.GetService<SignInManager<TUser>>();
var manager = context.HttpContext.RequestServices.GetService<SignInManager<TUser>>();
var userId = getUserIdCallback(context.Identity);
var user = await manager.ValidateSecurityStamp(context.Identity, userId);
var user = await manager.ValidateSecurityStampAsync(context.Identity, userId);
if (user != null)
{
bool isPersistent = false;

View File

@ -2,6 +2,7 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Security.Claims;
using System.Threading;
using System.Threading.Tasks;
namespace Microsoft.AspNet.Identity
@ -14,7 +15,8 @@ namespace Microsoft.AspNet.Identity
// remember browser for two factor
void ForgetClient();
void RememberClient(string userId);
Task<bool> IsClientRememeberedAsync(string userId);
Task<bool> IsClientRememeberedAsync(string userId,
CancellationToken cancellationToken = default(CancellationToken));
// half cookie
Task StoreUserId(string userId);

View File

@ -14,6 +14,7 @@ namespace Microsoft.AspNet.Identity
User = new UserOptions();
Password = new PasswordOptions();
Lockout = new LockoutOptions();
SignIn = new SignInOptions();
}
public ClaimsIdentityOptions ClaimsIdentity { get; set; }
@ -23,5 +24,8 @@ namespace Microsoft.AspNet.Identity
public PasswordOptions Password { get; set; }
public LockoutOptions Lockout { get; set; }
public SignInOptions SignIn { get; set; }
}
}

View File

@ -77,6 +77,7 @@
<Compile Include="SignInStatus.cs" />
<Compile Include="UserLoginInfo.cs" />
<Compile Include="UserManager.cs" />
<Compile Include="SignInOptions.cs" />
<Compile Include="UserOptions.cs" />
<Compile Include="UserValidator.cs" />
</ItemGroup>

View File

@ -4,7 +4,9 @@
using System;
using System.Security.Claims;
using System.Security.Principal;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Framework.OptionsModel;
namespace Microsoft.AspNet.Identity
{
@ -15,7 +17,7 @@ namespace Microsoft.AspNet.Identity
public class SignInManager<TUser> where TUser : class
{
public SignInManager(UserManager<TUser> userManager, IAuthenticationManager authenticationManager,
IClaimsIdentityFactory<TUser> claimsFactory)
IClaimsIdentityFactory<TUser> claimsFactory, IOptionsAccessor<IdentityOptions> optionsAccessor)
{
if (userManager == null)
{
@ -29,23 +31,45 @@ namespace Microsoft.AspNet.Identity
{
throw new ArgumentNullException("claimsFactory");
}
if (optionsAccessor == null || optionsAccessor.Options == null)
{
throw new ArgumentNullException("optionsAccessor");
}
UserManager = userManager;
AuthenticationManager = authenticationManager;
ClaimsFactory = claimsFactory;
Options = optionsAccessor.Options;
}
public UserManager<TUser> UserManager { get; private set; }
public IAuthenticationManager AuthenticationManager { get; private set; }
public IClaimsIdentityFactory<TUser> ClaimsFactory { get; private set; }
public IdentityOptions Options { get; private set; }
// Should this be a func?
public virtual async Task<ClaimsIdentity> CreateUserIdentityAsync(TUser user)
public virtual async Task<ClaimsIdentity> CreateUserIdentityAsync(TUser user,
CancellationToken cancellationToken = default(CancellationToken))
{
// REVIEW: should sign in manager take options instead of using the user manager instance?
return await ClaimsFactory.CreateAsync(user, UserManager.Options.ClaimsIdentity);
return await ClaimsFactory.CreateAsync(user, Options.ClaimsIdentity);
}
public virtual async Task SignInAsync(TUser user, bool isPersistent)
//public virtual async Task<bool> CanSignInAsync(TUser user,
// CancellationToken cancellationToken = default(CancellationToken))
//{
// if (Options.SignIn.RequireConfirmedEmail && !(await UserManager.IsEmailConfirmedAsync(user, cancellationToken)))
// {
// return false;
// }
// if (Options.SignIn.RequireConfirmedPhoneNumber && !(await UserManager.IsPhoneNumberConfirmedAsync(user, cancellationToken)))
// {
// return false;
// }
// return true;
//}
public virtual async Task SignInAsync(TUser user, bool isPersistent,
CancellationToken cancellationToken = default(CancellationToken))
{
var userIdentity = await CreateUserIdentityAsync(user);
AuthenticationManager.SignIn(userIdentity, isPersistent);
@ -55,7 +79,7 @@ namespace Microsoft.AspNet.Identity
public virtual void SignOut()
{
// REVIEW: need a new home for this option config?
AuthenticationManager.SignOut(UserManager.Options.ClaimsIdentity.AuthenticationType);
AuthenticationManager.SignOut(Options.ClaimsIdentity.AuthenticationType);
}
/// <summary>
@ -65,14 +89,15 @@ namespace Microsoft.AspNet.Identity
/// <param name="identity"></param>
/// <param name="userId"></param>
/// <returns></returns>
public virtual async Task<TUser> ValidateSecurityStamp(ClaimsIdentity identity, string userId)
public virtual async Task<TUser> ValidateSecurityStampAsync(ClaimsIdentity identity, string userId,
CancellationToken cancellationToken = default(CancellationToken))
{
var user = await UserManager.FindByIdAsync(userId);
var user = await UserManager.FindByIdAsync(userId, cancellationToken);
if (user != null && UserManager.SupportsUserSecurityStamp)
{
var securityStamp =
identity.FindFirstValue(UserManager.Options.ClaimsIdentity.SecurityStampClaimType);
if (securityStamp == await UserManager.GetSecurityStampAsync(user))
identity.FindFirstValue(Options.ClaimsIdentity.SecurityStampClaimType);
if (securityStamp == await UserManager.GetSecurityStampAsync(user, cancellationToken))
{
return user;
}
@ -81,26 +106,26 @@ namespace Microsoft.AspNet.Identity
}
public virtual async Task<SignInStatus> PasswordSignInAsync(string userName, string password,
bool isPersistent, bool shouldLockout)
bool isPersistent, bool shouldLockout, CancellationToken cancellationToken = default(CancellationToken))
{
var user = await UserManager.FindByNameAsync(userName);
var user = await UserManager.FindByNameAsync(userName, cancellationToken);
if (user == null)
{
return SignInStatus.Failure;
}
if (UserManager.SupportsUserLockout && await UserManager.IsLockedOutAsync(user))
if (UserManager.SupportsUserLockout && await UserManager.IsLockedOutAsync(user, cancellationToken))
{
return SignInStatus.LockedOut;
}
if (await UserManager.CheckPasswordAsync(user, password))
if (await UserManager.CheckPasswordAsync(user, password, cancellationToken))
{
return await SignInOrTwoFactor(user, isPersistent);
return await SignInOrTwoFactorAsync(user, isPersistent, cancellationToken);
}
if (UserManager.SupportsUserLockout && shouldLockout)
{
// If lockout is requested, increment access failed count which might lock out the user
await UserManager.AccessFailedAsync(user);
if (await UserManager.IsLockedOutAsync(user))
await UserManager.AccessFailedAsync(user, cancellationToken);
if (await UserManager.IsLockedOutAsync(user, cancellationToken))
{
return SignInStatus.LockedOut;
}
@ -108,7 +133,8 @@ namespace Microsoft.AspNet.Identity
return SignInStatus.Failure;
}
public virtual async Task<bool> SendTwoFactorCode(string provider)
public virtual async Task<bool> SendTwoFactorCodeAsync(string provider,
CancellationToken cancellationToken = default(CancellationToken))
{
var userId = await AuthenticationManager.RetrieveUserId();
if (userId == null)
@ -116,26 +142,28 @@ namespace Microsoft.AspNet.Identity
return false;
}
var user = await UserManager.FindByIdAsync(userId);
var user = await UserManager.FindByIdAsync(userId, cancellationToken);
if (user == null)
{
return false;
}
var token = await UserManager.GenerateTwoFactorTokenAsync(user, provider);
var token = await UserManager.GenerateTwoFactorTokenAsync(user, provider, cancellationToken);
// See IdentityConfig.cs to plug in Email/SMS services to actually send the code
await UserManager.NotifyTwoFactorTokenAsync(user, provider, token);
await UserManager.NotifyTwoFactorTokenAsync(user, provider, token, cancellationToken);
return true;
}
public async Task<bool> IsTwoFactorClientRemembered(TUser user)
public async Task<bool> IsTwoFactorClientRememberedAsync(TUser user,
CancellationToken cancellationToken = default(CancellationToken))
{
var userId = await UserManager.GetUserIdAsync(user);
return await AuthenticationManager.IsClientRememeberedAsync(userId);
var userId = await UserManager.GetUserIdAsync(user, cancellationToken);
return await AuthenticationManager.IsClientRememeberedAsync(userId, cancellationToken);
}
public virtual async Task RememberTwoFactorClient(TUser user)
public virtual async Task RememberTwoFactorClient(TUser user,
CancellationToken cancellationToken = default(CancellationToken))
{
var userId = await UserManager.GetUserIdAsync(user);
var userId = await UserManager.GetUserIdAsync(user, cancellationToken);
AuthenticationManager.RememberClient(userId);
}
@ -145,14 +173,15 @@ namespace Microsoft.AspNet.Identity
return Task.FromResult(0);
}
public virtual async Task<SignInStatus> TwoFactorSignInAsync(string provider, string code, bool isPersistent)
public virtual async Task<SignInStatus> TwoFactorSignInAsync(string provider, string code, bool isPersistent,
CancellationToken cancellationToken = default(CancellationToken))
{
var userId = await AuthenticationManager.RetrieveUserId();
if (userId == null)
{
return SignInStatus.Failure;
}
var user = await UserManager.FindByIdAsync(userId);
var user = await UserManager.FindByIdAsync(userId, cancellationToken);
if (user == null)
{
return SignInStatus.Failure;
@ -161,45 +190,47 @@ namespace Microsoft.AspNet.Identity
{
return SignInStatus.LockedOut;
}
if (await UserManager.VerifyTwoFactorTokenAsync(user, provider, code))
if (await UserManager.VerifyTwoFactorTokenAsync(user, provider, code, cancellationToken))
{
// When token is verified correctly, clear the access failed count used for lockout
await UserManager.ResetAccessFailedCountAsync(user);
await UserManager.ResetAccessFailedCountAsync(user, cancellationToken);
await SignInAsync(user, isPersistent);
return SignInStatus.Success;
}
// If the token is incorrect, record the failure which also may cause the user to be locked out
await UserManager.AccessFailedAsync(user);
await UserManager.AccessFailedAsync(user, cancellationToken);
return SignInStatus.Failure;
}
public async Task<SignInStatus> ExternalLoginSignInAsync(UserLoginInfo loginInfo, bool isPersistent)
public async Task<SignInStatus> ExternalLoginSignInAsync(UserLoginInfo loginInfo, bool isPersistent,
CancellationToken cancellationToken = default(CancellationToken))
{
var user = await UserManager.FindByLoginAsync(loginInfo);
var user = await UserManager.FindByLoginAsync(loginInfo, cancellationToken);
if (user == null)
{
return SignInStatus.Failure;
}
if (await UserManager.IsLockedOutAsync(user))
if (await UserManager.IsLockedOutAsync(user, cancellationToken))
{
return SignInStatus.LockedOut;
}
return await SignInOrTwoFactor(user, isPersistent);
return await SignInOrTwoFactorAsync(user, isPersistent, cancellationToken);
}
private async Task<SignInStatus> SignInOrTwoFactor(TUser user, bool isPersistent)
private async Task<SignInStatus> SignInOrTwoFactorAsync(TUser user, bool isPersistent,
CancellationToken cancellationToken)
{
if (UserManager.SupportsUserTwoFactor && await UserManager.GetTwoFactorEnabledAsync(user))
{
if (!await IsTwoFactorClientRemembered(user))
if (!await IsTwoFactorClientRememberedAsync(user, cancellationToken))
{
// Store the userId for use after two factor check
var userId = await UserManager.GetUserIdAsync(user);
var userId = await UserManager.GetUserIdAsync(user, cancellationToken);
await AuthenticationManager.StoreUserId(userId);
return SignInStatus.RequiresVerification;
}
}
await SignInAsync(user, isPersistent);
await SignInAsync(user, isPersistent, cancellationToken);
return SignInStatus.Success;
}
}

View File

@ -0,0 +1,20 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
namespace Microsoft.AspNet.Identity
{
public class SignInOptions
{
public SignInOptions() { }
/// <summary>
/// If set, requires a confirmed email to sign in
/// </summary>
public bool RequireConfirmedEmail { get; set; }
/// <summary>
/// If set, requires a confirmed phone number to sign in
/// </summary>
public bool RequireConfirmedPhoneNumber { get; set; }
}
}

View File

@ -5,6 +5,7 @@ using Microsoft.AspNet.Http;
using Microsoft.AspNet.Http.Security;
using Microsoft.AspNet.Identity.Test;
using Microsoft.Framework.DependencyInjection;
using Microsoft.Framework.OptionsModel;
using Moq;
using System;
using System.Security.Claims;
@ -68,11 +69,13 @@ namespace Microsoft.AspNet.Identity.Authentication.Test
[Fact]
public void ConstructorNullChecks()
{
Assert.Throws<ArgumentNullException>("userManager", () => new SignInManager<IdentityUser>(null, null, null));
Assert.Throws<ArgumentNullException>("userManager", () => new SignInManager<IdentityUser>(null, null, null, null));
var userManager = MockHelpers.MockUserManager<IdentityUser>().Object;
Assert.Throws<ArgumentNullException>("authenticationManager", () => new SignInManager<IdentityUser>(userManager, null, null));
Assert.Throws<ArgumentNullException>("authenticationManager", () => new SignInManager<IdentityUser>(userManager, null, null, null));
var authManager = new Mock<IAuthenticationManager>().Object;
Assert.Throws<ArgumentNullException>("claimsFactory", () => new SignInManager<IdentityUser>(userManager, authManager, null));
Assert.Throws<ArgumentNullException>("claimsFactory", () => new SignInManager<IdentityUser>(userManager, authManager, null, null));
var claimsFactory = new Mock<IClaimsIdentityFactory<IdentityUser>>().Object;
Assert.Throws<ArgumentNullException>("optionsAccessor", () => new SignInManager<IdentityUser>(userManager, authManager, claimsFactory, null));
}
//TODO: Mock fails in K (this works fine in net45)
@ -119,7 +122,10 @@ namespace Microsoft.AspNet.Identity.Authentication.Test
contextAccessor.Setup(a => a.Value).Returns(context.Object);
var roleManager = MockHelpers.MockRoleManager<TestRole>();
var claimsFactory = new Mock<ClaimsIdentityFactory<TestUser, TestRole>>(manager.Object, roleManager.Object);
var helper = new SignInManager<TestUser>(manager.Object, new HttpAuthenticationManager(contextAccessor.Object), claimsFactory.Object);
var identityOptions = new IdentityOptions();
var options = new Mock<IOptionsAccessor<IdentityOptions>>();
options.Setup(a => a.Options).Returns(identityOptions);
var helper = new SignInManager<TestUser>(manager.Object, new HttpAuthenticationManager(contextAccessor.Object), claimsFactory.Object, options.Object);
// Act
var result = await helper.PasswordSignInAsync(user.UserName, "bogus", false, false);
@ -148,9 +154,12 @@ namespace Microsoft.AspNet.Identity.Authentication.Test
var contextAccessor = new Mock<IContextAccessor<HttpContext>>();
contextAccessor.Setup(a => a.Value).Returns(context.Object);
var roleManager = MockHelpers.MockRoleManager<TestRole>();
var identityOptions = new IdentityOptions();
var claimsFactory = new Mock<ClaimsIdentityFactory<TestUser, TestRole>>(manager.Object, roleManager.Object);
claimsFactory.Setup(m => m.CreateAsync(user, manager.Object.Options.ClaimsIdentity, CancellationToken.None)).ReturnsAsync(new ClaimsIdentity("Microsoft.AspNet.Identity")).Verifiable();
var helper = new SignInManager<TestUser>(manager.Object, new HttpAuthenticationManager(contextAccessor.Object), claimsFactory.Object);
claimsFactory.Setup(m => m.CreateAsync(user, identityOptions.ClaimsIdentity, CancellationToken.None)).ReturnsAsync(new ClaimsIdentity("Microsoft.AspNet.Identity")).Verifiable();
var options = new Mock<IOptionsAccessor<IdentityOptions>>();
options.Setup(a => a.Options).Returns(identityOptions);
var helper = new SignInManager<TestUser>(manager.Object, new HttpAuthenticationManager(contextAccessor.Object), claimsFactory.Object, options.Object);
// Act
var result = await helper.PasswordSignInAsync(user.UserName, "password", isPersistent, false);
@ -182,7 +191,10 @@ namespace Microsoft.AspNet.Identity.Authentication.Test
contextAccessor.Setup(a => a.Value).Returns(context.Object);
var roleManager = MockHelpers.MockRoleManager<TestRole>();
var claimsFactory = new Mock<ClaimsIdentityFactory<TestUser, TestRole>>(manager.Object, roleManager.Object);
var helper = new SignInManager<TestUser>(manager.Object, new HttpAuthenticationManager(contextAccessor.Object), claimsFactory.Object);
var identityOptions = new IdentityOptions();
var options = new Mock<IOptionsAccessor<IdentityOptions>>();
options.Setup(a => a.Options).Returns(identityOptions);
var helper = new SignInManager<TestUser>(manager.Object, new HttpAuthenticationManager(contextAccessor.Object), claimsFactory.Object, options.Object);
// Act
var result = await helper.PasswordSignInAsync(user.UserName, "password", false, false);
@ -215,7 +227,10 @@ namespace Microsoft.AspNet.Identity.Authentication.Test
var contextAccessor = new Mock<IContextAccessor<HttpContext>>();
contextAccessor.Setup(a => a.Value).Returns(context.Object);
var roleManager = MockHelpers.MockRoleManager<TestRole>();
var helper = new SignInManager<TestUser>(manager.Object, new HttpAuthenticationManager(contextAccessor.Object), new ClaimsIdentityFactory<TestUser, TestRole>(manager.Object, roleManager.Object));
var identityOptions = new IdentityOptions();
var options = new Mock<IOptionsAccessor<IdentityOptions>>();
options.Setup(a => a.Options).Returns(identityOptions);
var helper = new SignInManager<TestUser>(manager.Object, new HttpAuthenticationManager(contextAccessor.Object), new ClaimsIdentityFactory<TestUser, TestRole>(manager.Object, roleManager.Object), options.Object);
// Act
var result = await helper.PasswordSignInAsync(user.UserName, "password", false, false);
@ -255,7 +270,10 @@ namespace Microsoft.AspNet.Identity.Authentication.Test
contextAccessor.Setup(a => a.Value).Returns(context.Object);
var roleManager = MockHelpers.MockRoleManager<TestRole>();
var claimsFactory = new ClaimsIdentityFactory<TestUser, TestRole>(manager.Object, roleManager.Object);
var helper = new SignInManager<TestUser>(manager.Object, new HttpAuthenticationManager(contextAccessor.Object), claimsFactory);
var identityOptions = new IdentityOptions();
var options = new Mock<IOptionsAccessor<IdentityOptions>>();
options.Setup(a => a.Options).Returns(identityOptions);
var helper = new SignInManager<TestUser>(manager.Object, new HttpAuthenticationManager(contextAccessor.Object), claimsFactory, options.Object);
// Act
var result = await helper.TwoFactorSignInAsync(provider, code, isPersistent);
@ -320,9 +338,12 @@ namespace Microsoft.AspNet.Identity.Authentication.Test
contextAccessor.Setup(a => a.Value).Returns(context.Object);
var signInService = new HttpAuthenticationManager(contextAccessor.Object);
var roleManager = MockHelpers.MockRoleManager<TestRole>();
var identityOptions = new IdentityOptions();
var claimsFactory = new Mock<ClaimsIdentityFactory<TestUser, TestRole>>(manager.Object, roleManager.Object);
claimsFactory.Setup(m => m.CreateAsync(user, manager.Object.Options.ClaimsIdentity, CancellationToken.None)).ReturnsAsync(new ClaimsIdentity(ClaimsIdentityOptions.DefaultAuthenticationType)).Verifiable();
var helper = new SignInManager<TestUser>(manager.Object, signInService, claimsFactory.Object);
claimsFactory.Setup(m => m.CreateAsync(user, identityOptions.ClaimsIdentity, CancellationToken.None)).ReturnsAsync(new ClaimsIdentity(ClaimsIdentityOptions.DefaultAuthenticationType)).Verifiable();
var options = new Mock<IOptionsAccessor<IdentityOptions>>();
options.Setup(a => a.Options).Returns(identityOptions);
var helper = new SignInManager<TestUser>(manager.Object, signInService, claimsFactory.Object, options.Object);
// Act
var result = await helper.PasswordSignInAsync(user.UserName, "password", isPersistent, false);
@ -351,8 +372,11 @@ namespace Microsoft.AspNet.Identity.Authentication.Test
contextAccessor.Setup(a => a.Value).Returns(context.Object);
var roleManager = MockHelpers.MockRoleManager<TestRole>();
var claimsFactory = new Mock<ClaimsIdentityFactory<TestUser, TestRole>>(manager.Object, roleManager.Object);
manager.Object.Options.ClaimsIdentity.AuthenticationType = authenticationType;
var helper = new SignInManager<TestUser>(manager.Object, new HttpAuthenticationManager(contextAccessor.Object), claimsFactory.Object);
var identityOptions = new IdentityOptions();
var options = new Mock<IOptionsAccessor<IdentityOptions>>();
options.Setup(a => a.Options).Returns(identityOptions);
identityOptions.ClaimsIdentity.AuthenticationType = authenticationType;
var helper = new SignInManager<TestUser>(manager.Object, new HttpAuthenticationManager(contextAccessor.Object), claimsFactory.Object, options.Object);
// Act
helper.SignOut();
@ -377,7 +401,10 @@ namespace Microsoft.AspNet.Identity.Authentication.Test
contextAccessor.Setup(a => a.Value).Returns(context.Object);
var roleManager = MockHelpers.MockRoleManager<TestRole>();
var claimsFactory = new Mock<ClaimsIdentityFactory<TestUser, TestRole>>(manager.Object, roleManager.Object);
var helper = new SignInManager<TestUser>(manager.Object, new HttpAuthenticationManager(contextAccessor.Object), claimsFactory.Object);
var identityOptions = new IdentityOptions();
var options = new Mock<IOptionsAccessor<IdentityOptions>>();
options.Setup(a => a.Options).Returns(identityOptions);
var helper = new SignInManager<TestUser>(manager.Object, new HttpAuthenticationManager(contextAccessor.Object), claimsFactory.Object, options.Object);
// Act
var result = await helper.PasswordSignInAsync(user.UserName, "bogus", false, false);
@ -397,7 +424,10 @@ namespace Microsoft.AspNet.Identity.Authentication.Test
contextAccessor.Setup(a => a.Value).Returns(context.Object);
var roleManager = MockHelpers.MockRoleManager<TestRole>();
var claimsFactory = new Mock<ClaimsIdentityFactory<TestUser, TestRole>>(manager.Object, roleManager.Object);
var helper = new SignInManager<TestUser>(manager.Object, new HttpAuthenticationManager(contextAccessor.Object), claimsFactory.Object);
var identityOptions = new IdentityOptions();
var options = new Mock<IOptionsAccessor<IdentityOptions>>();
options.Setup(a => a.Options).Returns(identityOptions);
var helper = new SignInManager<TestUser>(manager.Object, new HttpAuthenticationManager(contextAccessor.Object), claimsFactory.Object, options.Object);
// Act
var result = await helper.PasswordSignInAsync("bogus", "bogus", false, false);
@ -428,7 +458,10 @@ namespace Microsoft.AspNet.Identity.Authentication.Test
contextAccessor.Setup(a => a.Value).Returns(context.Object);
var roleManager = MockHelpers.MockRoleManager<TestRole>();
var claimsFactory = new Mock<ClaimsIdentityFactory<TestUser, TestRole>>(manager.Object, roleManager.Object);
var helper = new SignInManager<TestUser>(manager.Object, new HttpAuthenticationManager(contextAccessor.Object), claimsFactory.Object);
var identityOptions = new IdentityOptions();
var options = new Mock<IOptionsAccessor<IdentityOptions>>();
options.Setup(a => a.Options).Returns(identityOptions);
var helper = new SignInManager<TestUser>(manager.Object, new HttpAuthenticationManager(contextAccessor.Object), claimsFactory.Object, options.Object);
// Act
var result = await helper.PasswordSignInAsync(user.UserName, "bogus", false, true);

View File

@ -3,6 +3,7 @@
using System;
using System.Security.Claims;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNet.Http;
using Microsoft.AspNet.Http.Security;
@ -11,6 +12,7 @@ using Microsoft.AspNet.Security;
using Microsoft.AspNet.Security.Cookies;
using Microsoft.Framework.DependencyInjection;
using Microsoft.Framework.DependencyInjection.Fallback;
using Microsoft.Framework.OptionsModel;
using Moq;
using Xunit;
@ -22,7 +24,7 @@ namespace Microsoft.AspNet.Identity.Authentication.Test
public async Task OnValidateIdentityThrowsWithEmptyServiceCollection()
{
var httpContext = new Mock<HttpContext>();
httpContext.Setup(c => c.ApplicationServices).Returns(new ServiceCollection().BuildServiceProvider());
httpContext.Setup(c => c.RequestServices).Returns(new ServiceCollection().BuildServiceProvider());
var id = new ClaimsIdentity(ClaimsIdentityOptions.DefaultAuthenticationType);
var ticket = new AuthenticationTicket(id, new AuthenticationProperties { IssuedUtc = DateTimeOffset.UtcNow });
var context = new CookieValidateIdentityContext(httpContext.Object, ticket, new CookieAuthenticationOptions());
@ -39,13 +41,16 @@ namespace Microsoft.AspNet.Identity.Authentication.Test
var userManager = MockHelpers.MockUserManager<IdentityUser>();
var authManager = new Mock<IAuthenticationManager>();
var claimsManager = new Mock<IClaimsIdentityFactory<IdentityUser>>();
var identityOptions = new IdentityOptions();
var options = new Mock<IOptionsAccessor<IdentityOptions>>();
options.Setup(a => a.Options).Returns(identityOptions);
var signInManager = new Mock<SignInManager<IdentityUser>>(userManager.Object,
authManager.Object, claimsManager.Object);
signInManager.Setup(s => s.ValidateSecurityStamp(It.IsAny<ClaimsIdentity>(), user.Id)).ReturnsAsync(user).Verifiable();
signInManager.Setup(s => s.SignInAsync(user, isPersistent)).Returns(Task.FromResult(0)).Verifiable();
authManager.Object, claimsManager.Object, options.Object);
signInManager.Setup(s => s.ValidateSecurityStampAsync(It.IsAny<ClaimsIdentity>(), user.Id, CancellationToken.None)).ReturnsAsync(user).Verifiable();
signInManager.Setup(s => s.SignInAsync(user, isPersistent, CancellationToken.None)).Returns(Task.FromResult(0)).Verifiable();
var services = new ServiceCollection();
services.AddInstance(signInManager.Object);
httpContext.Setup(c => c.ApplicationServices).Returns(services.BuildServiceProvider());
httpContext.Setup(c => c.RequestServices).Returns(services.BuildServiceProvider());
var id = new ClaimsIdentity(ClaimsIdentityOptions.DefaultAuthenticationType);
id.AddClaim(new Claim(ClaimTypes.NameIdentifier, user.Id));
@ -68,12 +73,15 @@ namespace Microsoft.AspNet.Identity.Authentication.Test
var userManager = MockHelpers.MockUserManager<IdentityUser>();
var authManager = new Mock<IAuthenticationManager>();
var claimsManager = new Mock<IClaimsIdentityFactory<IdentityUser>>();
var identityOptions = new IdentityOptions();
var options = new Mock<IOptionsAccessor<IdentityOptions>>();
options.Setup(a => a.Options).Returns(identityOptions);
var signInManager = new Mock<SignInManager<IdentityUser>>(userManager.Object,
authManager.Object, claimsManager.Object);
signInManager.Setup(s => s.ValidateSecurityStamp(It.IsAny<ClaimsIdentity>(), user.Id)).ReturnsAsync(null).Verifiable();
authManager.Object, claimsManager.Object, options.Object);
signInManager.Setup(s => s.ValidateSecurityStampAsync(It.IsAny<ClaimsIdentity>(), user.Id, CancellationToken.None)).ReturnsAsync(null).Verifiable();
var services = new ServiceCollection();
services.AddInstance(signInManager.Object);
httpContext.Setup(c => c.ApplicationServices).Returns(services.BuildServiceProvider());
httpContext.Setup(c => c.RequestServices).Returns(services.BuildServiceProvider());
var id = new ClaimsIdentity(ClaimsIdentityOptions.DefaultAuthenticationType);
id.AddClaim(new Claim(ClaimTypes.NameIdentifier, user.Id));
@ -96,12 +104,15 @@ namespace Microsoft.AspNet.Identity.Authentication.Test
var userManager = MockHelpers.MockUserManager<IdentityUser>();
var authManager = new Mock<IAuthenticationManager>();
var claimsManager = new Mock<IClaimsIdentityFactory<IdentityUser>>();
var identityOptions = new IdentityOptions();
var options = new Mock<IOptionsAccessor<IdentityOptions>>();
options.Setup(a => a.Options).Returns(identityOptions);
var signInManager = new Mock<SignInManager<IdentityUser>>(userManager.Object,
authManager.Object, claimsManager.Object);
signInManager.Setup(s => s.ValidateSecurityStamp(It.IsAny<ClaimsIdentity>(), user.Id)).ReturnsAsync(null).Verifiable();
authManager.Object, claimsManager.Object, options.Object);
signInManager.Setup(s => s.ValidateSecurityStampAsync(It.IsAny<ClaimsIdentity>(), user.Id, CancellationToken.None)).ReturnsAsync(null).Verifiable();
var services = new ServiceCollection();
services.AddInstance(signInManager.Object);
httpContext.Setup(c => c.ApplicationServices).Returns(services.BuildServiceProvider());
httpContext.Setup(c => c.RequestServices).Returns(services.BuildServiceProvider());
var id = new ClaimsIdentity(ClaimsIdentityOptions.DefaultAuthenticationType);
id.AddClaim(new Claim(ClaimTypes.NameIdentifier, user.Id));
@ -124,13 +135,16 @@ namespace Microsoft.AspNet.Identity.Authentication.Test
var userManager = MockHelpers.MockUserManager<IdentityUser>();
var authManager = new Mock<IAuthenticationManager>();
var claimsManager = new Mock<IClaimsIdentityFactory<IdentityUser>>();
var identityOptions = new IdentityOptions();
var options = new Mock<IOptionsAccessor<IdentityOptions>>();
options.Setup(a => a.Options).Returns(identityOptions);
var signInManager = new Mock<SignInManager<IdentityUser>>(userManager.Object,
authManager.Object, claimsManager.Object);
signInManager.Setup(s => s.ValidateSecurityStamp(It.IsAny<ClaimsIdentity>(), user.Id)).Throws(new Exception("Shouldn't be called"));
signInManager.Setup(s => s.SignInAsync(user, false)).Throws(new Exception("Shouldn't be called"));
authManager.Object, claimsManager.Object, options.Object);
signInManager.Setup(s => s.ValidateSecurityStampAsync(It.IsAny<ClaimsIdentity>(), user.Id, CancellationToken.None)).Throws(new Exception("Shouldn't be called"));
signInManager.Setup(s => s.SignInAsync(user, false, CancellationToken.None)).Throws(new Exception("Shouldn't be called"));
var services = new ServiceCollection();
services.AddInstance(signInManager.Object);
httpContext.Setup(c => c.ApplicationServices).Returns(services.BuildServiceProvider());
httpContext.Setup(c => c.RequestServices).Returns(services.BuildServiceProvider());
var id = new ClaimsIdentity(ClaimsIdentityOptions.DefaultAuthenticationType);
id.AddClaim(new Claim(ClaimTypes.NameIdentifier, user.Id));