使用.net5 创建具有身份验证和授权的Blazor应用程序
kqw 人气:0如果代码生成出错
卸载 Microsoft.AspNetCore.Identity.UI ,再安装,然后运行添加基架项目
运行项目
访问 https://localhost:44335/Identity/Account/Register 页面正常
在 BlazorApp0228\Shared\ 添加 LoginDisplay.razor
<AuthorizeView> <Authorized> <a href="Identity/Account/Manage">Hello, @context.User.Identity.Name!</a> <form method="post" action="Identity/Account/LogOut"> <button type="submit" class="nav-link btn btn-link">Log out</button> </form> </Authorized> <NotAuthorized> <a href="Identity/Account/Register">Register</a> <a href="Identity/Account/Login">Log in</a> </NotAuthorized> </AuthorizeView>
在 APP.razor 增加嵌套
<CascadingAuthenticationState> <Router AppAssembly="@typeof(Program).Assembly" PreferExactMatches="@true"> <Found Context="routeData"> <AuthorizeRouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" /> </Found> <NotFound> <LayoutView Layout="@typeof(MainLayout)"> <p>Sorry, there's nothing at this address.</p> </LayoutView> </NotFound> </Router> </CascadingAuthenticationState>
在 MainLayout.razor 添加 LoginDisplay
在 setup 设置
Routing 后增加
app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseRouting(); app.UseAuthentication();//add app.UseAuthorization();//add app.UseEndpoints(endpoints => { endpoints.MapBlazorHub(); endpoints.MapFallbackToPage("/_Host"); });
修改 Areas.Identity.IdentityHostingStartup 注册选项
运行,如出现错误:
SqlException: Cannot open database "BlazorTest228" requested by the login.
则迁移生成数据库
PM> Add-Migration Test228V1
PM> Update-Database
添加自定义用户数据
public class BlazorTest228User : IdentityUser { [PersonalData] public string CustomName { get; set; } }
PM> Add-Migration Test228V1.1
Build started...
Build succeeded.
To undo this action, use Remove-Migration.
PM> Update-Database
Build started...
Build succeeded.
Done.
更新 "帐户/管理/索引" 页
InputModel用以下突出显示的代码更新 区域/ Identity /Pages/Account/Manage/Index.cshtml.cs 中的:
public class InputModel { [Required] [DataType(DataType.Text)] [Display(Name = "Custom name")] public string CustomName { get; set; } [Phone] [Display(Name = "Phone number")] public string PhoneNumber { get; set; } } private async Task LoadAsync(BlazorTest228User user) { var userName = await _userManager.GetUserNameAsync(user); var phoneNumber = await _userManager.GetPhoneNumberAsync(user); Username = userName; Input = new InputModel { CustomName = user.CustomName, PhoneNumber = phoneNumber }; } if (Input.CustomName != user.CustomName) { user.CustomName = Input.CustomName; } await _userManager.UpdateAsync(user); await _signInManager.RefreshSignInAsync(user);
用以下突出显示的标记更新 区域/ Identity /Pages/Account/Manage/Index.cshtml :
<form id="profile-form" method="post"> <div asp-validation-summary="ModelOnly" class="text-danger"></div> <div class="form-group"> <label asp-for="Input.CustomName"></label> <input asp-for="Input.CustomName" class="form-control" /> </div> <div class="form-group"> <label asp-for="Username"></label> <input asp-for="Username" class="form-control" disabled /> </div>
更新帐户/注册. cshtml 页
InputModel用以下突出显示的代码更新 区域/ Identity /Pages/Account/Register.cshtml.cs 中的:
public class InputModel { [Required] [DataType(DataType.Text)] [Display(Name = "Custom name")] public string CustomName { get; set; } [Required] [EmailAddress] [Display(Name = "Email")] public string Email { get; set; } public async Task<IActionResult> OnPostAsync(string returnUrl = null) { returnUrl ??= Url.Content("~/"); ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync()).ToList(); if (ModelState.IsValid) { var user = new BlazorTest228User { CustomName = Input.CustomName, UserName = Input.Email, Email = Input.Email }; var result = await _userManager.CreateAsync(user, Input.Password);
用以下突出显示的标记更新 区域/ Identity /Pages/Account/Register.cshtml :
<div asp-validation-summary="All" class="text-danger"></div> <div class="form-group"> <label asp-for="Input.CustomName"></label> <input asp-for="Input.CustomName" class="form-control" /> <span asp-validation-for="Input.CustomName" class="text-danger"></span> </div> <div class="form-group"> <label asp-for="Input.Email"></label> <input asp-for="Input.Email" class="form-control" /> <span asp-validation-for="Input.Email" class="text-danger"></span> </div>
修改LoginDisplay.razor 显示自定义字段
@using Microsoft.AspNetCore.Identity @using BlazorTest228.Areas.Identity.Data @inject UserManager<BlazorTest228User> UserManager <AuthorizeView> <Authorized> @*<a href="Identity/Account/Manage">Hello, @context.User.Identity.Name!</a>*@ <a href="Identity/Account/Manage"> @UserManager.GetUserAsync(context.User).Result.CustomName </a> <form method="post" action="Identity/Account/LogOut"> <button type="submit" class="nav-link btn btn-link">Log out</button> </form> </Authorized> <NotAuthorized> <a href="Identity/Account/Register">Register</a> <a href="Identity/Account/Login">Log in</a> </NotAuthorized> </AuthorizeView>
为页面添加访问许可
1)\Areas\Identity\IdentityHostingStartup.cs
public class IdentityHostingStartup : IHostingStartup { public void Configure(IWebHostBuilder builder) { builder.ConfigureServices((context, services) => { services.AddDbContext<BlazorTest228Context>(options => options.UseSqlServer( context.Configuration.GetConnectionString("BlazorTest228ContextConnection"))); services.AddDefaultIdentity<BlazorTest228User>(options => options.SignIn.RequireConfirmedAccount = false) .AddRoles<IdentityRole>() .AddEntityFrameworkStores<BlazorTest228Context>(); }); } }
2)app.razor 修改为
<CascadingAuthenticationState> <Router AppAssembly="@typeof(Program).Assembly" PreferExactMatches="@true"> <Found Context="routeData"> <AuthorizeRouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)"> <NotAuthorized> <h1>Sorry</h1> <p>You're not authorized to reach this page.</p> <p>You may need to log in as a different user.</p> </NotAuthorized> <Authorizing> <h1>Authorization in progress</h1> <p>Only visible while authorization is in progress.</p> </Authorizing> </AuthorizeRouteView> </Found> <NotFound> <LayoutView Layout="@typeof(MainLayout)"> <h1>Sorry</h1> <p>Sorry, there's nothing at this address.</p> </LayoutView> </NotFound> </Router> </CascadingAuthenticationState>
3)要求登陆的页面增加
@page "/counter" @attribute [Authorize] <h1>Counter</h1>
效果
对于页面局部内容,直接使用
<AuthorizeView> <Authorized> <h1>Hello, @context.User.Identity.Name!</h1> <p>登陆后显示的内容</p> </Authorized> <NotAuthorized> <h1>未登陆时的信息</h1> <p>用户尚未登陆</p> </NotAuthorized> </AuthorizeView>
加载全部内容