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

前言

近日,应一位朋友的邀请写了个Asp.Net Core基于JWT认证的数据接口网关Demo。朋友自己开了个公司,接到的一个升级项目,客户要求用Aps.Net Core做数据网关服务且基于JWT认证实现对前后端分离的数据服务支持,于是想到我一直做.Net开发,问我是否对.Net Core有所了解?能不能做个简单Demo出来看看?我说,分道扬镳之后我不是调用别人的接口就是提供接口给别人调用,于是便有了以下示例代码。

示例要求能演示获取Token及如何使用该Token访问数据资源,在Demo中实现了JWT的颁发及验证以及重写一个ActionAuthorizeAttribute实现对具体数据接口的调用权限控制,先看一下项目截图:

[项目截图]

项目文件介绍

解决方案下只有一个项目,项目名称就叫Jwt.Gateway,包含主要文件有:

  1. Controllers目录下的ApiActionFilterAttribute.cs文件,继承Microsoft.AspNetCore.Mvc.Filters.ActionFilterAttribute,用于校验接口调用者对具体接口的访问权限。
  2. Controllers目录下的ApiBase.cs文件,继承Microsoft.AspNetCore.Mvc.Controller,具有Microsoft.AspNetCore.Authorization.Authorize特性引用,用于让所有数据接口用途的控制器继承,定义有CurrentAppKey属性(来访应用程序的身份标识)并在OnActionExecuting事件中统一分析Claims并赋值。
  3. Controllers目录下的TokenController.cs控制器文件,用于对调用方应用程序获取及注销Token。
  4. Controllers目录下的UsersController.cs控制器文件,继承ApiBase.cs,作为数据调用示例。
  5. MiddleWares目录下的ApiCustomException.cs文件,是一个数据接口的统一异常处理中间件。
  6. Models目录下的ApiResponse.cs文件,用于做数据接口的统一数据及错误信息输出实体模型。
  7. Models目录下的User.cs文件,示例数据实体模型。
  8. Program.cs及Startup.cs文件就不介绍了,随便建个空项目都有。

项目文件代码

ApiActionFilterAttribute.cs

Controllers目录下的ApiActionFilterAttribute.cs文件,继承Microsoft.AspNetCore.Mvc.Filters.ActionFilterAttribute,用于校验接口调用者对具体接口的访问权限。

设想每一个到访的请求都是一个应用程序,每一个应用程序都分配有基本的Key和Password,每一个应用程序具有不同的接口访问权限,所以在具体的数据接口上应该声明该接口所要求的权限值,比如修改用户信息的接口应该在接口方法上声明需要具有“修改用户”的权限,用例: [ApiActionFilter("用户修改")]

大部分情况下一个接口(方法)对应一个操作,这样基本上就能应付了,但是不排除有时候可能需要多个权限组合进行验证,所以该文件中有一个对多个权限值进行校验的“与”和“和”枚举,用例: [ApiActionFilter(new string[] { "用户修改", "用户录入", "用户删除" },ApiActionFilterAttributeOption.AND)] ,这样好像就差不多了。

由于在一个接口调用之后可能需要将该接口所声明需要的权限值记入日志等需求,因此权限值集合将被写入到HttpContext.Items["Permissions"]中以方便可能的后续操作访问,看代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc.Filters;

namespace Jwt.Gateway.Controllers
{
 public enum ApiActionFilterAttributeOption
 {
 OR,AND
 }
 public class ApiActionFilterAttribute : Microsoft.AspNetCore.Mvc.Filters.ActionFilterAttribute
 {
 List<string> Permissions = new List<string>();
 ApiActionFilterAttributeOption Option = ApiActionFilterAttributeOption.AND;
 public ApiActionFilterAttribute(string permission)
 {
 Permissions.Add(permission);
 }
 public ApiActionFilterAttribute(string[] permissions, ApiActionFilterAttributeOption option)
 {
 foreach(var permission in permissions) {
 if (Permissions.Contains(permission))
 {
  continue;
 }
 Permissions.Add(permission);
 }
 Option = option;
 }

