Asp.Net Core之Identity應用(上篇)

1、前言

在前面的篇章介紹中,簡單介紹了IdentityServer4持久化存儲機制相關配置和操做數據,實現了數據遷移,可是未對用戶實現持久化操做說明。在總結中咱們也提到了,html

由於IdentityServer4本就支持了接入其餘認證方式,因此本身根據須要進行合理擴展的,好比咱們可使用 Asp.Net Core 自帶的 Identity 身份認證機制來實現擴展,實現用戶數據持久化操做。mysql

固然了,本篇暫時拋開IdentityServer4這個話題,而是單獨認識一下Asp.Net Core 自帶的 Identity 身份認證機制是什麼樣的?git

所以,本篇主要介紹的是將ASP.NET Core Identity 實戰應用。github

2、初識

ASP.NET Core Identity是用於構建ASP.NET Core Web應用程序的身份認證系統,包括用戶數據,用戶身份以及註冊登陸信息數據存儲,可讓您的應用擁有登陸功能以及持續化存儲登陸用戶相關數據。web

ASP.NET Core Identity(下文簡稱Identity)能夠簡單的用戶管理系統,可是倒是一個功能強大的系統,包含用戶管理的方方面面,主要包括:正則表達式

  1. 用戶數據存儲(使用任意你喜歡的關係型數據庫,從sqllite到mysql、sqlserver等等,由Entity Framwork 支持)
  2. 登錄、註冊外加身份認證(基於cookie的身份認證,若是你使用Vs那麼還能夠生成用於註冊登陸的用戶界面及處理代碼)
  3. 角色管理
  4. 基於聲明的認證模式

具體對於Identity的理解能夠參考Asp.Net Core之Identity入門sql

接下來咱們主要是實踐應用一下,理解Identity數據庫

3、實踐

3.1 建立項目

基於vs2019, .net core3.1建立asp.net core web 應用程序。json

3.1.1 流程:

1.選擇「文件」 > 「新建」 > 「項目」。
2.選擇「ASP.NET Core Web應用程序」。 將項目命名WebIdentityDemoV3.0具備項目下載相同的命名空間。 單擊 「肯定」。
3.選擇 ASP.NET Core Web MVC應用程序,而後選擇更改身份驗證。
4.選擇單個用戶賬戶而後單擊肯定。

生成的項目 ASP.NET Core Identity 以類庫形式 Razor 提供。安全

img

3.1.2 目錄結構:

img

3.1.3 遷移數據

找到appsettings.json文件, ConnectionStrings的數據庫鏈接字符串,默認是鏈接本地的數據庫,固然了,你也能夠改爲你指定的數據庫地址。

"ConnectionStrings": {
   "DefaultConnection": "Data Source=.;initial catalog=IdentityV3;user id=sa;password=123456;"
  },

基於生成的遷移代碼,同步到數據庫

PM> Update-Database

img

到了這裏,咱們基本完成了Identity項目的搭建了,能夠就此運行登陸註冊。

3.1.4 效果以下:

img

但是回到生成的目錄結構看來,卻發現沒有Identity用戶相關的model,cshtml等文件。這是爲什麼呢?

其實這些相關文件已由內置Razor類庫提供。因此生成的代碼目錄沒有。

但實際開發中,咱們須要生成相應的源代碼,以便根據開發需求拓展更改代碼和更改行爲。因此能夠根據net core爲咱們提供的基架標識(Scaffold Identiy)生成須要重寫的文件。

3.2 基架標識

在ASP.NET Core 2.1 及更高版本提供了ASP.NET Core Identity做爲Razor 類庫。 包含Identity的應用程序能夠應用基架,來有選擇地添加包含在Identity Razor 類庫 (RCL) 的源代碼。

3.2.1 流程:

1.從對應的項目中,右鍵單擊該項目 >添加 > 新基架項。

2.從左窗格添加基架對話框中,選擇標識 > 添加。

3.在中添加 標識添加對話框中,選擇所需的選項。

下面使用現有的數據上下文,選擇全部文件,以便後面重寫,以下所示。

這裏示例 因此我選擇只添加 RegisterLoginLogOutRegisterConfirmation 文件

img

3.2.2 效果:

生成後,目錄新增變化:

img

能夠發現,在Areas目錄下,生成了Razor Page文件,須要注意的是這不是MVC視圖控制器。

剛剛介紹說了,這是由於在ASP.NET Core 2.1及更高版本提供了ASP.NET Core Identity做爲Razor 類庫,再也不是以前的2.0的類庫, 由於是基於Razor Page的,

因此找不到原來在2.0版本下的Controllers(如Account等控制器)

這個時候若是你想該頁面或者的代碼,就須要基於基架重寫文件到你的項目中後,再作具體修改。

可是若是你又想實現MVC這種視圖控制器的話,你能夠基於Razor Page中的,重寫生成對應的控制器及業務邏輯,來實現視圖控制器這種方式。

4、區別

2.0 版本

看到有人問:.net core mvc模板選我的身份驗證後 Identity區域下Account控制器在哪裏?

