webapi授权认证

一、需要类包

  • Microsoft.AspNetCore.Authentication.JwtBearer

二、相关名词

Authentication(认证):标识用户的身份,一般发生在登录的时候。

Authorization(授权):授予用户权限,指定用户能访问哪些资源;授权的前提是知道这个用户是谁,所以授权必须在认证之后。

三、认证

3.1 基本步骤

1.安装相关 Nuget 包:Microsoft.AspNetCore.Authentication.JwtBearer
2.准备配置信息(密钥等)
3.注册服务
4.调用中间件
5.实现一个 JwtHelper,用于生成 Token
6.控制器限制访问(添加 Authorize 标签)

3.2 appsetting.json配置信息

 // token配置
"JwtConfig": {
"SecretKey": "zhouxxxxxx@qq.email", // 密钥
//"Issuer": "zhouBing", // 颁发单位
"Issuer": "https://www.baidu.com/", // 颁发单位
//"Audience": "http://localhost:8080", // 接收单位
"Audience": "https://www.baidu.com/", // 接收单位
"Expired": 30, // 过期时间(单位min)30min
"RefreshTokenExpired": 60, // 刷新Token 60min
"NotBefore": "", // 有效期自
"Expiration": "", // 到期时间
"SigningKey": "", // 签名密钥
"SigningCredentials": "" // 签名凭证
},

3.3 注册服务和调用中间件

//引入所需的命名空间
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens;
using System.Text; // 将 JwtHelper 的创建交由 DI 容器
builder.Services.AddSingleton(new GenerateJwt(_configuration, _dbContext)); JwtInfo jwtInfo = new JwtInfo();
builder.Configuration.Bind("JwtConfig", jwtInfo); builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) // 默认 Bearer JwtBearerDefaults.AuthenticationScheme
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters()
{
ValidateIssuer = true,//是否验证 Issuer(发行商)
ValidateAudience = true,//是否验证 Audience(受众者)
ValidateLifetime = true,//是否验证失效时间
ValidateIssuerSigningKey = true,//是否验证 Issuer 的签名键
ValidAudience = jwtInfo.Audience, //此处应该是IdentityServer的地址
ValidIssuer = jwtInfo.Issuer,// ValidAudience,ValidIssuer这两项的值要和验证中心的只保持一致。
ClockSkew = TimeSpan.FromSeconds(30), //过期时间容错值,解决服务器端时间不同步问题(秒)
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtInfo.SecretKey!))
};
}); //调用中间件:UseAuthentication(认证),必须在所有需要身份认证的中间件前调用,比如 UseAuthorization(授权)。
app.UseAuthentication();
app.UseAuthorization();

JwtInfo类型

 public class JwtInfo:BaseEntitys
{
public Guid Id { get; set; }
public string TokenId { get; set; } = null!;
//public JwtInfo Value => this;
[DisplayName("密钥")]
public string? SecretKey { get; set; } = null!;// 密钥
[DisplayName("颁发者")]
public string? Issuer { get; set; } // 颁发者
[DisplayName("接收者")]
public string? Audience { get; set; } // 接收者
[DisplayName("过期时间")]
public int Expired { get; set; }// 过期时间
[DisplayName("上次颁发时间")]
public DateTime NotBefore { get; set; } // 上次颁发时间
[DisplayName("发布时间")]
public DateTime IssuedAt { get; set; } // 发布时间
[DisplayName("到期时间")]
public DateTime Expiration { get; set; } // = IssuedAt.AddMinutes(Expired);// 到期时间
[DisplayName("签名密钥")]
public string? SigningKey { get; set; } = null!;// 签名密钥
//public static SecurityKey? SigningKey { get; set; } = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(SecretKey));// 签名密钥
[DisplayName("签名凭证")]
public string? SigningCredentials { get; set; } // 签名凭证
//public SigningCredentials? SigningCredentials { get; set; } = new SigningCredentials(SigningKey, SecurityAlgorithms.HmacSha256);// 签名凭证
}

3.4 JwtHelper 类实现

