.NET鉴权授权
gitee仓储地址
---------------------------------2022-03-30分界线-----------------------------------
一种是cookie鉴权授权,一种是token鉴权授权,先把权限授予它,才能鉴定它的权限是否符合我的权限校验
一.鉴权cookie方式
1.在program中添加鉴权授权中间件
2.在控制器某个方法上添加鉴权特性
3.在program中添加
点击查看代码
builder.Services.AddAuthentication("Cookies").AddCookie(o =>
{
o.LoginPath = "/Login/NoLogin";//鉴权不通过就跳到以下路径
});
4.添加一个控制器LoginController
点击查看代码
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
namespace AuthDemo.Api.Controllers
{
[Route("[controller]/[action]")]
[ApiController]
public class LoginController : ControllerBase
{
[HttpGet]
public async Task NoLoginAsync()
{
return "您还没有登录!";
}
}
}
5.在login控制器中添加一个方法
点击查看代码
[HttpPost]
public async Task LoginSucess(string userName,string password)
{
//判断当前的用户名和密码
if (userName=="Ace"&&password=="666")
{
//如果符合当前条件,则实例化一个实体,保存当前数据
ClaimsIdentity claimsIdentity = new ClaimsIdentity("Ctm");
claimsIdentity.AddClaim(new ( ClaimTypes.Name, userName));
claimsIdentity.AddClaim(new(ClaimTypes.NameIdentifier, "1"));
//cookies与program添加的鉴权架构一致
await HttpContext.SignInAsync("Cookies",new ClaimsPrincipal(claimsIdentity));
return "登录成功!";
}
else
{
return "登录失败!";
}
}
二.自定义token鉴权 自定义鉴权策略
1.新增一个文件夹CtmAuthentication,新增一个类文件TokenAuthenticationHandler,继承于IAuthenticationHandler接口,实现接口
2.TokenAuthenticationHandler类里的代码如下
点击查看代码
using Microsoft.AspNetCore.Authentication;
using System.Security.Claims;
namespace AuthDemo.Api.CtmAuthentication
{
public class TokenAuthenticationHandler : IAuthenticationHandler
{
private AuthenticationScheme _scheme;
private HttpContext _httpContext;
///
/// 鉴权初始化
///
/// 鉴权架构名称
/// HttpContext
///
public async Task InitializeAsync(AuthenticationScheme scheme, HttpContext context)
{
_scheme = scheme;
_httpContext = context;
}
///
/// 鉴权
///
///
public async Task AuthenticateAsync()
{
string token = _httpContext.Request.Headers["Authorization"];
if (token=="jaden")
{
ClaimsIdentity claimsIdentity = new("ctm");
claimsIdentity.AddClaims(new List
{
new Claim(ClaimTypes.Name,"jaden"),
new Claim(ClaimTypes.NameIdentifier,"6")
});
var claimsPrincipal = new ClaimsPrincipal(claimsIdentity);
return await Task.FromResult(AuthenticateResult.Success(new AuthenticationTicket(claimsPrincipal,_scheme.Name)));
}
return await Task.FromResult(AuthenticateResult.Fail("token错误,请重新登录"));
}
///
/// 未登录操作
///
///
///
public async Task ChallengeAsync(AuthenticationProperties? properties)
{
_httpContext.Response.Redirect("/Login/NoLogin");
}
///
/// 鉴权失败的操作
///
///
///
public async Task ForbidAsync(AuthenticationProperties? properties)
{
_httpContext.Response.StatusCode = 403;
}
}
}
3.修改program中的代码,如下
点击查看代码
using AuthDemo.Api.CtmAuthentication;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
#region 注册鉴权架构
//cookie
//builder.Services.AddAuthentication("Cookies").AddCookie(o =>
//{
// o.LoginPath = "/Login/NoLogin";//鉴权不通过就跳到以下路径
//});
//自定义token验证
builder.Services.AddAuthentication(op =>
{
//把自定义的鉴权方案添加到鉴权架构中
//token是个名字,下面的代表Scheme name方案名字
op.AddScheme("token","ctmToken");
op.DefaultAuthenticateScheme = "token";
op.DefaultChallengeScheme = "token";
op.DefaultForbidScheme = "token";
});
#endregion
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
//鉴权
app.UseAuthentication();
//授权
app.UseAuthorization();
app.MapControllers();
app.Run();
4.然后用postman或者apipost中测试,token中输入一些字符,发现token中存在这些字符,下面让我们继续改造,其实token就是存在我们发送请求的head文件里的
三.授权策略
1.在program中的鉴权策略下添加如下代码
点击查看代码
/*
自定义授权时,
控制器上加的Authorize授权,
后面记得加当前名称'MyPolicy',
才能匹配到当前的授权方案(一般配置为常量)
*/
//自定义授权
builder.Services.AddAuthorization(op =>
{
//判断当前的授权方案的
op.AddPolicy(AuthorizationConts.MyPolicy, p => p.RequireClaim(ClaimTypes.NameIdentifier, "6"));
});
新增一个常量类AuthorizationConts,存放一个常量MyPolicy,值也是这个
2.在WeatherForecastController控制器中的Authorize鉴权特性中添加常量,代表的意思是鉴权时匹配我们自定义的鉴权
代码如下:
点击查看代码
using AuthDemo.Api.Consts;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace AuthDemo.Api.Controllers
{
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
private static readonly string[] Summaries = new[]
{
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
};
private readonly ILogger _logger;
public WeatherForecastController(ILogger logger)
{
_logger = logger;
}
[Authorize(AuthorizationConts.MyPolicy)]
[HttpGet(Name = "GetWeatherForecast")]
public IEnumerable Get()
{
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Date = DateTime.Now.AddDays(index),
TemperatureC = Random.Shared.Next(-20, 55),
Summary = Summaries[Random.Shared.Next(Summaries.Length)]
})
.ToArray();
}
}
}
经过以上改造就完成了自定义授权
四.授权断言
1.什么叫授权断言?
首先判定你当前用户有没有这个身份,比如说你的name有没有,有我则继续判断匹配不匹配,没有则直接报错
2.program中的自定义授权改为如下代码
点击查看代码
//自定义授权
builder.Services.AddAuthorization(op =>
{
//判断当前的授权方案的
//op.AddPolicy(AuthorizationConts.MyPolicy, p => p.RequireClaim(ClaimTypes.NameIdentifier, "6"));
//授权断言
//先判断user的类型是不是NameIdentifier,如果是,则判断当前值匹配不匹配
//如果不是则直接报错
op.AddPolicy(AuthorizationConts.MyPolicy,p=>
p.RequireAssertion(
a=>a.User.HasClaim(c=>c.Type==ClaimTypes.NameIdentifier) &&
a.User.Claims.First(c=>c.Type.Equals(ClaimTypes.NameIdentifier)).Value=="6"
));
});
---------------------------------2022-03-31分界线-----------------------------------
五.自定义授权与双授权策略(多scheme)
持续更新