目录
- 建立默认带身份验证 Blazor 程序
- `角色/组件/特性/过程逻辑
- DB 改 Sqlite
- 将自定义字段添加到用户表
- 脚手架拉取IDS文件,本地化资源
- freesql 生成实体类,freesql 管理ids数据表
- 初始化 Roles,freesql 外键 => 导航属性
- 完善 freesql 和 bb 特性
本节源码
https://github.com/densen2014/Blazor100/tree/Blazor-教程15-2/b15blazorIDS
更改默认密码策略,添加管理员角色
有些同学说一直使用1qaz@WSX密码感觉不爽,那我们改一下策略
编辑Program.cs文件
找到
builder.Services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true) .AddEntityFrameworkStores<ApplicationDbContext>();
改为以下配置
builder.Services.AddDefaultIdentity<IdentityUser>(o => { // Password settings. o.Password.RequireDigit = false; o.Password.RequireLowercase = false; o.Password.RequireNonAlphanumeric = false; o.Password.RequireUppercase = false; o.Password.RequiredLength = 1; o.Password.RequiredUniqueChars = 1; } ) .AddRoles<IdentityRole>()
编辑页面Index.razor
页面头部加入
@using Microsoft.AspNetCore.Components @using Microsoft.AspNetCore.Identity @using System.Diagnostics.CodeAnalysis
初始化角色,添加默认管理员
最终页面代码
@code { [Inject] [NotNull] protected UserManager<IdentityUser>? UserManager { get; set; } [Inject] [NotNull] protected RoleManager<IdentityRole>? RoleManager { get; set; } protected override async Task OnAfterRenderAsync(bool firstRender) { await base.OnAfterRenderAsync(firstRender); if (!firstRender) return; var RoleResult = await RoleManager.FindByNameAsync(AuthorizeRoles.Admin.ToString()); if (RoleResult == null) { await RoleManager.CreateAsync(new IdentityRole(AuthorizeRoles.Admin.ToString())); Console.WriteLine("Admin Role Created"); } var user = await UserManager.FindByNameAsync("test@app.com"); if (user != null) { var UserResult = await UserManager.IsInRoleAsync(user, AuthorizeRoles.Admin.ToString()); if (!UserResult) { await UserManager.AddToRoleAsync(user, AuthorizeRoles.Admin.ToString()); Console.WriteLine("Admin Role Added to test@app.com"); } } var chekRole = RoleManager.RoleExistsAsync(AuthorizeRoles.R110.ToString()); if (chekRole.Result == false) { await RoleManager.CreateAsync(new IdentityRole(AuthorizeRoles.R110.ToString())); Console.WriteLine("R110Role Created"); } chekRole = RoleManager.RoleExistsAsync(AuthorizeRoles.Superuser.ToString()); if (chekRole.Result == false) { await RoleManager.CreateAsync(new IdentityRole(AuthorizeRoles.Superuser.ToString())); Console.WriteLine("Superuser Role Created"); } } public enum AuthorizeRoles { Admin, Superuser, R110, R120, R130, R140, } }
参考第一篇重新注册账号, 点击 Register 注册账号
| Password | Confirm Password | |
|---|---|---|
| test@app.com | 000000 | 000000 |
登录后,刷新两次首页,test@app.com就会被代码设置为管理员组

<AuthorizeView>组件
编辑 Index.razor 文件,加入以下代码
<AuthorizeView> <Authorized> 你好, @context.User.Identity?.Name @if (@context.User.IsInRole(AuthorizeRoles.Administrators.ToString())) { <span>管理员</span> } else if (@context.User.IsInRole(AuthorizeRoles.Superuser.ToString())) { <span>超级用户</span> } else { <span>能力者</span> } </Authorized> <NotAuthorized> <span>看起来你还没登录</span> </NotAuthorized> </AuthorizeView> @code{ public enum AuthorizeRoles { Superuser, Administrators, R110, R120, R130, R140, } }
运行截图

检查登录信息
新建Razor组件: LogInfo


编辑页面
@page "/logInfo" <PageTitle>登录信息</PageTitle> <h1>登录信息</h1> <button @onclick="LogUsername">检查登录信息</button> <p>@authMessage</p> @code { /// <summary> /// 级联参数获取身份验证状态数据 /// </summary> [CascadingParameter] private Task<AuthenticationState> authenticationStateTask { get; set; } private string authMessage; private async Task LogUsername() { var authState = await authenticationStateTask; var user = authState.User; if (user.Identity.IsAuthenticated) { authMessage = $"{user.Identity.Name} is authenticated."; } else { authMessage = "The user is NOT authenticated."; } } }
运行

添加导航菜单
编辑文件 SharedNavMenu.razor

<div class="nav-item px-3"> <NavLink class="nav-link" href="logInfo"> <span class="oi oi-plus" aria-hidden="true"></span> 登录信息 </NavLink> </div>
注销按钮
编辑 Index.razor 文件,加入以下代码
@using Microsoft.AspNetCore.Components.Authorization <form method="post" action="Identity/Account/Logout"> <button type="submit" class="nav-link btn btn-link">Log out</button> </form>
基于策略的授权 / 基于角色或基于策略的授权
基于策略的授权需要Program.cs添加相关配置,这里带过就好,不展开讨论.
<p>基于角色或基于策略的授权 </p> <AuthorizeView Roles="Admin, Superuser"> <p>You can only see this if you're an Admin or Superuser.</p> </AuthorizeView> <p>基于策略的授权</p> <AuthorizeView Policy="ContentEditor"> <p>You can only see this if you satisfy the "ContentEditor" policy.</p> </AuthorizeView>
在 Razor 组件中使用 [Authorize] 特性
新建AuthorizePage.razor组件
@page "/AuthorizePage" @attribute [Authorize] <PageTitle>已登录</PageTitle> <h1>You can only see this if you're signed in.</h1>
导航菜单SharedNavMenu.razor
<div class="nav-item px-3"> <NavLink class="nav-link" href="AuthorizePage"> <span class="oi oi-plus" aria-hidden="true"></span> 验证组件 </NavLink> </div>
未登录状态

登录后状态

在 Razor 组件中使用 [Authorize(Roles = "Admin, Superuser")] 特性
新建AuthorizeAdminPage.razor组件
@page "/AuthorizeAdminPage" @attribute [Authorize(Roles = "Admin, Superuser")] <PageTitle>Admin 已登录</PageTitle> <p>You can only see this if you're in the 'Admin' or 'Superuser' role.</p>
导航菜单SharedNavMenu.razor
<div class="nav-item px-3"> <NavLink class="nav-link" href="AuthorizeAdminPage"> <span class="oi oi-plus" aria-hidden="true"></span> Admin验证组件 </NavLink> </div>
管理员账号test@app.com登录

普通账号test@test.com登录

过程逻辑中检查授权规则 AuthenticationState
新建AuthenticationStatePage.razor组件
@page "/AuthenticationStatePage" @attribute [Authorize] <PageTitle>Admin 已登录</PageTitle> <pre>如果需要应用在过程逻辑中检查授权规则,请使用类型为 Task<AuthenticationState> 的级联参数来获取用户的 ClaimsPrincipal。 Task<AuthenticationState> 可以与其他服务(如 IAuthorizationService)结合使用来评估策略。</pre> @using Microsoft.AspNetCore.Authorization @inject IAuthorizationService AuthorizationService <button @onclick="@DoSomething">Do something important</button> <p>@Msg</p> @code { [CascadingParameter] private Task<AuthenticationState> authenticationStateTask { get; set; } private string? Msg { get; set; } private async Task DoSomething() { var user = (await authenticationStateTask).User; if (user.Identity.IsAuthenticated) { Msg = "Perform an action only available to authenticated (signed-in) users."; } if (user.IsInRole("admin")) { Msg = "Perform an action only available to users in the 'admin' role."; } //if ((await AuthorizationService.AuthorizeAsync(user, "content-editor")) // .Succeeded) //{ // Msg = "Perform an action only available to users satisfying the 'content-editor' policy."; //} } }
导航菜单SharedNavMenu.razor
<div class="nav-item px-3"> <NavLink class="nav-link" href="AuthenticationStatePage"> <span class="oi oi-plus" aria-hidden="true"></span> 验证过程逻辑 </NavLink> </div>

本节源码
https://github.com/densen2014/Blazor100/tree/Blazor-教程15-2/b15blazorIDS
源代码
https://github.com/densen2014/Blazor100
https://gitee.com/densen2014/Blazor100 (镜像/非最新版)