Module Zero之用戶管理


返回《Module Zero學習目錄》


用戶實體##

用戶實體代表應用的一個用戶,它派生自AbpUser類,如下所示:

public class User : AbpUser<Tenant, User>
{
    //這里添加你自己的用戶屬性
}

這個類是你在安裝module-zero時自動創建的。用戶數據存儲在數據庫中的AbpUsers表。你可以添加User類的自定義屬性(以及針對改變創建數據庫遷移)。
AbpUser類定義的基本屬性如下:

  • UserName:用戶的登錄名,對於一個租戶來說應該是唯一的。
  • EmailAddress:用戶的郵箱地址。對於租戶來說應該是唯一的。
  • Password:用戶的哈希密碼。
  • IsActive:如果用戶可以登錄到該應用,那么此值為true。
  • NameSurname:用戶的名和姓。

還有許多屬性,如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設置了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM