.net core webapi 的 JWT 授权认证
程序员文章站
2024-01-29 17:46:04
...
传统的授权认证:
传统验证基于Cookies和Session;但是由于http是无状态的(第一次和第二次发送的http请求没有任何区别),所以这种模式有很多局限,比如在多服务器集群时就无法使用;
和asp.net相比,core的不同,是在实例化类之前,就先进行身份认证,身份认证完了以后,再完成授权;
基于Token的授权认证
下边是基于token验证的流程图:
- 授权服务器发送的token由私钥加密;
- API得到的token,用公钥解密;
Token令牌的组成:
最终API如何能确定这个token就是授权服务器发来的呢?这个就是看签名。对得到的token,可以通过jwt.io网站来进行解读。
具体完成JWT授权
1.新建一个授权API项目,然后新建一个授权控制器;
2.为了实现解耦,新建一个服务类,完成token的颁发:
3.控制器的代码如下
[Route("api")]
[ApiController]
public class AuthenticationController : ControllerBase
{
#region MyRegion //region是为了方便折叠
private ILogger<AuthenticationController> _logger = null;
private IJWTService _iJWTService = null;
private readonly IConfiguration _iConfiguration;
public AuthenticationController(ILoggerFactory factory,//此处做了三个依赖注入;
ILogger<AuthenticationController> logger,
IConfiguration configuration
, IJWTService service)
{
this._logger = logger;
this._iConfiguration = configuration;
this._iJWTService = service;
}
#endregion
[Route("Get")]
[HttpGet]
public IEnumerable<int> Get()
{
return new List<int>() { 1, 2, 3, 4, 6, 7 };
}
[Route("Login")] //log是日志,login是注册;
[HttpGet]
public string Login(string name, string password)
{
///这里肯定是需要去连接数据库做数据校验
if ("Richard".Equals(name) && "123456".Equals(password))//应该数据库
{
string token = this._iJWTService.GetToken(name);//调用后台的个体Token方法
//,这样就可以获取token了。
return JsonConvert.SerializeObject(new //把结果转化为Json格式返回。
{
result = true,
token
});
}
else
{
return JsonConvert.SerializeObject(new
{
result = false,
token = ""
});
}}}
4.获取token的类的代码如下:首先声明一个接口,然后再实现这个接口
声明接口
public interface IJWTService
{
string GetToken(string UserName);
}
实现这个接口
public class JWTService : IJWTService
{
private readonly IConfiguration _configuration;
public JWTService(IConfiguration configuration)
{
_configuration = configuration;
}
public string GetToken(string UserName)
{
Claim[] claims = new[] //claim这里面包含的就是Token中的载荷的信息;
{
new Claim(ClaimTypes.Name, UserName),
new Claim("NickName","Richard"),
new Claim("Role","Administrator"),//传递其他信息
new Claim("abc","abccc")
//new Claim
};
SymmetricSecurityKey key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["SecurityKey"]));
//从配置文件中读去key(养成良好的编码习惯,把配置文件,尽量写在配置文件里)
SigningCredentials creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
//对key进行加密;
/**
* Claims (Payload)
Claims 部分包含了一些跟这个 token 有关的重要信息。 JWT 标准规定了一些字段,
下面节选一些字段:
iss: The issuer of the token,token 是给谁的
sub: The subject of the token,token 主题
exp: Expiration Time。 token 过期时间,Unix 时间戳格式
iat: Issued At。 token 创建时间, Unix 时间戳格式
jti: JWT ID。针对当前 token 的唯一标识
除了规定的字段外,可以包含其他任何 JSON 兼容的字段。
* */
var token = new JwtSecurityToken( //创建新的token
issuer: _configuration["issuer"],
audience: _configuration["audience"],
claims: claims,
expires: DateTime.Now.AddMinutes(5),//5分钟有效期
signingCredentials: creds);
string returnToken = new JwtSecurityTokenHandler().WriteToken(token);
//生成token需要引用Tokens.jwt的安装包
return returnToken;
}
}
配置文件的声明:
5.新建受保护的API
在startup里面配置授权服务:
#region JWT鉴权授权
//1.Nuget引入程序包:Microsoft.AspNetCore.Authentication.JwtBearer
//services.AddAuthentication();//禁用
var ValidAudience = this.Configuration["audience"];
var ValidIssuer = this.Configuration["issuer"];
var SecurityKey = this.Configuration["SecurityKey"];
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) //默认授权机制名称;
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,//是否验证Issuer
ValidateAudience = true,//是否验证Audience
ValidateLifetime = true,//是否验证失效时间
ValidateIssuerSigningKey = true,//是否验证SecurityKey
ValidAudience = ValidAudience,//Audience
ValidIssuer = ValidIssuer,//Issuer,这两项和前面签发jwt的设置一致 表示谁签发的Token
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(SecurityKey))//拿到SecurityKey
//AudienceValidator = (m, n, z) =>
//{
// return m != null && m.FirstOrDefault().Equals(this.Configuration["audience"]);
//},//自定义校验规则,可以新登录后将之前的无效
};});
#endregion
6.在中间件管道里面添加身份认证和授权的中间件:
app.UseAuthentication();//身份认证
app.UseAuthorization();//授权
7.在需要保护的API上添加 [Authorize] 属性
[Authorize] //Microsoft.AspNetCore.Authorization
public IActionResult GetAuthorizeData()
{
var Name = base.HttpContext.AuthenticateAsync().Result.Principal.Claims.FirstOrDefault(a=>a.Type.Equals("Name"))?.Value;
Console.WriteLine($"this is Name {Name}");
return new JsonResult(new
{
Data = "已授权",
Type = "GetAuthorizeData"
//Claims=Newtonsoft.Json.JsonConvert.SerializeObject(Claims)
});
}
8.也可以直接添加到类上,对命名空间里,所有的方法都授权认证,多例外不需要的,添加 [AllowAnonymous] 允许匿名属性;
题外话:
#region这个语法,是用来方便折叠的。
参考资料联系侵删;
推荐阅读
-
.net core webapi集成jwt实现身份认证
-
.NET Core 集成JWT认证
-
.net core webapi 的 JWT 授权认证
-
asp.net core 2.0 webapi 使用 Autofac 进行依赖注入遇到的问题
-
ASP.NET Core 2.1中基于角色的授权
-
04 .NET CORE 2.2 使用OCELOT -- identity认证授权
-
.net core 3.0webapi Jwt认证
-
你所不知道的ASP.NET Core MVC/WebApi基础系列 (一)
-
Asp.Net Core添加请求头自定义认证的示例
-
手把手教你AspNetCore WebApi认证与授权的方法