其實這是由於在ASP.NET Core 2.1及更高版本提供了ASP.NET Core Identity做爲Razor 類庫,再也不是以前的2.0的類庫, 由於是基於Razor Page的,因此找不到原來在2.0版本下的Controllers(如Account等控制器)

可是若是你又想實現MVC這種視圖控制器的話,你能夠基於Razor Page中的,重寫生成對應的控制器及業務邏輯,來實現視圖控制器這種方式。固然了,你也能夠利用2.0版本的項目進行參考重寫你的業務。

4.1 建立項目

基於vs2019, .net core2.0 建立asp.net core web 應用程序。

4.1.1 流程:

1.選擇「文件」 > 「新建」 > 「項目」。
2.選擇「ASP.NET Core Web應用程序」。 將項目命名WebIdentityDemoV2.0具備項目下載相同的命名空間。 單擊 「肯定」。
3.選擇 ASP.NET Core Web MVC應用程序,而後選擇更改身份驗證。
4.選擇單個用戶賬戶而後單擊肯定。

生成的項目 ASP.NET Core Identity 以類庫形式 Razor 提供。

img

4.1.2 目錄結構:

img

能夠發現, 在咱們選擇我的身份認證的時候 Identity被自動添加到項目中,而且生成了

  • 帳戶控制器AccountController 註冊和登錄相關的代碼都在這裏)
  • 登錄註冊頁面(還有其它的 如:確認郵件、訪問受限等等)
  • 管理控制器(ManageController 這是給註冊用戶用的,主要有兩個功能,改密碼和雙因子驗證)

已經出現了MVC這種視圖控制器,也能夠找到對應的控制器方法了。這也是相比於升級到2.1及更高版本的不一樣之處。

在2.0版本中的MVC視圖控制器模式而升級到2.1及更高版本後,直接採用了Razor類庫,改爲了將控制器寫到了cshtml文件上了。

4.1.3 遷移數據:

找到appsettings.json文件, ConnectionStrings的數據庫鏈接字符串,默認是鏈接本地的數據庫,固然了,你也能夠改爲你指定的數據庫地址。

"ConnectionStrings": {
   "DefaultConnection": "Data Source=.;initial catalog=IdentityV2;user id=sa;password=123456;"
  },

基於生成的遷移代碼,同步到數據庫

PM> Update-Database

到了這裏,咱們基本完成了2.0 版本的Identity項目的搭建了,能夠就此運行登陸註冊了。

到了這裏, 咱們也就體驗了Asp.Net Core2.0以及在升級到2.1及更高版本後發生的變化了。

5、擴展

5.1 配置問題

5.1.1 默認配置:

以下是代碼Identity的默認選項配置,服務經過依賴關係注入提供應用程序。

public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<ApplicationDbContext>(options =>
        options.UseSqlServer(
        Configuration.GetConnectionString("DefaultConnection")));
          //這裏須要注意的是 options.SignIn.RequireConfirmedAccount 設置項,缺省設置爲true,
         //這種狀況下,新註冊的用戶須要進行確認才能完成註冊,若是沒有安裝郵件系統,這個步驟沒法完成,因此這裏改成false。
        services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = false)
        .AddEntityFrameworkStores<ApplicationDbContext>();
    services.AddControllersWithViews();
    services.AddRazorPages();
}

經過調用啓用 UseAuthenticationUseAuthentication 將身份驗證 中間件 添加到請求管道。

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
        app.UseDatabaseErrorPage();
    }
    else
    {
        app.UseExceptionHandler("/Error");
        app.UseHsts();
    }
    app.UseHttpsRedirection();
    app.UseStaticFiles();
    app.UseRouting();
    app.UseAuthentication();
    app.UseAuthorization();
    app.UseEndpoints(endpoints =>
    {
        endpoints.MapRazorPages();
    });
}

除了上面的默認配置選項之後,你也能夠根據自身的業務要求,好比有些想要對用戶名作限制,有些須要在密碼作限制等等。

典型模式是調用全部 Add{Service} 方法,而後調用全部 services.Configure{Service} 方法。

5.1.2 自定義配置:

a. 配置用戶名:

services.AddDefaultIdentity<IdentityUser>(options =>
{
    options.User = new UserOptions
    {
        RequireUniqueEmail = true, //要求Email惟一
        AllowedUserNameCharacters = "abcdefgABCDEFG" //容許的用戶名字符,默認是 abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._@+
    };
});

不支持正則表達式,若是須要支持漢字,可能須要添加不少漢字才行。。

b. 配置密碼:

services.AddDefaultIdentity<IdentityUser>(options=>
{
    options.Password = new PasswordOptions
    {
        RequireDigit = true, //要求有數字介於0-9 之間,  默認true
        RequiredLength = 8, //要求密碼最小長度,   默認是 6 個字符
        RequireLowercase = true, //要求小寫字母,  默認true
        RequireNonAlphanumeric = true, //要求特殊字符,  默認true
        RequiredUniqueChars = 3, //要求須要密碼中的非重複字符數,  默認1
        RequireUppercase = true //要求大寫字母 ,默認true
    };
})

