向ASP.NET应用程序添加双向身份验证

German Lorenz cipher machine by Timitrius used under CC Attributin

ASP.NET Identity 2.0 was released last month and it's got a number of significant updates and new features that are worth checking out. For historical context, read the "Introduction to ASP.NET Identity" article that includes a lot of background and information on why certain decisions were made, as well as an  overview of some of the goals of ASP.NET Identity 2.0 like:

ASP.NET Identity 2.0于上个月发布,其中有许多重要更新和新功能值得一试。 对于历史背景,请阅读“ ASP.NET身份简介”一文,其中包括许多背景和有关为何做出某些决定的信息,以及ASP.NET Identity 2.0的一些目标概述,例如:

  • One Identity system for ASP.NET Web Forms, MVC, Web API, and Web Pages

    一个用于ASP.NET Web窗体,MVC,Web API和Web页面的身份系统
  • Total control over user profile schema.

    对用户配置文件架构的完全控制。
  • Pluggable storage mechanisms from Windows Azure Storage Table Service to NoSQL databases

    从Windows Azure存储表服务到NoSQL数据库的可插入存储机制
  • Unit Testable

    可单元测试
  • Claims-based Auth adds more choice over simple role membership

    基于声明的Auth增加了简单角色成员身份的更多选择
  • Social Logins (MSFT, FB, Google, Twitter, etc)

    社交登录(MSFT,FB,Google,Twitter等)
  • Based on OWIN middleware, ASP.NET Identity has no System.Web dependency

    基于OWIN中间件,ASP.NET Identity不具有System.Web依赖性

You can watch a video of Pranav Rastogi and I upgrading the ASP.NET Membership systems on an older ASP.NET application to the latest bits. There's also migration docs in detail:

您可以观看有关Pranav Rastogi的视频,我将在较旧的ASP.NET应用程序上将ASP.NET成员资格系统升级到最新版本。 还有详细的迁移文档:

ASP.NET Identity is on CodePlex today (and soon to be open sourced...paperwork) at https://aspnetidentity.codeplex.com/ or access the NuGet feed for nightly builds.

ASP.NET Identity现在可在CodePlex上使用(并即将开源...文书工作),网址https://aspnetidentity.codeplex.com/或访问NuGet feed进行夜间构建。

向ASP.NET应用程序添加双向身份验证 (Adding Two-Factor authentication to an ASP.NET application)

I recently changed all my accounts online to two-factor auth, and I really recommend you do as well. Here's how to add Two-Factor Auth to an ASP.NET application using Identity 2.0.

最近将所有在线帐户都更改为两因素auth ,因此我也建议您也这样做。 这是使用Identity 2.0将双向验证添加到ASP.NET应用程序的方法。

You'll have a class that is a UserManager that handles access to users and how they are stored. Inside this manager there's an IIdentityMessageService that you can implement to validate a user with whatever you want, like email, SMS, or a time-based token.

您将拥有一个UserManager类,用于处理对用户的访问及其存储方式。 在此管理器内部,您可以实现IIdentityMessageService来使用所需的任何内容(例如电子邮件,SMS或基于时间的令牌)验证用户。

Send Verification Code

Here's an example SmsService where I'm using Twilio to send text messages. Again, you can do whatever you want in your implementation.

这是一个示例SmsService,其中我正在使用Twilio发送文本消息。 同样,您可以在实现中做任何您想做的事情。

public class SmsService : IIdentityMessageService
{
public Task SendAsync(IdentityMessage message)
{
// Plug in your sms service here to send a text message.
message.Destination = Keys.ToPhone; //your number here
var twilio = new TwilioRestClient(Keys.TwilioSid, Keys.TwilioToken);
var result = twilio.SendMessage(Keys.FromPhone, message.Destination, message.Body);

return Task.FromResult(0);
}
}

If I were sending an EmailMessage, I'd do something like this. Note it's just another implementation of the same simple interface:

如果我正在发送EmailMessage,我会做这样的事情。 请注意,这只是同一简单界面的另一种实现:

public class EmailService : IIdentityMessageService
{
public Task SendAsync(IdentityMessage message)
{
string text = message.Body;
string html = message.Body;
//do whatever you want to the message
MailMessage msg = new MailMessage();
msg.From = new MailAddress("scott@hanselman.com");
msg.To.Add(new MailAddress(message.Destination));
msg.Subject = message.Subject;
msg.AlternateViews.Add(AlternateView.CreateAlternateViewFromString(text, null, MediaTypeNames.Text.Plain));
msg.AlternateViews.Add(AlternateView.CreateAlternateViewFromString(html, null, MediaTypeNames.Text.Html));

SmtpClient smtpClient = new SmtpClient("smtp.whatever.net", Convert.ToInt32(587));
System.Net.NetworkCredential credentials = new System.Net.NetworkCredential(Keys.EmailUser, Keys.EMailKey);
smtpClient.Credentials = credentials;
smtpClient.Send(msg);

return Task.FromResult(0);
}
}

