Module Zero之用户管理
2015-12-06 17:50
387 查看
返回《Module Zero学习目录》
用户实体
用户管理者
用户认证
这个类是你在安装module-zero时自动创建的。用户数据存储在数据库中的AbpUsers表。你可以添加User类的自定义属性(以及针对改变创建数据库迁移)。
AbpUser类定义的基本属性如下:
UserName:用户的登录名,对于一个租户来说应该是唯一的。
EmailAddress:用户的邮箱地址。对于租户来说应该是唯一的。
Password:用户的哈希密码。
IsActive:如果用户可以登录到该应用,那么此值为true。
Name和Surname:用户的名和姓。
还有许多属性,如Roles, Permissions, Tenant, Settings, IsEmailConfirmed等等。你可以在AbpUser类中查看更多信息。
AbpUser类派生自FullAuditedEntity。这意味着它有创建,修改和删除的审计属性。它也支持软删除。因此当我们删除一个用户的时候,实际上它并没有从数据库中删除,而是仅仅标记为已删除的状态。
为了在一个多租户的应用中更好地工作,AbpUser类实现了IMayHaveTenant过滤器。
最后,User的Id定义为long类型。
你可以注入用户管理者,然后使用它来创建,删除,更新用户,为用户授权,改变角色以及更多。你可以在这里添加你自己的方法。而且,你可以重写AbpUserManager基类的任何方法来满足你自己的需求。
曾经设计UserManager的目的是为单租户服务的。默认是为当前租户服务的。接下来看一下UserManager的一些用法:
Module-zero定义了CheckErrors扩展方法,它可以自动地检查错误,如果需要,也会抛出异常(本地化的UserFriendlyException)。样例用法:
为了获得一个本地化的异常,我们应该提供一个ILocalizationManager实例:
对于很多情况,UserManager定义了一个名叫“外部认证资源”的扩展点。我们可以创建一个派生自IExternalAuthenticationSource 的类,然后将它注册到配置中。有一个简化了IExternalAuthenticationSource的实现的类DefaultExternalAuthenticationSource ,来看一个例子:
在TryAuthenticateAsync方法中,我们可以检查来自某些资源的用户名和密码,如果给定的用户通过了该资源的认证,那么返回true。而且,我们可以重写CreateUser和UpdateUser方法来控制该资源的用户创建和更新。
当外部资源验证通过一个用户后,module-zero会检查数据库(AbpUser表)中是否存在该用户。如果不存在,就会调用CreateUser来创建该用户,否则调用UpdateUser使外部源更新已存在的用户信息。
在一个应用中,我们可以定义不止一个外部源。AbpUser实体有一个AuthenticationSource属性,它表明了哪个源认证了该用户。
为了注册认证源,我们可以在模块中的PreInitialize方法使用这些代码:
如果我们想要使用LDAP认证,那么我们首先要将Abp.Zero.Ldap添加到项目中(通常添加到Core(领域)项目)。然后,我们应该给应用扩展LdapAuthenticationSource,如下所示:
最后,我们应该设置AbpZeroLdapModule的模块依赖,然后开启上面创建的LDAP认证源:
这些步骤之后,你的应用就开启了LDAP模块。但LDAP认证默认没有开启,我们可以使用设置来开启它。
正如你在MyLdapAuthenticationSource的构造函数中看到的,LdapAuthenticationSource期望ILdapSettings作为构造函数参数。该接口用于获得LDAP设置,如领域,用户名和密码,以连接到活动目录。默认的实现(LdapSetting类)从设置管理者中获得这些设置。
如果你使用了设置管理者,你可以使用设置管理者的API改变LDAP的设置。如果你想要的话,你可以通过将一个初始化/种子数据添加到数据库来默认开启LDAP认证。
注意:如果你没有定义领域,用户名和密码,且你的应用运行在具有合适权限的领域中,那么LDAP认证只对当前的领域有效。
然后在模块中的PreInitialize方法里将它注册到IOC中:
这样,你就可以从其他资源获得LDAP设置了。
用户实体
用户管理者
用户认证
用户实体
用户实体代表应用的一个用户,它派生自AbpUser类,如下所示:public class User : AbpUser<Tenant, User> { //这里添加你自己的用户属性 }
这个类是你在安装module-zero时自动创建的。用户数据存储在数据库中的AbpUsers表。你可以添加User类的自定义属性(以及针对改变创建数据库迁移)。
AbpUser类定义的基本属性如下:
UserName:用户的登录名,对于一个租户来说应该是唯一的。
EmailAddress:用户的邮箱地址。对于租户来说应该是唯一的。
Password:用户的哈希密码。
IsActive:如果用户可以登录到该应用,那么此值为true。
Name和Surname:用户的名和姓。
还有许多属性,如Roles, Permissions, Tenant, Settings, IsEmailConfirmed等等。你可以在AbpUser类中查看更多信息。
AbpUser类派生自FullAuditedEntity。这意味着它有创建,修改和删除的审计属性。它也支持软删除。因此当我们删除一个用户的时候,实际上它并没有从数据库中删除,而是仅仅标记为已删除的状态。
为了在一个多租户的应用中更好地工作,AbpUser类实现了IMayHaveTenant过滤器。
最后,User的Id定义为long类型。
用户管理者
用户管理者是执行用户领域逻辑的服务:public class UserManager : AbpUserManager<Tenant, Role, User> { //... }
你可以注入用户管理者,然后使用它来创建,删除,更新用户,为用户授权,改变角色以及更多。你可以在这里添加你自己的方法。而且,你可以重写AbpUserManager基类的任何方法来满足你自己的需求。
多租户
如果你创建的不是一个多租户应用,那么你可以跳过本节。曾经设计UserManager的目的是为单租户服务的。默认是为当前租户服务的。接下来看一下UserManager的一些用法:
public class MyTestAppService : ApplicationService { private readonly UserManager _userManager; public MyTestAppService(UserManager userManager) { _userManager = userManager; } public void TestMethod_1() { //Find a user by email for current tenant var user = _userManager.FindByEmail("sampleuser@aspnetboilerplate.com"); } public void TestMethod_2() { //Switch to tenant 42 CurrentUnitOfWork.SetFilterParameter(AbpDataFilters.MayHaveTenant, AbpDataFilters.Parameters.TenantId, 42); //Find a user by email for the tenant 42 var user = _userManager.FindByEmail("sampleuser@aspnetboilerplate.com"); } public void TestMethod_3() { //Disabling MayHaveTenant filter, so we can reach to all users using (CurrentUnitOfWork.DisableFilter(AbpDataFilters.MayHaveTenant)) { //Now, we can search for a user name in all tenants var users = _userManager.Users.Where(u => u.UserName == "sampleuser").ToList(); //Or we can add TenantId filter if we want to search for a specific tenant var user = _userManager.Users.FirstOrDefault(u => u.TenantId == 42 && u.UserName == "sampleuser"); } } }
用户登录
UserManager有一个登录到该应用的LoginAsync方法。它检查所有的登录逻辑并返回一个登录结果。查看样例AccountController中Login方法的示例用法。关于IdentityResults
UserManager的一些方法返回了IdentityResult作为结果而不是抛出一些情况的异常。这是ASP.NET Identity Framework的本质。Module-zero也遵循这个。因此,我们可以查看这个返回的结果对象就可知道操作是否成功。Module-zero定义了CheckErrors扩展方法,它可以自动地检查错误,如果需要,也会抛出异常(本地化的UserFriendlyException)。样例用法:
(await UserManager.CreateAsync(user)).CheckErrors();
为了获得一个本地化的异常,我们应该提供一个ILocalizationManager实例:
(await UserManager.CreateAsync(user)).CheckErrors(LocalizationManager);
外部认证
Module-zero的Login方法会认证数据库的AbpUsers表中的用户。一些应用可能要求认证来自外部资源的用户(比如活动目录,来自其他数据库的表,甚至来自一个远程服务)。对于很多情况,UserManager定义了一个名叫“外部认证资源”的扩展点。我们可以创建一个派生自IExternalAuthenticationSource 的类,然后将它注册到配置中。有一个简化了IExternalAuthenticationSource的实现的类DefaultExternalAuthenticationSource ,来看一个例子:
public class MyExternalAuthSource : DefaultExternalAuthenticationSource<Tenant, User> { public override string Name { get { return "MyCustomSource"; } } public override Task<bool> TryAuthenticateAsync(string userNameOrEmailAddress, string plainPassword, Tenant tenant) { //TODO: authenticate user and return true or false } }
在TryAuthenticateAsync方法中,我们可以检查来自某些资源的用户名和密码,如果给定的用户通过了该资源的认证,那么返回true。而且,我们可以重写CreateUser和UpdateUser方法来控制该资源的用户创建和更新。
当外部资源验证通过一个用户后,module-zero会检查数据库(AbpUser表)中是否存在该用户。如果不存在,就会调用CreateUser来创建该用户,否则调用UpdateUser使外部源更新已存在的用户信息。
在一个应用中,我们可以定义不止一个外部源。AbpUser实体有一个AuthenticationSource属性,它表明了哪个源认证了该用户。
为了注册认证源,我们可以在模块中的PreInitialize方法使用这些代码:
Configuration.Modules.Zero().UserManagement.ExternalAuthenticationSources.Add<MyExternalAuthSource>();
LDAP/活动目录
LdapAuthenticationSource是一个外部认证的实现,它可以让用户使用他们的LDAP(活动目录)用户名和密码登录。如果我们想要使用LDAP认证,那么我们首先要将Abp.Zero.Ldap添加到项目中(通常添加到Core(领域)项目)。然后,我们应该给应用扩展LdapAuthenticationSource,如下所示:
public class MyLdapAuthenticationSource : LdapAuthenticationSource<Tenant, User> { public MyLdapAuthenticationSource(ILdapSettings settings, IAbpZeroLdapModuleConfig ldapModuleConfig) : base(settings, ldapModuleConfig) { } }
最后,我们应该设置AbpZeroLdapModule的模块依赖,然后开启上面创建的LDAP认证源:
[DependsOn(typeof(AbpZeroLdapModule))] public class MyApplicationCoreModule : AbpModule { public override void PreInitialize() { Configuration.Modules.ZeroLdap().Enable(typeof (MyLdapAuthenticationSource)); } ... }
这些步骤之后,你的应用就开启了LDAP模块。但LDAP认证默认没有开启,我们可以使用设置来开启它。
设置
LdapSettingNames类定义了一些设置名称的常量。当要改变设置(或者获取设置)时,你可以使用这些常量名称。LDAP设置是每个租户的(对于多租户应用)。因此,不同的租户有不同的设置。(在github上查看设置的定义)正如你在MyLdapAuthenticationSource的构造函数中看到的,LdapAuthenticationSource期望ILdapSettings作为构造函数参数。该接口用于获得LDAP设置,如领域,用户名和密码,以连接到活动目录。默认的实现(LdapSetting类)从设置管理者中获得这些设置。
如果你使用了设置管理者,你可以使用设置管理者的API改变LDAP的设置。如果你想要的话,你可以通过将一个初始化/种子数据添加到数据库来默认开启LDAP认证。
注意:如果你没有定义领域,用户名和密码,且你的应用运行在具有合适权限的领域中,那么LDAP认证只对当前的领域有效。
自定义设置
如果你想定义其他的设置源,那么你可以实现一个自定义的ILdapSettings类,如下所示:public class MyLdapSettings : ILdapSettings { public async Task<bool> GetIsEnabled(int? tenantId) { return true; } public async Task<ContextType> GetContextType(int? tenantId) { return ContextType.Domain; } public async Task<string> GetContainer(int? tenantId) { return null; } public async Task<string> GetDomain(int? tenantId) { return null; } public async Task<string> GetUserName(int? tenantId) { return null; } public async Task<string> GetPassword(int? tenantId) { return null; } }
然后在模块中的PreInitialize方法里将它注册到IOC中:
[DependsOn(typeof(AbpZeroLdapModule))] public class MyApplicationCoreModule : AbpModule { public override void PreInitialize() { IocManager.Register<ILdapSettings, MyLdapSettings>(); //change default setting source Configuration.Modules.ZeroLdap().Enable(typeof (MyLdapAuthenticationSource)); } ... }
这样,你就可以从其他资源获得LDAP设置了。
相关文章推荐
- SSL/TLS 协议详解
- linux常用查看硬件设备信息命令
- wireshark抓取OpenFlow数据包
- Java GC - 垃圾回收机制
- 编程珠玑 第三部分 应用
- 快速排序的两种实现方法
- 迭代器(Iterator)
- int与float在内存中的存储形式_对比与转换
- 使用markdown进行代码阅读笔记
- 南大软院大神养成计划第二十一天
- android错误详解教程二
- ECONOMETRICS CHAPTER1
- ASCII码对应表chr(9)、chr(10)、chr(13)、chr(32)、chr(34)、chr(39)、
- 一个Ip2long函数,通过调用go tool pprof分析,竟发现内存分配了3G
- Introduction to Recommender System 之 Module 4 User-User Collaborative Filtering
- 【OpenCV】边缘检测:梯度,sobel算子的理解
- Android - User Interface
- HDU 4325 Flowers(线段树+离散化)
- I/O流性能比拼
- POJ3295——Tautology