使用 MembershipReboot 保护 ASP.NET MVC 应用程序的登录、电子邮件确认和密码重置
安全性和简易性
我们一直希望有一种简单、安全的方式来管理用户帐户和身份验证。感谢 ASP.NET 团队,实现这一目标的方法每天都在不断改进,我们可以看到,多年来,为此目的发布了库。我们已经从 ASP.NET Membership 转向 SimpleMembership,现在是 ASP.NET Identity。我可以回顾我职业生涯的早期,看到自己努力尝试扩展或添加当时 ASP.NET Membership 的额外配置。随着这一发展,我们也从基于角色的授权转向基于声明的授权。
MembershipReboot (MR)是一个基于声明的用户帐户和身份管理框架,可让您轻松管理用户帐户。它封装了重要的安全逻辑,同时具有高度可配置性和可扩展性。它的一些功能如下所列:
- 可扩展的电子邮件通知模板
- 单租户或多租户帐户管理
- 与外部身份提供者(企业或社交)的帐户链接
- 帐户活动和更新的通知系统
- 声明感知用户身份
- 灵活的账户存储设计(您可以选择将数据存储在关系或非关系数据存储中)
在本教程中,我将向您展示如何使用 MR 保护您的 ASP.NET MVC 应用。我将介绍设置、用户帐户创建、启用电子邮件验证和密码设置。我将使用新项目执行此操作,但对于现有应用,您可以跳到有关安装所需 nuget 包的部分。
创建新的 MVC Web 应用程序
- 选择文件 > 新建项目 > ASP.NET Web 应用程序。输入名称并单击确定。
- 选择 MVC 模板。
- 单击“更改身份验证”按钮,选择“无身份验证”,然后单击“确定”
- 现在我们已经设置好了项目,可以开始行动了
安装 nuget 包
NuGet(nuget)是微软开发平台的免费包管理器,我们需要安装以下nuget包:
- 安装包 BrockAllen.MembershipReboot.WebHost
这是 Web Host 包,它执行发布 cookie 以跟踪已登录的用户、执行双因素身份验证以及处理 ApplicationInformation 详细信息的工作。它依赖于BrockAllen.MembershipReboot(框架的核心)。因此,当我们运行上述命令时,这些 nuget 包就被安装了。
- 安装包 BrockAllen.MembershipReboot.Ef
这是 Entity Framework 持久性实现,负责将数据持久化到 SQL 数据存储中。这是因为它具有灵活的存储设计,您可以选择将数据存储在 SQL 或 NoSQL 数据库中。在本教程中,我选择使用此包来处理 SQL 数据存储。
- 安装包 SimpleInjector.Integration.Web.Mvc
- 安装包 SimpleInjector.Extensions.ExecutionContextScoping
如您所见,我们已经下载了 SimpleInjector 包。我们将使用 SimpleInjector 作为我们的依赖注入器 (DI) 容器。
使用会话身份验证模块 (SAM) 替代表单身份验证
由于 MR 是基于声明的,因此我们需要将基于声明的身份和会话身份验证模块 (SAM) 的设置添加到 web.config。为此,我们需要:
- 首先添加对System.IdentityModel和System.IdentityModel.Services的引用。
- 在 web.config 中添加一些<configSections>元素
<section name="system.identityModel" type="System.IdentityModel.Configuration.SystemIdentityModelSection, System.IdentityModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" />
<section name="system.identityModel.services" type="System.IdentityModel.Services.Configuration.SystemIdentityModelServicesSection, System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" />
- 添加联邦配置的配置部分
<system.identityModel.services>
<federationConfiguration>
<cookieHandler requireSsl="false" /> <!-- // set to true before deploying to production server // -->
</federationConfiguration>
</system.identityModel.services>
- 在<system.webServer>.<modules>下,将 SAM (会话身份验证模块) 添加到 http 模块列表:
<add name="SessionAuthenticationModule" type="System.IdentityModel.Services.SessionAuthenticationModule, System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" preCondition="managedHandler" />
添加连接数据库的设置
就像我之前提到的,MembershipReboot 允许灵活存储用户帐户数据。有一个 EntityFramework 包实现了适当的持久性接口,我们已经安装了它。为此,我们需要设置连接字符串值,默认情况下,它会查找名为MembershipReboot的 connectionString 。在本教程中,我将使用此默认值。
在您的 web.config 文件中添加此内容类似于:
<add name="MembershipReboot" connectionString="Data Source=(LocalDb)\v11.0;Initial Catalog=MembershipReboot;Integrated Security=True" providerName="System.Data.SqlClient" />
为 MR 配置电子邮件和安全设置
有三个重要的类用于配置MembershipReboot:
- 安全设置
SecuritySettings 类包含用于配置 MembershipReboot 的某些安全设置(例如帐户锁定持续时间以及是否需要电子邮件验证)的设置。
- 申请信息
ApplicationInformation 是一个类,它让 MembershipReboot 知道应用程序的名称以及应用程序为各种帐户相关功能提供的 URL。此信息主要用于向用户发送电子邮件或短信。
- 会员重启配置
MembershipRebootConfiguration 是 UserAccountService 使用的主要配置类。它包含 SecuritySettings,并提供扩展点,用于在帐户相关数据发生变化时添加与验证或事件通知相关的任何自定义逻辑。
配置应用程序的安全设置。
这些值可以通过配置文件中的自定义配置元素进行设置,使用 SecuritySettings类,然后将其传递给 MembershipRebootConfiguration 类,或者在创建MembershipRebootConfiguration类时传递。我将在这里使用最后一个选项。
为此,我们添加了一个类,该类返回具有所需设置的MembershipRebootConfiguration类的实例。
public class MembershipRebootConfig
{
public static MembershipRebootConfiguration Create()
{
var config = new MembershipRebootConfiguration();
config.RequireAccountVerification = true;
config.EmailIsUsername = false;
return config;
}
}
上面,我将RequireAccountVerification属性设置为 true,因为我希望验证帐户。我将其他设置保留为默认值。此页面显示了您可以设置/配置的其他设置选项及其默认值。
添加发送电子邮件的设置
电子邮件通知是作为 MR 事件系统的一部分进行处理的。当对UserAccount类进行操作时,会引发一个事件来指示该操作。我们安装的包中有一个用于处理电子邮件事件的事件处理程序类。它被称为EmailAccountEventsHandler。此类的注册是通过AddEventHandler API 在 MembershipRebootConfiguration 类上执行的。要实例化EmailAccountEventsHandler类,需要一个EmailMessageFormatter的实例。EmailMessageFormatter类读取嵌入在 MembershipReboot 程序集本身中的模板文本文件,而EmailAccountEventsHandler类从此类读取将包含在电子邮件中的文本。可以通过从 EmailMessageFormatter 派生或定义实现 IMessageFormatter 的新类来自定义此文本。
发送电子邮件时,EmailMessageFormatter需要将 URL 嵌入回应用程序。这些端点预计由应用程序本身实现。要将URL告知EmailMessageFormatter ,可以使用AspNetApplicationInformation类或OwinApplicationInformation(用于基于 owin 的应用程序)。它允许指示各种 URL 的相对路径。如果需要更多自定义,可以使用基本ApplicationInformation类。
对于我们的解决方案,我们将使用AspNetApplicationInformation类,因此我们需要更新创建MembershipRebootConfiguration类的新实例的代码。以下是对此类所做的更新:
public class MembershipRebootConfig
{
public static MembershipRebootConfiguration Create()
{
var config = new MembershipRebootConfiguration();
config.RequireAccountVerification = true;
config.EmailIsUsername = false;
var appInfo = new AspNetApplicationInformation(
"Test",
"Test Hack.guide tutorials",
"Account/Login/",
"Account/ConfirmEmail/",
"UserAccount/CancelRegistration/",
"Account/ConfirmPasswordReset/");
var emailFormatter = new EmailMessageFormatter(appInfo);
config.AddEventHandler(new EmailAccountEventsHandler(emailFormatter));
return config;
}
}
在实例化AspNetApplicationInformation类时,我们添加了稍后将要实现的操作的 URL。这些 URL 包括登录、确认帐户和重置密码的链接。
为了使电子邮件正常工作,我们需要在 web.config 文件中添加 SMTP 设置。将其添加到您的 web.config 中:
<system.net>
<mailSettings>
<smtp from="###">
<network host="###" userName="###" password="#" port="#" />
</smtp>
</mailSettings>
</system.net>
配置 SimpleInjector
接下来,配置 SimpleInjector 以解析应用程序中所需的 MR 类的实例。我将使用依赖注入 (DI) 模式;可以使用任何其他 DI 库,但在本教程中我选择使用 SimpleInjector。如果其他 DI 容器有其他配置要注入的服务的方式,则这些服务的解析方式将有所不同。
为此,我将在 App_Start 文件夹中添加一个名为SimpleInjectorConfig的类。我在这里添加这个类,因为我更喜欢在这个文件中包含我的启动配置,所以这是一个偏好问题,如何做到这一点取决于你。在那里,我将添加一个静态方法,其中包含如何解析所需 MR 类的设置,并将在 Global.asax.cs 的 Application_Start 中调用。下面是我配置这个类的方式:
public class SimpleInjectorConfig
{
public static void Register()
{
// Create the container as usual.
var container = new Container();
container.Options.DefaultScopedLifestyle = new WebRequestLifestyle();
// Register types:
container.RegisterSingleton<MembershipRebootConfiguration>(MembershipRebootConfig.Create);
container.RegisterPerWebRequest<DefaultMembershipRebootDatabase>(() => new DefaultMembershipRebootDatabase());
container.Register<UserAccountService>(() => new UserAccountService(container.GetInstance<MembershipRebootConfiguration>(), container.GetInstance<IUserAccountRepository>()));//Or make it InstancePerHttpRequest
container.Register<AuthenticationService, SamAuthenticationService>();
var defaultAccountRepositoryRegistration =
Lifestyle.Scoped.CreateRegistration<DefaultUserAccountRepository>(container);
container.AddRegistration(typeof(IUserAccountQuery), defaultAccountRepositoryRegistration);
container.AddRegistration(typeof(IUserAccountRepository), defaultAccountRepositoryRegistration);
// This is an extension method from the integration package.
container.RegisterMvcControllers(Assembly.GetExecutingAssembly());
// This is an extension method from the integration package as well.
container.RegisterMvcIntegratedFilterProvider();
container.Verify();
//Set dependency resolver for MVC
DependencyResolver.SetResolver(new SimpleInjectorDependencyResolver(container));
}
}
现在更新您的 Global.asax.cs 类以调用SimpleInjectorConfig.Register()<fon
免责声明:本内容来源于第三方作者授权、网友推荐或互联网整理,旨在为广大用户提供学习与参考之用。所有文本和图片版权归原创网站或作者本人所有,其观点并不代表本站立场。如有任何版权侵犯或转载不当之情况,请与我们取得联系,我们将尽快进行相关处理与修改。感谢您的理解与支持!

请先 登录后发表评论 ~