• 重庆“轮椅教师”高位截瘫仍坚守讲台 2019-07-07
  • 百度车联网携手宝马 合作伙伴全面升级为国际OEM厂商 2019-07-01
  • 全面从严治党永远在路上——辽宁代表团开放日侧记 2019-07-01
  • 【学习时刻】华侨大学黄日涵:“一带一路”盛会开启合作发展新篇章 2019-06-24
  • 秒变迷弟!吴建豪晒与甄子丹合影:偶像给我签名 2019-06-20
  • 军统头目戴笠留下哪些巨额遗产 令蒋介石身边人惊诧 2019-06-20
  • 初春喝藿香汤 解表化湿,散寒温经 2019-06-18
  • 新华时评:磋商,不等于反复折腾 2019-06-09
  • 天山特克斯峡谷 中国国家地理网 2019-06-08
  • 端午小长假珠海口岸将迎双向客流高峰 2019-06-08
  • 王朝崩塌!恒大半个月内双线出局 卡帅敲响下课警钟 2019-06-07
  • 一周人事:国务院发布任免刘伟当选北京市总工会主席 2019-06-07
  • 敞篷式设计 日产聆风Open Car官图发布 2019-06-06
  • 习近平为传统文化“代言” 2019-06-05
  • 奋力谱写新时代追赶超越新篇章——访陕西省委书记胡和平 2019-06-04
  • 香港赛马会官方透码:Asp.Net Core基于JWT认证的数据接口网关实例代码

    香港赛马会网站惠泽社绝杀八码 www.mwcrz.tw  更新时间:2019年03月08日 10:49:03   作者:如兹   我要评论

    这篇文章主要给大家介绍了关于Asp.Net Core基于JWT认证的数据接口网关的相关资料,文中通过示例代码以及图文介绍的非常详细,对大家的学习或者使用Asp.net Core具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧

    前言

    近日,应一位朋友的邀请写了个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": "//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错误!

    总结

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

    相关文章

    最新评论

  • 重庆“轮椅教师”高位截瘫仍坚守讲台 2019-07-07
  • 百度车联网携手宝马 合作伙伴全面升级为国际OEM厂商 2019-07-01
  • 全面从严治党永远在路上——辽宁代表团开放日侧记 2019-07-01
  • 【学习时刻】华侨大学黄日涵:“一带一路”盛会开启合作发展新篇章 2019-06-24
  • 秒变迷弟!吴建豪晒与甄子丹合影:偶像给我签名 2019-06-20
  • 军统头目戴笠留下哪些巨额遗产 令蒋介石身边人惊诧 2019-06-20
  • 初春喝藿香汤 解表化湿,散寒温经 2019-06-18
  • 新华时评:磋商,不等于反复折腾 2019-06-09
  • 天山特克斯峡谷 中国国家地理网 2019-06-08
  • 端午小长假珠海口岸将迎双向客流高峰 2019-06-08
  • 王朝崩塌!恒大半个月内双线出局 卡帅敲响下课警钟 2019-06-07
  • 一周人事:国务院发布任免刘伟当选北京市总工会主席 2019-06-07
  • 敞篷式设计 日产聆风Open Car官图发布 2019-06-06
  • 习近平为传统文化“代言” 2019-06-05
  • 奋力谱写新时代追赶超越新篇章——访陕西省委书记胡和平 2019-06-04
  • 大航海时代APP下载 恒大武里南联阿奇姆蓬 广东快乐十分实时开奖 急速赛车计划软件 2月28号北京单场预测 pt电子游戏论坛 德黑兰独立阿尔艾因 全天时时彩计划万位 山东群英会最新开奖号 疯狂赌徒2闯关