使用JwtBearer可以很方便地实现基于token的认证,这里做一个基本的例子备忘:
-
安装Nuget包:
VS中依次打开菜单工具(Tools)、Nuget包管理器Nuget Package Manager、包管理控制台Package Manager Console如下图
在包管理控制台命令行下运行如下命令:
dotnet add package Microsoft.AspNetCore.Authentication.JwtBearer
也可以在项目的包管理菜单项中安装,注意选择合适的版本,不同.NET版本的包的版本也不同,版本不同不能成功安装,上面用命令行的方式能自动适配版本。
- 在Startup类的ConfigureServices方法里添加下面的配置(处于两个“//#############”之间的部分是需要添加的部分)
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
//###########################
//for authentication
var tokenSection = Configuration.GetSection("Security:Token");
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuer = true,
ValidateIssuerSigningKey = true,
ValidIssuer = tokenSection["Issuer"],
ValidAudience = tokenSection["Audience"],
IssuerSigningKey = new SymmetricSecurityKey(
Encoding.UTF8.GetBytes(tokenSection["Key"])
),
ClockSkew = TimeSpan.Zero
};
});
//###########################
}
在Startup类中添加app.UseAuthentication();如下所示(这一行一定要在“app.UseAuthorization();”这一行的前面):
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
//#################################
//for authentication
app.UseAuthentication();
//#################################
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
}
- 在appsettings.json里潜加如下用于token加密运算的部分(注意里面的三个元素都需要根据实际需要进行修改):
"Security": {
"Token": {
"Issuer": "demo_issuer",
"Audience": "demo_audience",
"Key": "<your_secret_key>"
}
}
看起来像这样:
- 添加一个用于登录的控制器名叫Authenticate,如下代码:
public class AuthenticateController : Controller
{
//###########################
public IConfiguration Configuration { get; }
public AuthenticateController(IConfiguration configuration)
{
Configuration = configuration;
}
public IActionResult Login(string user, string password)
{
//*************
//for user verification
if (user != "demouser" || password != "demopwd")
{
return Unauthorized();
}
//*************
var claims = new List<Claim>{
new Claim(JwtRegisteredClaimNames.Sub, user)
};
var tokenConfigSection = Configuration.GetSection("Security:Token");
var key = new SymmetricSecurityKey(
Encoding.UTF8.GetBytes(tokenConfigSection["Key"])
);
var signCredential = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
var jwtToken = new JwtSecurityToken(
issuer: tokenConfigSection["Issuer"],
audience: tokenConfigSection["Audience"],
claims: claims,
expires: DateTime.Now.AddMinutes(5),
signingCredentials: signCredential
);
return Ok(new
{
token = new JwtSecurityTokenHandler().WriteToken(jwtToken),
expiration = TimeZoneInfo.ConvertTimeFromUtc(jwtToken.ValidTo, TimeZoneInfo.Local)
});
}
//###########################
public IActionResult Index()
{
return View();
}
}
- 接下来为所有需要用到这个认证功能的控制器进行配置,用法很简单,在适当的地方加上“[Authorize]”即可(注意要:using Microsoft.AspNetCore.Authorization;),要整个控制器就在类的上面加,要某个方法使用认证就给对应的方法加如下所示:
[Authorize]
public class EmployeeController : Controller
{
public IActionResult Index()
{
return View();
}
public string Help()
{
return "Help with autorization";
}
[AllowAnonymous]
public string Help1()
{
return "Help without authorization";
}
}
要注意的是给整个控制器加了,那么控制器里所有的方法都需要认证,如果某个方法不需要认证,就要允许它进行匿名访问,如上面Help1所示,加上允许匿名访问的标签“[AllowAnonymous]”。
- 测试,我们这里使用Microsoft Edge浏览安装http测试插件Postwoman来进行测试,要注意在测试的时候,下面提到的网址需要根据实际情况进行变更,比如端口号:
6.1测试不需要认证的可以匿名访问的Employee控制器下的Help1方法:
网址:https://localhost:44375/Employee/Help1
6.2 测试需要认证的Help方法:
网址:https://localhost:44375/Employee/Help
6.3 进行登录以获得token:
网址:https://localhost:44375/Authenticate/Login?user=demouser&password=demopwd
6.4 利用获得的token访问需要认证的Employee控制器下的Help方法:
网址:https://localhost:44375/Employee/Help
这里需要将这个取得的token跟Bearer拼起来,命名为Authorization的键通过http头传过去:
要注意这里的键名是“Authorization”,值是“Bearer ”(注意Bearer后有一个空格)加取得的token。