Remove identity message apis
Fixes https://github.com/aspnet/Identity/issues/359
This commit is contained in:
parent
04599f92c1
commit
c2e96fa570
|
|
@ -2,13 +2,15 @@
|
|||
using System.Security.Claims;
|
||||
using System.Security.Principal;
|
||||
using System.Threading.Tasks;
|
||||
using IdentitySample.Models;
|
||||
using IdentitySamples;
|
||||
using Microsoft.AspNet.Authentication;
|
||||
using Microsoft.AspNet.Authorization;
|
||||
using Microsoft.AspNet.Identity;
|
||||
using Microsoft.AspNet.Mvc;
|
||||
using Microsoft.AspNet.Mvc.Rendering;
|
||||
using Microsoft.AspNet.Authorization;
|
||||
|
||||
namespace IdentitySample.Models
|
||||
namespace IdentitySample.Controllers
|
||||
{
|
||||
[Authorize]
|
||||
public class AccountController : Controller
|
||||
|
|
@ -92,13 +94,8 @@ namespace IdentitySample.Models
|
|||
{
|
||||
var code = await UserManager.GenerateEmailConfirmationTokenAsync(user);
|
||||
var callbackUrl = Url.Action("ConfirmEmail", "Account", new { userId = user.Id, code = code }, protocol: Context.Request.Scheme);
|
||||
var email = new IdentityMessage
|
||||
{
|
||||
Destination = model.Email,
|
||||
Subject = "Confirm your account",
|
||||
Body = "Please confirm your account by clicking this link: <a href=\"" + callbackUrl + "\">link</a>"
|
||||
};
|
||||
await UserManager.SendMessageAsync("Email", email);
|
||||
await MessageServices.SendEmailAsync(model.Email, "Confirm your account",
|
||||
"Please confirm your account by clicking this link: <a href=\"" + callbackUrl + "\">link</a>");
|
||||
ViewBag.Link = callbackUrl;
|
||||
return View("DisplayEmail");
|
||||
}
|
||||
|
|
@ -255,13 +252,8 @@ namespace IdentitySample.Models
|
|||
|
||||
var code = await UserManager.GeneratePasswordResetTokenAsync(user);
|
||||
var callbackUrl = Url.Action("ResetPassword", "Account", new { userId = user.Id, code = code }, protocol: Context.Request.Scheme);
|
||||
var email = new IdentityMessage
|
||||
{
|
||||
Destination = model.Email,
|
||||
Subject = "Reset Password",
|
||||
Body = "Please reset your password by clicking here: <a href=\"" + callbackUrl + "\">link</a>"
|
||||
};
|
||||
await UserManager.SendMessageAsync("Email", email);
|
||||
await MessageServices.SendEmailAsync(model.Email, "Reset Password",
|
||||
"Please reset your password by clicking here: <a href=\"" + callbackUrl + "\">link</a>");
|
||||
ViewBag.Link = callbackUrl;
|
||||
return View("ForgotPasswordConfirmation");
|
||||
}
|
||||
|
|
@ -351,11 +343,29 @@ namespace IdentitySample.Models
|
|||
return View();
|
||||
}
|
||||
|
||||
// Generate the token and send it
|
||||
if (!await SignInManager.SendTwoFactorCodeAsync(model.SelectedProvider))
|
||||
var user = await SignInManager.GetTwoFactorAuthenticationUserAsync();
|
||||
if (user == null)
|
||||
{
|
||||
return View("Error");
|
||||
}
|
||||
|
||||
// Generate the token and send it
|
||||
var code = await UserManager.GenerateTwoFactorTokenAsync(user, model.SelectedProvider);
|
||||
if (string.IsNullOrWhiteSpace(code))
|
||||
{
|
||||
return View("Error");
|
||||
}
|
||||
|
||||
var message = "Your security code is: " + code;
|
||||
if (model.SelectedProvider == "Email")
|
||||
{
|
||||
await MessageServices.SendEmailAsync(await UserManager.GetEmailAsync(user), "Security Code", message);
|
||||
}
|
||||
else if (model.SelectedProvider == "Phone")
|
||||
{
|
||||
await MessageServices.SendSmsAsync(await UserManager.GetPhoneNumberAsync(user), message);
|
||||
}
|
||||
|
||||
return RedirectToAction("VerifyCode", new { Provider = model.SelectedProvider, ReturnUrl = model.ReturnUrl, RememberMe = model.RememberMe });
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
using Microsoft.AspNet.Mvc;
|
||||
|
||||
namespace IdentitySample.Models
|
||||
namespace IdentitySample.Controllers
|
||||
{
|
||||
public class HomeController : Controller
|
||||
{
|
||||
|
|
|
|||
|
|
@ -2,11 +2,12 @@
|
|||
using System.Security.Principal;
|
||||
using System.Threading.Tasks;
|
||||
using IdentitySample.Models;
|
||||
using IdentitySamples;
|
||||
using Microsoft.AspNet.Authorization;
|
||||
using Microsoft.AspNet.Identity;
|
||||
using Microsoft.AspNet.Mvc;
|
||||
|
||||
namespace IdentitySample
|
||||
namespace IdentitySample.Controllers
|
||||
{
|
||||
[Authorize]
|
||||
public class ManageController : Controller
|
||||
|
|
@ -98,12 +99,7 @@ namespace IdentitySample
|
|||
// Generate the token and send it
|
||||
var user = await GetCurrentUserAsync();
|
||||
var code = await UserManager.GenerateChangePhoneNumberTokenAsync(user, model.Number);
|
||||
var message = new IdentityMessage
|
||||
{
|
||||
Destination = model.Number,
|
||||
Body = "Your security code is: " + code
|
||||
};
|
||||
await UserManager.SendMessageAsync("SMS", message);
|
||||
await MessageServices.SendSmsAsync(model.Number, "Your security code is: " + code);
|
||||
return RedirectToAction("VerifyPhoneNumber", new { PhoneNumber = model.Number });
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,20 @@
|
|||
using System.Threading.Tasks;
|
||||
|
||||
namespace IdentitySamples
|
||||
{
|
||||
public static class MessageServices
|
||||
{
|
||||
public static Task SendEmailAsync(string email, string subject, string message)
|
||||
{
|
||||
// Plug in your email service
|
||||
return Task.FromResult(0);
|
||||
}
|
||||
|
||||
public static Task SendSmsAsync(string number, string message)
|
||||
{
|
||||
// Plug in your sms service
|
||||
return Task.FromResult(0);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -1,16 +1,12 @@
|
|||
using System;
|
||||
using IdentitySample.Models;
|
||||
using Microsoft.AspNet.Builder;
|
||||
using Microsoft.AspNet.Diagnostics;
|
||||
using Microsoft.AspNet.Identity;
|
||||
using Microsoft.AspNet.Routing;
|
||||
using Microsoft.Data.Entity;
|
||||
using Microsoft.Framework.ConfigurationModel;
|
||||
using Microsoft.Framework.DependencyInjection;
|
||||
using Microsoft.Framework.Logging;
|
||||
using Microsoft.Framework.Logging.Console;
|
||||
using System.Threading.Tasks;
|
||||
using System.Threading;
|
||||
|
||||
namespace IdentitySamples
|
||||
{
|
||||
|
|
@ -42,9 +38,7 @@ namespace IdentitySamples
|
|||
|
||||
services.AddIdentity<ApplicationUser, IdentityRole>(Configuration)
|
||||
.AddEntityFrameworkStores<ApplicationDbContext>()
|
||||
.AddDefaultTokenProviders()
|
||||
.AddMessageProvider<EmailMessageProvider>()
|
||||
.AddMessageProvider<SmsMessageProvider>();
|
||||
.AddDefaultTokenProviders();
|
||||
|
||||
services.ConfigureFacebookAuthentication(options =>
|
||||
{
|
||||
|
|
@ -86,39 +80,5 @@ namespace IdentitySamples
|
|||
SampleData.InitializeIdentityDatabaseAsync(app.ApplicationServices).Wait();
|
||||
}
|
||||
|
||||
public class EmailMessageProvider : IIdentityMessageProvider
|
||||
{
|
||||
public string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
return "Email";
|
||||
}
|
||||
}
|
||||
|
||||
public Task SendAsync(IdentityMessage message, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
// Plug in your service
|
||||
return Task.FromResult(0);
|
||||
}
|
||||
}
|
||||
|
||||
public class SmsMessageProvider : IIdentityMessageProvider
|
||||
{
|
||||
public string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
return "SMS";
|
||||
}
|
||||
}
|
||||
|
||||
public Task SendAsync(IdentityMessage message, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
// Plug in your service
|
||||
return Task.FromResult(0);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,4 @@
|
|||
using System;
|
||||
using System.Globalization;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Framework.OptionsModel;
|
||||
|
||||
|
|
@ -8,16 +6,7 @@ namespace Microsoft.AspNet.Identity
|
|||
{
|
||||
public class EmailTokenProviderOptions
|
||||
{
|
||||
public string Name { get; set; } = Resources.DefaultEmailTokenProviderName;
|
||||
|
||||
public string MessageProvider { get; set; } = "Email";
|
||||
|
||||
public string Subject { get; set; } = "Security Code";
|
||||
|
||||
/// <summary>
|
||||
/// Format string which will be used for the email body, it will be passed the token for the first parameter
|
||||
/// </summary>
|
||||
public string BodyFormat { get; set; } = "Your security code is: {0}";
|
||||
public string Name { get; set; } = "Email";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -65,27 +54,5 @@ namespace Microsoft.AspNet.Identity
|
|||
var email = await manager.GetEmailAsync(user);
|
||||
return "Email:" + purpose + ":" + email;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Notifies the user with a token via email using the Subject and BodyFormat
|
||||
/// </summary>
|
||||
/// <param name="token"></param>
|
||||
/// <param name="manager"></param>
|
||||
/// <param name="user"></param>
|
||||
/// <returns></returns>
|
||||
public override async Task NotifyAsync(string token, UserManager<TUser> manager, TUser user)
|
||||
{
|
||||
if (manager == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(manager));
|
||||
}
|
||||
var msg = new IdentityMessage
|
||||
{
|
||||
Destination = await manager.GetEmailAsync(user),
|
||||
Subject = Options.Subject,
|
||||
Body = string.Format(CultureInfo.CurrentCulture, Options.BodyFormat, token)
|
||||
};
|
||||
await manager.SendMessageAsync(Options.MessageProvider, msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
// 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.
|
||||
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.AspNet.Identity
|
||||
{
|
||||
public interface IIdentityMessageProvider
|
||||
{
|
||||
string Name { get; }
|
||||
|
||||
Task SendAsync(IdentityMessage message, CancellationToken cancellationToken);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,7 +1,6 @@
|
|||
// 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.
|
||||
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.AspNet.Identity
|
||||
|
|
@ -35,15 +34,6 @@ namespace Microsoft.AspNet.Identity
|
|||
/// <returns></returns>
|
||||
Task<bool> ValidateAsync(string purpose, string token, UserManager<TUser> manager, TUser user);
|
||||
|
||||
/// <summary>
|
||||
/// Notifies the user that a token has been generated, i.e. via email or sms, or can no-op
|
||||
/// </summary>
|
||||
/// <param name="token"></param>
|
||||
/// <param name="manager"></param>
|
||||
/// <param name="user"></param>
|
||||
/// <returns></returns>
|
||||
Task NotifyAsync(string token, UserManager<TUser> manager, TUser user);
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if provider can be used for this user to generate two factor tokens, i.e. could require a user to have an email
|
||||
/// </summary>
|
||||
|
|
|
|||
|
|
@ -66,11 +66,6 @@ namespace Microsoft.AspNet.Identity
|
|||
return AddScoped(typeof(IUserTokenProvider<>).MakeGenericType(UserType), provider);
|
||||
}
|
||||
|
||||
public virtual IdentityBuilder AddMessageProvider<TProvider>() where TProvider : IIdentityMessageProvider
|
||||
{
|
||||
return AddScoped(typeof(IIdentityMessageProvider), typeof(TProvider));
|
||||
}
|
||||
|
||||
public virtual IdentityBuilder AddDefaultTokenProviders()
|
||||
{
|
||||
Services.Configure<DataProtectionTokenProviderOptions>(options =>
|
||||
|
|
|
|||
|
|
@ -1,26 +0,0 @@
|
|||
// 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
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a message
|
||||
/// </summary>
|
||||
public class IdentityMessage
|
||||
{
|
||||
/// <summary>
|
||||
/// Target for the message, i.e. email or phone number
|
||||
/// </summary>
|
||||
public virtual string Destination { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Subject
|
||||
/// </summary>
|
||||
public virtual string Subject { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Message contents
|
||||
/// </summary>
|
||||
public virtual string Body { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -7,14 +7,7 @@ namespace Microsoft.AspNet.Identity
|
|||
{
|
||||
public class PhoneNumberTokenProviderOptions
|
||||
{
|
||||
public string Name { get; set; } = Resources.DefaultPhoneNumberTokenProviderName;
|
||||
|
||||
public string MessageProvider { get; set; } = "SMS";
|
||||
|
||||
/// <summary>
|
||||
/// Message contents which should contain a format string which the token will be the only argument
|
||||
/// </summary>
|
||||
public string MessageFormat { get; set; } = Resources.DefaultPhoneNumberTokenProviderMessageFormat;
|
||||
public string Name { get; set; } = "Phone";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -69,26 +62,5 @@ namespace Microsoft.AspNet.Identity
|
|||
var phoneNumber = await manager.GetPhoneNumberAsync(user);
|
||||
return "PhoneNumber:" + purpose + ":" + phoneNumber;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Notifies the user with a token via SMS using the MessageFormat
|
||||
/// </summary>
|
||||
/// <param name="token"></param>
|
||||
/// <param name="manager"></param>
|
||||
/// <param name="user"></param>
|
||||
/// <returns></returns>
|
||||
public override async Task NotifyAsync(string token, UserManager<TUser> manager, TUser user)
|
||||
{
|
||||
if (manager == null)
|
||||
{
|
||||
throw new ArgumentNullException("manager");
|
||||
}
|
||||
var msg = new IdentityMessage
|
||||
{
|
||||
Destination = await manager.GetPhoneNumberAsync(user),
|
||||
Body = string.Format(CultureInfo.CurrentCulture, Options.MessageFormat, token)
|
||||
};
|
||||
await manager.SendMessageAsync(Options.MessageProvider, msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -26,54 +26,6 @@ namespace Microsoft.AspNet.Identity
|
|||
return GetString("ConcurrencyFailure");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Your security code is: {0}
|
||||
/// </summary>
|
||||
internal static string DefaultEmailTokenProviderBodyFormat
|
||||
{
|
||||
get { return GetString("DefaultEmailTokenProviderBodyFormat"); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Your security code is: {0}
|
||||
/// </summary>
|
||||
internal static string FormatDefaultEmailTokenProviderBodyFormat(object p0)
|
||||
{
|
||||
return string.Format(CultureInfo.CurrentCulture, GetString("DefaultEmailTokenProviderBodyFormat"), p0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Email
|
||||
/// </summary>
|
||||
internal static string DefaultEmailTokenProviderName
|
||||
{
|
||||
get { return GetString("DefaultEmailTokenProviderName"); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Email
|
||||
/// </summary>
|
||||
internal static string FormatDefaultEmailTokenProviderName()
|
||||
{
|
||||
return GetString("DefaultEmailTokenProviderName");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Security code
|
||||
/// </summary>
|
||||
internal static string DefaultEmailTokenProviderSubject
|
||||
{
|
||||
get { return GetString("DefaultEmailTokenProviderSubject"); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Security code
|
||||
/// </summary>
|
||||
internal static string FormatDefaultEmailTokenProviderSubject()
|
||||
{
|
||||
return GetString("DefaultEmailTokenProviderSubject");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// An unknown failure has occured.
|
||||
/// </summary>
|
||||
|
|
@ -90,38 +42,6 @@ namespace Microsoft.AspNet.Identity
|
|||
return GetString("DefaultError");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Your security code is: {0}
|
||||
/// </summary>
|
||||
internal static string DefaultPhoneNumberTokenProviderMessageFormat
|
||||
{
|
||||
get { return GetString("DefaultPhoneNumberTokenProviderMessageFormat"); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Your security code is: {0}
|
||||
/// </summary>
|
||||
internal static string FormatDefaultPhoneNumberTokenProviderMessageFormat(object p0)
|
||||
{
|
||||
return string.Format(CultureInfo.CurrentCulture, GetString("DefaultPhoneNumberTokenProviderMessageFormat"), p0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Phone
|
||||
/// </summary>
|
||||
internal static string DefaultPhoneNumberTokenProviderName
|
||||
{
|
||||
get { return GetString("DefaultPhoneNumberTokenProviderName"); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Phone
|
||||
/// </summary>
|
||||
internal static string FormatDefaultPhoneNumberTokenProviderName()
|
||||
{
|
||||
return GetString("DefaultPhoneNumberTokenProviderName");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Default Token Provider
|
||||
/// </summary>
|
||||
|
|
@ -298,22 +218,6 @@ namespace Microsoft.AspNet.Identity
|
|||
return GetString("LoginAlreadyAssociated");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// No IUserMessageProvider named '{0}' is registered.
|
||||
/// </summary>
|
||||
internal static string NoMessageProvider
|
||||
{
|
||||
get { return GetString("NoMessageProvider"); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// No IUserMessageProvider named '{0}' is registered.
|
||||
/// </summary>
|
||||
internal static string FormatNoMessageProvider(object p0)
|
||||
{
|
||||
return string.Format(CultureInfo.CurrentCulture, GetString("NoMessageProvider"), p0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// No IUserTokenProvider named '{0}' is registered.
|
||||
/// </summary>
|
||||
|
|
|
|||
|
|
@ -121,30 +121,10 @@
|
|||
<value>Optimistic concurrency failure, object has been modified.</value>
|
||||
<comment>Error when optimistic concurrency fails</comment>
|
||||
</data>
|
||||
<data name="DefaultEmailTokenProviderBodyFormat" xml:space="preserve">
|
||||
<value>Your security code is: {0}</value>
|
||||
<comment>Default body format for the email</comment>
|
||||
</data>
|
||||
<data name="DefaultEmailTokenProviderName" xml:space="preserve">
|
||||
<value>Email</value>
|
||||
<comment>Default name for the email token provider</comment>
|
||||
</data>
|
||||
<data name="DefaultEmailTokenProviderSubject" xml:space="preserve">
|
||||
<value>Security code</value>
|
||||
<comment>Default subject for the email</comment>
|
||||
</data>
|
||||
<data name="DefaultError" xml:space="preserve">
|
||||
<value>An unknown failure has occured.</value>
|
||||
<comment>Default identity result error message</comment>
|
||||
</data>
|
||||
<data name="DefaultPhoneNumberTokenProviderMessageFormat" xml:space="preserve">
|
||||
<value>Your security code is: {0}</value>
|
||||
<comment>Default message format for the phone number token provider</comment>
|
||||
</data>
|
||||
<data name="DefaultPhoneNumberTokenProviderName" xml:space="preserve">
|
||||
<value>Phone</value>
|
||||
<comment>Default name for the phone number token provider</comment>
|
||||
</data>
|
||||
<data name="DefaultTokenProvider" xml:space="preserve">
|
||||
<value>Default Token Provider</value>
|
||||
<comment>Name of the default token provider</comment>
|
||||
|
|
@ -189,10 +169,6 @@
|
|||
<value>A user with this login already exists.</value>
|
||||
<comment>Error when a login already linked</comment>
|
||||
</data>
|
||||
<data name="NoMessageProvider" xml:space="preserve">
|
||||
<value>No IUserMessageProvider named '{0}' is registered.</value>
|
||||
<comment>Error when there is no IUserMessageProvider</comment>
|
||||
</data>
|
||||
<data name="NoTokenProvider" xml:space="preserve">
|
||||
<value>No IUserTokenProvider named '{0}' is registered.</value>
|
||||
<comment>Error when there is no IUserTokenProvider</comment>
|
||||
|
|
|
|||
|
|
@ -202,24 +202,6 @@ namespace Microsoft.AspNet.Identity
|
|||
return identity;
|
||||
}
|
||||
|
||||
public virtual async Task<bool> SendTwoFactorCodeAsync(string provider)
|
||||
{
|
||||
var twoFactorInfo = await RetrieveTwoFactorInfoAsync();
|
||||
if (twoFactorInfo == null || twoFactorInfo.UserId == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var user = await UserManager.FindByIdAsync(twoFactorInfo.UserId);
|
||||
if (user == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
var token = await UserManager.GenerateTwoFactorTokenAsync(user, provider);
|
||||
await UserManager.NotifyTwoFactorTokenAsync(user, provider, token);
|
||||
return await LogResultAsync(true, user);
|
||||
}
|
||||
|
||||
public virtual async Task<bool> IsTwoFactorClientRememberedAsync(TUser user)
|
||||
{
|
||||
var userId = await UserManager.GetUserIdAsync(user);
|
||||
|
|
|
|||
|
|
@ -15,18 +15,6 @@ namespace Microsoft.AspNet.Identity
|
|||
{
|
||||
public abstract string Name { get; }
|
||||
|
||||
/// <summary>
|
||||
/// This token provider does not notify the user by default
|
||||
/// </summary>
|
||||
/// <param name="token"></param>
|
||||
/// <param name="manager"></param>
|
||||
/// <param name="user"></param>
|
||||
/// <returns></returns>
|
||||
public virtual Task NotifyAsync(string token, UserManager<TUser> manager, TUser user)
|
||||
{
|
||||
return Task.FromResult(0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generate a token for the user using their security stamp
|
||||
/// </summary>
|
||||
|
|
|
|||
|
|
@ -24,8 +24,6 @@ namespace Microsoft.AspNet.Identity
|
|||
{
|
||||
private readonly Dictionary<string, IUserTokenProvider<TUser>> _tokenProviders =
|
||||
new Dictionary<string, IUserTokenProvider<TUser>>();
|
||||
private readonly Dictionary<string, IIdentityMessageProvider> _msgProviders =
|
||||
new Dictionary<string, IIdentityMessageProvider>();
|
||||
|
||||
private TimeSpan _defaultLockout = TimeSpan.Zero;
|
||||
private bool _disposed;
|
||||
|
|
@ -42,7 +40,6 @@ namespace Microsoft.AspNet.Identity
|
|||
/// <param name="keyNormalizer"></param>
|
||||
/// <param name="errors"></param>
|
||||
/// <param name="tokenProviders"></param>
|
||||
/// <param name="msgProviders"></param>
|
||||
/// <param name="loggerFactory"></param>
|
||||
public UserManager(IUserStore<TUser> store,
|
||||
IOptions<IdentityOptions> optionsAccessor,
|
||||
|
|
@ -52,7 +49,6 @@ namespace Microsoft.AspNet.Identity
|
|||
ILookupNormalizer keyNormalizer,
|
||||
IdentityErrorDescriber errors,
|
||||
IEnumerable<IUserTokenProvider<TUser>> tokenProviders,
|
||||
IEnumerable<IIdentityMessageProvider> msgProviders,
|
||||
ILogger<UserManager<TUser>> logger,
|
||||
IHttpContextAccessor contextAccessor)
|
||||
{
|
||||
|
|
@ -91,13 +87,6 @@ namespace Microsoft.AspNet.Identity
|
|||
RegisterTokenProvider(tokenProvider);
|
||||
}
|
||||
}
|
||||
if (msgProviders != null)
|
||||
{
|
||||
foreach (var msgProvider in msgProviders)
|
||||
{
|
||||
RegisterMessageProvider(msgProvider);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -1527,20 +1516,6 @@ namespace Microsoft.AspNet.Identity
|
|||
_tokenProviders[provider.Name] = provider;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Register a user message provider
|
||||
/// </summary>
|
||||
/// <param name="provider"></param>
|
||||
public virtual void RegisterMessageProvider(IIdentityMessageProvider provider)
|
||||
{
|
||||
ThrowIfDisposed();
|
||||
if (provider == null)
|
||||
{
|
||||
throw new ArgumentNullException("provider");
|
||||
}
|
||||
_msgProviders[provider.Name] = provider;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a list of valid two factor providers for a user
|
||||
/// </summary>
|
||||
|
|
@ -1619,33 +1594,6 @@ namespace Microsoft.AspNet.Identity
|
|||
return token;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Notify a user with a token from a specific user factor provider
|
||||
/// </summary>
|
||||
/// <param name="user"></param>
|
||||
/// <param name="tokenProvider"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
public virtual async Task<IdentityResult> NotifyTwoFactorTokenAsync(TUser user, string tokenProvider, string token)
|
||||
{
|
||||
ThrowIfDisposed();
|
||||
if (user == null)
|
||||
{
|
||||
throw new ArgumentNullException("user");
|
||||
}
|
||||
if (tokenProvider == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(tokenProvider));
|
||||
}
|
||||
if (!_tokenProviders.ContainsKey(tokenProvider))
|
||||
{
|
||||
throw new NotSupportedException(String.Format(CultureInfo.CurrentCulture,
|
||||
Resources.NoTokenProvider, tokenProvider));
|
||||
}
|
||||
await _tokenProviders[tokenProvider].NotifyAsync(token, this, user);
|
||||
return await LogResultAsync(IdentityResult.Success, user);
|
||||
}
|
||||
|
||||
// IUserFactorStore methods
|
||||
internal IUserTwoFactorStore<TUser> GetUserTwoFactorStore()
|
||||
{
|
||||
|
|
@ -1692,30 +1640,6 @@ namespace Microsoft.AspNet.Identity
|
|||
return await LogResultAsync(await UpdateUserAsync(user), user);
|
||||
}
|
||||
|
||||
// Messaging methods
|
||||
|
||||
/// <summary>
|
||||
/// Send a message to the user using the specified provider
|
||||
/// </summary>
|
||||
/// <param name="messageProvider"></param>
|
||||
/// <param name="message"></param>
|
||||
/// <returns></returns>
|
||||
public virtual async Task<IdentityResult> SendMessageAsync(string messageProvider, IdentityMessage message)
|
||||
{
|
||||
ThrowIfDisposed();
|
||||
if (message == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(message));
|
||||
}
|
||||
if (!_msgProviders.ContainsKey(messageProvider))
|
||||
{
|
||||
throw new NotSupportedException(String.Format(CultureInfo.CurrentCulture,
|
||||
Resources.NoMessageProvider, messageProvider));
|
||||
}
|
||||
await _msgProviders[messageProvider].SendAsync(message, CancellationToken);
|
||||
return IdentityResult.Success;
|
||||
}
|
||||
|
||||
// IUserLockoutStore methods
|
||||
internal IUserLockoutStore<TUser> GetUserLockoutStore()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -234,7 +234,7 @@ namespace Microsoft.AspNet.Identity.Test
|
|||
|
||||
private class MyUserManager : UserManager<TestUser>
|
||||
{
|
||||
public MyUserManager(IUserStore<TestUser> store) : base(store, null, null, null, null, null, null, null, null, null, null) { }
|
||||
public MyUserManager(IUserStore<TestUser> store) : base(store, null, null, null, null, null, null, null, null, null) { }
|
||||
}
|
||||
|
||||
private class MyRoleManager : RoleManager<TestRole>
|
||||
|
|
|
|||
|
|
@ -631,7 +631,7 @@ namespace Microsoft.AspNet.Identity.Test
|
|||
public async Task ManagerPublicNullChecks()
|
||||
{
|
||||
Assert.Throws<ArgumentNullException>("store",
|
||||
() => new UserManager<TestUser>(null, null, null, null, null, null, null, null, null, null, null));
|
||||
() => new UserManager<TestUser>(null, null, null, null, null, null, null, null, null, null));
|
||||
|
||||
var manager = MockHelpers.TestUserManager(new NotImplementedStore());
|
||||
|
||||
|
|
@ -736,8 +736,6 @@ namespace Microsoft.AspNet.Identity.Test
|
|||
async () => await manager.GenerateTwoFactorTokenAsync(null, null));
|
||||
await Assert.ThrowsAsync<ArgumentNullException>("user",
|
||||
async () => await manager.VerifyTwoFactorTokenAsync(null, null, null));
|
||||
await Assert.ThrowsAsync<ArgumentNullException>("user",
|
||||
async () => await manager.NotifyTwoFactorTokenAsync(null, null, null));
|
||||
await Assert.ThrowsAsync<ArgumentNullException>("user",
|
||||
async () => await manager.GetValidTwoFactorProvidersAsync(null));
|
||||
await Assert.ThrowsAsync<ArgumentNullException>("user",
|
||||
|
|
@ -797,7 +795,6 @@ namespace Microsoft.AspNet.Identity.Test
|
|||
await Assert.ThrowsAsync<ObjectDisposedException>(() => manager.GenerateEmailConfirmationTokenAsync(null));
|
||||
await Assert.ThrowsAsync<ObjectDisposedException>(() => manager.IsEmailConfirmedAsync(null));
|
||||
await Assert.ThrowsAsync<ObjectDisposedException>(() => manager.ConfirmEmailAsync(null, null));
|
||||
await Assert.ThrowsAsync<ObjectDisposedException>(() => manager.SendMessageAsync(null, null));
|
||||
}
|
||||
|
||||
private class BadPasswordValidator<TUser> : IPasswordValidator<TUser> where TUser : class
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ namespace Microsoft.AspNet.Identity.Test
|
|||
public static Mock<UserManager<TUser>> MockUserManager<TUser>() where TUser : class
|
||||
{
|
||||
var store = new Mock<IUserStore<TUser>>();
|
||||
var mgr = new Mock<UserManager<TUser>>(store.Object, null, null, null, null, null, null, null, null, null, null);
|
||||
var mgr = new Mock<UserManager<TUser>>(store.Object, null, null, null, null, null, null, null, null, null);
|
||||
mgr.Object.UserValidators.Add(new UserValidator<TUser>());
|
||||
mgr.Object.PasswordValidators.Add(new PasswordValidator<TUser>());
|
||||
return mgr;
|
||||
|
|
@ -63,7 +63,6 @@ namespace Microsoft.AspNet.Identity.Test
|
|||
var userManager = new UserManager<TUser>(store, options.Object, new PasswordHasher<TUser>(),
|
||||
userValidators, pwdValidators, new UpperInvariantLookupNormalizer(),
|
||||
new IdentityErrorDescriber(), Enumerable.Empty<IUserTokenProvider<TUser>>(),
|
||||
Enumerable.Empty<IIdentityMessageProvider>(),
|
||||
new Logger<UserManager<TUser>>(new LoggerFactory()),
|
||||
null);
|
||||
validator.Setup(v => v.ValidateAsync(userManager, It.IsAny<TUser>()))
|
||||
|
|
|
|||
|
|
@ -1,23 +0,0 @@
|
|||
// 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.
|
||||
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.AspNet.Identity.Test
|
||||
{
|
||||
public class TestMessageService<TUser> : IIdentityMessageProvider
|
||||
{
|
||||
public IdentityMessage Message { get; set; }
|
||||
|
||||
public string Name { get; set; } = "Test";
|
||||
|
||||
public Task SendAsync(IdentityMessage message, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
Message = message;
|
||||
return Task.FromResult(0);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1447,76 +1447,6 @@ namespace Microsoft.AspNet.Identity.Test
|
|||
Assert.Equal(stamp, user.SecurityStamp);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task CanEmailTwoFactorToken()
|
||||
{
|
||||
var manager = CreateManager();
|
||||
var messageService = new TestMessageService<TUser> { Name = "Email" };
|
||||
manager.RegisterMessageProvider(messageService);
|
||||
const string factorId = "Email"; // default
|
||||
var user = new TUser() { UserName = "EmailCodeTest", Email = "foo@foo.com" };
|
||||
user.EmailConfirmed = true;
|
||||
const string password = "password";
|
||||
IdentityResultAssert.IsSuccess(await manager.CreateAsync(user, password));
|
||||
var stamp = user.SecurityStamp;
|
||||
Assert.NotNull(stamp);
|
||||
var token = await manager.GenerateTwoFactorTokenAsync(user, factorId);
|
||||
Assert.NotNull(token);
|
||||
Assert.Null(messageService.Message);
|
||||
IdentityResultAssert.IsSuccess(await manager.NotifyTwoFactorTokenAsync(user, factorId, token));
|
||||
Assert.NotNull(messageService.Message);
|
||||
Assert.Equal("Your security code is: " + token, messageService.Message.Body);
|
||||
Assert.True(await manager.VerifyTwoFactorTokenAsync(user, factorId, token));
|
||||
IdentityResultAssert.VerifyUserManagerSuccessLog(manager.Logger, "VerifyTwoFactorTokenAsync", user.Id.ToString());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task NotifyWithUnknownProviderFails()
|
||||
{
|
||||
var manager = CreateManager();
|
||||
var user = CreateTestUser();
|
||||
IdentityResultAssert.IsSuccess(await manager.CreateAsync(user));
|
||||
await
|
||||
ExceptionAssert.ThrowsAsync<NotSupportedException>(
|
||||
async () => await manager.NotifyTwoFactorTokenAsync(user, "Bogus", "token"),
|
||||
"No IUserTokenProvider named 'Bogus' is registered.");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task EmailTokenFactorWithFormatTest()
|
||||
{
|
||||
// CONSIDER: do we want to support multiple email token options?
|
||||
const string factorId = "Email"; // default
|
||||
const string subject = "Custom subject";
|
||||
const string body = "Your code is {0}!";
|
||||
var services = new ServiceCollection();
|
||||
services.Configure<EmailTokenProviderOptions>(o =>
|
||||
{
|
||||
o.Name = factorId;
|
||||
o.Subject = subject;
|
||||
o.BodyFormat = body;
|
||||
});
|
||||
var manager = CreateManager(null, services);
|
||||
var messageService = new TestMessageService<TUser> { Name = "Email" };
|
||||
manager.RegisterMessageProvider(messageService);
|
||||
var user = CreateTestUser();
|
||||
user.Email = user.UserName + "@foo.com";
|
||||
const string password = "password";
|
||||
IdentityResultAssert.IsSuccess(await manager.CreateAsync(user, password));
|
||||
var stamp = user.SecurityStamp;
|
||||
Assert.NotNull(stamp);
|
||||
var token = await manager.GenerateTwoFactorTokenAsync(user, factorId);
|
||||
Assert.NotNull(token);
|
||||
IdentityResultAssert.VerifyUserManagerSuccessLog(manager.Logger, "GenerateTwoFactorTokenAsync", user.Id.ToString());
|
||||
Assert.Null(messageService.Message);
|
||||
IdentityResultAssert.IsSuccess(await manager.NotifyTwoFactorTokenAsync(user, factorId, token));
|
||||
Assert.NotNull(messageService.Message);
|
||||
Assert.Equal(subject, messageService.Message.Subject);
|
||||
Assert.Equal(string.Format(body, token), messageService.Message.Body);
|
||||
IdentityResultAssert.VerifyUserManagerSuccessLog(manager.Logger, "NotifyTwoFactorTokenAsync", user.Id.ToString());
|
||||
Assert.True(await manager.VerifyTwoFactorTokenAsync(user, factorId, token));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task EmailFactorFailsAfterSecurityStampChangeTest()
|
||||
{
|
||||
|
|
@ -1548,69 +1478,6 @@ namespace Microsoft.AspNet.Identity.Test
|
|||
Assert.True(await manager.GetTwoFactorEnabledAsync(user));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task CanSendMessage()
|
||||
{
|
||||
var manager = CreateManager();
|
||||
var messageService = new TestMessageService<TUser>();
|
||||
manager.RegisterMessageProvider(messageService);
|
||||
var user = CreateTestUser();
|
||||
IdentityResultAssert.IsSuccess(await manager.CreateAsync(user));
|
||||
await manager.SendMessageAsync(messageService.Name, new IdentityMessage { Destination = "foo", Subject = "Hi", Body = "Body" });
|
||||
Assert.NotNull(messageService.Message);
|
||||
Assert.Equal("foo", messageService.Message.Destination);
|
||||
Assert.Equal("Hi", messageService.Message.Subject);
|
||||
Assert.Equal("Body", messageService.Message.Body);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task CanSmsTwoFactorToken()
|
||||
{
|
||||
var manager = CreateManager();
|
||||
var messageService = new TestMessageService<TUser> { Name = "SMS" };
|
||||
manager.RegisterMessageProvider(messageService);
|
||||
const string factorId = "Phone"; // default
|
||||
var user = CreateTestUser();
|
||||
user.PhoneNumber = "4251234567";
|
||||
IdentityResultAssert.IsSuccess(await manager.CreateAsync(user));
|
||||
var stamp = user.SecurityStamp;
|
||||
Assert.NotNull(stamp);
|
||||
var token = await manager.GenerateTwoFactorTokenAsync(user, factorId);
|
||||
Assert.NotNull(token);
|
||||
Assert.Null(messageService.Message);
|
||||
IdentityResultAssert.IsSuccess(await manager.NotifyTwoFactorTokenAsync(user, factorId, token));
|
||||
Assert.NotNull(messageService.Message);
|
||||
Assert.Equal("Your security code is: " + token, messageService.Message.Body);
|
||||
Assert.True(await manager.VerifyTwoFactorTokenAsync(user, factorId, token));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task PhoneTokenFactorFormatTest()
|
||||
{
|
||||
const string factorId = "Phone"; // default
|
||||
var services = new ServiceCollection();
|
||||
services.Configure<PhoneNumberTokenProviderOptions>(o =>
|
||||
{
|
||||
o.Name = factorId;
|
||||
o.MessageFormat = "Your code is: {0}";
|
||||
});
|
||||
var manager = CreateManager(null, services);
|
||||
var messageService = new TestMessageService<TUser> { Name = "SMS" };
|
||||
manager.RegisterMessageProvider(messageService);
|
||||
var user = CreateTestUser();
|
||||
user.PhoneNumber = "4251234567";
|
||||
IdentityResultAssert.IsSuccess(await manager.CreateAsync(user));
|
||||
var stamp = user.SecurityStamp;
|
||||
Assert.NotNull(stamp);
|
||||
var token = await manager.GenerateTwoFactorTokenAsync(user, factorId);
|
||||
Assert.NotNull(token);
|
||||
Assert.Null(messageService.Message);
|
||||
IdentityResultAssert.IsSuccess(await manager.NotifyTwoFactorTokenAsync(user, factorId, token));
|
||||
Assert.NotNull(messageService.Message);
|
||||
Assert.Equal("Your code is: " + token, messageService.Message.Body);
|
||||
Assert.True(await manager.VerifyTwoFactorTokenAsync(user, factorId, token));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GenerateTwoFactorWithUnknownFactorProviderWillThrow()
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in New Issue