Ocelot统一权限验证
Ocelot作為網關,可以用來作統一驗證,接上一篇博客Ocelot網關,我們繼續
前一篇,我們創建了OcelotGateway網關項目,DemoAAPI項目,DemoBAPI項目,為了驗證用戶并分發Token,現在還需要添加AuthenticationAPI項目,也是asp.net core web api項目,整體思路是,當用戶首次請求(Request)時web服務,網關會判斷本請求有無Token,并是否正確,如果沒有或不正確,就會反回401 Unauthorized;如果請求調用登錄,正確輸入用戶名或密碼,AuthenticationAPI會驗證并分發Token;當客戶端帶上Token再次訪問web服務時,網關就會放過本請求,當請求到達web服務時,web服務要對本Token進行授權驗證,如果有訪問請求的地址,會成功返回應答,負責會提示沒有權驗,所以只要具有正確的Token,應答返回都是200 OK,因為Token正確,只是沒有權限訪問請求的內容。
下面創建最重要的一個項目Ocelot.JWTAuthorizePolicy,選.NET Standard的類庫作為項目模板創建本項目,本項目的作用是為網關項目(OcelotGateway),web服務項目(DemoAAPI和DemoBAPI),和AuthenticationAPI提供注入JWT或自定義策略的API,關于自定義策略,可參考(http://www.cnblogs.com/axzxs2001/p/7530929.html)
本項目中的組成部分:
Permission.cs
namespace Ocelot.JWTAuthorizePolicy
{
/// <summary>
/// 用戶或角色或其他憑據實體
/// </summary>
public class Permission
{
/// <summary>
/// 用戶或角色或其他憑據名稱
/// </summary>
public virtual string Name
{ get; set; }
/// <summary>
/// 請求Url
/// </summary>
public virtual string Url
{ get; set; }
}
}
PermissionRequirement.cs
using Microsoft.AspNetCore.Authorization;
using Microsoft.IdentityModel.Tokens;
using System;
using System.Collections.Generic;
namespace Ocelot.JWTAuthorizePolicy
{
/// <summary>
/// 必要參數類
/// </summary>
public class PermissionRequirement : IAuthorizationRequirement
{
/// <summary>
/// 無權限action
/// </summary>
public string DeniedAction { get; set; }
/// <summary>
/// 認證授權類型
/// </summary>
public string ClaimType { internal get; set; }
/// <summary>
/// 請求路徑
/// </summary>
public string LoginPath { get; set; } = "/Api/Login";
/// <summary>
/// 發行人
/// </summary>
public string Issuer { get; set; }
/// <summary>
/// 訂閱人
/// </summary>
public string Audience { get; set; }
/// <summary>
/// 過期時間
/// </summary>
public TimeSpan Expiration { get; set; }
/// <summary>
/// 簽名驗證
/// </summary>
public SigningCredentials SigningCredentials { get; set; }
/// <summary>
/// 構造
/// </summary>
/// <param name="deniedAction">無權限action</param>
/// <param name="userPermissions">用戶權限集合</param>
/// <summary>
/// 構造
/// </summary>
/// <param name="deniedAction">拒約請求的url</param>?
/// <param name="claimType">聲明類型</param>
/// <param name="issuer">發行人</param>
/// <param name="audience">訂閱人</param>
/// <param name="signingCredentials">簽名驗證實體</param>
public PermissionRequirement(string deniedAction, string claimType, string issuer, string audience, SigningCredentials signingCredentials, TimeSpan expiration)
{
ClaimType = claimType;
DeniedAction = deniedAction;?
Issuer = issuer;
Audience = audience;
Expiration = expiration;
SigningCredentials = signingCredentials;
}
}
}
PermissionHandler.cs
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Authorization;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
namespace Ocelot.JWTAuthorizePolicy
{
/// <summary>
/// 權限授權Handler
/// </summary>
public class PermissionHandler : AuthorizationHandler<PermissionRequirement>
{
/// <summary>
/// 驗證方案提供對象
/// </summary>
public IAuthenticationSchemeProvider Schemes { get; set; }
/// <summary>
/// 用戶權限集合
/// </summary>
List<Permission> _permissions;
/// <summary>
/// 構造
/// </summary>
/// <param name="schemes"></param>
public PermissionHandler(IAuthenticationSchemeProvider schemes, List<Permission> permissions=null)
{
Schemes = schemes;
_permissions = permissions;
}
protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context, PermissionRequirement requirement)
{
//從AuthorizationHandlerContext轉成HttpContext,以便取出表求信息
var httpContext = (context.Resource as Microsoft.AspNetCore.Mvc.Filters.AuthorizationFilterContext).HttpContext;
//請求Url
var questUrl = httpContext.Request.Path.Value.ToLower();
//判斷請求是否停止
var handlers = httpContext.RequestServices.GetRequiredService<IAuthenticationHandlerProvider>();
foreach (var scheme in await Schemes.GetRequestHandlerSchemesAsync())
{
var handler = await handlers.GetHandlerAsync(httpContext, scheme.Name) as IAuthenticationRequestHandler;
if (handler != null && await handler.HandleRequestAsync())
{
context.Fail();
return;
}
}
//判斷請求是否擁有憑據,即有沒有登錄
var defaultAuthenticate = await Schemes.GetDefaultAuthenticateSchemeAsync();
if (defaultAuthenticate != null)
{
var result = await httpContext.AuthenticateAsync(defaultAuthenticate.Name);
//result?.Principal不為空即登錄成功
if (result?.Principal != null)
{
httpContext.User = result.Principal;
//權限中是否存在請求的url
if (_permissions!=null&&_permissions.GroupBy(g => g.Url).Where(w => w.Key.ToLower() == questUrl).Count() > 0)
{
var name = httpContext.User.Claims.SingleOrDefault(s => s.Type == requirement.ClaimType).Value;
//驗證權限
if (_permissions.Where(w => w.Name == name && w.Url.ToLower() == questUrl).Count() == 0)
{
//無權限跳轉到拒絕頁面?
httpContext.Response.Redirect(requirement.DeniedAction);
context.Succeed(requirement);
return;
}
}
//判斷過期時間
if (DateTime.Parse(httpContext.User.Claims.SingleOrDefault(s => s.Type == ClaimTypes.Expiration).Value) >= DateTime.Now)
{
context.Succeed(requirement);
}
else
{
context.Fail();
}
return;
}
}
//判斷沒有登錄時,是否訪問登錄的url,并且是Post請求,并且是form表單提交類型,否則為失敗
if (!questUrl.Equals(requirement.LoginPath.ToLower(), StringComparison.Ordinal) && (!httpContext.Request.Method.Equals("POST")
|| !httpContext.Request.HasFormContentType))
{
context.Fail();
return;
}
context.Succeed(requirement);
}
}
}
JwtToken.cs
using System;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
namespace Ocelot.JWTAuthorizePolicy
{
/// <summary>
/// JWTToken生成類
/// </summary>
public class JwtToken
{
/// <summary>
/// 獲取基于JWT的Token
/// </summary>
/// <param name="username"></param>
/// <returns></returns>
public static dynamic BuildJwtToken(Claim[] claims, PermissionRequirement permissionRequirement)
{
var now = DateTime.UtcNow;
var jwt = new JwtSecurityToken(
issuer: permissionRequirement.Issuer,
audience: permissionRequirement.Audience,
claims: claims,
notBefore: now,
expires: now.Add(permissionRequirement.Expiration),
signingCredentials: permissionRequirement.SigningCredentials
);
var encodedJwt = new JwtSecurityTokenHandler().WriteToken(jwt);
var responseJson = new
{
Status = true,
access_token = encodedJwt,
expires_in = permissionRequirement.Expiration.TotalMilliseconds,
token_type = "Bearer"
};
return responseJson;
}
}
}
OcelotJwtBearerExtension.cs,本類型中的方法分別用于網關,web服務,和驗證服務,請參看注釋
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authorization;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.IdentityModel.Tokens;
using System;
using System.Collections.Generic;
using System.Security.Claims;
using System.Text;
namespace Ocelot.JWTAuthorizePolicy
{
/// <summary>
/// Ocelot下JwtBearer擴展
/// </summary>
public static class OcelotJwtBearerExtension
{
/// <summary>
/// 注入Ocelot下JwtBearer,在ocelot網關的Startup的ConfigureServices中調用
/// </summary>
/// <param name="services">IServiceCollection</param>
/// <param name="issuer">發行人</param>
/// <param name="audience">訂閱人</param>
/// <param name="secret">密鑰</param>
/// <param name="defaultScheme">默認架構</param>
/// <param name="isHttps">是否https</param>
/// <returns></returns>
public static AuthenticationBuilder AddOcelotJwtBearer(this IServiceCollection services, string issuer, string audience, string secret, string defaultScheme, bool isHttps = false)
{
var keyByteArray = Encoding.ASCII.GetBytes(secret);
var signingKey = new SymmetricSecurityKey(keyByteArray);
var tokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = signingKey,
ValidateIssuer = true,
ValidIssuer = issuer,//發行人
ValidateAudience = true,
ValidAudience = audience,//訂閱人
ValidateLifetime = true,
ClockSkew = TimeSpan.Zero,
RequireExpirationTime = true,
};
return services.AddAuthentication(options =>
{
options.DefaultScheme = defaultScheme;
})
.AddJwtBearer(defaultScheme, opt =>
{
//不使用https
opt.RequireHttpsMetadata = isHttps;
opt.TokenValidationParameters = tokenValidationParameters;
});
}
/// <summary>
/// 注入Ocelot jwt策略,在業務API應用中的Startup的ConfigureServices調用
/// </summary>
/// <param name="services">IServiceCollection</param>
/// <param name="issuer">發行人</param>
/// <param name="audience">訂閱人</param>
/// <param name="secret">密鑰</param>
/// <param name="defaultScheme">默認架構</param>
/// <param name="policyName">自定義策略名稱</param>
/// <param name="deniedUrl">拒絕路由</param>
/// <param name="isHttps">是否https</param>
/// <returns></returns>
public static AuthenticationBuilder AddOcelotPolicyJwtBearer(this IServiceCollection services, string issuer, string audience, string secret, string defaultScheme, string policyName, string deniedUrl, bool isHttps = false)
{
var keyByteArray = Encoding.ASCII.GetBytes(secret);
var signingKey = new SymmetricSecurityKey(keyByteArray);
var tokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = signingKey,
ValidateIssuer = true,
ValidIssuer = issuer,//發行人
ValidateAudience = true,
ValidAudience = audience,//訂閱人
ValidateLifetime = true,
ClockSkew = TimeSpan.Zero,
RequireExpirationTime = true,
};
var signingCredentials = new SigningCredentials(signingKey, SecurityAlgorithms.HmacSha256);
//如果第三個參數,是ClaimTypes.Role,上面集合的每個元素的Name為角色名稱,如果ClaimTypes.Name,即上面集合的每個元素的Name為用戶名
var permissionRequirement = new PermissionRequirement(
deniedUrl,
ClaimTypes.Role,
issuer,
audience,
signingCredentials,
expiration: TimeSpan.FromHours(10)
);
//注入授權Handler
services.AddSingleton<IAuthorizationHandler, PermissionHandler>();
services.AddSingleton(permissionRequirement);
return services.AddAuthorization(options =>
{
options.AddPolicy(policyName,
policy => policy.Requirements.Add(permissionRequirement));
})
.AddAuthentication(options =>
{
options.DefaultScheme = defaultScheme;
})
.AddJwtBearer(defaultScheme, o =>
{
//不使用https
o.RequireHttpsMetadata = isHttps;
o.TokenValidationParameters = tokenValidationParameters;
});
}
/// <summary>
/// 注入Token生成器參數,在token生成項目的Startup的ConfigureServices中使用
/// </summary>
/// <param name="services">IServiceCollection</param>
/// <param name="issuer">發行人</param>
/// <param name="audience">訂閱人</param>
/// <param name="secret">密鑰</param>
/// <param name="deniedUrl">拒絕路由</param>
/// <returns></returns>
public static IServiceCollection AddJTokenBuild(this IServiceCollection services, string issuer, string audience, string secret, string deniedUrl)
{
var signingCredentials = new SigningCredentials(new SymmetricSecurityKey(Encoding.ASCII.GetBytes(secret)), SecurityAlgorithms.HmacSha256);
//如果第三個參數,是ClaimTypes.Role,上面集合的每個元素的Name為角色名稱,如果ClaimTypes.Name,即上面集合的每個元素的Name為用戶名
var permissionRequirement = new PermissionRequirement(
deniedUrl,
ClaimTypes.Role,
issuer,
audience,
signingCredentials,
expiration: TimeSpan.FromHours(10)
);
return services.AddSingleton(permissionRequirement);
}
}
}
接下來看AuthenticationAPI項目:
appsettings.json
{
"Logging": {
"IncludeScopes": false,
"Debug": {
"LogLevel": {
"Default": "Information"
}
},
"Console": {
"LogLevel": {
"Default": "Information"
}
}
},
"Audience": {
"Secret": "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890",
"Issuer": "gsw",
"Audience": "everone"
}
}
Startup.cs
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Ocelot.JWTAuthorizePolicy;
namespace AuthenticationAPI
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
var audienceConfig = Configuration.GetSection("Audience");
//注入OcelotJwtBearer
services.AddJTokenBuild(audienceConfig["Issuer"], audienceConfig["Issuer"], audienceConfig["Secret"], "/api/denied");
services.AddMvc();
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseMvc();
}
}
}
PermissionController.cs
using System;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Authorization;
using System.Security.Claims;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Ocelot.JWTAuthorizePolicy;
namespace AuthenticationAPI
{?
public class PermissionController : Controller
{
/// <summary>
/// 自定義策略參數
/// </summary>
PermissionRequirement _requirement;
public PermissionController(PermissionRequirement requirement)
{
_requirement = requirement;
}
[AllowAnonymous]
[HttpPost("/authapi/login")]
public IActionResult Login(string username, string password)
{
var isValidated = (username == "gsw" && password == "111111")|| (username == "ggg" && password == "222222");
var role=username=="gsw"?"admin" :"system";
if (!isValidated)
{
return new JsonResult(new
{
Status = false,
Message = "認證失敗"
});
}
else
{?
//如果是基于用戶的授權策略,這里要添加用戶;如果是基于角色的授權策略,這里要添加角色
var claims = new Claim[] { new Claim(ClaimTypes.Name, username), new Claim(ClaimTypes.Role, role), new Claim(ClaimTypes.Expiration ,DateTime.Now.AddSeconds(_requirement.Expiration.TotalSeconds).ToString())};
//用戶標識
var identity = new ClaimsIdentity(JwtBearerDefaults.AuthenticationScheme);
identity.AddClaims(claims);
var token = JwtToken.BuildJwtToken(claims, _requirement);
return new JsonResult(token);
}
}?
}
}
DemoAAPI項目,DemoBAPI項目類似
appsettings.json與網關,AuthenticationAPI相同
Startup.cs
using System.Collections.Generic;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Ocelot.JWTAuthorizePolicy;
namespace DemoAAPI
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
//讀取配置文件
var audienceConfig = Configuration.GetSection("Audience");
services.AddOcelotPolicyJwtBearer(audienceConfig["Issuer"], audienceConfig["Issuer"], audienceConfig["Secret"], "GSWBearer", "Permission", "/demoaapi/denied");
//這個集合模擬用戶權限表,可從數據庫中查詢出來
var permission = new List<Permission> {
new Permission { Url="/demoaapi/values", Name="system"},
new Permission { Url="/", Name="system"}?
};
services.AddSingleton(permission);
services.AddMvc();
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
loggerFactory.AddConsole(Configuration.GetSection("Logging"));
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseMvc();
}
}
}
ValuesController.cs
using System.Collections.Generic;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace DemoAAPI.Controllers
{
[Authorize("Permission")]
[Route("demoaapi/[controller]")]
public class ValuesController : Controller
{?
[HttpGet]
public IEnumerable<string> Get()
{
return new string[] { "DemoA服務", "請求" };
}
[AllowAnonymous]
[HttpGet("/demoaapi/denied")]
public IActionResult Denied()
{
return new JsonResult(new
{
Status = false,
Message = "demoaapi你無權限訪問"
});
}
}
}
OcelotGateway項目
configuration.json,注意每個連接的AuthenticationOptions. AuthenticationProviderKey,要設置成
{
"ReRoutes": [
{
"DownstreamPathTemplate": "/demoaapi/values",
"DownstreamScheme": "http",
"DownstreamPort": 5001,
"DownstreamHost": "localhost",
"UpstreamPathTemplate": "/demoaapi/values",
"UpstreamHttpMethod": [ "Get" ],
"QoSOptions": {
"ExceptionsAllowedBeforeBreaking": 3,
"DurationOfBreak": 10,
"TimeoutValue": 5000
},
"HttpHandlerOptions": {
"AllowAutoRedirect": false,
"UseCookieContainer": false
},
"AuthenticationOptions": {
"AuthenticationProviderKey": "GSWBearer",
"AllowedScopes": []
}
},
{
"DownstreamPathTemplate": "/demoaapi/denied",
"DownstreamScheme": "http",
"DownstreamPort": 5001,
"DownstreamHost": "localhost",
"UpstreamPathTemplate": "/demoaapi/denied",
"UpstreamHttpMethod": [ "Get" ],
"QoSOptions": {
"ExceptionsAllowedBeforeBreaking": 3,
"DurationOfBreak": 10,
"TimeoutValue": 5000
},
"AuthenticationOptions": {
}
},
{
"DownstreamPathTemplate": "/demobapi/values",
"DownstreamScheme": "http",
"DownstreamPort": 5002,
"DownstreamHost": "localhost",
"UpstreamPathTemplate": "/demobapi/values",
"UpstreamHttpMethod": [ "Get" ],
"QoSOptions": {
"ExceptionsAllowedBeforeBreaking": 3,
"DurationOfBreak": 10,
"TimeoutValue": 5000
},
"HttpHandlerOptions": {
"AllowAutoRedirect": false,
"UseCookieContainer": false
},
"AuthenticationOptions": {
"AuthenticationProviderKey": "GSWBearer",
"AllowedScopes": []
}
},
{
"DownstreamPathTemplate": "/demobapi/denied",
"DownstreamScheme": "http",
"DownstreamPort": 5002,
"DownstreamHost": "localhost",
"UpstreamPathTemplate": "/demobapi/denied",
"UpstreamHttpMethod": [ "Get" ],
"QoSOptions": {
"ExceptionsAllowedBeforeBreaking": 3,
"DurationOfBreak": 10,
"TimeoutValue": 5000
},
"AuthenticationOptions": {
}
},
{
"DownstreamPathTemplate": "/authapi/login",
"DownstreamScheme": "http",
"DownstreamPort": 5003,
"DownstreamHost": "localhost",
"UpstreamPathTemplate": "/authapi/login",
"UpstreamHttpMethod": [ "Get", "Post" ],
"QoSOptions": {
"ExceptionsAllowedBeforeBreaking": 3,
"DurationOfBreak": 10,
"TimeoutValue": 5000
},
"AuthenticationOptions": {
}
}
]
}
Startup.cs
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Ocelot.DependencyInjection;
using Ocelot.Middleware;
using Ocelot.JWTAuthorizePolicy;
namespace OcelotGateway
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }?
public void ConfigureServices(IServiceCollection services)
{
var audienceConfig = Configuration.GetSection("Audience");
//注入OcelotJwtBearer
services.AddOcelotJwtBearer(audienceConfig["Issuer"], audienceConfig["Issuer"], audienceConfig["Secret"], "GSWBearer");
//注入配置文件,AddOcelot要求參數是IConfigurationRoot類型,所以要作個轉換
services.AddOcelot(Configuration as ConfigurationRoot);
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseOcelot().Wait();
}
}
}
接下來是測試項目,創建一個控制項目TestClient
Nuget中添加RestSharp包
Program.cs
using RestSharp;
using System;
using System.Diagnostics;
namespace TestClient
{
class Program
{
/// <summary>
/// 訪問Url
/// </summary>
static string _url = "http://127.0.0.1:5000";
static void Main(string[] args)
{
Console.Title = "TestClient";
dynamic token = null;
while (true)
{
Console.WriteLine("1、登錄【admin】 2、登錄【system】 3、登錄【錯誤用戶名密碼】 4、查詢HisUser數據 5、查詢LisUser數據 ");
var mark = Console.ReadLine();
var stopwatch = new Stopwatch();
stopwatch.Start();
switch (mark)
{
case "1":
token = AdminLogin();
break;
case "2":
token = SystemLogin();
break;
case "3":
token = NullLogin();
break;
case "4":
DemoAAPI(token);
break;
case "5":
DemoBAPI(token);
break;
}
stopwatch.Stop();
TimeSpan timespan = stopwatch.Elapsed;
Console.WriteLine($"間隔時間:{timespan.TotalSeconds}");
tokenString = "Bearer " + Convert.ToString(token?.access_token);
}
}
static string tokenString = "";
static dynamic NullLogin()
{
var loginClient = new RestClient(_url);
var loginRequest = new RestRequest("/authapi/login", Method.POST);
loginRequest.AddParameter("username", "gswaa");
loginRequest.AddParameter("password", "111111");
//或用用戶名密碼查詢對應角色
loginRequest.AddParameter("role", "system");
IRestResponse loginResponse = loginClient.Execute(loginRequest);
var loginContent = loginResponse.Content;
Console.WriteLine(loginContent);
return Newtonsoft.Json.JsonConvert.DeserializeObject(loginContent);
}
static dynamic SystemLogin()
{
var loginClient = new RestClient(_url);
var loginRequest = new RestRequest("/authapi/login", Method.POST);
loginRequest.AddParameter("username", "ggg");
loginRequest.AddParameter("password", "222222");
IRestResponse loginResponse = loginClient.Execute(loginRequest);
var loginContent = loginResponse.Content;
Console.WriteLine(loginContent);
return Newtonsoft.Json.JsonConvert.DeserializeObject(loginContent);
}
static dynamic AdminLogin()
{
var loginClient = new RestClient(_url);
var loginRequest = new RestRequest("/authapi/login", Method.POST);
loginRequest.AddParameter("username", "gsw");
loginRequest.AddParameter("password", "111111");
IRestResponse loginResponse = loginClient.Execute(loginRequest);
var loginContent = loginResponse.Content;
Console.WriteLine(loginContent);
return Newtonsoft.Json.JsonConvert.DeserializeObject(loginContent);
}
static void DemoAAPI(dynamic token)
{
var client = new RestClient(_url);
//這里要在獲取的令牌字符串前加Bearer
string tk = "Bearer " + Convert.ToString(token?.access_token);
client.AddDefaultHeader("Authorization", tk);
var request = new RestRequest("/demoaapi/values", Method.GET);
IRestResponse response = client.Execute(request);
var content = response.Content;
Console.WriteLine($"狀態碼:{(int)response.StatusCode} 狀態信息:{response.StatusCode} 返回結果:{content}");
}
static void DemoBAPI(dynamic token)
{
var client = new RestClient(_url);
//這里要在獲取的令牌字符串前加Bearer
string tk = "Bearer " + Convert.ToString(token?.access_token);
client.AddDefaultHeader("Authorization", tk);
var request = new RestRequest("/demobapi/values", Method.GET);
IRestResponse response = client.Execute(request);
var content = response.Content; Console.WriteLine($"狀態碼:{(int)response.StatusCode} 狀態信息:{response.StatusCode} 返回結果:{content}");
}
}
}
相關文章:
-
Ocelot——初識基于.Net Core的API網關
-
Ocelot API網關的實現剖析
-
微服務網關Ocelot
-
API網關Ocelot 使用Polly 處理部分失敗問題
-
談談微服務中的 API 網關(API Gateway)
-
Ocelot網關
原文:http://www.cnblogs.com/axzxs2001/p/8005084.html
.NET社區新聞,深度好文,歡迎訪問公眾號文章匯總 http://www.csharpkit.com
總結
以上是生活随笔為你收集整理的Ocelot统一权限验证的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 在.NET Core类库中使用EF Co
- 下一篇: Visual Studio 2017 1