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() > )
{
var name = httpContext.User.Claims.SingleOrDefault(s => s.Type == requirement.ClaimType).Value;
//验证权限
if (_permissions.Where(w => w.Name == name && w.Url.ToLower() == questUrl).Count() == )
{
//无权限跳转到拒绝页面
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()
);
//注入授权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()
);
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 == "")|| (username == "ggg" && password == "");
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 "":
token = AdminLogin();
break;
case "":
token = SystemLogin();
break;
case "":
token = NullLogin();
break;
case "":
DemoAAPI(token);
break;
case "":
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", "");
//或用用户名密码查询对应角色
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", "");
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", "");
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}");
}
}
}

代码下载

《基于.net core微服务架构视频》

 http://edu.51cto.com/course/13342.html

Ocelot统一权限验证的更多相关文章

  1. WebAPI接口设计:SwaggerUI文档 / 统一响应格式 / 统一异常处理 / 统一权限验证

    为什么还要写这类文章?因为我看过网上很多讲解的都不够全面,而本文结合实际工作讲解了swaggerui文档,统一响应格式,异常处理,权限验证等常用模块,并提供一套完善的案例源代码,在实际工作中可直接参考 ...

  2. Swagger如何访问Ocelot中带权限验证的API

    先亮源代码:https://github.com/axzxs2001/Asp.NetCoreExperiment/tree/master/Asp.NetCoreExperiment/SwaggerDe ...

  3. .net core使用Ocelot+Identity Server统一网关验证

    源码下载地址:下载 项目结构如下图: 在Identity Server授权中,实现IResourceOwnerPasswordValidator接口: public class IdentityVal ...

  4. asp.net获取当前页面文件名,参数,域名等方法。统一session验证和权限验证的方法

    转:http://blog.csdn.net/llll29550242/article/details/6054323 ASP.net后台获取当前页面的文件名 System.IO.Path.GetFi ...

  5. Nginx ACCESS阶段 统一的用户权限验证系统

    L59 需要编译到Nginx --with-http_auth_request_module 功能介绍: 主要当收到用户请求的时候 通过反向代理方式生成子请求至上游服务器,如果上游服务器返回2xx 则 ...

  6. 2_MVC+EF+Autofac(dbfirst)轻型项目框架_用户权限验证

    前言 接上面两篇 0_MVC+EF+Autofac(dbfirst)轻型项目框架_基本框架 与 1_MVC+EF+Autofac(dbfirst)轻型项目框架_core层(以登陆为例) .在第一篇中介 ...

  7. 从壹开始前后端分离【 .NET Core2.0 +Vue2.0 】框架之五 || Swagger的使用 3.3 JWT权限验证【必看】

    前言 关于JWT一共三篇 姊妹篇,内容分别从简单到复杂,一定要多看多想: 一.Swagger的使用 3.3 JWT权限验证[修改] 二.解决JWT权限验证过期问题 三.JWT完美实现权限与接口的动态分 ...

  8. [Abp 源码分析]十二、多租户体系与权限验证

    0.简介 承接上篇文章我们会在这篇文章详细解说一下 Abp 是如何结合 IPermissionChecker 与 IFeatureChecker 来实现一个完整的多租户系统的权限校验的. 1.多租户的 ...

  9. 【ASP.NET】ASP.NET中权限验证使用OnAuthorization实现

    在项目开发中,通常我们都会涉及到用户登录才能访问的网页,比如购物网站,我们浏览商品,添加购物车(以前开发的时候在这里就需要登录用户,但是现在有了缓存的实现,这里可以将商品加入缓存,等到结账的时候再登录 ...

随机推荐

  1. Luogu P3381 (模板题) 最小费用最大流

    <题目链接> 题目大意: 给定一张图,给定条边的容量和单位流量费用,并且给定源点和汇点.问你从源点到汇点的最带流和在流量最大的情况下的最小费用. 解题分析: 最小费用最大流果题. 下面的是 ...

  2. 前端axios下载excel无法获取header所有字段问题

    后端设置header后,前端无法获取到其他字段,只需要在服务器端header里面设置 Access-Control-Expose-Headers: Content-Disposition

  3. python 爬虫与数据可视化--matplotlib模块应用

    一.数据分析的目的(利用大数据量数据分析,帮助人们做出战略决策) 二.什么是matplotlib? matplotlib: 最流行的Python底层绘图库,主要做数据可视化图表,名字取材于MATLAB ...

  4. 英语词汇—V01

    今日词汇 1, wash [wɒʃ] n. 洗涤:洗的衣服:化妆水:冲积物 vt. 洗涤:洗刷:冲走:拍打 vi. 洗澡:被冲蚀 2, dust [dʌst] n. 灰尘:尘埃:尘土 vt. 撒:拂去 ...

  5. 我的 FPGA 学习历程(01)—— FPGA 基础知识和 Quartus 的安装

    高级的嵌入式市场主要分为以下三类:ARM.DSP 和 FPGA. 其中 ARM 是行业内的佼佼者,目前几乎所有的安卓智能手机都使用 ARM 授权的 CPU架构:而 DSP(数字信号处理器) 早年就被大 ...

  6. 将Redhat,CentOS,Ubuntu虚拟机的IP设为静态IP的方法

    一般在主机上创建的虚拟机默认是通过DHCP(Dynamic Host Configuration Protocol,动态主机配置协议)网络协议来动态生成的,这样会导致你安装的虚拟机的IP地址是动态变化 ...

  7. sqlserver安装检测不通过 (重新启动失败)

    打开注册表,HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager 删除“PendingFileRenameOperat ...

  8. 基于vue-cli配置移动端自适应

    移动端自适应:手淘的 lib-flexible + rem 配置 flexible 安装 lib-flexible 在命令行中运行如下安装: 1 npm i lib-flexible --save 引 ...

  9. oracle中文乱码问题解决

    中文乱码问题解决:1.查看服务器端编码select userenv('language') from dual;我实际查到的结果为:AMERICAN_AMERICA.ZHS16GBK2.执行语句 se ...

  10. JAVA多线程学习笔记(1)

    JAVA多线程学习笔记(1) 由于笔者使用markdown格式书写,后续copy到blog可能存在格式不美观的问题,本文的.mk文件已经上传到个人的github,会进行同步更新.github传送门 一 ...