 public override void OnActionExecuting(ActionExecutingContext context)
 {
 var key = GetAppKey(context);
 List<string> keyPermissions = GetAppKeyPermissions(key);
 var isAnd = Option == ApiActionFilterAttributeOption.AND;
 var permissionsCount = Permissions.Count;
 var keyPermissionsCount = keyPermissions.Count;
 for (var i = 0; i < permissionsCount; i++)
 {
 bool flag = false;
 for (var j = 0; j < keyPermissions.Count; j++)
 {
  if (flag = string.Equals(Permissions[i], keyPermissions[j], StringComparison.OrdinalIgnoreCase))
  {
  break;
  }
 }
 if (flag)
 {
  continue;
 }
 if (isAnd)
 {
  throw new Exception("应用“" + key + "”缺少“" + Permissions[i] + "”的权限");
 }
 }

 context.HttpContext.Items.Add("Permissions", Permissions);

 base.OnActionExecuting(context);
 }

 private string GetAppKey(ActionExecutingContext context)
 {
 var claims = context.HttpContext.User.Claims;
 if (claims == null)
 {
 throw new Exception("未能获取到应用标识");
 }
 var claimKey = claims.ToList().Find(o => string.Equals(o.Type, "AppKey", StringComparison.OrdinalIgnoreCase));
 if (claimKey == null)
 {
 throw new Exception("未能获取到应用标识");
 }

 return claimKey.Value;
 }
 private List<string> GetAppKeyPermissions(string appKey)
 {
 List<string> li = new List<string>
 {
 "用户明细","用户列表","用户录入","用户修改","用户删除"
 };
 return li;
 }

 }
}

ApiActionAuthorizeAttribute.cs

ApiBase.cs

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

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

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;

namespace Jwt.Gateway.MiddleWares
{
 //参考: https://www.cnblogs.com/ShenNan/p/10197231.html

 public enum ApiCustomExceptionHandleType
 {
 JsonHandle = 0,
 PageHandle = 1,
 Both = 2
 }
 public class ApiCustomExceptionMiddleWareOption
 {
 public ApiCustomExceptionMiddleWareOption(
  ApiCustomExceptionHandleType handleType = ApiCustomExceptionHandleType.JsonHandle,
  IList<PathString> jsonHandleUrlKeys = null,
  string errorHandingPath = "")
 {
  HandleType = handleType;
  JsonHandleUrlKeys = jsonHandleUrlKeys;
  ErrorHandingPath = errorHandingPath;
 }
 public ApiCustomExceptionHandleType HandleType { get; set; }
 public IList<PathString> JsonHandleUrlKeys { get; set; }
 public PathString ErrorHandingPath { get; set; }
 }
 public class ApiCustomExceptionMiddleWare
 {
 private RequestDelegate _next;
 private ApiCustomExceptionMiddleWareOption _option;
 private IDictionary<int, string> _exceptionStatusCodeDic;

 public ApiCustomExceptionMiddleWare(RequestDelegate next, ApiCustomExceptionMiddleWareOption option)
 {
  _next = next;
  _option = option;
  _exceptionStatusCodeDic = new Dictionary<int, string>
  {
  { 401, "未授权的请求" },
  { 404, "找不到该页面" },
  { 403, "访问被拒绝" },
  { 500, "服务器发生意外的错误" }
  //其余状态自行扩展
  };
 }

