程序地带

给.Net 5 Api增加JwtBearer认证


JSON WEB TOKEN

JWT是Json Web Token的缩写。JWT, 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准(RFC 7519)。该token被设计为紧凑且安全的,特别适用于分布式站点的单点登录(SSO)场景。JWT的声明一般被用来在身份提供者和服务提供者间传递被认证的用户身份信息,以便于从资源服务器获取资源,也可以增加一些额外的其它业务逻辑所必须的声明信息,该token也可直接被用于认证,也可被加密。


安装包引用

这里我们需要安装两个nuget包,所以在开始之前,请先通过nuget管理工具安装:


Microsoft.AspNetCore.Authentication.JwtBearer
Swashbuckle.AspNetCore

Microsoft.AspNetCore.Authentication.JwtBearer这个用于做JWT Token的生成和认证。Swashbuckle.AspNetCore这个方便在开发环境调用调式API。


Add Authentication

接下来我们来添加JwtBearer认证,打开Startup.cs文件,然后在ConfigureServices(IServiceCollection services)方法中添加以下代码:


services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, options =>
{
options.TokenValidationParameters = new TokenValidationParameters()
{
ValidateIssuer = true,
ValidIssuer = "Security:Tokens:Issuer",
ValidateAudience = true,
ValidAudience = "Security:Tokens:Audience",
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("Security:Tokens:Key"))
};
});

这样系统就支持JWT认证了,接下来就可以在要使用认证的API中添加JWT认证了。在API上增加Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)即可:


[HttpGet("Get"), Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
public IEnumerable<WeatherForecast> Get()
{
var rng = new Random();
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Date = DateTime.Now.AddDays(index),
TemperatureC = rng.Next(-20, 55),
Summary = Summaries[rng.Next(Summaries.Length)]
})
.ToArray();
}
生成JWT Token

现在GetAPI已经是需要认证才能调用了,所以我们需要生成一个JWT Token,并在调用API的时候带上这个Token,这样可以调用API了。


我们写一个BuildToken的私有方法,该方法用于将用户的ID生成为Token:


private string BuildToken(string userId)
{
var tokenHandler = new JwtSecurityTokenHandler();
var key = Encoding.ASCII.GetBytes("Security:Tokens:Key");
var tokenDescriptor = new SecurityTokenDescriptor
{
Issuer = "Security:Tokens:Issuer",
Audience = "Security:Tokens:Audience",
Subject = new ClaimsIdentity(new[] { new Claim(ClaimTypes.Name, userId) }),
Expires = DateTime.UtcNow.AddDays(7),
SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256)
};
var token = tokenHandler.CreateToken(tokenDescriptor);
return tokenHandler.WriteToken(token);
}

再写一个API来返回这个Token。在实际项目中,可以通过用户名和密码来确认用户,确认成功后再返回对应的Token。这里为了方便,就直接返回admin用户的Token:


[HttpGet("GetToken")]
public IActionResult GetToken()
{
return Ok(new { Token = BuildToken("admin") });
}
使用Swagger调用API

API的JWT认证已经配置完成了,接下来我们来配置swagger,swagger可以很方便的调用API。


同样打开Startup.cs文件,并在ConfigureServices(IServiceCollection services)方法中添加以下代码:


services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo { Title = "WebAPI", Version = "v1" });
var securityScheme = new OpenApiSecurityScheme
{
Name = "JWT Authentication",
Description = "Enter JWT Bearer token **_only_**",
In = ParameterLocation.Header,
Type = SecuritySchemeType.Http,
Scheme = "bearer",
BearerFormat = "JWT",
Reference = new OpenApiReference
{
Id = JwtBearerDefaults.AuthenticationScheme,
Type = ReferenceType.SecurityScheme
}
};
c.AddSecurityDefinition(securityScheme.Reference.Id, securityScheme);
c.AddSecurityRequirement(new OpenApiSecurityRequirement
{
{ securityScheme, new string[] { } }
});
});

然后在Configure(IApplicationBuilder app, IWebHostEnvironment env)方法中添加以下代码:


app.UseSwagger();
app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "WebAPI v1"));

这样所有配置就完成了。运行项目进行测试。


测试API

我们先直接测试一下GetAPI,点击“Try it out”:



然后点击"Execute":



 


 


 


API返回了401,说明API现在不能调用成功,需要认证:


 


 


 


 


获取Token

我们通过调用GetTokenAPI来获取Token:



 


然后复制Token内容,注意不要复制整个结果,只要复制token的值就可以了:



 


 


 


然后点击“Authorize”,粘贴刚刚复制的Token后再点击Authorize就可以了,


 


 


 


 


我们再调用一次GetAPI试试,现在已经可以调用成功了:


 


 


 


 


完整源代码:https://github.com/SeriaWei/JwtBearerWebAPI


原文地址:http://www.zkea.net/codesnippet/detail/dotnet-api-jwt-bearer.html


版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/seriawei/p/dotnet-api-jwt-bearer.html

随机推荐

MySQL笔记 8 子查询

SQL学习指南笔记1什么是子查询2子查询类型3非关联查询3.1多行单列子查询in和notin运算符all运算符any运算符3.2多列子查询4关联子查询4.1exists运算符4.2关联子查询操作数据5...

vbs16 阅读(764)

python封装概念_封装-python

六封装从封装本身的意思去理解,封装就好像是拿来一个麻袋,把小猫,小狗,小王八,还有alex一起装进麻袋,然后把麻袋封...

weixin_39787594 阅读(616)

CCS 如何打开一个工程 Code Composer Studio

CCS软件是一个eclipse框架软件,但做单片机的多数都对此类软件是文盲,遇到问题多百度。CCS软件可以新建一个工程,也可以通过import导入别人的工程。...

x1131230123 阅读(542)