NET6完整项目实战系列第5篇:用户登录番外篇--app.UseAuthentication()和app.UseAuthorization()的使用(中)
在运行之前,先将Program.cs中唯一和认证授权有关的语句 app.UseAuthorization(); 注释起来,如下:
然后对 Login.cshtml 和 Login.cshtml.cs 文件中做少少改动,增加账号密码的非空校验,最后将登录信息写入cookie中,
编码如下:
Login.cshtml
@page
@model WebApplication1.Pages.LoginModel
@{
}
<div style="color:red;">@Model.ErrorMsg</div>
<br />
<form method="post">
账号:<input type="text" name="acc" /> <br /><br />
密码:<input type="text" name="pwd" /> <br /><br />
<input type="submit" name="send" value="确定" />
</form>
@Model.ErrorMsg 中 ErrorMsg 是 Login.cshtml.cs 的一个字段,用来记录错误信息 。
Login.cshtml.csusing Microsoft.AspNetCore.Authentication;using Microsoft.AspNetCore.Authentication.Cookies;using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using System.Security.Claims;
namespace WebApplication1.Pages
{
public class LoginModel : PageModel
{
public void OnGet()
{
}
public string ErrorMsg = string.Empty;
public async Task<IActionResult> OnPostAsync()
{
string acc = Request.Form["acc"];
string pwd = Request.Form["pwd"];
if (string.IsNullOrWhiteSpace(acc) || string.IsNullOrWhiteSpace(pwd))
{
ErrorMsg = "账号或密码不能为空!";
return Page();
}
string roleName = acc == "admin" ? "AdminRole" : "UserRole";
string url = acc == "admin" ? "adminmng/adminindex" : "usermng/userindex";
//1. 声明
List<Claim> claims = new()
{
new Claim(ClaimTypes.Name, acc),
new Claim(ClaimTypes.Role, roleName),
new Claim("UserName", "张先生"),
};
//2. 标识
ClaimsIdentity identity = new (claims, CookieAuthenticationDefaults.AuthenticationScheme);
//3. 主体
ClaimsPrincipal principal = new(identity);
//4. 写入cookie,SignInAsync()方法创建加密的 cookie 并将其添加到当前响应中。
await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, principal);
return Redirect(url);
}
}
}
说明:
1.因为 Login.cshtml 页面是 POST 提交,所以 Login.cshtml.cs 中对应的处理方法是 OnPost( ) , 这是 net6 的规则 。
2. HttpContext.SignInAsync( ) 是异步方法,前面要加 await 关键字,对应的 OnPost( ) 方法签名要加 async 关键字,
且返回值类型 IActionResult 必须是 Task<T> 的泛型类型。
3. 认证过程很简单,4步即可。
---ClaimsIdentity表示标识,身份证、护照 、驾驶证、火车票 就是4种不同的 ClaimsIdentity 。
---Claim 是标识中的声明,每种ClaimsIdentity都有相应的Claim,
身份证中的Claim包含 姓名、民族、性别、编号等信息;
驾驶证中的Claim包含 姓名、性别、准驾车型、有效期 等信息;
火车票中的Claim包含 车次、乘车日期、始发站、终点站 等信息;
---ClaimsPrincipal 表示认证主体,一个主体可以包含多个标识 ClaimsIdentity,比如我们坐高铁时就需要同时检查身份证和火车票 ;
4. CookieAuthenticationDefaults.AuthenticationScheme 是方案名称,每个方案有相应的认证处理程序,处理程序也可以自定义。
我们运行WEB应用后点 “登录” 连接,然后点确定,得到如下结果:
输入 admin/123 后点确定按钮得到如下页面:
错误提示 : 没有注册认证处理程序 ,按提示添加如下代码:
重新编译后运行,打开浏览器的开发人员工具查看,没有cookie消息(这里的Cookie不是login.cshtml.cs中设置的,
而是防止请求伪造 (XSRF/CSRF) 攻击用的,这一点以后再讲):
输入 admin/123 后查看 cookie 信息如下:
可以看到 cookie 已经生成了,在 adminindex.cshtml 中增加读取认证信息代码如下:
@page
@using System.Security.Claims
@model WebApplication1.Pages.AdminMng.AdminIndexModel
@{
}
<span>Admin首页,用户是否认证 : </span>
<span>@HttpContext.User.Identity?.IsAuthenticated</span><br />
@foreach(Claim item in HttpContext.User.Claims)
{
<div>声明(@item.Type)的值是:@item.Value</div>
}
重新编译后刷新页面如下:
可以看到并没有如我们期望的那样显示 True,也没有显示 Claim 中的信息 , 这是因为net6中生成的cookie需要
认证中间件做相应的识别是合法的cookie,这就是 app.UseAuthentication() 的作用,详情见下篇。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人