Asp.Net Core基于JWT认证的数据接口网关实例代码(2)

Controllers目录下的ApiBase.cs文件,继承Microsoft.AspNetCore.Mvc.Controller,具有Microsoft.AspNetCore.Authorization.Authorize特性引用,用于让所有数据接口用途的控制器继承,定义有CurrentAppKey属性(来访应用程序的身份标识)并在OnActionExecuting事件中统一分析Claims并赋值。

通过验证之后,Aps.Net Core会在HttpContext.User.Claims中将将来访者的身份信息记录下来,我们可以通过该集合得到来访者的身份信息。

using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Filters; namespace Jwt.Gateway.Controllers { [Microsoft.AspNetCore.Authorization.Authorize] public class ApiBase : Microsoft.AspNetCore.Mvc.Controller { private string _CurrentAppKey = ""; public string CurrentAppKey { get { return _CurrentAppKey; } } public override void OnActionExecuting(ActionExecutingContext context) { var claims = context.HttpContext.User.Claims.ToList(); var claim = claims.Find(o => o.Type == "appKey"); if (claim == null) { throw new Exception("未通过认证"); } var appKey = claim.Value; if (string.IsNullOrEmpty(appKey)) { throw new Exception("appKey不合法"); } _CurrentAppKey = appKey; base.OnActionExecuting(context); } } } ApiBase.cs

TokenController.cs

Controllers目录下的TokenController.cs控制器文件,用于对调用方应用程序获取及注销Token。

using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; namespace Jwt.Gateway.Controllers { [Route("api/[controller]/[action]")] public class TokenController : Controller { private readonly Microsoft.Extensions.Configuration.IConfiguration _configuration; public TokenController(Microsoft.Extensions.Configuration.IConfiguration configuration) { _configuration = configuration; } // /api/token/get public IActionResult Get(string appKey, string appPassword) { try { if (string.IsNullOrEmpty(appKey)) { throw new Exception("缺少appKey"); } if (string.IsNullOrEmpty(appKey)) { throw new Exception("缺少appPassword"); } if (appKey != "myKey" && appPassword != "myPassword")//固定的appKey及appPassword,实际项目中应该来自数据库或配置文件 { throw new Exception("配置不存在"); } var key = new Microsoft.IdentityModel.Tokens.SymmetricSecurityKey(System.Text.Encoding.UTF8.GetBytes(_configuration["JwtSecurityKey"])); var creds = new Microsoft.IdentityModel.Tokens.SigningCredentials(key, Microsoft.IdentityModel.Tokens.SecurityAlgorithms.HmacSha256); var claims = new List<System.Security.Claims.Claim>(); claims.Add(new System.Security.Claims.Claim("appKey", appKey));//仅在Token中记录appKey var token = new System.IdentityModel.Tokens.Jwt.JwtSecurityToken( issuer: _configuration["JwtTokenIssuer"], audience: _configuration["JwtTokenAudience"], claims: claims, expires: DateTime.Now.AddMinutes(30), signingCredentials: creds); return Ok(new Models.ApiResponse { status = 1, message = "OK", data = new System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler().WriteToken(token) }); } catch(Exception ex) { return Ok(new Models.ApiResponse { status = 0, message = ex.Message, data = "" }); } } // /api/token/delete public IActionResult Delete(string token) { //code: 加入黑名单,使其无效 return Ok(new Models.ApiResponse { status = 1, message = "OK", data = "" }); } } } TokenController.cs

UsersController.cs

Controllers目录下的UsersController.cs控制器文件,继承ApiBase.cs,作为数据调用示例。

该控制器定义了对User对象常规的明细、列表、录入、修改、删除等操作。

using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; namespace Jwt.Gateway.Controllers { [Produces("application/json")] [Route("api/[controller]/[action]")] public class UsersController : ApiBase { /* * 1.要访问访问该控制器提供的接口请先通过"/api/token/get"获取token * 2.访问该控制器提供的接口http请求头必须具有值为"Bearer+空格+token"的Authorization键,格式参考: * "Authorization"="Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoiQXBwIiwiYXBwS2V5IjoibXlLZXkiLCJleHAiOjE1NTE3ODc2MDMsImlzcyI6IkdhdGV3YXkiLCJhdWQiOiJhdWRpZW5jZSJ9.gQ9_Q7HUT31oFyfl533T-bNO5IWD2drl0NmD1JwQkMI" */ /// <summary> /// 临时用户测试数据,实际项目中应该来自数据库等媒介 /// </summary> static List<Models.User> _Users = null; static object _Lock = new object(); public UsersController() { if (_Users == null) { lock (_Lock) { if (_Users == null) { _Users = new List<Models.User>(); var now = DateTime.Now; for(var i = 0; i < 10; i++) { var num = i + 1; _Users.Add(new Models.User { UserId = num, UserName = "name"+num, UserPassword = "pwd"+num, UserJoinTime = now }); } } } } } // /api/users/detail [ApiActionFilter("用户明细")] public IActionResult Detail(long userId) { /* //获取appKey(在ApiBase中写入) var appKey = CurrentAppKey; //获取使用的权限(在ApiActionAuthorizeAttribute中写入) var permissions = HttpContext.Items["Permissions"]; */ var user = _Users.Find(o => o.UserId == userId); if (user == null) { throw new Exception("用户不存在"); } return Ok(new Models.ApiResponse { data = user, status = 1, message = "OK" }); } // /api/users/list [ApiActionFilter("用户列表")] public IActionResult List(int page, int size) { page = page < 1 ? 1 : page; size = size < 1 ? 1 : size; var total = _Users.Count(); var pages = total % size == 0 ? total / size : ((long)Math.Floor((double)total / size + 1)); if (page > pages) { return Ok(new Models.ApiResponse { data = new List<Models.User>(), status = 1, message = "OK", total = total }); } var li = new List<Models.User>(); var startIndex = page * size - size; var endIndex = startIndex + size - 1; if (endIndex > total - 1) { endIndex = total - 1; } for(; startIndex <= endIndex; startIndex++) { li.Add(_Users[startIndex]); } return Ok(new Models.ApiResponse { data = li, status = 1, message = "OK", total = total }); } // /api/users/add [ApiActionFilter("用户录入")] public IActionResult Add() { return Ok(new Models.ApiResponse { status = 1, message = "OK" }); } // /api/users/update [ApiActionFilter(new string[] { "用户修改", "用户录入", "用户删除" },ApiActionFilterAttributeOption.AND)] public IActionResult Update() { return Ok(new Models.ApiResponse { status = 1, message = "OK" }); } // /api/users/delete [ApiActionFilter("用户删除")] public IActionResult Delete() { return Ok(new Models.ApiResponse { status = 1, message = "OK" }); } } } UsersController.cs

ApiCustomException.cs

MiddleWares目录下的ApiCustomException.cs文件,是一个数据接口的统一异常处理中间件。

该文件整理并抄袭自:https://www.cnblogs.com/ShenNan/p/10197231.html

在此特别感谢一下作者的先行贡献,并请原谅我无耻的抄袭。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wdsgsp.html