 public async Task Invoke(HttpContext context)
 {
  Exception exception = null;
  try
  {
  await _next(context);
  }
  catch (Exception ex)
  {
  context.Response.Clear();
  context.Response.StatusCode = 200;//手动设置状态码(总是成功)
  exception = ex;
  }
  finally
  {
  if (_exceptionStatusCodeDic.ContainsKey(context.Response.StatusCode) &&
   !context.Items.ContainsKey("ExceptionHandled"))
  {
   var errorMsg = string.Empty;
   if (context.Response.StatusCode == 500 && exception != null)
   {
   errorMsg = $"{_exceptionStatusCodeDic[context.Response.StatusCode]}\r\n{(exception.InnerException != null ? exception.InnerException.Message : exception.Message)}";
   }
   else
   {
   errorMsg = _exceptionStatusCodeDic[context.Response.StatusCode];
   }
   exception = new Exception(errorMsg);
  }
  if (exception != null)
  {
   var handleType = _option.HandleType;
   if (handleType == ApiCustomExceptionHandleType.Both)
   {
   var requestPath = context.Request.Path;
   handleType = _option.JsonHandleUrlKeys != null && _option.JsonHandleUrlKeys.Count(
    k => requestPath.StartsWithSegments(k, StringComparison.CurrentCultureIgnoreCase)) > 0 ?
    ApiCustomExceptionHandleType.JsonHandle :
    ApiCustomExceptionHandleType.PageHandle;
   }

   if (handleType == ApiCustomExceptionHandleType.JsonHandle)
   await JsonHandle(context, exception);
   else
   await PageHandle(context, exception, _option.ErrorHandingPath);
  }
  }
 }
 private Jwt.Gateway.Models.ApiResponse GetApiResponse(Exception ex)
 {
  return new Jwt.Gateway.Models.ApiResponse() { status = 0, message = ex.Message };
 }
 private async Task JsonHandle(HttpContext context, Exception ex)
 {
  var apiResponse = GetApiResponse(ex);
  var serialzeStr = Newtonsoft.Json.JsonConvert.SerializeObject(apiResponse);
  context.Response.ContentType = "application/json";
  await context.Response.WriteAsync(serialzeStr, System.Text.Encoding.UTF8);
 }
 private async Task PageHandle(HttpContext context, Exception ex, PathString path)
 {
  context.Items.Add("Exception", ex);
  var originPath = context.Request.Path;
  context.Request.Path = path;
  try
  {
  await _next(context);
  }
  catch { }
  finally
  {
  context.Request.Path = originPath;
  }
 }
 }
 public static class ApiCustomExceptionMiddleWareExtensions
 {
 public static IApplicationBuilder UseApiCustomException(this IApplicationBuilder app, ApiCustomExceptionMiddleWareOption option)
 {
  return app.UseMiddleware<ApiCustomExceptionMiddleWare>(option);
 }
 }
}

ApiCustomException.cs

配置相关

appsettings.json

算法'HS256'要求SecurityKey.KeySize大于'128'位,所以JwtSecurityKey可不要太短了哦。

{
 "Urls": "http://localhost:60000",
 "AllowedHosts": "*",
 "JwtSecurityKey": "areyouokhhhhhhhhhhhhhhhhhhhhhhhhhhh",
 "JwtTokenIssuer": "Jwt.Gateway",
 "JwtTokenAudience": "App"
}

appsettings.json

Startup.cs

关于JWT的配置可以在通过JwtBearerOptions加入一些自己的事件处理逻辑,共有4个事件可供调用:

OnAuthenticationFailed,OnMessageReceived,OnTokenValidated,OnChallenge, 本示例中是在OnTokenValidated中插入Token黑名单的校验逻辑。黑名单应该是Jwt应用场景中主动使Token过期的主流做法了。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Jwt.Gateway.MiddleWares;
using Microsoft.Extensions.DependencyInjection;

namespace Jwt.Gateway
{
 public class Startup
 {
  private readonly Microsoft.Extensions.Configuration.IConfiguration _configuration;

  public Startup(Microsoft.Extensions.Configuration.IConfiguration configuration)
  {
   _configuration = configuration;
  }

  public void ConfigureServices(IServiceCollection services)
  {
   services.AddAuthentication(Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(options => {
     options.Events = new Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerEvents
     {
      /*OnMessageReceived = context =>
      {
       context.Token = context.Request.Query["access_token"];
       return Task.CompletedTask;
      },*/
      OnTokenValidated = context =>
      {
       var token = ((System.IdentityModel.Tokens.Jwt.JwtSecurityToken)context.SecurityToken).RawData;
       if (InBlacklist(token))
       {
        context.Fail("token in blacklist");
       }
       return Task.CompletedTask;
      }
     };
     options.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters
     {
      ValidateIssuer = true,
      ValidateAudience = true,
      ValidateLifetime = true,
      ValidateIssuerSigningKey = true,
      ValidAudience = _configuration["JwtTokenAudience"],
      ValidIssuer = _configuration["JwtTokenIssuer"],
      IssuerSigningKey = new Microsoft.IdentityModel.Tokens.SymmetricSecurityKey(System.Text.Encoding.UTF8.GetBytes(_configuration["JwtSecurityKey"]))
     };
    });
   services.AddMvc().AddJsonOptions(option=> {
    option.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss.fff";
   });
  }

  public void Configure(IApplicationBuilder app, IHostingEnvironment env)
  {
   if (env.IsDevelopment())
   {
    app.UseDeveloperExceptionPage();
   }

   app.UseApiCustomException(new ApiCustomExceptionMiddleWareOption(
      handleType: ApiCustomExceptionHandleType.Both,
      jsonHandleUrlKeys: new PathString[] { "/api" },
      errorHandingPath: "/home/error"));

   app.UseAuthentication();

   app.UseMvc();
  }

  bool InBlacklist(string token)
  {
   //code: 实际项目中应该查询数据库或配置文件进行比对

   return false;
  }

 }
}

Startup.cs

Program.cs

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;

namespace Jwt.Gateway
{
 public class Program
 {
  public static void Main(string[] args)
  {
   BuildWebHost(args).Run();
  }

