React to Options/Cookie changes

Moved cookie instance options into IdentityCookieOptions
IUserTokenProvider changes
This commit is contained in:
Hao Kung 2015-09-02 15:15:40 -07:00
parent a13dfc1eb5
commit 2113ef5abc
37 changed files with 380 additions and 428 deletions

View File

@ -29,7 +29,7 @@ namespace IdentitySample.Models
/// <returns></returns>
private static async Task CreateAdminUser(IServiceProvider serviceProvider)
{
var options = serviceProvider.GetRequiredService<IOptions<IdentityDbContextOptions>>().Options;
var options = serviceProvider.GetRequiredService<IOptions<IdentityDbContextOptions>>().Value;
const string adminRole = "Administrator";
var userManager = serviceProvider.GetRequiredService<UserManager<ApplicationUser>>();

View File

@ -5,6 +5,7 @@ using System;
using Microsoft.AspNet.Identity;
using Microsoft.Framework.DependencyInjection;
using Microsoft.Framework.OptionsModel;
namespace Microsoft.AspNet.Builder
{
@ -31,10 +32,11 @@ namespace Microsoft.AspNet.Builder
throw new InvalidOperationException(Resources.MustCallAddIdentity);
}
app.UseCookieAuthentication(null, IdentityOptions.ExternalCookieAuthenticationScheme);
app.UseCookieAuthentication(null, IdentityOptions.TwoFactorRememberMeCookieAuthenticationScheme);
app.UseCookieAuthentication(null, IdentityOptions.TwoFactorUserIdCookieAuthenticationScheme);
app.UseCookieAuthentication(null, IdentityOptions.ApplicationCookieAuthenticationScheme);
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;
}
}

View File

@ -28,7 +28,7 @@ namespace Microsoft.AspNet.Identity
{
throw new ArgumentNullException(nameof(dataProtectionProvider));
}
Options = options?.Options ?? new DataProtectionTokenProviderOptions();
Options = options?.Value ?? new DataProtectionTokenProviderOptions();
// Use the Name as the purpose which should usually be distinct from others
Protector = dataProtectionProvider.CreateProtector(Name ?? "DataProtectorTokenProvider");
}

View File