In your IdentityConfig.cs you can register as many TwoFactorProviders as you'd like. I'm adding both Email and Sms here. They include token providers but again, everything is pluggable.

在您的IdentityConfig.cs中,您可以注册任意数量的TwoFactorProvider。 我在此处添加电子邮件和短信。 它们包括令牌提供者,但同样,所有内容都是可插入的。

manager.RegisterTwoFactorProvider("PhoneCode", new PhoneNumberTokenProvider<ApplicationUser> {
MessageFormat = "Your security code is: {0}"
});
manager.RegisterTwoFactorProvider("EmailCode", new EmailTokenProvider<ApplicationUser> {
Subject = "SecurityCode",
BodyFormat = "Your security code is {0}"
});

manager.EmailService = new EmailService();
manager.SmsService = new SmsService();

If a user tries to login you need to make sure they are a VerifiedUser. If not, get a valid two factor provider and send them a code to validate. In this case, since there are two providers to choice from, I let them pick from a dropdown. Here's the POST to /Account/SendCode:

如果用户尝试登录,则需要确保他们是经过验证的用户。 如果不是,请获取有效的两因素提供者并将其发送给他们进行验证的代码。 在这种情况下,由于有两个提供程序可供选择,因此我让他们从下拉列表中进行选择。 这是到/ Account / SendCode的POST:

public async Task<ActionResult> SendCode(SendCodeViewModel model)
{
// Generate the token and send it
if (!ModelState.IsValid)
{
return View();
}

if (!await SignInHelper.SendTwoFactorCode(model.SelectedProvider))
{
return View("Error");
}
return RedirectToAction("VerifyCode", new { Provider = model.SelectedProvider, ReturnUrl = model.ReturnUrl });
}

The sender of the two factor code depends on your implementation, of course.

当然,两个因素代码的发送者取决于您的实现。

public async Task<bool> SendTwoFactorCode(string provider)
{
var userId = await GetVerifiedUserIdAsync();
if (userId == null)
{
return false;
}

var token = await UserManager.GenerateTwoFactorTokenAsync(userId, provider);
// See IdentityConfig.cs to plug in Email/SMS services to actually send the code
await UserManager.NotifyTwoFactorTokenAsync(userId, provider, token);
return true;
}

When it's time to get the code from them, they need to have logged in with name and password already, and we're now checking the code:

当需要从他们那里获取代码时,他们需要已经使用名称和密码登录,我们现在正在检查代码:

[AllowAnonymous]
public async Task<ActionResult> VerifyCode(string provider, string returnUrl)
{
// Require that the user has already logged in via username/password or external login
if (!await SignInHelper.HasBeenVerified())
{
return View("Error");
}
var user = await UserManager.FindByIdAsync(await SignInHelper.GetVerifiedUserIdAsync());
return View(new VerifyCodeViewModel { Provider = provider, ReturnUrl = returnUrl });
}

We can sign users potentially a number of ways, like with External Sign Ins (Twitter, etc) but here's the TwoFactorSignIn

我们可以通过多种方式对用户进行签名,例如使用外部登录(Twitter等),但这是TwoFactorSignIn

public async Task<SignInStatus> TwoFactorSignIn(string provider, string code, bool isPersistent, bool rememberBrowser)
{
var userId = await GetVerifiedUserIdAsync();
if (userId == null)
{
return SignInStatus.Failure;
}
var user = await UserManager.FindByIdAsync(userId);
if (user == null)
{
return SignInStatus.Failure;
}
if (await UserManager.IsLockedOutAsync(user.Id))
{
return SignInStatus.LockedOut;
}
if (await UserManager.VerifyTwoFactorTokenAsync(user.Id, provider, code))
{
// When token is verified correctly, clear the access failed count used for lockout
await UserManager.ResetAccessFailedCountAsync(user.Id);
await SignInAsync(user, isPersistent, rememberBrowser);
return SignInStatus.Success;
}
// If the token is incorrect, record the failure which also may cause the user to be locked out
await UserManager.AccessFailedAsync(user.Id);
return SignInStatus.Failure;
}

If you want this blog post's sample code, make an EMPTY ASP.NET Web Application and run this NuGet command from the Package Manager Console

如果需要此博客文章的示例代码,请制作一个EMPTY ASP.NET Web应用程序,然后从“程序包管理器”控制台中运行此NuGet命令。

Install-Package Microsoft.AspNet.Identity.Samples -Pre

Have fun!

玩得开心!

相关链接 (Related Links)

* Photo of German Lorenz cipher machine by Timitrius used under CC Attribution 

*蒂米特里乌斯(Timitrius)在CC归属下使用的德国洛伦兹密码机照片

翻译自: https://www.hanselman.com/blog/adding-twofactor-authentication-to-an-aspnet-application

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值