Blazor 是微软的新型的web开发方案,用来做全栈开发真是太爽了。
之前用 Blazor 做了几个小应用,但是一直没有去做身份验证系统,之前也没有ASP.NET的基础,C#也是最近学的,而且重要的是,网上居然几乎没有相关的资料,于是咱就结合网上的一些信息和微软的官方文档(微软的文档是我见过最好的文档了)做了一个身份鉴权的小Demo。
首先创建 Blazor Service 项目:
然后在项目的目录下创建Auth目录存放鉴权的基础设施
Provider 是鉴权的服务提供者
UserAccount 是用户账号模型
UserAccountService 是用户账号服务
UserSession 是用户 session 数据模型
在 Provider 下写自定义的基础认证服务,这里使用的session的形式做鉴权认证。
using Microsoft.AspNetCore.Components.Authorization;
using Microsoft.AspNetCore.Components.Server.ProtectedBrowserStorage;
using System.Security.Claims;
namespace BSAuth.Auth
{
public class Provider : AuthenticationStateProvider
{
private readonly ProtectedSessionStorage _sessionStorage;
private readonly ClaimsPrincipal _anonymous = new ClaimsPrincipal(new ClaimsIdentity());
public Provider(ProtectedSessionStorage sessionStorage)
{
_sessionStorage = sessionStorage;
}
public override async Task<AuthenticationState> GetAuthenticationStateAsync()
{
try
{
var userSessionStorageResult = await _sessionStorage.GetAsync<UserSession>("UserSession");
var userSession = userSessionStorageResult.Success ? userSessionStorageResult.Value : null;
if (userSession == null)
{
return await Task.FromResult(new AuthenticationState(_anonymous));
}
var claimsPrincipal = new ClaimsPrincipal(new ClaimsIdentity(new List<Claim>
{
new Claim(ClaimTypes.Name,userSession.UserName),
new Claim(ClaimTypes.Role,userSession.Role)
}, "customAuth")); ;
return await Task.FromResult(new AuthenticationState(claimsPrincipal));
}
catch
{
return await Task.FromResult(new AuthenticationState(_anonymous));
}
}
public async Task UpdateAuthState(UserSession userSession)
{
ClaimsPrincipal claimsPrincipal;
if (userSession is not null)
{
await _sessionStorage.SetAsync("UserSession", userSession);
claimsPrincipal = new ClaimsPrincipal(new ClaimsIdentity(new List<Claim>
{
new Claim(ClaimTypes.Name,userSession.UserName),
new Claim(ClaimTypes.Role,userSession.Role)
}));
}
else
{
await _sessionStorage.DeleteAsync("UserSession");
claimsPrincipal = _anonymous;
}
NotifyAuthenticationStateChanged(Task.FromResult(new AuthenticationState(claimsPrincipal)));
}
}
}
创建 UserSession 模型和 UserAccount 模型
namespace BSAuth.Auth
{
public class UserSession
{
public string UserName { get; set;}
public string Role { get; set;}
}
}
namespace BSAuth.Auth
{
public class UserAccount
{
public string UserName { get; set; }
public string Password { get; set; }
public string Role { get; set; }
}
}
然后建立账户系统服务,这里Demo用的内存数据模拟,实际应该使用数据库
namespace BSAuth.Auth
{
public class UserAccountService
{
private List<UserAccount> _user;
public UserAccountService()
{
_user = new List<UserAccount>
{
new UserAccount{UserName="张三",Password="zs",Role="admin"},
new UserAccount{UserName="李四",Password="ls",Role="user"}
};
}
public UserAccount? GetByUserName(string userName)
{
return _user.FirstOrDefault(x => x.UserName == userName);
}
}
}
然后鉴权服务就做好啦,下面要将这些服务注入到项目中。
在Program里依赖注入的形式注入基础认证服务和账号服务
接下来在App.razor下使用认证视图标签
一个简单的登录页面示例;
@page "/login"
@inject IJSRuntime ij
@using BSAuth.Auth
@inject UserAccountService userAccountService
@inject AuthenticationStateProvider authStateProvider
@inject NavigationManager navigation
<h3>Login</h3>
<input @bind="UserName" type="text"/>
<input @bind="PassWord" type="password"/>
<button @onclick="LoginAuth">登录</button>
@code {
string UserName { get; set; }
string PassWord{ get; set; }
private async Task LoginAuth()
{
var userAccount = userAccountService.GetByUserName(UserName);
if(userAccount is null || userAccount.Password != PassWord)
{
await ij.InvokeVoidAsync("alert", "登录失败");
return;
}
var provider = (Provider)authStateProvider;
await provider.UpdateAuthState(new UserSession
{
UserName = userAccount.UserName,
Role = userAccount.Role
});
await ij.InvokeVoidAsync("alert", "登录成功");
navigation.NavigateTo("/");
}
}
然后可以在需要鉴权的视图资源下使用 AuthorizeView 组件
具体使用方式请参照微软文档:ASP.NET Core Blazor 身份验证和授权 | Microsoft Learn
发表回复