安装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的认证的更多相关文章

  1. 使用 AngularJS &amp; NodeJS 实现基于token 的认证应用(转)

    认证是任何 web 应用中不可或缺的一部分.在这个教程中,我们会讨论基于 token 的认证系统以及它和传统的登录系统的不同.这篇教程的末尾,你会看到一个使用 AngularJS 和 NodeJS 构 ...

  2. 使用 AngularJS &amp; NodeJS 实现基于 token 的认证应用

      认证是任何Web应用中不可或缺的一部分.在这个教程中,我们会讨论基于token的认证系统以及它和传统的登录系统的不同.这篇教程的末尾,你会看到一个使用 AngularJS 和 NodeJS 构建的 ...

  3. NodeJS 实现基于 token 的认证应用

    此段摘自 http://zhuanlan.zhihu.com/FrontendMagazine/19920223 英文原文 http://code.tutsplus.com/tutorials/tok ...

  4. 基于Token的WEB后台认证机制

    几种常用的认证机制 HTTP Basic Auth HTTP Basic Auth简单点说明就是每次请求API时都提供用户的username和password,简言之,Basic Auth是配合RES ...

  5. Java实现基于token认证

    随着互联网的不断发展,技术的迭代也非常之快.我们的用户认证也从刚开始的用户名密码转变到基于cookie的session认证,然而到了今天,这种认证已经不能满足与我们的业务需求了(分布式,微服务).我们 ...

  6. 【转】基于Token的WEB后台认证机制

    原谅地址:http://www.cnblogs.com/xiekeli/p/5607107.html 几种常用的认证机制 HTTP Basic Auth HTTP Basic Auth简单点说明就是每 ...

  7. JWT(Json web token)认证详解

    JWT(Json web token)认证详解 什么是JWT Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准((RFC 7519).该to ...

  8. 基于token的后台身份验证(转载)

    几种常用的认证机制 HTTP Basic Auth HTTP Basic Auth简单点说明就是每次请求API时都提供用户的username和password,简言之,Basic Auth是配合RES ...

  9. 基于token的验证

    认证.权限和限制 身份验证是将传入请求与一组标识凭据(例如请求来自的用户或其签名的令牌)相关联的机制.然后 权限 和 限制 组件决定是否拒绝这个请求. 简单来说就是: 认证确定了你是谁 权限确定你能不 ...

  10. 基于token的会话保持机制

    session简介 做过Web开发的程序员应该对Session都比较熟悉,Session是一块保存在服务器端的内存空间,一般用于保存用户的会话信息. 用户通过用户名和密码登陆成功之后,服务器端程序会在 ...

随机推荐

  1. Visual Studio 2013 Ultimate因为CodeLens功能导致Microsoft.Alm.Shared.Remoting.RemoteContainer.dll高CPU占用率的折中解决方案

    1.为什么Microsoft.Alm.Shared.Remoting.RemoteContainer.dll的CPU占用率以及内存使用率会那么高? 在Visual Studio 2013 Ultima ...

  2. 20145314郑凯杰《信息安全系统设计基础》GDB调试32位汇编堆栈分析

    20145314郑凯杰<信息安全系统设计基础>GDB调试32位汇编堆栈分析 本篇博客将对第五周博客中的GDB调试32位汇编堆栈进行分析 首先放上以前环境配置的图: 图1: 测试代码: #i ...

  3. 阿里云OSS NET SDK 引用示范程序

    1.引入SDK bin文件,下载地址:https://docs-aliyun.cn-hangzhou.oss.aliyun-inc.com/internal/oss/0.0.4/assets/sdk/ ...

  4. nodejs学习笔记&lt;五&gt;npm使用

    NPM是随同NodeJS一起安装的包管理工具,能解决NodeJS代码部署上的很多问题. 以下是几种常见使用场景: 允许用户从NPM服务器下载别人编写的第三方包到本地使用. 允许用户从NPM服务器下载并 ...

  5. hdoj 3478 Catch(二分图判定+并查集)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3478 思路分析:该问题需要求是否存在某一个时刻,thief可能存在图中没一个点:将该问题转换为图论问题 ...

  6. java面向对象--抽象类和接口

    如果某个父类只知道其子类应该包含哪些方法,但无法知道如何实现这些方法,同时要使用多态的特性,怎么办? 抽象方法:关键字abstract允许在一个类中创建一个或多个没有方法体的方法--只提供方法签名,但 ...

  7. swift之函数式编程(三)

    文章来源于<Functional Programing in Swift>,本系列仅仅是观后概括的一些内容 Wrapping Core Image 上一篇文章我们介绍了 高阶函数并且展示了 ...

  8. [转帖]NUMA

    作者:ibless 来源:CSDN 原文:https://blog.csdn.net/ibless/article/details/80114009 其实 很早之前对这一块有了解 比较多的的是 CCN ...

  9. 15.4-uC/OS-III资源管理(二值信号量)

    互斥信号量是 uC/OS 操作系统的一个内核对象, 与多值信号量非常相似,但它是二值的,只能是 0 或 1,所以也叫二值信号量, 主要用于保护资源. 1.如果想要使用互斥信号量,就必须事先使能互斥信号 ...

  10. Mysql增量恢复

    mysqldump增量恢复何时需要使用备份的数据? 备份最牛逼的层次,就是永远都用不上备份.--老男孩 不管是逻辑备份还是物理备份,备份的数据什么时候需要用?===================== ...