Module Zero之用户管理
用戶(hù)實(shí)體
用戶(hù)實(shí)體代表應(yīng)用的一個(gè)用戶(hù),它派生自AbpUser類(lèi),如下所示:
public class User : AbpUser<Tenant, User> {//這里添加你自己的用戶(hù)屬性 }這個(gè)類(lèi)是你在安裝module-zero時(shí)自動(dòng)創(chuàng)建的。用戶(hù)數(shù)據(jù)存儲(chǔ)在數(shù)據(jù)庫(kù)中的AbpUsers表。你可以添加User類(lèi)的自定義屬性(以及針對(duì)改變創(chuàng)建數(shù)據(jù)庫(kù)遷移)。
AbpUser類(lèi)定義的基本屬性如下:
- UserName:用戶(hù)的登錄名,對(duì)于一個(gè)租戶(hù)來(lái)說(shuō)應(yīng)該是唯一的。
- EmailAddress:用戶(hù)的郵箱地址。對(duì)于租戶(hù)來(lái)說(shuō)應(yīng)該是唯一的。
- Password:用戶(hù)的哈希密碼。
- IsActive:如果用戶(hù)可以登錄到該應(yīng)用,那么此值為true。
- Name和Surname:用戶(hù)的名和姓。
還有許多屬性,如Roles, Permissions, Tenant, Settings, IsEmailConfirmed等等。你可以在AbpUser類(lèi)中查看更多信息。
AbpUser類(lèi)派生自FullAuditedEntity。這意味著它有創(chuàng)建,修改和刪除的審計(jì)屬性。它也支持軟刪除。因此當(dāng)我們刪除一個(gè)用戶(hù)的時(shí)候,實(shí)際上它并沒(méi)有從數(shù)據(jù)庫(kù)中刪除,而是僅僅標(biāo)記為已刪除的狀態(tài)。
為了在一個(gè)多租戶(hù)的應(yīng)用中更好地工作,AbpUser類(lèi)實(shí)現(xiàn)了IMayHaveTenant過(guò)濾器。
最后,User的Id定義為long類(lèi)型。
用戶(hù)管理者
用戶(hù)管理者是執(zhí)行用戶(hù)領(lǐng)域邏輯的服務(wù):
public class UserManager : AbpUserManager<Tenant, Role, User> {//... }你可以注入用戶(hù)管理者,然后使用它來(lái)創(chuàng)建,刪除,更新用戶(hù),為用戶(hù)授權(quán),改變角色以及更多。你可以在這里添加你自己的方法。而且,你可以重寫(xiě)AbpUserManager基類(lèi)的任何方法來(lái)滿(mǎn)足你自己的需求。
多租戶(hù)
如果你創(chuàng)建的不是一個(gè)多租戶(hù)應(yīng)用,那么你可以跳過(guò)本節(jié)。
曾經(jīng)設(shè)計(jì)UserManager的目的是為單租戶(hù)服務(wù)的。默認(rèn)是為當(dāng)前租戶(hù)服務(wù)的。接下來(lái)看一下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 tenantvar user = _userManager.FindByEmail("sampleuser@aspnetboilerplate.com");}public void TestMethod_2(){//Switch to tenant 42CurrentUnitOfWork.SetFilterParameter(AbpDataFilters.MayHaveTenant, AbpDataFilters.Parameters.TenantId, 42);//Find a user by email for the tenant 42var user = _userManager.FindByEmail("sampleuser@aspnetboilerplate.com");}public void TestMethod_3(){//Disabling MayHaveTenant filter, so we can reach to all usersusing (CurrentUnitOfWork.DisableFilter(AbpDataFilters.MayHaveTenant)){//Now, we can search for a user name in all tenantsvar users = _userManager.Users.Where(u => u.UserName == "sampleuser").ToList();//Or we can add TenantId filter if we want to search for a specific tenantvar user = _userManager.Users.FirstOrDefault(u => u.TenantId == 42 && u.UserName == "sampleuser");}} }用戶(hù)登錄
UserManager有一個(gè)登錄到該應(yīng)用的LoginAsync方法。它檢查所有的登錄邏輯并返回一個(gè)登錄結(jié)果。查看樣例AccountController中Login方法的示例用法。
關(guān)于IdentityResults
UserManager的一些方法返回了IdentityResult作為結(jié)果而不是拋出一些情況的異常。這是ASP.NET Identity Framework的本質(zhì)。Module-zero也遵循這個(gè)。因此,我們可以查看這個(gè)返回的結(jié)果對(duì)象就可知道操作是否成功。
Module-zero定義了CheckErrors擴(kuò)展方法,它可以自動(dòng)地檢查錯(cuò)誤,如果需要,也會(huì)拋出異常(本地化的UserFriendlyException)。樣例用法:
(await UserManager.CreateAsync(user)).CheckErrors();為了獲得一個(gè)本地化的異常,我們應(yīng)該提供一個(gè)ILocalizationManager實(shí)例:
(await UserManager.CreateAsync(user)).CheckErrors(LocalizationManager);外部認(rèn)證
Module-zero的Login方法會(huì)認(rèn)證數(shù)據(jù)庫(kù)的AbpUsers表中的用戶(hù)。一些應(yīng)用可能要求認(rèn)證來(lái)自外部資源的用戶(hù)(比如活動(dòng)目錄,來(lái)自其他數(shù)據(jù)庫(kù)的表,甚至來(lái)自一個(gè)遠(yuǎn)程服務(wù))。
對(duì)于很多情況,UserManager定義了一個(gè)名叫“外部認(rèn)證資源”的擴(kuò)展點(diǎn)。我們可以創(chuàng)建一個(gè)派生自IExternalAuthenticationSource?的類(lèi),然后將它注冊(cè)到配置中。有一個(gè)簡(jiǎn)化了IExternalAuthenticationSource的實(shí)現(xiàn)的類(lèi)DefaultExternalAuthenticationSource?,來(lái)看一個(gè)例子:
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方法中,我們可以檢查來(lái)自某些資源的用戶(hù)名和密碼,如果給定的用戶(hù)通過(guò)了該資源的認(rèn)證,那么返回true。而且,我們可以重寫(xiě)CreateUser和UpdateUser方法來(lái)控制該資源的用戶(hù)創(chuàng)建和更新。
當(dāng)外部資源驗(yàn)證通過(guò)一個(gè)用戶(hù)后,module-zero會(huì)檢查數(shù)據(jù)庫(kù)(AbpUser表)中是否存在該用戶(hù)。如果不存在,就會(huì)調(diào)用CreateUser來(lái)創(chuàng)建該用戶(hù),否則調(diào)用UpdateUser使外部源更新已存在的用戶(hù)信息。
在一個(gè)應(yīng)用中,我們可以定義不止一個(gè)外部源。AbpUser實(shí)體有一個(gè)AuthenticationSource屬性,它表明了哪個(gè)源認(rèn)證了該用戶(hù)。
為了注冊(cè)認(rèn)證源,我們可以在模塊中的PreInitialize方法使用這些代碼:
Configuration.Modules.Zero().UserManagement.ExternalAuthenticationSources.Add<MyExternalAuthSource>();LDAP/活動(dòng)目錄
LdapAuthenticationSource是一個(gè)外部認(rèn)證的實(shí)現(xiàn),它可以讓用戶(hù)使用他們的LDAP(活動(dòng)目錄)用戶(hù)名和密碼登錄。
如果我們想要使用LDAP認(rèn)證,那么我們首先要將Abp.Zero.Ldap添加到項(xiàng)目中(通常添加到Core(領(lǐng)域)項(xiàng)目)。然后,我們應(yīng)該給應(yīng)用擴(kuò)展LdapAuthenticationSource,如下所示:
public class MyLdapAuthenticationSource : LdapAuthenticationSource<Tenant, User> {public MyLdapAuthenticationSource(ILdapSettings settings, IAbpZeroLdapModuleConfig ldapModuleConfig): base(settings, ldapModuleConfig){} }最后,我們應(yīng)該設(shè)置AbpZeroLdapModule的模塊依賴(lài),然后開(kāi)啟上面創(chuàng)建的LDAP認(rèn)證源:
[DependsOn(typeof(AbpZeroLdapModule))] public class MyApplicationCoreModule : AbpModule {public override void PreInitialize(){Configuration.Modules.ZeroLdap().Enable(typeof (MyLdapAuthenticationSource));}... }這些步驟之后,你的應(yīng)用就開(kāi)啟了LDAP模塊。但LDAP認(rèn)證默認(rèn)沒(méi)有開(kāi)啟,我們可以使用設(shè)置來(lái)開(kāi)啟它。
設(shè)置
LdapSettingNames類(lèi)定義了一些設(shè)置名稱(chēng)的常量。當(dāng)要改變?cè)O(shè)置(或者獲取設(shè)置)時(shí),你可以使用這些常量名稱(chēng)。LDAP設(shè)置是每個(gè)租戶(hù)的(對(duì)于多租戶(hù)應(yīng)用)。因此,不同的租戶(hù)有不同的設(shè)置。(在github上查看設(shè)置的定義)
正如你在MyLdapAuthenticationSource的構(gòu)造函數(shù)中看到的,LdapAuthenticationSource期望ILdapSettings作為構(gòu)造函數(shù)參數(shù)。該接口用于獲得LDAP設(shè)置,如領(lǐng)域,用戶(hù)名和密碼,以連接到活動(dòng)目錄。默認(rèn)的實(shí)現(xiàn)(LdapSetting類(lèi))從設(shè)置管理者中獲得這些設(shè)置。
如果你使用了設(shè)置管理者,你可以使用設(shè)置管理者的API改變LDAP的設(shè)置。如果你想要的話(huà),你可以通過(guò)將一個(gè)初始化/種子數(shù)據(jù)添加到數(shù)據(jù)庫(kù)來(lái)默認(rèn)開(kāi)啟LDAP認(rèn)證。
注意:如果你沒(méi)有定義領(lǐng)域,用戶(hù)名和密碼,且你的應(yīng)用運(yùn)行在具有合適權(quán)限的領(lǐng)域中,那么LDAP認(rèn)證只對(duì)當(dāng)前的領(lǐng)域有效。
自定義設(shè)置
如果你想定義其他的設(shè)置源,那么你可以實(shí)現(xiàn)一個(gè)自定義的ILdapSettings類(lèi),如下所示:
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方法里將它注冊(cè)到IOC中:
[DependsOn(typeof(AbpZeroLdapModule))] public class MyApplicationCoreModule : AbpModule {public override void PreInitialize(){IocManager.Register<ILdapSettings, MyLdapSettings>(); //change default setting sourceConfiguration.Modules.ZeroLdap().Enable(typeof (MyLdapAuthenticationSource));}... }這樣,你就可以從其他資源獲得LDAP設(shè)置了。
本文轉(zhuǎn)自tkbSimplest博客園博客,原文鏈接:http://www.cnblogs.com/farb/p/moduleZeroUserManagement.html,如需轉(zhuǎn)載請(qǐng)自行聯(lián)系原作者
總結(jié)
以上是生活随笔為你收集整理的Module Zero之用户管理的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Hadoop MapReduce概念学习
- 下一篇: 电脑进程详情