public class GenerateJwt
{
public JwtInfoDto _jwtConfig;
public readonly IConfiguration _configuration;
// public readonly MysqlDbContext _dbContext;
public GenerateJwt(IConfiguration configuration)z
// public GenerateJwt(IConfiguration configuration, MysqlDbContext dbContext)
{
_configuration = configuration;
_jwtConfig = _configuration.GetSection("JwtConfig").Get<JwtInfoDto>();
// _dbContext = dbContext;
}
/// <summary>
/// 生成token
/// </summary>
/// <param name="sub"></param>
/// <param name="customClaims">携带的用户信息</param>
/// <returns></returns>
public JwtTokenResult GenerateEncodedTokenAsync(string sub, LoginUserModel customClaims)
{
//创建用户身份标识,可按需要添加更多信息
var claims = new List<Claim>
{
//new Claim("Userid", customClaims.Userid),
new Claim("Username", customClaims.Username),
new Claim("Realname",customClaims.Realname),
new Claim("Roles", customClaims.Roles),
new Claim("Permissions", customClaims.Permissions),
new Claim("NormalPermissions", customClaims.NormalPermissions),
new Claim(JwtRegisteredClaimNames.Sub, sub),
}; DateTime dateNow = DateTime.Now;
var authSecurityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["JwtConfig:SecretKey"]));
//创建令牌
var jwt = new JwtSecurityToken(
issuer: _jwtConfig.Issuer,
audience: _jwtConfig.Audience,
claims: claims,
//notBefore: _jwtConfig.NotBefore,
notBefore: dateNow,
//expires: _jwtConfig.Expiration,
expires: dateNow.AddMinutes(_jwtConfig.Expired),
//signingCredentials: null, // 签名凭证
signingCredentials: new SigningCredentials(authSecurityKey, SecurityAlgorithms.HmacSha256) // 签名凭证
);
string access_token = new JwtSecurityTokenHandler().WriteToken(jwt);
string refresh_Token = CreateRefreshTokenBase64(); return new JwtTokenResult()
{
Access_token = access_token,
Expires_in = dateNow.AddMinutes(_jwtConfig.Expired), // 过期时间
//Expires_in = _jwtConfig.Expired * 60, // 过期时间(秒)
Token_type = JwtBearerDefaults.AuthenticationScheme,
Refresh_token = refresh_Token,
User = customClaims,
SigningCredentials = jwt.SigningCredentials
};
} /// <summary>
/// 简单的生成RefreshToken
/// </summary>
/// <param name="access_token"></param>
/// <param name="refresh_Token"></param>
/// <returns></returns>
public string CreateRefreshTokenBase64()
{
// 创建一个随机的Token用做Refresh Token
var randomNumber = new byte[32]; using var rng = RandomNumberGenerator.Create();
rng.GetBytes(randomNumber); return Convert.ToBase64String(randomNumber);
} /// <summary>
/// 生成RefreshToken
/// </summary>
/// <param name="token"></param>
/// <returns></returns>
/// <exception cref="SecurityTokenException"></exception>
public string CreateRefreshToken(string UserId)
{
GetDbContext dbContext = new GetDbContext(_configuration);
var _dbContext = dbContext.GetContext();
var context = new MysqlDbContext(_dbContext);
if (!context.UserToken.Where(x => x.UserId.Equals(UserId) && x.Refresh_token == null).Any())
{
return CreateRefreshTokenBase64();
}
return "";
} /// <summary>
/// 根据过期Token生成新的Token
/// </summary>
/// <param name="token"></param>
/// <returns></returns>
/// <exception cref="SecurityTokenException"></exception>
public bool GetPrincipalFromExpiredToken(string token)
{
// 根据已过期的Token获取用户相关的Principal数据,用来生成新的Token
var jwtSettings = _configuration.GetSection("JwtConfig");
var authSecurityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["JwtConfig:SecretKey"]));
try
{
var tokenValidationParameters = new TokenValidationParameters
{
ValidateAudience = true,
ValidateIssuer = true,
ValidateIssuerSigningKey = true,
IssuerSigningKey = authSecurityKey,
ValidateLifetime = true,
ValidIssuer = jwtSettings["Issuer"],
ValidAudience = jwtSettings["Audience"],
}; var tokenHandler = new JwtSecurityTokenHandler();
var principal = tokenHandler.ValidateToken(token, tokenValidationParameters, out var securityToken);
if (securityToken is not JwtSecurityToken jwtSecurityToken ||
!jwtSecurityToken.Header.Alg.Equals(SecurityAlgorithms.HmacSha256, StringComparison.InvariantCultureIgnoreCase))
{
return false;
}
}
catch(Exception ex)
{
return false;
} return true;
}
}

四、测试

4.1 操作步骤