  public static IWebHost BuildWebHost(string[] args)
  {
   var config = new ConfigurationBuilder()
    .SetBasePath(Directory.GetCurrentDirectory())
    .AddJsonFile("appsettings.json", optional: true)
    .Build();

   return WebHost.CreateDefaultBuilder(args)
    .UseKestrel()
    .UseConfiguration(config)
    .UseStartup<Startup>()
    .Build();
  }
 }
}

Program.cs

运行截图

[运行截图-获取Token]

[运行截图-配置Fiddler调用接口获取数据]

[运行截图-获取到数据]

如果Token校验失败将会返回401错误!

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对我们的支持。

(0)

相关推荐

  • asp net core2.1如何使用jwt从原理到精通(二)

    在aspnet core中,自定义jwt管道验证 有了上一节的内容作为基础,那这点也是非常容易的,关键点在中间件,只是把上一级在测试类中的自定义验证放到中间件中来即可, 不过需要注意:中间件 的位置很重要,只有它后面的管道才会收到影响: 那我们先建一个自定义中间件类:(中间件的详细内容这里就不讲了,大家可以参考官网和其他博文) /// <summary> /// 自定义授权中间件 /// </summary> public class JwtCustomerAuthorizeMid

  • asp net core 2.1中如何使用jwt(从原理到精通)

    为什么使用 Jwt 最近,移动开发的劲头越来越足,学校搞的各种比赛都需要用手机 APP 来撑场面,所以,作为写后端的,很有必要改进一下以往的基于 Session 的身份认证方式了,理由如下: 移动端经常要保持长时间(1 到 2 星期)在线,但是 Session 却不好在服务端保存这么久,虽然可以持久化到数据库,但是还是挺费资源 移动端往往不是使用的网页技术,所以藏在 Cookie 里面的 SessionId 不是很方便的传递给服务端 服务端暴露给客户端的接口往往是 RESTful 风格的,这是一

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

    前言 近日,应一位朋友的邀请写了个Asp.Net Core基于JWT认证的数据接口网关Demo.朋友自己开了个公司,接到的一个升级项目,客户要求用Aps.Net Core做数据网关服务且基于JWT认证实现对前后端分离的数据服务支持,于是想到我一直做.Net开发,问我是否对.Net Core有所了解?能不能做个简单Demo出来看看?我说,分道扬镳之后我不是调用别人的接口就是提供接口给别人调用,于是便有了以下示例代码. 示例要求能演示获取Token及如何使用该Token访问数据资源,在Demo中实现

  • ASP.NET Core使用JWT认证授权的方法

    demo地址: https://github.com/william0705/JWTS 名词解析 认证 : 识别用户是否合法 授权: 赋予用户权限 (能访问哪些资源) 鉴权: 鉴定权限是否合法 Jwt优势与劣势 优势 1. 无状态 token 存储身份验证所有信息 , 服务端不需要保存用户身份验证信息, 减少服务端压力 , 服务端更容易水平扩展, 由于无状态, 又会导致它最大缺点 , 很难注销 2. 支持跨域访问 Cookie是不允许垮域访问的,token支持 3. 跨语言 基于标准化的 JSO

  • ASP.NET Core应用JWT进行用户认证及Token的刷新方案

    目录 一.什么是JWT? 为什么要使用JWT? 二.JWT的组成: Header Payload Signature 三.认证流程 四.应用实例 认证服务 User相关: TokenHelper: 应用服务 五.Token的刷新 本文将通过实际的例子来演示如何在ASP.NET Core中应用JWT进行用户认证以及Token的刷新方案 一.什么是JWT? JWT(json web token)基于开放标准(RFC 7519),是一种无状态的分布式的身份验证方式,主要用于在网络应用环境间安全地传递声