@ -1,23 +1,7 @@
using System;
using System.Threading.Tasks;
using Microsoft.Framework.OptionsModel;
namespace Microsoft.AspNet.Identity
{
/// <summary>
/// Options for the <see cref="EmailTokenProvider{TUser}"/> class.
/// </summary>
public class EmailTokenProviderOptions
{
/// <summary>
/// Gets or sets the unique name used for an instance of <see cref="EmailTokenProvider{TUser}"/>.
/// </summary>
/// <value>
/// The unique name used for an instance of <see cref="EmailTokenProvider{TUser}"/>.
/// </value>
public string Name { get; set; } = "Email";
}
/// <summary>
/// TokenProvider that generates tokens from the user's security stamp and notifies a user via email.
/// </summary>
@ -25,36 +9,6 @@ namespace Microsoft.AspNet.Identity
public class EmailTokenProvider<TUser> : TotpSecurityStampBasedTokenProvider<TUser>
where TUser : class
{
/// <summary>
/// Initializes a new instance of the <see cref="EmailTokenProvider{TUser}"/> class.
/// </summary>
/// <param name="options">The configured <see cref="DataProtectionTokenProviderOptions"/>.</param>
/// <param name="name">The unique name for this instance of <see cref="EmailTokenProvider{TUser}"/>.</param>
public EmailTokenProvider(IOptions<EmailTokenProviderOptions> options, string name = "")
{
if (options == null)
{
throw new ArgumentNullException(nameof(options));
}
Options = options.GetNamedOptions(name);
}
/// <summary>
/// Gets the options for this instance of <see cref="EmailTokenProvider{TUser}"/>.
/// </summary>
/// <value>
/// The options for this instance of <see cref="EmailTokenProvider{TUser}"/>.
/// </value>
public EmailTokenProviderOptions Options { get; private set; }
/// <summary>
/// Gets the unique name for this instance of <see cref="EmailTokenProvider{TUser}"/>.
/// </summary>
/// <value>
/// The unique name for this instance of <see cref="EmailTokenProvider{TUser}"/>.
/// </value>
public override string Name { get { return Options.Name; } }
/// <summary>
/// Checks if a two factor authentication token can be generated for the specified <paramref name="user"/>.
/// </summary>

View File

@ -11,12 +11,6 @@ namespace Microsoft.AspNet.Identity
/// <typeparam name="TUser">The type encapsulating a user.</typeparam>
public interface IUserTokenProvider<TUser> where TUser : class
{
/// <summary>
/// Gets the name of the token provider.
/// </summary>
/// <value>The name of the token provider.</value>
string Name { get; }
/// <summary>
/// Generates a token for the specified <paramref name="ref"/> and <paramref name="purpose"/>, as an asynchronous operation.
/// </summary>

View File

@ -121,20 +121,31 @@ namespace Microsoft.AspNet.Identity
/// Adds a token provider.
/// </summary>
/// <typeparam name="TProvider">The type of the token provider to add.</typeparam>
/// <param name="providerName">The name of the provider to add.</param>
/// <returns>The <see cref="IdentityBuilder"/>.</returns>
public virtual IdentityBuilder AddTokenProvider<TProvider>() where TProvider : class
public virtual IdentityBuilder AddTokenProvider<TProvider>(string providerName) where TProvider : class
{
return AddTokenProvider(typeof(TProvider));
return AddTokenProvider(providerName, typeof(TProvider));
}
/// <summary>
/// Adds a token provider for the <seealso cref="UserType"/>.
/// </summary>
/// <param name="providerName">The name of the provider to add.</param>
/// <param name="provider">The type of the <see cref="IUserTokenProvider{TUser}"/> to add.</param>
/// <returns>The <see cref="IdentityBuilder"/>.</returns>
public virtual IdentityBuilder AddTokenProvider(Type provider)
public virtual IdentityBuilder AddTokenProvider(string providerName, Type provider)
{
return AddScoped(typeof(IUserTokenProvider<>).MakeGenericType(UserType), provider);
if (!typeof(IUserTokenProvider<>).MakeGenericType(UserType).GetTypeInfo().IsAssignableFrom(provider.GetTypeInfo()))
{
throw new InvalidOperationException(Resources.FormatInvalidManagerType(provider.Name, "IUserTokenProvider", UserType.Name));
}
Services.Configure<IdentityOptions>(options =>
{
options.Tokens.ProviderMap[providerName] = new TokenProviderDescriptor(provider);
});
Services.AddTransient(provider);
return this;
}
/// <summary>
@ -143,14 +154,12 @@ namespace Microsoft.AspNet.Identity
/// <returns>The <see cref="IdentityBuilder"/>.</returns>
public virtual IdentityBuilder AddDefaultTokenProviders()
{
Services.Configure<DataProtectionTokenProviderOptions>(options =>
{
options.Name = Resources.DefaultTokenProvider;
});
return AddTokenProvider(typeof(DataProtectorTokenProvider<>).MakeGenericType(UserType))
.AddTokenProvider(typeof(PhoneNumberTokenProvider<>).MakeGenericType(UserType))
.AddTokenProvider(typeof(EmailTokenProvider<>).MakeGenericType(UserType));
var dataProtectionProviderType = typeof(DataProtectorTokenProvider<>).MakeGenericType(UserType);
var phoneNumberProviderType = typeof(PhoneNumberTokenProvider<>).MakeGenericType(UserType);
var emailTokenProviderType = typeof(EmailTokenProvider<>).MakeGenericType(UserType);
return AddTokenProvider(TokenOptions.DefaultProvider, dataProtectionProviderType)
.AddTokenProvider(TokenOptions.DefaultEmailProvider, emailTokenProviderType)
.AddTokenProvider(TokenOptions.DefaultPhoneProvider, phoneNumberProviderType);
}
/// <summary>

View File

@ -0,0 +1,86 @@
// 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.AspNet.Authentication.Cookies;
using Microsoft.AspNet.Http;
namespace Microsoft.AspNet.Identity
{
/// <summary>
/// Represents all the options you can use to configure the cookies middleware uesd by the identity system.
/// </summary>
public class IdentityCookieOptions
{
public IdentityCookieOptions()
{
// Configure all of the cookie middlewares
ApplicationCookie = new CookieAuthenticationOptions
{
AuthenticationScheme = ApplicationCookieAuthenticationScheme,
AutomaticAuthentication = true,
LoginPath = new PathString("/Account/Login"),
Notifications = new CookieAuthenticationNotifications
{
OnValidatePrincipal = SecurityStampValidator.ValidatePrincipalAsync
}
};
ExternalCookie = new CookieAuthenticationOptions
{
AuthenticationScheme = ExternalCookieAuthenticationScheme,
CookieName = ExternalCookieAuthenticationScheme,
ExpireTimeSpan = TimeSpan.FromMinutes(5)
};
TwoFactorRememberMeCookie = new CookieAuthenticationOptions
{
AuthenticationScheme = TwoFactorRememberMeCookieAuthenticationScheme,
CookieName = TwoFactorRememberMeCookieAuthenticationScheme
};
TwoFactorUserIdCookie = new CookieAuthenticationOptions
{
AuthenticationScheme = TwoFactorUserIdCookieAuthenticationScheme,
CookieName = TwoFactorUserIdCookieAuthenticationScheme,
ExpireTimeSpan = TimeSpan.FromMinutes(5)
};
}
public CookieAuthenticationOptions ApplicationCookie { get; set; }
public CookieAuthenticationOptions ExternalCookie { get; set; }
public CookieAuthenticationOptions TwoFactorRememberMeCookie { get; set; }
public CookieAuthenticationOptions TwoFactorUserIdCookie { get; set; }
/// <summary>
/// Gets or sets the scheme used to identify application authentication cookies.
/// </summary>
/// <value>The scheme used to identify application authentication cookies.</value>
public string ApplicationCookieAuthenticationScheme { get; set; } = ApplicationCookieAuthenticationType;
/// <summary>
/// Gets or sets the scheme used to identify external authentication cookies.
/// </summary>
/// <value>The scheme used to identify external authentication cookies.</value>
public string ExternalCookieAuthenticationScheme { get; set; } = typeof(IdentityCookieOptions).Namespace + ".External.AuthType";
/// <summary>
/// Gets or sets 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 { get; set; } = typeof(IdentityCookieOptions).Namespace + ".TwoFactorUserId.AuthType";
/// <summary>
/// Gets or sets 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 { get; set; } = typeof(IdentityCookieOptions).Namespace + ".TwoFactorRemeberMe.AuthType";
/// <summary>
/// Gets or sets the authentication type used when constructing an <see cref="ClaimsIdentity"/> from an application cookie.
/// </summary>
/// <value>The authentication type used when constructing an <see cref="ClaimsIdentity"/> from an application cookie.</value>
public static string ApplicationCookieAuthenticationType { get; set; } = typeof(IdentityCookieOptions).Namespace + ".Application.AuthType";
}
}

View File

@ -6,7 +6,7 @@ using System;
namespace Microsoft.AspNet.Identity
{
/// <summary>
/// Represents all the options you can used to configure the identity system.
/// Represents all the options you can use to configure the identity system.
/// </summary>
public class IdentityOptions
{
@ -50,6 +50,22 @@ namespace Microsoft.AspNet.Identity
/// </value>
public SignInOptions SignIn { get; set; } = new SignInOptions();
/// <summary>
/// Gets or sets the <see cref="IdentityCookieOptions"/> for the identity system.
/// </summary>
/// <value>
/// The <see cref="IdentityCookieOptions"/> for the identity system.
/// </value>
public IdentityCookieOptions Cookies { get; set; } = new IdentityCookieOptions();
/// <summary>
/// Gets or sets the <see cref="TokenOptions"/> for the identity system.
/// </summary>
/// <value>
/// The <see cref="TokenOptions"/> for the identity system.
/// </value>
public TokenOptions Tokens { get; set; } = new TokenOptions();
/// <summary>
/// Gets or sets the <see cref="TimeSpan"/> after which security stamps are re-validated.
/// </summary>
@ -57,78 +73,5 @@ namespace Microsoft.AspNet.Identity
/// The <see cref="TimeSpan"/> after which security stamps are re-validated.
/// </value>
public TimeSpan SecurityStampValidationInterval { get; set; } = TimeSpan.FromMinutes(30);
/// <summary>
/// Gets or sets the <see cref="EmailConfirmationTokenProvider"/> used to generate tokens used in account confirmation emails.
/// </summary>
/// <value>
/// The <see cref="EmailConfirmationTokenProvider"/> used to generate tokens used in account confirmation emails.
/// </value>
public string EmailConfirmationTokenProvider { get; set; } = Resources.DefaultTokenProvider;
/// <summary>
/// Gets or sets the <see cref="PasswordResetTokenProvider"/> used to generate tokens used in password reset emails.
/// </summary>
/// <value>
/// The <see cref="PasswordResetTokenProvider"/> used to generate tokens used in password reset emails.
/// </value>
public string PasswordResetTokenProvider { get; set; } = Resources.DefaultTokenProvider;
/// <summary>
/// Gets or sets the <see cref="ChangeEmailTokenProvider"/> used to generate tokens used in email change confirmation emails.
/// </summary>
/// <value>
/// The <see cref="ChangeEmailTokenProvider"/> used to generate tokens used in email change confirmation emails.
/// </value>
public string ChangeEmailTokenProvider { get; set; } = Resources.DefaultTokenProvider;
/// <summary>
/// Gets or sets the scheme used to identify application authentication cookies.
/// </summary>
/// <value>The scheme used to identify application authentication cookies.</value>
public static string ApplicationCookieAuthenticationScheme { get; set; } = typeof(IdentityOptions).Namespace + ".Application";
/// <summary>
/// Gets or sets the scheme used to identify external authentication cookies.
/// </summary>
/// <value>The scheme used to identify external authentication cookies.</value>
public static string ExternalCookieAuthenticationScheme { get; set; } = typeof(IdentityOptions).Namespace + ".External";
/// <summary>
/// Gets or sets 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 static string TwoFactorUserIdCookieAuthenticationScheme { get; set; } = typeof(IdentityOptions).Namespace + ".TwoFactorUserId";
/// <summary>
/// Gets or sets 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 static string TwoFactorRememberMeCookieAuthenticationScheme { get; set; } = typeof(IdentityOptions).Namespace + ".TwoFactorRememberMe";
/// <summary>
/// Gets or sets the authentication type used when constructing an <see cref="ClaimsIdentity"/> from an application cookie.
/// </summary>
/// <value>The authentication type used when constructing an <see cref="ClaimsIdentity"/> from an application cookie.</value>
public static string ApplicationCookieAuthenticationType { get; set; } = typeof(IdentityOptions).Namespace + ".Application.AuthType";
/// <summary>
/// Gets or sets the authentication type used when constructing an <see cref="ClaimsIdentity"/> from an external identity cookie.
/// </summary>
/// <value>The authentication type used when constructing an <see cref="ClaimsIdentity"/> from an external identity cookie.</value>
public static string ExternalCookieAuthenticationType { get; set; } = typeof(IdentityOptions).Namespace + ".External.AuthType";
/// <summary>
/// Gets or sets the authentication type used when constructing an <see cref="ClaimsIdentity"/> from an two factor authentication cookie.
/// </summary>
/// <value>The authentication type used when constructing an <see cref="ClaimsIdentity"/> from an two factor authentication cookie.</value>
public static string TwoFactorUserIdCookieAuthenticationType { get; set; } = typeof(IdentityOptions).Namespace + ".TwoFactorUserId.AuthType";
/// <summary>
/// Gets or sets the authentication type used when constructing an <see cref="ClaimsIdentity"/> from an two factor remember me authentication cookie.
/// </summary>
/// <value>The authentication type used when constructing an <see cref="ClaimsIdentity"/> from an two factor remember me authentication cookie.</value>
public static string TwoFactorRememberMeCookieAuthenticationType { get; set; } = typeof(IdentityOptions).Namespace + ".TwoFactorRemeberMe.AuthType";
}
}

View File

@ -2,10 +2,8 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using Microsoft.AspNet.Http;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Authentication;
using Microsoft.AspNet.Authentication.Cookies;
using Microsoft.AspNet.Identity;
using Microsoft.Framework.Configuration;
using Microsoft.Framework.DependencyInjection.Extensions;
@ -16,39 +14,6 @@ namespace Microsoft.Framework.DependencyInjection
/// </summary>
public static class IdentityServiceCollectionExtensions
{
/// <summary>
/// Configures a set of <see cref="IdentityOptions"/> for the application
/// </summary>
/// <param name="services">The services available in the application.</param>
/// <param name="setupAction">An action to configure the <see cref="IdentityOptions"/>.</param>
/// <returns>The <see cref="IServiceCollection"/> instance this method extends.</returns>
public static IServiceCollection ConfigureIdentity(this IServiceCollection services, Action<IdentityOptions> setupAction)
{
return services.Configure(setupAction);
}
/// <summary>
/// Configures a set of <see cref="IdentityOptions"/> for the application
/// </summary>
/// <param name="services">The services available in the application.</param>
/// <param name="config">The configuration for the <see cref="IdentityOptions>"/>.</param>
/// <returns>The <see cref="IServiceCollection"/> instance this method extends.</returns>
public static IServiceCollection ConfigureIdentity(this IServiceCollection services, IConfiguration config)
{
return services.Configure<IdentityOptions>(config);
}
/// <summary>
/// Configures a set of <see cref="CookieAuthenticationOptions"/> for the application
/// </summary>
/// <param name="services">The services available in the application.</param>
/// <param name="setupAction">An action to configure the <see cref="CookieAuthenticationOptions"/>.</param>
/// <returns>The <see cref="IServiceCollection"/> instance this method extends.</returns>
public static IServiceCollection ConfigureIdentityApplicationCookie(this IServiceCollection services, Action<CookieAuthenticationOptions> setupAction)
{
return services.ConfigureCookieAuthentication(setupAction, IdentityOptions.ApplicationCookieAuthenticationScheme);
}
/// <summary>
/// Adds the default identity system configuration for the specified User and Role types.
/// </summary>
@ -99,43 +64,14 @@ namespace Microsoft.Framework.DependencyInjection
if (setupAction != null)
{
services.ConfigureIdentity(setupAction);
services.Configure<IdentityOptions>(setupAction);
}
services.Configure<SharedAuthenticationOptions>(options =>
{
options.SignInScheme = IdentityOptions.ExternalCookieAuthenticationScheme;
// This is the Default value for ExternalCookieAuthenticationScheme
options.SignInScheme = new IdentityCookieOptions().ExternalCookieAuthenticationScheme;
});
// Configure all of the cookie middlewares
services.ConfigureIdentityApplicationCookie(options =>
{
options.AuthenticationScheme = IdentityOptions.ApplicationCookieAuthenticationScheme;
options.AutomaticAuthentication = true;
options.LoginPath = new PathString("/Account/Login");
options.Notifications = new CookieAuthenticationNotifications
{
OnValidatePrincipal = SecurityStampValidator.ValidatePrincipalAsync
};
});
services.ConfigureCookieAuthentication(options =>
{
options.AuthenticationScheme = IdentityOptions.ExternalCookieAuthenticationScheme;
options.CookieName = IdentityOptions.ExternalCookieAuthenticationScheme;
options.ExpireTimeSpan = TimeSpan.FromMinutes(5);
}, IdentityOptions.ExternalCookieAuthenticationScheme);
services.ConfigureCookieAuthentication(options =>
{
options.AuthenticationScheme = IdentityOptions.TwoFactorRememberMeCookieAuthenticationScheme;
options.CookieName = IdentityOptions.TwoFactorRememberMeCookieAuthenticationScheme;
}, IdentityOptions.TwoFactorRememberMeCookieAuthenticationScheme);
services.ConfigureCookieAuthentication(options =>
{
options.AuthenticationScheme = IdentityOptions.TwoFactorUserIdCookieAuthenticationScheme;
options.CookieName = IdentityOptions.TwoFactorUserIdCookieAuthenticationScheme;
options.ExpireTimeSpan = TimeSpan.FromMinutes(5);
}, IdentityOptions.TwoFactorUserIdCookieAuthenticationScheme);
return new IdentityBuilder(typeof(TUser), typeof(TRole), services);
}
}

View File

@ -40,7 +40,7 @@ namespace Microsoft.AspNet.Identity
/// <param name="options">The options for this instance.</param>
public PasswordHasher(IOptions<PasswordHasherOptions> optionsAccessor = null)
{
var options = optionsAccessor?.Options ?? new PasswordHasherOptions();
var options = optionsAccessor?.Value ?? new PasswordHasherOptions();
_compatibilityMode = options.CompatibilityMode;
switch (_compatibilityMode)

View File

@ -1,23 +1,8 @@
using System;
using System.Threading.Tasks;
using Microsoft.Framework.OptionsModel;
namespace Microsoft.AspNet.Identity
{
/// <summary>
/// Encapsulations options for a <see cref="PhoneNumberTokenProvider{TUser}"/>.
/// </summary>
public class PhoneNumberTokenProviderOptions
{
/// <summary>
/// Gets or sets the name for the <see cref="PhoneNumberTokenProvider{TUser}"/>.
/// </summary>
/// <value>
/// The name for the <see cref="PhoneNumberTokenProvider{TUser}"/>.
/// </value>
public string Name { get; set; } = "Phone";
}
/// <summary>
/// Represents a token provider that generates tokens from a user's security stamp and
/// sends them to the user via their phone number.
@ -26,31 +11,6 @@ namespace Microsoft.AspNet.Identity
public class PhoneNumberTokenProvider<TUser> : TotpSecurityStampBasedTokenProvider<TUser>
where TUser : class
{
/// <summary>
/// Creates a new instance of <see cref="PhoneNumberTokenProvider{TUser}"/> with the specified <paramref name="options"/>.
/// </summary>
/// <param name="options">The options to use for the created instance of a <see cref="PhoneNumberTokenProvider{TUser}"/>.</param>
public PhoneNumberTokenProvider(IOptions<PhoneNumberTokenProviderOptions> options)
{
if (options == null || options.Options == null)
{
throw new ArgumentNullException(nameof(options));
}
Options = options.Options;
}
/// <summary>
/// Gets the options for this instance of <see cref="PhoneNumberTokenProvider{TUser}"/>.
/// </summary>
/// <value>The options for this instance of <see cref="PhoneNumberTokenProvider{TUser}"/>.</value>
public PhoneNumberTokenProviderOptions Options { get; private set; }
/// <summary>
/// Gets the name for this instance of <see cref="PhoneNumberTokenProvider{TUser}"/>.
/// </summary>
/// <value>The name for this instance of <see cref="PhoneNumberTokenProvider{TUser}"/>.</value>
public override string Name { get { return Options.Name; } }
/// <summary>
/// Returns a flag indicating whether the token provider can generate a token suitable for two factor authentication token for
/// the specified <paramref name="ref"/>.

View File

@ -53,7 +53,7 @@ namespace System.Security.Claims
throw new ArgumentNullException(nameof(principal));
}
return principal?.Identities != null &&
principal.Identities.Any(i => i.AuthenticationType == IdentityOptions.ApplicationCookieAuthenticationType);
principal.Identities.Any(i => i.AuthenticationType == IdentityCookieOptions.ApplicationCookieAuthenticationType);
}
/// <summary>

View File

@ -42,22 +42,6 @@ namespace Microsoft.AspNet.Identity
return GetString("DefaultError");
}
/// <summary>
/// Default Token Provider
/// </summary>
internal static string DefaultTokenProvider
{
get { return GetString("DefaultTokenProvider"); }
}
/// <summary>
/// Default Token Provider
/// </summary>
internal static string FormatDefaultTokenProvider()
{
return GetString("DefaultTokenProvider");
}
/// <summary>
/// Email '{0}' is already taken.
/// </summary>
@ -123,7 +107,7 @@ namespace Microsoft.AspNet.Identity
}
/// <summary>
/// Type {0} must be derived from {1}&lt;{2}&gt;.
/// Type {0} must derive from {1}&lt;{2}&gt;.
/// </summary>
internal static string InvalidManagerType
{
@ -131,7 +115,7 @@ namespace Microsoft.AspNet.Identity
}
/// <summary>
/// Type {0} must be derived from {1}&lt;{2}&gt;.
/// Type {0} must derive from {1}&lt;{2}&gt;.
/// </summary>
internal static string FormatInvalidManagerType(object p0, object p1, object p2)
{

View File

@ -125,10 +125,6 @@
<value>An unknown failure has occured.</value>
<comment>Default identity result error message</comment>
</data>
<data name="DefaultTokenProvider" xml:space="preserve">
<value>Default Token Provider</value>
<comment>Name of the default token provider</comment>
</data>
<data name="DuplicateEmail" xml:space="preserve">
<value>Email '{0}' is already taken.</value>
<comment>Error for duplicate emails</comment>

View File

@ -74,7 +74,7 @@ namespace Microsoft.AspNet.Identity
{
var timeElapsed = currentUtc.Subtract(issuedUtc.Value);
var accessor = context.HttpContext.RequestServices.GetRequiredService<IOptions<IdentityOptions>>();
validate = timeElapsed > accessor.Options.SecurityStampValidationInterval;
validate = timeElapsed > accessor.Value.SecurityStampValidationInterval;
}
if (validate)
{

View File

@ -54,7 +54,7 @@ namespace Microsoft.AspNet.Identity
UserManager = userManager;
Context = contextAccessor.HttpContext;
ClaimsFactory = claimsFactory;
Options = optionsAccessor?.Options ?? new IdentityOptions();
Options = optionsAccessor?.Value ?? new IdentityOptions();
Logger = logger;
}
@ -109,7 +109,7 @@ namespace Microsoft.AspNet.Identity
/// <returns>The task object representing the asynchronous operation.</returns>
public virtual async Task RefreshSignInAsync(TUser user)
{
var auth = new AuthenticateContext(IdentityOptions.ApplicationCookieAuthenticationScheme);
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);
@ -142,7 +142,7 @@ namespace Microsoft.AspNet.Identity
{
userPrincipal.Identities.First().AddClaim(new Claim(ClaimTypes.AuthenticationMethod, authenticationMethod));
}
await Context.Authentication.SignInAsync(IdentityOptions.ApplicationCookieAuthenticationScheme,
await Context.Authentication.SignInAsync(Options.Cookies.ApplicationCookieAuthenticationScheme,
userPrincipal,
authenticationProperties ?? new AuthenticationProperties());
}
@ -152,9 +152,9 @@ namespace Microsoft.AspNet.Identity
/// </summary>
public virtual async Task SignOutAsync()
{
await Context.Authentication.SignOutAsync(IdentityOptions.ApplicationCookieAuthenticationScheme);
await Context.Authentication.SignOutAsync(IdentityOptions.ExternalCookieAuthenticationScheme);
await Context.Authentication.SignOutAsync(IdentityOptions.TwoFactorUserIdCookieAuthenticationScheme);
await Context.Authentication.SignOutAsync(Options.Cookies.ApplicationCookieAuthenticationScheme);
await Context.Authentication.SignOutAsync(Options.Cookies.ExternalCookieAuthenticationScheme);
await Context.Authentication.SignOutAsync(Options.Cookies.TwoFactorUserIdCookieAuthenticationScheme);
}
/// <summary>
@ -260,7 +260,7 @@ namespace Microsoft.AspNet.Identity
public virtual async Task<bool> IsTwoFactorClientRememberedAsync(TUser user)
{
var userId = await UserManager.GetUserIdAsync(user);
var result = await Context.Authentication.AuthenticateAsync(IdentityOptions.TwoFactorRememberMeCookieAuthenticationScheme);
var result = await Context.Authentication.AuthenticateAsync(Options.Cookies.TwoFactorRememberMeCookieAuthenticationScheme);
return (result != null && result.FindFirstValue(ClaimTypes.Name) == userId);
}
@ -273,9 +273,9 @@ namespace Microsoft.AspNet.Identity
public virtual async Task RememberTwoFactorClientAsync(TUser user)
{
var userId = await UserManager.GetUserIdAsync(user);
var rememberBrowserIdentity = new ClaimsIdentity(IdentityOptions.TwoFactorRememberMeCookieAuthenticationType);
var rememberBrowserIdentity = new ClaimsIdentity(Options.Cookies.TwoFactorRememberMeCookieAuthenticationScheme);
rememberBrowserIdentity.AddClaim(new Claim(ClaimTypes.Name, userId));
await Context.Authentication.SignInAsync(IdentityOptions.TwoFactorRememberMeCookieAuthenticationScheme,
await Context.Authentication.SignInAsync(Options.Cookies.TwoFactorRememberMeCookieAuthenticationScheme,
new ClaimsPrincipal(rememberBrowserIdentity),
new AuthenticationProperties { IsPersistent = true });
}
@ -286,7 +286,7 @@ namespace Microsoft.AspNet.Identity
/// <returns>The task object representing the asynchronous operation.</returns>
public virtual Task ForgetTwoFactorClientAsync()
{
return Context.Authentication.SignOutAsync(IdentityOptions.TwoFactorRememberMeCookieAuthenticationScheme);
return Context.Authentication.SignOutAsync(Options.Cookies.TwoFactorRememberMeCookieAuthenticationScheme);
}
/// <summary>
@ -325,7 +325,7 @@ namespace Microsoft.AspNet.Identity
// Cleanup external cookie
if (twoFactorInfo.LoginProvider != null)
{
await Context.Authentication.SignOutAsync(IdentityOptions.ExternalCookieAuthenticationScheme);
await Context.Authentication.SignOutAsync(Options.Cookies.ExternalCookieAuthenticationScheme);
}
if (rememberClient)
{
@ -397,7 +397,7 @@ namespace Microsoft.AspNet.Identity
/// for the sign-in attempt.</returns>
public virtual async Task<ExternalLoginInfo> GetExternalLoginInfoAsync(string expectedXsrf = null)
{
var auth = new AuthenticateContext(IdentityOptions.ExternalCookieAuthenticationScheme);
var auth = new AuthenticateContext(Options.Cookies.ExternalCookieAuthenticationScheme);
await Context.Authentication.AuthenticateAsync(auth);
if (auth.Principal == null || auth.Properties == null || !auth.Properties.ContainsKey(LoginProviderKey))
{
@ -451,9 +451,9 @@ namespace Microsoft.AspNet.Identity
/// <param name="userId">The user whose is logging in via 2fa.</param>
/// <param name="loginProvider">The 2fa provider.</param>
/// <returns>A <see cref="ClaimsPrincipal"/> containing the user 2fa information.</returns>
internal static ClaimsPrincipal StoreTwoFactorInfo(string userId, string loginProvider)
internal ClaimsPrincipal StoreTwoFactorInfo(string userId, string loginProvider)
{
var identity = new ClaimsIdentity(IdentityOptions.TwoFactorUserIdCookieAuthenticationType);
var identity = new ClaimsIdentity(Options.Cookies.TwoFactorUserIdCookieAuthenticationScheme);
identity.AddClaim(new Claim(ClaimTypes.Name, userId));
if (loginProvider != null)
{
@ -462,13 +462,13 @@ namespace Microsoft.AspNet.Identity
return new ClaimsPrincipal(identity);
}
private static ClaimsIdentity CreateIdentity(TwoFactorAuthenticationInfo info)
private ClaimsIdentity CreateIdentity(TwoFactorAuthenticationInfo info)
{
if (info == null)
{
return null;
}
var identity = new ClaimsIdentity(IdentityOptions.TwoFactorUserIdCookieAuthenticationType);
var identity = new ClaimsIdentity(Options.Cookies.TwoFactorUserIdCookieAuthenticationScheme);
identity.AddClaim(new Claim(ClaimTypes.Name, info.UserId));
if (info.LoginProvider != null)
{
@ -488,14 +488,14 @@ namespace Microsoft.AspNet.Identity
{
// Store the userId for use after two factor check
var userId = await UserManager.GetUserIdAsync(user);
await Context.Authentication.SignInAsync(IdentityOptions.TwoFactorUserIdCookieAuthenticationScheme, StoreTwoFactorInfo(userId, loginProvider));
await Context.Authentication.SignInAsync(Options.Cookies.TwoFactorUserIdCookieAuthenticationScheme, StoreTwoFactorInfo(userId, loginProvider));
return SignInResult.TwoFactorRequired;
}
}
// Cleanup external cookie
if (loginProvider != null)
{
await Context.Authentication.SignOutAsync(IdentityOptions.ExternalCookieAuthenticationScheme);
await Context.Authentication.SignOutAsync(Options.Cookies.ExternalCookieAuthenticationScheme);
}
await SignInAsync(user, isPersistent, loginProvider);
return SignInResult.Success;
@ -503,7 +503,7 @@ namespace Microsoft.AspNet.Identity
private async Task<TwoFactorAuthenticationInfo> RetrieveTwoFactorInfoAsync()
{
var result = await Context.Authentication.AuthenticateAsync(IdentityOptions.TwoFactorUserIdCookieAuthenticationScheme);
var result = await Context.Authentication.AuthenticateAsync(Options.Cookies.TwoFactorUserIdCookieAuthenticationScheme);
if (result != null)
{
return new TwoFactorAuthenticationInfo

View File

@ -0,0 +1,44 @@
// 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 System.Collections.Generic;
namespace Microsoft.AspNet.Identity
{
public class TokenOptions
{
public static readonly string DefaultProvider = "Default";
public static readonly string DefaultEmailProvider = "Email";
public static readonly string DefaultPhoneProvider = "Phone";
/// <summary>
/// Will be used to construct UserTokenProviders with the key used as the providerName.
/// </summary>
public Dictionary<string, TokenProviderDescriptor> ProviderMap { get; set; } = new Dictionary<string, TokenProviderDescriptor>();
/// <summary>
/// Gets or sets the <see cref="EmailConfirmationTokenProvider"/> used to generate tokens used in account confirmation emails.
/// </summary>
/// <value>
/// The <see cref="EmailConfirmationTokenProvider"/> used to generate tokens used in account confirmation emails.
/// </value>
public string EmailConfirmationTokenProvider { get; set; } = DefaultProvider;
/// <summary>
/// Gets or sets the <see cref="PasswordResetTokenProvider"/> used to generate tokens used in password reset emails.
/// </summary>
/// <value>
/// The <see cref="PasswordResetTokenProvider"/> used to generate tokens used in password reset emails.
/// </value>
public string PasswordResetTokenProvider { get; set; } = DefaultProvider;
/// <summary>
/// Gets or sets the <see cref="ChangeEmailTokenProvider"/> used to generate tokens used in email change confirmation emails.
/// </summary>
/// <value>
/// The <see cref="ChangeEmailTokenProvider"/> used to generate tokens used in email change confirmation emails.
/// </value>
public string ChangeEmailTokenProvider { get; set; } = DefaultProvider;
}
}

View File

@ -0,0 +1,17 @@
// 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;
namespace Microsoft.AspNet.Identity
{
public class TokenProviderDescriptor
{
public TokenProviderDescriptor(Type type)
{
ProviderType = type;
}
public Type ProviderType { get; }
}
}

View File

@ -12,12 +12,6 @@ namespace Microsoft.AspNet.Identity
public abstract class TotpSecurityStampBasedTokenProvider<TUser> : IUserTokenProvider<TUser>
where TUser : class
{
/// <summary>
/// Gets the name of the token provider.
/// </summary>
/// <value>The name of the token provider.</value>
public abstract string Name { get; }
/// <summary>
/// Generates a token for the specified <paramref name="ref"/> and <paramref name="purpose"/>, as an asynchronous operation.
/// </summary>

View File

@ -38,13 +38,13 @@ namespace Microsoft.AspNet.Identity
{
throw new ArgumentNullException(nameof(roleManager));
}
if (optionsAccessor == null || optionsAccessor.Options == null)
if (optionsAccessor == null || optionsAccessor.Value == null)
{
throw new ArgumentNullException(nameof(optionsAccessor));
}
UserManager = userManager;
RoleManager = roleManager;
Options = optionsAccessor.Options;
Options = optionsAccessor.Value;
}
/// <summary>
@ -85,7 +85,7 @@ namespace Microsoft.AspNet.Identity
}
var userId = await UserManager.GetUserIdAsync(user);
var userName = await UserManager.GetUserNameAsync(user);
var id = new ClaimsIdentity(IdentityOptions.ApplicationCookieAuthenticationType,
var id = new ClaimsIdentity(Options.Cookies.TwoFactorRememberMeCookieAuthenticationScheme,
Options.ClaimsIdentity.UserNameClaimType,
Options.ClaimsIdentity.RoleClaimType);
id.AddClaim(new Claim(Options.ClaimsIdentity.UserIdClaimType, userId));

View File

@ -12,6 +12,7 @@ using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNet.Hosting;
using Microsoft.AspNet.Http;
using Microsoft.Framework.DependencyInjection;
using Microsoft.Framework.Logging;
using Microsoft.Framework.OptionsModel;
@ -51,7 +52,7 @@ namespace Microsoft.AspNet.Identity
IEnumerable<IPasswordValidator<TUser>> passwordValidators,
ILookupNormalizer keyNormalizer,
IdentityErrorDescriber errors,
IEnumerable<IUserTokenProvider<TUser>> tokenProviders,
IServiceProvider services,
ILogger<UserManager<TUser>> logger,
IHttpContextAccessor contextAccessor)
{
@ -60,7 +61,7 @@ namespace Microsoft.AspNet.Identity
throw new ArgumentNullException(nameof(store));
}
Store = store;
Options = optionsAccessor?.Options ?? new IdentityOptions();
Options = optionsAccessor?.Value ?? new IdentityOptions();
_context = contextAccessor?.HttpContext;
PasswordHasher = passwordHasher;
KeyNormalizer = keyNormalizer;
@ -82,11 +83,15 @@ namespace Microsoft.AspNet.Identity
}
}
if (tokenProviders != null)
if (services != null)
{
foreach (var tokenProvider in tokenProviders)
foreach (var providerName in Options.Tokens.ProviderMap.Keys)
{
RegisterTokenProvider(tokenProvider);
var provider = services.GetRequiredService(Options.Tokens.ProviderMap[providerName].ProviderType) as IUserTokenProvider<TUser>;
if (provider != null)
{
RegisterTokenProvider(providerName, provider);
}
}
}
}
@ -715,7 +720,7 @@ namespace Microsoft.AspNet.Identity
public virtual Task<string> GeneratePasswordResetTokenAsync(TUser user)
{
ThrowIfDisposed();
return GenerateUserTokenAsync(user, Options.PasswordResetTokenProvider, "ResetPassword");
return GenerateUserTokenAsync(user, Options.Tokens.PasswordResetTokenProvider, "ResetPassword");
}
/// <summary>
@ -738,7 +743,7 @@ namespace Microsoft.AspNet.Identity
}
// Make sure the token is valid and the stamp matches
if (!await VerifyUserTokenAsync(user, Options.PasswordResetTokenProvider, "ResetPassword", token))
if (!await VerifyUserTokenAsync(user, Options.Tokens.PasswordResetTokenProvider, "ResetPassword", token))
{
return IdentityResult.Failed(ErrorDescriber.InvalidToken());
}
@ -1260,7 +1265,7 @@ namespace Microsoft.AspNet.Identity
public virtual Task<string> GenerateEmailConfirmationTokenAsync(TUser user)
{
ThrowIfDisposed();
return GenerateUserTokenAsync(user, Options.EmailConfirmationTokenProvider, "EmailConfirmation");
return GenerateUserTokenAsync(user, Options.Tokens.EmailConfirmationTokenProvider, "EmailConfirmation");
}
/// <summary>
@ -1281,7 +1286,7 @@ namespace Microsoft.AspNet.Identity
throw new ArgumentNullException("user");
}
if (!await VerifyUserTokenAsync(user, Options.EmailConfirmationTokenProvider, "EmailConfirmation", token))
if (!await VerifyUserTokenAsync(user, Options.Tokens.EmailConfirmationTokenProvider, "EmailConfirmation", token))
{
return IdentityResult.Failed(ErrorDescriber.InvalidToken());
}
@ -1319,7 +1324,7 @@ namespace Microsoft.AspNet.Identity
public virtual Task<string> GenerateChangeEmailTokenAsync(TUser user, string newEmail)
{
ThrowIfDisposed();
return GenerateUserTokenAsync(user, Options.ChangeEmailTokenProvider, GetChangeEmailPurpose(newEmail));
return GenerateUserTokenAsync(user, Options.Tokens.ChangeEmailTokenProvider, GetChangeEmailPurpose(newEmail));
}
/// <summary>
@ -1341,7 +1346,7 @@ namespace Microsoft.AspNet.Identity
}
// Make sure the token is valid and the stamp matches
if (!await VerifyUserTokenAsync(user, Options.ChangeEmailTokenProvider, GetChangeEmailPurpose(newEmail), token))
if (!await VerifyUserTokenAsync(user, Options.Tokens.ChangeEmailTokenProvider, GetChangeEmailPurpose(newEmail), token))
{
return IdentityResult.Failed(ErrorDescriber.InvalidToken());
}
@ -1556,15 +1561,16 @@ namespace Microsoft.AspNet.Identity
/// <summary>
/// Registers a token provider.
/// </summary>
/// <param name="providerName">The name of the provider to register.</param>
/// <param name="provider">The provider to register.</param>
public virtual void RegisterTokenProvider(IUserTokenProvider<TUser> provider)
public virtual void RegisterTokenProvider(string providerName, IUserTokenProvider<TUser> provider)
{
ThrowIfDisposed();
if (provider == null)
{
throw new ArgumentNullException("provider");
}
_tokenProviders[provider.Name] = provider;
_tokenProviders[providerName] = provider;
}
/// <summary>

View File

@ -1,8 +1,6 @@
// 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;
namespace Microsoft.AspNet.Identity
{
/// <summary>

View File

@ -13,5 +13,8 @@
<PropertyGroup>
<SchemaVersion>2.0</SchemaVersion>
</PropertyGroup>
<ItemGroup>
<Service Include="{82a7f48d-3b50-4b1e-b82e-3ada8210c358}" />
</ItemGroup>
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.targets" Condition="'$(VSToolsPath)' != ''" />
</Project>

View File

@ -37,7 +37,7 @@ namespace Microsoft.AspNet.Identity.InMemory
public async Task CanChangePasswordOptions()
{
var clock = new TestClock();
var server = CreateServer(services => services.ConfigureIdentity(options =>
var server = CreateServer(services => services.Configure<IdentityOptions>(options =>
{
options.Password.RequireUppercase = false;
options.Password.RequireNonLetterOrDigit = false;
@ -53,11 +53,11 @@ namespace Microsoft.AspNet.Identity.InMemory
public async Task CanCreateMeLoginAndCookieStopsWorkingAfterExpiration()
{
var clock = new TestClock();
var server = CreateServer(services => services.ConfigureIdentityApplicationCookie(appCookieOptions =>
var server = CreateServer(services => services.Configure<IdentityOptions>(options =>
{
appCookieOptions.SystemClock = clock;
appCookieOptions.ExpireTimeSpan = TimeSpan.FromMinutes(10);
appCookieOptions.SlidingExpiration = false;
options.Cookies.ApplicationCookie.SystemClock = clock;
options.Cookies.ApplicationCookie.ExpireTimeSpan = TimeSpan.FromMinutes(10);
options.Cookies.ApplicationCookie.SlidingExpiration = false;
}));
var transaction1 = await SendAsync(server, "http://example.com/createMe");
@ -92,9 +92,9 @@ namespace Microsoft.AspNet.Identity.InMemory
public async Task CanCreateMeLoginAndSecurityStampExtendsExpiration(bool rememberMe)
{
var clock = new TestClock();
var server = CreateServer(services => services.ConfigureIdentityApplicationCookie(appCookieOptions =>
var server = CreateServer(services => services.Configure<IdentityOptions>(options =>
{
appCookieOptions.SystemClock = clock;
options.Cookies.ApplicationCookie.SystemClock = clock;
}));
var transaction1 = await SendAsync(server, "http://example.com/createMe");
@ -148,7 +148,7 @@ namespace Microsoft.AspNet.Identity.InMemory
transaction2.Response.StatusCode.ShouldBe(HttpStatusCode.OK);
string setCookie = transaction2.SetCookie;
setCookie.ShouldContain(IdentityOptions.TwoFactorRememberMeCookieAuthenticationScheme + "=");
setCookie.ShouldContain(new IdentityCookieOptions().TwoFactorRememberMeCookieAuthenticationScheme + "=");
setCookie.ShouldContain("; expires=");
var transaction3 = await SendAsync(server, "http://example.com/isTwoFactorRememebered", transaction2.CookieNameValue);

View File

@ -30,7 +30,7 @@ namespace Microsoft.AspNet.Identity.InMemory.Test
var context = new Mock<HttpContext>();
var auth = new Mock<AuthenticationManager>();
context.Setup(c => c.Authentication).Returns(auth.Object).Verifiable();
auth.Setup(a => a.SignInAsync(IdentityOptions.ApplicationCookieAuthenticationScheme,
auth.Setup(a => a.SignInAsync(new IdentityCookieOptions().ApplicationCookieAuthenticationScheme,
It.IsAny<ClaimsPrincipal>(),
It.IsAny<AuthenticationProperties>())).Returns(Task.FromResult(0)).Verifiable();
// REVIEW: is persistant mocking broken

View File

@ -13,5 +13,8 @@
<PropertyGroup>
<SchemaVersion>2.0</SchemaVersion>
</PropertyGroup>
<ItemGroup>
<Service Include="{82a7f48d-3b50-4b1e-b82e-3ada8210c358}" />
</ItemGroup>
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.targets" Condition="'$(VSToolsPath)' != ''" />
</Project>

View File

@ -7,6 +7,7 @@ using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Framework.DependencyInjection;
using Microsoft.Framework.OptionsModel;
using Xunit;
namespace Microsoft.AspNet.Identity.Test
@ -105,10 +106,30 @@ namespace Microsoft.AspNet.Identity.Test
services.AddIdentity<TestUser,TestRole>().AddDefaultTokenProviders();
var provider = services.BuildServiceProvider();
var tokenProviders = provider.GetRequiredService<IEnumerable<IUserTokenProvider<TestUser>>>();
var tokenProviders = provider.GetRequiredService<IOptions<IdentityOptions>>().Value.Tokens.ProviderMap.Values;
Assert.Equal(3, tokenProviders.Count());
}
[Fact]
public void AddManagerWithWrongTypesThrows()
{
var services = new ServiceCollection();
var builder = services.AddIdentity<TestUser, TestRole>();
Assert.Throws<InvalidOperationException>(() => builder.AddUserManager<UserManager<TestUser>>());
Assert.Throws<InvalidOperationException>(() => builder.AddRoleManager<RoleManager<TestRole>>());
Assert.Throws<InvalidOperationException>(() => builder.AddUserManager<object>());
Assert.Throws<InvalidOperationException>(() => builder.AddRoleManager<object>());
}
[Fact]
public void AddTokenProviderWithWrongTypesThrows()
{
var services = new ServiceCollection();
var builder = services.AddIdentity<TestUser, TestRole>();
Assert.Throws<InvalidOperationException>(() => builder.AddTokenProvider<object>("whatevs"));
Assert.Throws<InvalidOperationException>(() => builder.AddTokenProvider("whatevs", typeof(object)));
}
private class MyUberThingy : IUserValidator<TestUser>, IPasswordValidator<TestUser>, IRoleValidator<TestRole>, IUserStore<TestUser>, IRoleStore<TestRole>
{
public Task<IdentityResult> CreateAsync(TestRole role, CancellationToken cancellationToken = default(CancellationToken))

View File

@ -66,10 +66,10 @@ namespace Microsoft.AspNet.Identity.Test
var services = new ServiceCollection();
services.AddIdentity<TestUser,TestRole>();
services.ConfigureIdentity(config.GetSection("identity"));
services.Configure<IdentityOptions>(config.GetSection("identity"));
var accessor = services.BuildServiceProvider().GetRequiredService<IOptions<IdentityOptions>>();
Assert.NotNull(accessor);
var options = accessor.Options;
var options = accessor.Value;
Assert.Equal(roleClaimType, options.ClaimsIdentity.RoleClaimType);
Assert.Equal(useridClaimType, options.ClaimsIdentity.UserIdClaimType);
Assert.Equal(usernameClaimType, options.ClaimsIdentity.UserNameClaimType);
@ -96,11 +96,11 @@ namespace Microsoft.AspNet.Identity.Test
var builder = new ConfigurationBuilder(new MemoryConfigurationSource(dic));
var config = builder.Build();
var services = new ServiceCollection();
services.ConfigureIdentity(config.GetSection("identity"));
services.Configure<IdentityOptions>(config.GetSection("identity"));
services.AddIdentity<TestUser, TestRole>(o => { o.User.RequireUniqueEmail = false; o.Lockout.MaxFailedAccessAttempts++; });
var accessor = services.BuildServiceProvider().GetRequiredService<IOptions<IdentityOptions>>();
Assert.NotNull(accessor);
var options = accessor.Options;
var options = accessor.Value;
Assert.False(options.User.RequireUniqueEmail);
Assert.Equal(1001, options.Lockout.MaxFailedAccessAttempts);
}
@ -124,7 +124,7 @@ namespace Microsoft.AspNet.Identity.Test
Assert.IsType(typeof(PasswordsNegativeLengthSetup), setup);
var optionsGetter = serviceProvider.GetRequiredService<IOptions<IdentityOptions>>();
Assert.NotNull(optionsGetter);
var myOptions = optionsGetter.Options;
var myOptions = optionsGetter.Value;
Assert.True(myOptions.Password.RequireLowercase);
Assert.True(myOptions.Password.RequireDigit);
Assert.True(myOptions.Password.RequireNonLetterOrDigit);
@ -135,16 +135,14 @@ namespace Microsoft.AspNet.Identity.Test
[Fact]
public void CanSetupIdentityOptions()
{
var services = new ServiceCollection()
.AddOptions()
.ConfigureIdentity(options => options.User.RequireUniqueEmail = true);
services.AddIdentity<TestUser,TestRole>();
var services = new ServiceCollection();
services.AddIdentity<TestUser,TestRole>(options => options.User.RequireUniqueEmail = true);
var serviceProvider = services.BuildServiceProvider();
var optionsGetter = serviceProvider.GetRequiredService<IOptions<IdentityOptions>>();
Assert.NotNull(optionsGetter);
var myOptions = optionsGetter.Options;
var myOptions = optionsGetter.Value;
Assert.True(myOptions.User.RequireUniqueEmail);
}
}

View File

@ -164,14 +164,14 @@ namespace Microsoft.AspNet.Identity.Test
var options = new PasswordHasherOptionsAccessor();
if (compatMode != null)
{
options.Options.CompatibilityMode = (PasswordHasherCompatibilityMode)compatMode;
options.Value.CompatibilityMode = (PasswordHasherCompatibilityMode)compatMode;
}
if (iterCount != null)
{
options.Options.IterationCount = (int)iterCount;
options.Value.IterationCount = (int)iterCount;
}
Assert.NotNull(options.Options.Rng); // should have a default value
options.Options.Rng = new SequentialRandomNumberGenerator();
Assert.NotNull(options.Value.Rng); // should have a default value
options.Value.Rng = new SequentialRandomNumberGenerator();
return options;
}
}

View File

@ -51,7 +51,7 @@ namespace Microsoft.AspNet.Identity.Test
private static ClaimsPrincipal CreateAppIdentity(string authType = null)
{
authType = authType ?? IdentityOptions.ApplicationCookieAuthenticationType;
authType = authType ?? new IdentityCookieOptions().ApplicationCookieAuthenticationScheme;
return new ClaimsPrincipal(new ClaimsIdentity(
new[]
{

View File

@ -21,10 +21,11 @@ namespace Microsoft.AspNet.Identity.Test
[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(IdentityOptions.ApplicationCookieAuthenticationScheme));
var ticket = new AuthenticationTicket(id, new AuthenticationProperties { IssuedUtc = DateTimeOffset.UtcNow }, IdentityOptions.ApplicationCookieAuthenticationScheme);
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 ex = await Assert.ThrowsAsync<InvalidOperationException>(() => SecurityStampValidator.ValidatePrincipalAsync(context));
Assert.True(ex.Message.Contains("No service for type 'Microsoft.Framework.OptionsModel.IOptions"));
@ -40,11 +41,11 @@ namespace Microsoft.AspNet.Identity.Test
var claimsManager = new Mock<IUserClaimsPrincipalFactory<TestUser>>();
var identityOptions = new IdentityOptions { SecurityStampValidationInterval = TimeSpan.Zero };
var options = new Mock<IOptions<IdentityOptions>>();
options.Setup(a => a.Options).Returns(identityOptions);
options.Setup(a => a.Value).Returns(identityOptions);
var httpContext = new Mock<HttpContext>();
var contextAccessor = new Mock<IHttpContextAccessor>();
contextAccessor.Setup(a => a.HttpContext).Returns(httpContext.Object);
var id = new ClaimsIdentity(IdentityOptions.ApplicationCookieAuthenticationScheme);
var id = new ClaimsIdentity(identityOptions.Cookies.ApplicationCookieAuthenticationScheme);
id.AddClaim(new Claim(ClaimTypes.NameIdentifier, user.Id));
var principal = new ClaimsPrincipal(id);
@ -61,7 +62,7 @@ namespace Microsoft.AspNet.Identity.Test
var ticket = new AuthenticationTicket(principal,
properties,
IdentityOptions.ApplicationCookieAuthenticationScheme);
identityOptions.Cookies.ApplicationCookieAuthenticationScheme);
var context = new CookieValidatePrincipalContext(httpContext.Object, ticket, new CookieAuthenticationOptions());
Assert.NotNull(context.Properties);
Assert.NotNull(context.Options);
@ -80,7 +81,7 @@ namespace Microsoft.AspNet.Identity.Test
var claimsManager = new Mock<IUserClaimsPrincipalFactory<TestUser>>();
var identityOptions = new IdentityOptions { SecurityStampValidationInterval = TimeSpan.Zero };
var options = new Mock<IOptions<IdentityOptions>>();
options.Setup(a => a.Options).Returns(identityOptions);
options.Setup(a => a.Value).Returns(identityOptions);
var httpContext = new Mock<HttpContext>();
var contextAccessor = new Mock<IHttpContextAccessor>();
contextAccessor.Setup(a => a.HttpContext).Returns(httpContext.Object);
@ -92,12 +93,12 @@ namespace Microsoft.AspNet.Identity.Test
services.AddInstance(signInManager.Object);
services.AddInstance<ISecurityStampValidator>(new SecurityStampValidator<TestUser>());
httpContext.Setup(c => c.RequestServices).Returns(services.BuildServiceProvider());
var id = new ClaimsIdentity(IdentityOptions.ApplicationCookieAuthenticationScheme);
var id = new ClaimsIdentity(identityOptions.Cookies.ApplicationCookieAuthenticationScheme);
id.AddClaim(new Claim(ClaimTypes.NameIdentifier, user.Id));
var ticket = new AuthenticationTicket(new ClaimsPrincipal(id),
new AuthenticationProperties { IssuedUtc = DateTimeOffset.UtcNow },
IdentityOptions.ApplicationCookieAuthenticationScheme);
identityOptions.Cookies.ApplicationCookieAuthenticationScheme);
var context = new CookieValidatePrincipalContext(httpContext.Object, ticket, new CookieAuthenticationOptions());
Assert.NotNull(context.Properties);
Assert.NotNull(context.Options);
@ -116,7 +117,7 @@ namespace Microsoft.AspNet.Identity.Test
var claimsManager = new Mock<IUserClaimsPrincipalFactory<TestUser>>();
var identityOptions = new IdentityOptions { SecurityStampValidationInterval = TimeSpan.Zero };
var options = new Mock<IOptions<IdentityOptions>>();
options.Setup(a => a.Options).Returns(identityOptions);
options.Setup(a => a.Value).Returns(identityOptions);
var contextAccessor = new Mock<IHttpContextAccessor>();
contextAccessor.Setup(a => a.HttpContext).Returns(httpContext.Object);
var signInManager = new Mock<SignInManager<TestUser>>(userManager.Object,
@ -127,12 +128,12 @@ namespace Microsoft.AspNet.Identity.Test
services.AddInstance(signInManager.Object);
services.AddInstance<ISecurityStampValidator>(new SecurityStampValidator<TestUser>());
httpContext.Setup(c => c.RequestServices).Returns(services.BuildServiceProvider());
var id = new ClaimsIdentity(IdentityOptions.ApplicationCookieAuthenticationScheme);
var id = new ClaimsIdentity(identityOptions.Cookies.ApplicationCookieAuthenticationScheme);
id.AddClaim(new Claim(ClaimTypes.NameIdentifier, user.Id));
var ticket = new AuthenticationTicket(new ClaimsPrincipal(id),
new AuthenticationProperties(),
IdentityOptions.ApplicationCookieAuthenticationScheme);
identityOptions.Cookies.ApplicationCookieAuthenticationScheme);
var context = new CookieValidatePrincipalContext(httpContext.Object, ticket, new CookieAuthenticationOptions());
Assert.NotNull(context.Properties);
Assert.NotNull(context.Options);
@ -151,7 +152,7 @@ namespace Microsoft.AspNet.Identity.Test
var claimsManager = new Mock<IUserClaimsPrincipalFactory<TestUser>>();
var identityOptions = new IdentityOptions { SecurityStampValidationInterval = TimeSpan.FromDays(1) };
var options = new Mock<IOptions<IdentityOptions>>();
options.Setup(a => a.Options).Returns(identityOptions);
options.Setup(a => a.Value).Returns(identityOptions);
var contextAccessor = new Mock<IHttpContextAccessor>();
contextAccessor.Setup(a => a.HttpContext).Returns(httpContext.Object);
var signInManager = new Mock<SignInManager<TestUser>>(userManager.Object,
@ -163,12 +164,12 @@ namespace Microsoft.AspNet.Identity.Test
services.AddInstance(signInManager.Object);
services.AddInstance<ISecurityStampValidator>(new SecurityStampValidator<TestUser>());
httpContext.Setup(c => c.RequestServices).Returns(services.BuildServiceProvider());
var id = new ClaimsIdentity(IdentityOptions.ApplicationCookieAuthenticationScheme);
var id = new ClaimsIdentity(identityOptions.Cookies.ApplicationCookieAuthenticationScheme);
id.AddClaim(new Claim(ClaimTypes.NameIdentifier, user.Id));
var ticket = new AuthenticationTicket(new ClaimsPrincipal(id),
new AuthenticationProperties { IssuedUtc = DateTimeOffset.UtcNow },
IdentityOptions.ApplicationCookieAuthenticationScheme);
identityOptions.Cookies.ApplicationCookieAuthenticationScheme);
var context = new CookieValidatePrincipalContext(httpContext.Object, ticket, new CookieAuthenticationOptions());
Assert.NotNull(context.Properties);
Assert.NotNull(context.Options);

View File

@ -122,7 +122,7 @@ namespace Microsoft.AspNet.Identity.Test
var roleManager = MockHelpers.MockRoleManager<TestRole>();
var identityOptions = new IdentityOptions();
var options = new Mock<IOptions<IdentityOptions>>();
options.Setup(a => a.Options).Returns(identityOptions);
options.Setup(a => a.Value).Returns(identityOptions);
var claimsFactory = new UserClaimsPrincipalFactory<TestUser, TestRole>(manager.Object, roleManager.Object, options.Object);
var logStore = new StringBuilder();
var logger = MockHelpers.MockILogger<SignInManager<TestUser>>(logStore);
@ -155,7 +155,7 @@ namespace Microsoft.AspNet.Identity.Test
var roleManager = MockHelpers.MockRoleManager<TestRole>();
identityOptions = identityOptions ?? new IdentityOptions();
var options = new Mock<IOptions<IdentityOptions>>();
options.Setup(a => a.Options).Returns(identityOptions);
options.Setup(a => a.Value).Returns(identityOptions);
var claimsFactory = new UserClaimsPrincipalFactory<TestUser, TestRole>(manager, roleManager.Object, options.Object);
var sm = new SignInManager<TestUser>(manager, contextAccessor.Object, claimsFactory, options.Object, null);
sm.Logger = MockHelpers.MockILogger<SignInManager<TestUser>>(logStore ?? new StringBuilder()).Object;
@ -268,11 +268,11 @@ namespace Microsoft.AspNet.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(IdentityOptions.TwoFactorUserIdCookieAuthenticationScheme,
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 helper = SetupSignInManager(manager.Object, context.Object);
// Act
var result = await helper.PasswordSignInAsync(user.UserName, "password", false, false);
@ -340,7 +340,7 @@ namespace Microsoft.AspNet.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 == IdentityOptions.ApplicationCookieAuthenticationScheme)))
auth.Setup(a => a.AuthenticateAsync(It.Is<AuthenticateContext>(c => c.AuthenticationScheme == IdentityCookieOptions.ApplicationCookieAuthenticationType)))
.Returns(Task.FromResult(0)).Verifiable();
var manager = SetupUserManager(user);
@ -398,17 +398,18 @@ namespace Microsoft.AspNet.Identity.Test
var auth = new Mock<AuthenticationManager>();
var twoFactorInfo = new SignInManager<TestUser>.TwoFactorAuthenticationInfo { UserId = user.Id };
var loginProvider = "loginprovider";
var id = SignInManager<TestUser>.StoreTwoFactorInfo(user.Id, externalLogin ? loginProvider : null);
var helper = SetupSignInManager(manager.Object, context.Object);
var id = helper.StoreTwoFactorInfo(user.Id, externalLogin ? loginProvider : null);
if (externalLogin)
{
auth.Setup(a => a.SignInAsync(
IdentityOptions.ApplicationCookieAuthenticationScheme,
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(IdentityOptions.ExternalCookieAuthenticationScheme)).Returns(Task.FromResult(0)).Verifiable();
auth.Setup(a => a.SignOutAsync(helper.Options.Cookies.ExternalCookieAuthenticationScheme)).Returns(Task.FromResult(0)).Verifiable();
}
else
{
@ -417,15 +418,14 @@ namespace Microsoft.AspNet.Identity.Test
if (rememberClient)
{
auth.Setup(a => a.SignInAsync(
IdentityOptions.TwoFactorRememberMeCookieAuthenticationScheme,
helper.Options.Cookies.TwoFactorRememberMeCookieAuthenticationScheme,
It.Is<ClaimsPrincipal>(i => i.FindFirstValue(ClaimTypes.Name) == user.Id
&& i.Identities.First().AuthenticationType == IdentityOptions.TwoFactorRememberMeCookieAuthenticationType),
&& 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(IdentityOptions.TwoFactorUserIdCookieAuthenticationScheme)).ReturnsAsync(id).Verifiable();
auth.Setup(a => a.AuthenticateAsync(helper.Options.Cookies.TwoFactorUserIdCookieAuthenticationScheme)).ReturnsAsync(id).Verifiable();
context.Setup(c => c.Authentication).Returns(auth.Object).Verifiable();
var helper = SetupSignInManager(manager.Object, context.Object);
// Act
var result = await helper.TwoFactorSignInAsync(provider, code, isPersistent, rememberClient);
@ -447,9 +447,9 @@ namespace Microsoft.AspNet.Identity.Test
var auth = new Mock<AuthenticationManager>();
context.Setup(c => c.Authentication).Returns(auth.Object).Verifiable();
auth.Setup(a => a.SignInAsync(
IdentityOptions.TwoFactorRememberMeCookieAuthenticationScheme,
manager.Object.Options.Cookies.TwoFactorRememberMeCookieAuthenticationScheme,
It.Is<ClaimsPrincipal>(i => i.FindFirstValue(ClaimTypes.Name) == user.Id
&& i.Identities.First().AuthenticationType == IdentityOptions.TwoFactorRememberMeCookieAuthenticationType),
&& 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);
@ -483,9 +483,9 @@ namespace Microsoft.AspNet.Identity.Test
var auth = new Mock<AuthenticationManager>();
context.Setup(c => c.Authentication).Returns(auth.Object).Verifiable();
SetupSignIn(auth);
var id = new ClaimsIdentity(IdentityOptions.TwoFactorRememberMeCookieAuthenticationType);
var id = new ClaimsIdentity(manager.Object.Options.Cookies.TwoFactorRememberMeCookieAuthenticationScheme);
id.AddClaim(new Claim(ClaimTypes.Name, user.Id));
auth.Setup(a => a.AuthenticateAsync(IdentityOptions.TwoFactorRememberMeCookieAuthenticationScheme)).ReturnsAsync(new ClaimsPrincipal(id)).Verifiable();
auth.Setup(a => a.AuthenticateAsync(manager.Object.Options.Cookies.TwoFactorRememberMeCookieAuthenticationScheme)).ReturnsAsync(new ClaimsPrincipal(id)).Verifiable();
var helper = SetupSignInManager(manager.Object, context.Object);
// Act
@ -509,9 +509,9 @@ namespace Microsoft.AspNet.Identity.Test
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(IdentityOptions.TwoFactorUserIdCookieAuthenticationScheme)).Returns(Task.FromResult(0)).Verifiable();
auth.Setup(a => a.SignOutAsync(IdentityOptions.ExternalCookieAuthenticationScheme)).Returns(Task.FromResult(0)).Verifiable();
IdentityOptions.ApplicationCookieAuthenticationScheme = authenticationScheme;
auth.Setup(a => a.SignOutAsync(manager.Object.Options.Cookies.TwoFactorUserIdCookieAuthenticationScheme)).Returns(Task.FromResult(0)).Verifiable();
auth.Setup(a => a.SignOutAsync(manager.Object.Options.Cookies.ExternalCookieAuthenticationScheme)).Returns(Task.FromResult(0)).Verifiable();
IdentityCookieOptions.ApplicationCookieAuthenticationType = authenticationScheme;
var helper = SetupSignInManager(manager.Object, context.Object);
// Act
@ -631,7 +631,7 @@ namespace Microsoft.AspNet.Identity.Test
private static void SetupSignIn(Mock<AuthenticationManager> auth, string userId = null, bool? isPersistent = null, string loginProvider = null)
{
auth.Setup(a => a.SignInAsync(IdentityOptions.ApplicationCookieAuthenticationScheme,
auth.Setup(a => a.SignInAsync(IdentityCookieOptions.ApplicationCookieAuthenticationType,
It.Is<ClaimsPrincipal>(id =>
(userId == null || id.FindFirstValue(ClaimTypes.NameIdentifier) == userId) &&
(loginProvider == null || id.FindFirstValue(ClaimTypes.AuthenticationMethod) == loginProvider)),

View File

@ -22,7 +22,7 @@ namespace Microsoft.AspNet.Identity.Test
Assert.Throws<ArgumentNullException>("optionsAccessor",
() => new UserClaimsPrincipalFactory<TestUser, TestRole>(userManager, roleManager, options.Object));
var identityOptions = new IdentityOptions();
options.Setup(a => a.Options).Returns(identityOptions);
options.Setup(a => a.Value).Returns(identityOptions);
var factory = new UserClaimsPrincipalFactory<TestUser, TestRole>(userManager, roleManager, options.Object);
await Assert.ThrowsAsync<ArgumentNullException>("user",
async () => await factory.CreateAsync(null));
@ -72,7 +72,7 @@ namespace Microsoft.AspNet.Identity.Test
var options = new Mock<IOptions<IdentityOptions>>();
var identityOptions = new IdentityOptions();
options.Setup(a => a.Options).Returns(identityOptions);
options.Setup(a => a.Value).Returns(identityOptions);
var factory = new UserClaimsPrincipalFactory<TestUser, TestRole>(userManager.Object, roleManager.Object, options.Object);
// Act
@ -83,7 +83,7 @@ namespace Microsoft.AspNet.Identity.Test
var manager = userManager.Object;
Assert.NotNull(identity);
Assert.Equal(1, principal.Identities.Count());
Assert.Equal(IdentityOptions.ApplicationCookieAuthenticationType, identity.AuthenticationType);
Assert.Equal(identityOptions.Cookies.TwoFactorRememberMeCookieAuthenticationScheme, identity.AuthenticationType);
var claims = identity.Claims.ToList();
Assert.NotNull(claims);
Assert.True(

View File

@ -48,17 +48,6 @@ namespace Microsoft.AspNet.Identity.Test
provider.GetRequiredService<CustomRoleManager>());
}
[Fact]
public void AddManagerWithWrongTypesThrows()
{
var services = new ServiceCollection();
var builder = services.AddIdentity<TestUser, TestRole>();
Assert.Throws<InvalidOperationException>(() => builder.AddUserManager<UserManager<TestUser>>());
Assert.Throws<InvalidOperationException>(() => builder.AddRoleManager<RoleManager<TestRole>>());
Assert.Throws<InvalidOperationException>(() => builder.AddUserManager<object>());
Assert.Throws<InvalidOperationException>(() => builder.AddRoleManager<object>());
}
public class CustomUserManager : UserManager<TestUser>
{
public CustomUserManager() : base(new Mock<IUserStore<TestUser>>().Object, null, null, null, null, null, null, null, null, null)
@ -714,7 +703,7 @@ namespace Microsoft.AspNet.Identity.Test
await Assert.ThrowsAsync<ArgumentNullException>("providerKey",
async () => await manager.RemoveLoginAsync(null, "", null));
await Assert.ThrowsAsync<ArgumentNullException>("email", async () => await manager.FindByEmailAsync(null));
Assert.Throws<ArgumentNullException>("provider", () => manager.RegisterTokenProvider(null));
Assert.Throws<ArgumentNullException>("provider", () => manager.RegisterTokenProvider("whatever", null));
await Assert.ThrowsAsync<ArgumentNullException>("roles", async () => await manager.AddToRolesAsync(new TestUser(), null));
await Assert.ThrowsAsync<ArgumentNullException>("roles", async () => await manager.RemoveFromRolesAsync(new TestUser(), null));
}
@ -723,7 +712,7 @@ namespace Microsoft.AspNet.Identity.Test
public async Task MethodsFailWithUnknownUserTest()
{
var manager = MockHelpers.TestUserManager(new EmptyStore());
manager.RegisterTokenProvider(new NoOpTokenProvider());
manager.RegisterTokenProvider("whatever", new NoOpTokenProvider());
await Assert.ThrowsAsync<ArgumentNullException>("user",
async () => await manager.GetUserNameAsync(null));
await Assert.ThrowsAsync<ArgumentNullException>("user",

View File

@ -3,14 +3,11 @@
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using System.Text;
using Microsoft.Framework.Logging;
using Moq;
using Microsoft.Framework.OptionsModel;
using System.Linq;
using Microsoft.AspNet.Hosting;
namespace Microsoft.AspNet.Identity.Test
{
@ -70,7 +67,7 @@ namespace Microsoft.AspNet.Identity.Test
var options = new Mock<IOptions<IdentityOptions>>();
var idOptions = new IdentityOptions();
idOptions.Lockout.AllowedForNewUsers = false;
options.Setup(o => o.Options).Returns(idOptions);
options.Setup(o => o.Value).Returns(idOptions);
var userValidators = new List<IUserValidator<TUser>>();
var validator = new Mock<IUserValidator<TUser>>();
userValidators.Add(validator.Object);
@ -78,7 +75,7 @@ namespace Microsoft.AspNet.Identity.Test
pwdValidators.Add(new PasswordValidator<TUser>());
var userManager = new UserManager<TUser>(store, options.Object, new PasswordHasher<TUser>(),
userValidators, pwdValidators, new UpperInvariantLookupNormalizer(),
new IdentityErrorDescriber(), Enumerable.Empty<IUserTokenProvider<TUser>>(),
new IdentityErrorDescriber(), null,
new Mock<ILogger<UserManager<TUser>>>().Object,
null);
validator.Setup(v => v.ValidateAsync(userManager, It.IsAny<TUser>()))

View File

@ -8,11 +8,6 @@ namespace Microsoft.AspNet.Identity.Test
{
internal class PasswordHasherOptionsAccessor : IOptions<PasswordHasherOptions>
{
public PasswordHasherOptions Options { get; } = new PasswordHasherOptions();
public PasswordHasherOptions GetNamedOptions(string name)
{
throw new NotImplementedException();
}
public PasswordHasherOptions Value { get; } = new PasswordHasherOptions();
}
}

View File

@ -32,23 +32,22 @@ namespace Microsoft.AspNet.Identity.Test
protected virtual void SetupIdentityServices(IServiceCollection services, object context = null)
{
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
services.AddIdentity<TUser, TRole>().AddDefaultTokenProviders();
AddUserStore(services, context);
AddRoleStore(services, context);
services.AddLogging();
services.AddInstance<ILogger<UserManager<TUser>>>(new TestLogger<UserManager<TUser>>());
services.AddInstance<ILogger<RoleManager<TRole>>>(new TestLogger<RoleManager<TRole>>());
services.ConfigureIdentity(options =>
services.AddIdentity<TUser, TRole>(options =>
{
options.Password.RequireDigit = false;
options.Password.RequireLowercase = false;
options.Password.RequireNonLetterOrDigit = false;
options.Password.RequireUppercase = false;
options.User.AllowedUserNameCharacters = null;
});
}).AddDefaultTokenProviders();
AddUserStore(services, context);
AddRoleStore(services, context);
services.AddLogging();
services.AddInstance<ILogger<UserManager<TUser>>>(new TestLogger<UserManager<TUser>>());
services.AddInstance<ILogger<RoleManager<TRole>>>(new TestLogger<RoleManager<TRole>>());
}
protected virtual UserManager<TUser> CreateManager(object context = null, IServiceCollection services = null)
protected virtual UserManager<TUser> CreateManager(object context = null, IServiceCollection services = null, Action<IServiceCollection> configureServices = null)
{
if (services == null)
{
@ -59,6 +58,10 @@ namespace Microsoft.AspNet.Identity.Test
context = CreateTestContext();
}
SetupIdentityServices(services, context);
if (configureServices != null)
{
configureServices(services);
}
return services.BuildServiceProvider().GetService<UserManager<TUser>>();
}
@ -648,8 +651,6 @@ namespace Microsoft.AspNet.Identity.Test
private class StaticTokenProvider : IUserTokenProvider<TUser>
{
public string Name { get; } = "Static";
public async Task<string> GenerateAsync(string purpose, UserManager<TUser> manager, TUser user)
{
return MakeToken(purpose, await manager.GetUserIdAsync(user));
@ -680,8 +681,8 @@ namespace Microsoft.AspNet.Identity.Test
public async Task CanResetPasswordWithStaticTokenProvider()
{
var manager = CreateManager();
manager.RegisterTokenProvider(new StaticTokenProvider());
manager.Options.PasswordResetTokenProvider = "Static";
manager.RegisterTokenProvider("Static", new StaticTokenProvider());
manager.Options.Tokens.PasswordResetTokenProvider = "Static";
var user = CreateTestUser();
const string password = "password";
const string newPassword = "newpassword";
@ -701,8 +702,8 @@ namespace Microsoft.AspNet.Identity.Test
public async Task PasswordValidatorCanBlockResetPasswordWithStaticTokenProvider()
{
var manager = CreateManager();
manager.RegisterTokenProvider(new StaticTokenProvider());
manager.Options.PasswordResetTokenProvider = "Static";
manager.RegisterTokenProvider("Static", new StaticTokenProvider());
manager.Options.Tokens.PasswordResetTokenProvider = "Static";
var user = CreateTestUser();
const string password = "password";
const string newPassword = "newpassword";
@ -723,8 +724,8 @@ namespace Microsoft.AspNet.Identity.Test
public async Task ResetPasswordWithStaticTokenProviderFailsWithWrongToken()
{
var manager = CreateManager();
manager.RegisterTokenProvider(new StaticTokenProvider());
manager.Options.PasswordResetTokenProvider = "Static";
manager.RegisterTokenProvider("Static", new StaticTokenProvider());
manager.Options.Tokens.PasswordResetTokenProvider = "Static";
var user = CreateTestUser();
const string password = "password";
const string newPassword = "newpassword";
@ -741,7 +742,7 @@ namespace Microsoft.AspNet.Identity.Test
public async Task CanGenerateAndVerifyUserTokenWithStaticTokenProvider()
{
var manager = CreateManager();
manager.RegisterTokenProvider(new StaticTokenProvider());
manager.RegisterTokenProvider("Static", new StaticTokenProvider());
var user = CreateTestUser();
var user2 = CreateTestUser();
IdentityResultAssert.IsSuccess(await manager.CreateAsync(user));
@ -765,8 +766,8 @@ namespace Microsoft.AspNet.Identity.Test
public async Task CanConfirmEmailWithStaticToken()
{
var manager = CreateManager();
manager.RegisterTokenProvider(new StaticTokenProvider());
manager.Options.EmailConfirmationTokenProvider = "Static";
manager.RegisterTokenProvider("Static", new StaticTokenProvider());
manager.Options.Tokens.EmailConfirmationTokenProvider = "Static";
var user = CreateTestUser();
Assert.False(await manager.IsEmailConfirmedAsync(user));
IdentityResultAssert.IsSuccess(await manager.CreateAsync(user));
@ -783,8 +784,8 @@ namespace Microsoft.AspNet.Identity.Test
public async Task ConfirmEmailWithStaticTokenFailsWithWrongToken()
{
var manager = CreateManager();
manager.RegisterTokenProvider(new StaticTokenProvider());
manager.Options.EmailConfirmationTokenProvider = "Static";
manager.RegisterTokenProvider("Static", new StaticTokenProvider());
manager.Options.Tokens.EmailConfirmationTokenProvider = "Static";
var user = CreateTestUser();
Assert.False(await manager.IsEmailConfirmedAsync(user));
IdentityResultAssert.IsSuccess(await manager.CreateAsync(user));
@ -1449,6 +1450,27 @@ namespace Microsoft.AspNet.Identity.Test
Assert.NotEqual(stamp, await manager.GetSecurityStampAsync(user));
}
[Fact]
public async Task CanChangeEmailWithDifferentTokenProvider()
{
var manager = CreateManager(context: null, services: null,
configureServices: s => s.Configure<IdentityOptions>(
o => o.Tokens.ProviderMap["NewProvider2"] = new TokenProviderDescriptor(typeof(EmailTokenProvider<TUser>))));
manager.Options.Tokens.ChangeEmailTokenProvider = "NewProvider2";
var user = CreateTestUser("foouser");
IdentityResultAssert.IsSuccess(await manager.CreateAsync(user));
var email = await manager.GetUserNameAsync(user) + "@diddly.bop";
IdentityResultAssert.IsSuccess(await manager.SetEmailAsync(user, email));
Assert.False(await manager.IsEmailConfirmedAsync(user));
var stamp = await manager.GetSecurityStampAsync(user);
var newEmail = await manager.GetUserNameAsync(user) + "@en.vec";
var token1 = await manager.GenerateChangeEmailTokenAsync(user, newEmail);
IdentityResultAssert.IsSuccess(await manager.ChangeEmailAsync(user, newEmail, token1));
Assert.True(await manager.IsEmailConfirmedAsync(user));
Assert.Equal(await manager.GetEmailAsync(user), newEmail);
Assert.NotEqual(stamp, await manager.GetSecurityStampAsync(user));
}
[Fact]
public async Task ChangeEmailFailsWithWrongToken()
{