1. 生成Token
2. 携带Token访问接口

控制器

[ApiController]
[Route("[controller]/[action]")]
public class UserController : ControllerBase
{
private string connectionString; private IConfiguration _configuration;
private readonly JwtInfo _config;
private IServiceProvider _serviceProvider;
private readonly MysqlDbContext _dbContext; //private IdentifityApp _IdentifityApp;
//private IConnectionFactory _IConnectionFactory;
public UserController(IConfiguration configuration, IOptions<JwtInfo> config, IServiceProvider serviceProvider, MysqlDbContext dbContext)
{
_configuration = configuration;
_config = config.Value;
//_IConnectionFactory = iConnectionFactory;
_serviceProvider = serviceProvider;
//_IdentifityApp=identifityApp;
connectionString = _configuration.GetConnectionString("MySQLConnection");
_dbContext = dbContext;
} // 生成Token
//[Authorize(Roles = "Administrators")]
[Authorize(Roles= "admin")]
[HttpPost]
public JsonResult GetAuthority()
{
//using (var cnn = _IConnectionFactory.Connection())
//{
string result = "";
List<Authority> list = new List<Authority>();
using (MySqlConnection connection = new MySqlConnection(_configuration.GetConnectionString("MySQLConnection"))) {
string sql = "select * from Authority";
MySqlCommand command = new MySqlCommand(sql, connection);
connection.Open();
using (MySqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
list.Add(new Authority
{
Id = reader.GetInt16("Id"),
AuthorityName = reader.GetString("AuthorityName"),
});
}
}
}
JsonResult json = new JsonResult(new
{
code = 200,
msg = "成功",
resule = list
});
return json;
//} } [HttpPost]
public JsonResult GenerateToken()
{
LoginUserModel loginUserModel = new LoginUserModel();
//loginUserModel.Userid = "08db7530-382f-42bf-828c-32dd169ac2d9";
loginUserModel.Username = "admin";
loginUserModel.Realname = "zxx";
loginUserModel.Roles = "admin";
loginUserModel.Permissions = "1";
loginUserModel.NormalPermissions = "2"; GenerateJwt generateJwt = new GenerateJwt(_configuration, _dbContext);
JwtTokenResult JwtInfo = generateJwt.GenerateEncodedTokenAsync("Sub", loginUserModel); JsonResult json = new JsonResult(new
{
code = "200",
msg = "成功",
result = JwtInfo
}); return json;
} [HttpGet]
//[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
[Authorize]
public object GetData()
{
return new
{
Id = 1,
Name = "Tom"
};
}
}

4.2 Postman测试

4.2.1 获取token

4.2.2 调用权限接口