  • 浅谈ASP.NET Core 中jwt授权认证的流程原理

    1,快速实现授权验证 什么是 JWT ?为什么要用 JWT ?JWT 的组成? 这些百度可以直接找到,这里不再赘述. 实际上,只需要知道 JWT 认证模式是使用一段 Token 作为认证依据的手段. 我们看一下 Postman 设置 Token 的位置. 那么,如何使用 C# 的 HttpClient 访问一个 JWT 认证的 WebAPI 呢? 下面来创建一个 ASP.NET Core 项目,尝试添加 JWT 验证功能. 1.1 添加 JWT 服务配置 在 Startup.cs 的 Confi

  • asp.net core集成JWT的步骤记录

    [什么是JWT] JSON Web Token(JWT)是目前最流行的跨域身份验证解决方案. JWT的官网地址:https://jwt.io/ 通俗地来讲,JWT是能代表用户身份的令牌,可以使用JWT令牌在api接口中校验用户的身份以确认用户是否有访问api的权限. JWT中包含了身份认证必须的参数以及用户自定义的参数,JWT可以使用秘密(使用HMAC算法)或使用RSA或ECDSA的公钥/私钥对进行签名. [什么时候应该使用JSON Web令牌?] 授权:这是使用JWT的最常见方案.一旦用户登录

  • ASP.Net Core基于EF6、Unitwork、Autofac实现Repository模式

    一.实现的思路和结构图 Repository的共同性 有一些公共的方法(增删改查), 这些方法无关于Repository操作的是哪个实体类,可以把这些方法定义成接口IRepository,然后有个基类BaseRepository实现该接口的方法.常见的方法,比如Find, Filter, Delete, Create等 Repository的差异性 每个Repository类又会有一些差异性,应当允许它们能够继承BaseRepository之外,还能够再扩展自己的一些方法.所以每个类都可以再定义

  • ASP.NET Core基于现有数据库创建EF模型

    1.简介 Entity Framework Core可通过数据库提供给应用程序的插件访问许多不同的数据库.我们可以通过使用Entity Framework Core构建执行基本数据访问的ASP.NET Core MVC应用程序,对现有数据库进行反向工程以便创建Entity Framework模型. 2.创建数据库 我们可以通过Visual Studio创建一个数据库再进行演示,步骤如下:●打开Visual Studio开发工具●“工具”>“连接到数据库”●选择“Microsoft SQL Ser

  • ASP.Net Core基于ABP架构配置To Json序列化

    一. 前言 我们采用ABP架构用MVC Controller或Web API返回给前端结果ToJson序列化后得到的属性命名都是采用js的驼峰格式,即首字母小写,后面单词首字母大写的格式(如:后台属性名为OrderName,返回的前端js为orderName).但在实际项目开发中由于某种原因(比如给老系统提供接口或现有系统集成等)需要采用给后台属性名一致或自己特定的格式,下面就介绍一下基于ABP架构ToJson如何修改默认配置和自定义配置. 二. 修改ToJson序列化默认配置 在Startup

  • ASP.NET实现基于Forms认证的WebService应用实例

    本文实例讲述了ASP.NET实现基于Forms认证的WebService应用方法.分享给大家供大家参考.具体实现方法如下: 在安全性要求不是很高的ASP.Net程序中,基于Forms的身份验证是经常使用的一种方式,而如果需要对WebService进行身份验证,最常用的可能是基于Soap 标头的自定义身份验证方式.如果对两者做一下比较的话,显然,基于Forms的验证方式更加方便易用,能否将Forms验证方式应用到WebService中去呢? 从理论上讲,使用基于Forms的方式对WebServic

  • ASP.NET Core 实现基本认证的示例代码

    HTTP基本认证 在HTTP中,HTTP基本认证(Basic Authentication)是一种允许网页浏览器或其他客户端程序以(用户名:口令) 请求资源的身份验证方式,不要求cookie,session identifier.login page等标记或载体. - 所有浏览器据支持HTTP基本认证方式 - 基本身证原理不保证传输凭证的安全性,仅被based64编码,并没有encrypted或者hashed,一般部署在客户端和服务端互信的网络,在公网中应用BA认证通常与https结合 http

随机推荐