c. 鎖定帳戶

services.AddDefaultIdentity<IdentityUser>(options=>
{
    options.Lockout = new LockoutOptions
    {
        AllowedForNewUsers = true, // 新用戶鎖定帳戶, 默認true
        DefaultLockoutTimeSpan = TimeSpan.FromHours(1), //鎖定時長,默認是 5 分鐘
        MaxFailedAccessAttempts = 3 //登陸錯誤最大嘗試次數,默認 5 次
    };
})

d. 數據庫存儲

services.AddDefaultIdentity<IdentityUser>(options=>
{
    options.Stores = new StoreOptions
    {
        MaxLengthForKeys = 128, // 主鍵的最大長度
        ProtectPersonalData = true //保護用戶數據,要求實現 IProtectedUserStore 接口
    };
})

若是不設置,主鍵則是 max 的字符串長度。

e. 令牌配置

services.AddDefaultIdentity<IdentityUser>(options=>
{
    options.Tokens = new TokenOptions
    {
         AuthenticatorTokenProvider = "MyAuthenticatorTokenProvider", //用於使用驗證器驗證雙重登陸的。
         ChangeEmailTokenProvider = "MyChangeEmailTokenProvider", //用於生成電子郵件更改確認電子郵件中使用的令牌的。
          ChangePhoneNumberTokenProvider = "MyChangePhoneNumberTokenProvider", //用於生成更改電話號碼時使用的令牌的。
          EmailConfirmationTokenProvider = "MyEmailConfirmationTokenProvider", //用於生成賬戶確認電子郵件中使用的令牌的令牌提供程序。
         PasswordResetTokenProvider = "MyPasswordResetTokenProvider", //用於生成密碼重置電子郵件中使用的令牌
        ProviderMap = new Dictionary<string, TokenProviderDescriptor>(),  //用做提供程序名稱的密鑰構造 用戶令牌提供程序 。
        AuthenticatorIssuer = "Identity", //認證的消費者      
    };
})

如何生成令牌,而後用什麼方式將令牌發給用戶,請求用戶驗證。

f. 聲明配置

services.AddDefaultIdentity<IdentityUser>(options=>
{
    options.ClaimsIdentity = new ClaimsIdentityOptions
    {
        RoleClaimType = "IdentityRole", // 用於角色聲明的聲明類型。
        UserIdClaimType = "IdentityId", // 用於用戶標識符聲明的聲明類型。
        SecurityStampClaimType = "SecurityStamp", //用於安全戳聲明的聲明類型。
        UserNameClaimType = "IdentityName" //用於用戶名聲明的聲明類型。
    };
})

g. 登陸配置:

services.AddDefaultIdentity<IdentityUser>(options=>
{
    options.SignIn = new SignInOptions
    {
        RequireConfirmedEmail = true, //要求激活郵箱., 默認false
        RequireConfirmedPhoneNumber = true //要求激活手機號才能登陸,默認false
    };
})

在登陸的時候,若是手機號或郵箱沒有激活/確認,則沒法登陸。

services.ConfigureApplicationCookie(options =>
{
    options.AccessDeniedPath = "/Identity/Account/AccessDenied";
    options.Cookie.Name = "YourAppCookieName";
    options.Cookie.HttpOnly = true;
    options.ExpireTimeSpan = TimeSpan.FromMinutes(60);
    options.LoginPath = "/Identity/Account/Login";
    // ReturnUrlParameter requires 
    //using Microsoft.AspNetCore.Authentication.Cookies;
    options.ReturnUrlParameter = CookieAuthenticationDefaults.ReturnUrlParameter;
    options.SlidingExpiration = true;
});

在中配置應用 cookie 程序 Startup.ConfigureServices 。 ConfigureApplication Cookie調用或 後必須調用 AddIdentity``AddDefaultIdentity

i. Password Hasher 設置:

services.Configure<PasswordHasherOptions>(option =>
{
    option.IterationCount = 12000; //使用 PBKDF2 對密碼進行哈希處理時使用的迭代次數。
});

PasswordHasherOptions 獲取和設置用於密碼哈希的選項。

j. 全局要求對全部用戶進行身份驗證

services.AddAuthorization(options =>
    {
        options.FallbackPolicy = new AuthorizationPolicyBuilder()
            .RequireAuthenticatedUser()
            .Build();
    });

6、總結

  1. 本篇簡單介紹了 Asp.Net Core 自帶的 Identity,一個負責對用戶的身份進行認證的組件庫,同時進行了相關的實戰應用體驗。
  2. 後續會對Identity自定義用戶以及表結構說明。
  3. 若是有不對的或不理解的地方,但願你們能夠多多指正,提出問題,一塊兒討論,不斷學習,共同進步。
  4. 項目地址

7、附加

Asp.Net Core簡介Identity

配置 ASP.NET Core Identity

Asp.Net Core之Identity入門

相關文章
相關標籤/搜索