MVC之实现基于token的认证
安装Nuget包
项目中添加包:dotnet add package Microsoft.AspNetCore.Authentication.JwtBearer
添加认证配置
Startup类中添加如下配置:
public void ConfigureServices(IServiceCollection services)
{
...
services.AddAuthentication(defaultScheme: JwtBearerDefaults.AuthenticationScheme);
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
...
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
AddAuthentication方法会向依赖注入容器添加认证服务和它所使用的其他服务,其参数defaultScheme用于指定当未指定具体的认证方案时将会使用的默认方案,上例为Bearer认证。
AddAuthentication方法的另一重载能够使用AuthenticationOptions类为认证过程中的每一个动作指明所使用的认证方案,如DefaultAuthenticateScheme、
DefaultChallengeScheme、
DefaultSignInScheme、
DefaultSignOutScheme、
DefaultForbidScheme。
如果没有为这些属性设置认证方案,则将使用DefaultScheme属性所指定的值。
当添加JwtBearer认证方式时,JwtBearerOptions对象能够配置该认证的选项,它的TokenValidationParameters属性用于指定验证Token时的规则:
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
};
});
TokenValidationParameters类作为Token验证参数类,它包含了一些属性,这些属性如ValidateAudience、ValidateIssuer、ValidateLifetime和ValidateIssuerSigningKey,它们都是布尔类型,用于指明是否验证相应的项;而ValidIssuer和ValidAudience属性则用于指明合法的签发者(Issuer)与接受方(Audience)。在上例中,它们的值都从配置文件中获取;IssuerSigningKey属性的值用于指定进行签名验证的安全密钥,它的值为SymmetricSecurityKey对象,即对称加密密钥;ClockSkew属性的值表示验证时间的时间偏移值。
上述代码会从配置文件中读取关于Token的信息,因此还需在appsettings.json中添加如下内容。
"Security": {
"Token": {
"Issuer": "demo_issuer",
"Audience": "demo_audience",
"Key": "<your_secret_key>"
}
}
为Controller添加认证
接下来,为了使用ASP.NET Core的认证功能来保护资源,应为Controller或Action添加[Authorize]特性,该特性能够实现在访问相应的Controller或Action时,要求请求方提供指定的认证方式,它位于Microsoft.AspNetCore.Authorization命名空间中。需要为AuthorController和BookController添加该特性。
[Authorize]
public class AuthorController : ControllerBase
{
}
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
public class BookController : ControllerBase
{
}
如果使用了多个认证方式,则可以使用[Authorize]特性的AuthenticationSchemes属性指明当前Controller或Action要使用哪一种认证方式(如上例中的BookController);如果不设置,则会使用所添加认证时设置的默认方案;如果没有设置默认方案,则会出现InvalidOperationException异常,并提示未指定默认方案;此外,如果为AuthenticationSchemes属性指定了不存在的方案名称,也会出现InvalidOperationException异常。
此时再访问Book和Author资源,会出现401 Unauthorized异常:
如果要允许某个Action可以被匿名访问,可以在Action方法上添加属性标记 [AllowAnonymous]:
[AllowAnonymous]
public async Task<ActionResult<IEnumerable<AuthorDto>>> GetAuthorsAsync([FromQuery] AuthorResourceParameters parameters)
添加认证信息生成接口
JwtBearer中间件提供了对JWT的验证功能,然而并未提供生成Token的功能。要生成Token,可以使用JwtSecurityTokenHandler类,它位于System.IdentityModel.Tokens.Jwt命名空间,它不仅能够生成JWT,由于它实现了ISecurityTokenValidator接口,因此对JWT的验证也是由它完成的。接下来,我们将创建一个Controller,它将会根据用户的认证信息生成JWT,并返回给客户端。
在Controllers文件夹中创建一个Controller,名为AuthenticateController,内容如下:
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.IdentityModel.Tokens;
namespace Library.Api.Controllers
{
[ApiController, Route("api/auth")]
public class AuthenticateController : ControllerBase
{
public IConfiguration Configuration { get; }
public AuthenticateController(IConfiguration configuration)
{
Configuration = configuration;
}
[HttpPost("token", Name = nameof(GenerateToken))]
public IActionResult GenerateToken(string username, string password)
{
if (username != "demouser" || password != "demopassword")
{
return Unauthorized();
}
var claims = new List<Claim>{
new Claim(JwtRegisteredClaimNames.Sub, username)
};
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(3),
signingCredentials: signCredential
);
return Ok(new {
token = new JwtSecurityTokenHandler().WriteToken(jwtToken),
expiration = TimeZoneInfo.ConvertTimeFromUtc(jwtToken.ValidTo, TimeZoneInfo.Local)
});
}
}
}
在AuthenticateController中的GenerateToken方法中,通过创建JwtSecurityToken对象,并使用JwtSecurityTokenHandler对象的WriteToken方法最终得到生成的JWT。当创建JwtSecurityToken对象时,我们可以指定issuer、audience以及当前用户的Claim信息,此外,还可以指定该Token的有效时间。这里需要注意,由于JWT不支持销毁以及撤回功能,因此在设置它的有效时间时,应设置一个较短的时间(如上例中的3分钟),这样可以有效避免Token在意外被窃取后所带来的风险。
现在就可以请求认证接口获取 token:
这时重新请求资源接口,在请求头中添加Authorization项,值为Bearer ,就可以得到结果了:
这次示例中,使用了固定的用户名和密码,实际情况中,用户名和密码通常是存在数据库中的,可以使用ASP.NET Core Identity来实现这一功能。
MVC之实现基于token的认证的更多相关文章
- 使用 AngularJS & NodeJS 实现基于token 的认证应用(转)
认证是任何 web 应用中不可或缺的一部分.在这个教程中,我们会讨论基于 token 的认证系统以及它和传统的登录系统的不同.这篇教程的末尾,你会看到一个使用 AngularJS 和 NodeJS 构 ...
- 使用 AngularJS & NodeJS 实现基于 token 的认证应用
认证是任何Web应用中不可或缺的一部分.在这个教程中,我们会讨论基于token的认证系统以及它和传统的登录系统的不同.这篇教程的末尾,你会看到一个使用 AngularJS 和 NodeJS 构建的 ...
- NodeJS 实现基于 token 的认证应用
此段摘自 http://zhuanlan.zhihu.com/FrontendMagazine/19920223 英文原文 http://code.tutsplus.com/tutorials/tok ...
- 基于Token的WEB后台认证机制
几种常用的认证机制 HTTP Basic Auth HTTP Basic Auth简单点说明就是每次请求API时都提供用户的username和password,简言之,Basic Auth是配合RES ...
- Java实现基于token认证
随着互联网的不断发展,技术的迭代也非常之快.我们的用户认证也从刚开始的用户名密码转变到基于cookie的session认证,然而到了今天,这种认证已经不能满足与我们的业务需求了(分布式,微服务).我们 ...
- 【转】基于Token的WEB后台认证机制
原谅地址:http://www.cnblogs.com/xiekeli/p/5607107.html 几种常用的认证机制 HTTP Basic Auth HTTP Basic Auth简单点说明就是每 ...
- JWT(Json web token)认证详解
JWT(Json web token)认证详解 什么是JWT Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准((RFC 7519).该to ...
- 基于token的后台身份验证(转载)
几种常用的认证机制 HTTP Basic Auth HTTP Basic Auth简单点说明就是每次请求API时都提供用户的username和password,简言之,Basic Auth是配合RES ...
- 基于token的验证
认证.权限和限制 身份验证是将传入请求与一组标识凭据(例如请求来自的用户或其签名的令牌)相关联的机制.然后 权限 和 限制 组件决定是否拒绝这个请求. 简单来说就是: 认证确定了你是谁 权限确定你能不 ...
随机推荐
- Web性能优化之瘦身秘笈
Web 传输的内容当然是越少越好,最近一段时间的工作一直致力于 Web 性能优化,这是我近期使用过的一些缩减 Web 体积的手段 这些手段主要是为了减少 Web 传输的内容大小,只有干货 CSS 删除 ...
- 定西+简单dp
定西 ECNU-3531 #include<iostream> #include<cstdio> #include<algorithm> #include<c ...
- CVE-2017-7504-JBoss JMXInvokerServlet 反序列化
漏洞分析 https://paper.seebug.org/312/ 漏洞原理 这是经典的JBoss反序列化漏洞,JBoss在/invoker/JMXInvokerServlet请求中读取了用户传入的 ...
- AtCoder Beginner Contest 186
A Brick int n, m; int main() { scanf("%d%d", &n, &m); printf("%d\n", n / ...
- Apache配置 9.访问控制-Diretory\FileMatch
(1)介绍 访问控制限制白名单IP,针对文件和目录. (2)目录配置 #vim /usr/local/apache2.4/conf/extra/httpd-vhosts.conf <Virtua ...
- react+ts封装AntdUI的日期选择框之月份选择器DatePicker.month
需求:由于在项目开发中,当需要使用该组件时都需要对该组件进行大量的代码输出,为了方便代码统一管理,减少冗余代码,所以将此组件进行二次封装. 其他成员在使用中只需将自己的设置通过对应的参数传递到该组件, ...
- BuaacodingT651 我知道你不知道圣诞节做什么 题解(逻辑)
题目链接 我知道你不知道圣诞节做什么 解题思路 第一句话:x,y不都为质数. 第二句话:对于xy=t,存在唯一一种x+y使得x,y不都为质数. 第三句话:对于x+y=s,存在唯一一种t=xy使得对于任 ...
- 如何配置Nginx,实现http访问重定向到https?
现在越来越多的网站,当我们输入域名时,会自动重定向到https,我们只需要简单修改下Nginx配置文件/usr/local/nginx/conf/nginx.conf(根据个人的实际存储路径)即可. ...
- Android Studio 待看博文
•前言 学习过程中找到的一些好的博文,有些可能当时就看完了并解决了我的问题,有些可能需要好几天的事件才能消化. 特此记录,方便查阅. •CSDN 给新人的一些基础常识 TextView的文字长度测量及 ...
- vue 快速入门 系列 —— 侦测数据的变化 - [vue 源码分析]
其他章节请看: vue 快速入门 系列 侦测数据的变化 - [vue 源码分析] 本文将 vue 中与数据侦测相关的源码摘了出来,配合上文(侦测数据的变化 - [基本实现]) 一起来分析一下 vue ...