webapi授权认证的更多相关文章

  1. Asp.NetCore3.1 WebApi 使用Jwt 授权认证使用

    1:导入NuGet包 Microsoft.AspNetCore.Authentication.JwtBearer 2:配置 jwt相关信息 3:在 startUp中 public void Confi ...

  2. 手把手教你AspNetCore WebApi:认证与授权

    前言 这几天小明又有烦恼了,之前给小红的接口没有做认证授权,直接裸奔在线上,被马老板发现后狠狠的骂了一顿,赶紧让小明把授权加上.赶紧Baidu一下,发现大家都在用JWT认证授权,这个倒是挺适合自己的. ...

  3. 使用微服务架构思想,设计部署OAuth2.0授权认证框架

    1,授权认证与微服务架构 1.1,由不同团队合作引发的授权认证问题 去年的时候,公司开发一款新产品,但人手不够,将B/S系统的Web开发外包,外包团队使用Vue.js框架,调用我们的WebAPI,但是 ...

  4. 【从零开始搭建自己的.NET Core Api框架】(七)授权认证进阶篇

    系列目录 一.  创建项目并集成swagger 1.1 创建 1.2 完善 二. 搭建项目整体架构 三. 集成轻量级ORM框架——SqlSugar 3.1 搭建环境 3.2 实战篇:利用SqlSuga ...

  5. API代理网关和OAuth2.0授权认证框架

    API代理网关和OAuth2.0授权认证框架 https://www.cnblogs.com/bluedoctor/p/8967951.html 1,授权认证与微服务架构 1.1,由不同团队合作引发的 ...

  6. 授权认证(IdentityServer4)

    区别 OpenId: Authentication :认证 Oauth: Aurhorize :授权 输入账号密码,QQ确认输入了正确的账号密码可以登录 --->认证 下面需要勾选的复选框(获取 ...

  7. ASP.NET Core 中jwt授权认证的流程原理

    目录 1,快速实现授权验证 1.1 添加 JWT 服务配置 1.2 颁发 Token 1.3 添加 API访问 2,探究授权认证中间件 2.1 实现 Token 解析 2.2 实现校验认证 1,快速实 ...

  8. C#进阶系列——WebApi 身份认证解决方案:Basic基础认证

    前言:最近,讨论到数据库安全的问题,于是就引出了WebApi服务没有加任何验证的问题.也就是说,任何人只要知道了接口的url,都能够模拟http请求去访问我们的服务接口,从而去增删改查数据库,这后果想 ...

  9. IOS第三天-新浪微博 - 版本新特性,OAuth授权认证

    *********版本新特性 #import "HWNewfeatureViewController.h" #import "HWTabBarViewController ...

  10. 七天学会ASP.NET MVC (四)——用户授权认证问题

    小编应各位的要求,快马加鞭,马不停蹄的终于:七天学会 Asp.Net MVC 第四篇出炉,在第四天的学习中,我们主要了学习如何在MVC中如何实现认证授权等问题,本节主要讲了验证错误时的错误值,客户端验 ...

随机推荐

  1. 马文·柯林斯的教育之道 「Marva Collins' Way」 阅读笔记

    <马文·柯林斯的教育之道> 是 哈佛幸福课(积极心理学) 中强列推荐的一本书 这本书主写的是 马文·柯林斯 的成长经历已经和教育理念,仅看介绍,会误认为这本书只是在说鼓励式的教学理念,看完 ...

  2. quartus之LPM_COMPARE测试

    quartus之LPM_COMPARE测试 1.IP描述 比较器的IP,可以比较两路数据是否相等.相等输出为1,不等输出为0的aeb信号是需要测试的量. 2.基础测试 module compare_t ...

  3. KingabseES 表空间限额子句(QUOTA Clause)

    概述 在Oracle数据库中,DBA权限用户,可以为其他用户,创建对象,即使该用户没有任何权限.当DBA用户在该用户的表,插入数据时,提示 超出表空间的空间限额 .这就需要设置该用户的表空间的空间限额 ...

  4. UE4 c++ -- 简单的UMG

    说明 学习一下如何将Widget蓝图与C++连接起来,将处理逻辑写在C++中 基础 在蓝图中,我们显示Widget是通过一个Actor或者PlayerController,甚至关卡蓝图,利用Creat ...

  5. apue 文章集锦

    与 apue 相关的一系列文章比较庞杂,按原书目录整理了一下,形成目录,方便系统性阅读. 另外这些文章是在我快读完的时候开始写的,之前的一些章节还多有遗漏,后面慢慢补上. chapter 1: UNI ...

  6. C++设计模式 - 模板方法(Template Method)

    组件协作模式: 现代软件专业分工之后的第一个结果是"框架与应用程序的划分","组件协作"模式通过晚期绑定,来实现框架与应用程序之间的松耦合,是二者之间协作时常用 ...

  7. #决策单调性dp,分治#LOJ 6039「雅礼集训 2017 Day5」珠宝

    题目传送门 分析 观察到这个0/1背包中单个物品的体积不超过300,考虑分体积考虑. 设 \(dp[i]\) 表示容量大小为 \(i\) 的背包能获得的最大价值, \(dp[i]=\max\{dp[i ...

  8. vue3中router配置中的children怎么用

    在Vue 3中,当你使用Vue Router创建路由配置时, children属性允许你为某个路由定义嵌套路由.这意味着你可以在父路由下设置子路由,从而构建出具有层级结构的URL路径. 这里是一个基本 ...

  9. OpenHarmony 3.1 Release版本关键特性解析——ArkUI框架又有哪些新增能力?

     ArkUI 是一套 UI 开发框架,它提供了开发者进行应用 UI 开发时所必须的能力.随着 OpenAtom OpenHarmony(以下简称"OpenHarmony") 3.1 ...

  10. HMS Core分析服务智能运营,“智能时机”上线,轻松提升Push点击

    对于运营者来说,消息推送一直是提升用户活跃与转化的重要工具,如何在提升转化的情况下,同时不降低用户的接受程度,这一直是运营不断追求的目标. 好的推送不只在于优质的推送内容,还需要把握合适的时机.在合适 ...