博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
小试YARP
阅读量:4033 次
发布时间:2019-05-24

本文共 7487 字,大约阅读时间需要 24 分钟。

.net core下,一个轻量组反向代理库,由微软发起。

做了一个简单的带验证的反向代理,应用结构如上图,一个验证服务,两个业务服务和一个YARP服务。

源码

https://github.com/axzxs2001/Asp.NetCoreExperiment/tree/master/Asp.NetCoreExperiment/YARP

YARP的Starup.cs如下,主要是用来添加YARP组件和添加权限组件部分。

using Microsoft.AspNetCore.Authentication.JwtBearer;using Microsoft.AspNetCore.Authorization;using Microsoft.AspNetCore.Builder;using Microsoft.AspNetCore.Hosting;using Microsoft.Extensions.Configuration;using Microsoft.Extensions.DependencyInjection;using System.IdentityModel.Tokens.Jwt;using Microsoft.IdentityModel.Tokens;using Microsoft.Extensions.Hosting;using System.Collections.Generic;using System.Security.Claims;using System.Threading.Tasks;using System.Text;using System;namespace YARPDemo01{    public class Startup    {        public IConfiguration Configuration { get; }        public Startup(IConfiguration configuration)        {            Configuration = configuration;        }        public void ConfigureServices(IServiceCollection services)        {            AddAuth(services);            services.AddReverseProxy().LoadFromConfig(Configuration.GetSection("ReverseProxy"));        }        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)        {            if (env.IsDevelopment())            {                app.UseDeveloperExceptionPage();            }            app.UseAuthentication();            app.UseRouting();            app.UseAuthorization();            app.UseEndpoints(endpoints =>            {                endpoints.MapReverseProxy();            });        }        void AddAuth(IServiceCollection services)        {            //读取配置文件            var audienceConfig = Configuration.GetSection("Audience");            var symmetricKeyAsBase64 = audienceConfig["Secret"];            var keyByteArray = Encoding.ASCII.GetBytes(symmetricKeyAsBase64);            var signingKey = new SymmetricSecurityKey(keyByteArray);            var tokenValidationParameters = new TokenValidationParameters            {                ValidateIssuerSigningKey = true,                IssuerSigningKey = signingKey,                ValidateIssuer = true,                ValidIssuer = audienceConfig["Issuer"],                ValidateAudience = true,                ValidAudience = audienceConfig["Audience"],                ValidateLifetime = true,                ClockSkew = TimeSpan.Zero,                RequireExpirationTime = true,            };            var signingCredentials = new SigningCredentials(signingKey, SecurityAlgorithms.HmacSha256);            //这个集合模拟用户权限表,可从数据库中查询出来            var permission = new List
{ new Permission { Url="/webapi01/test1", Name="admin"}, new Permission { Url="/webapi01/test3", Name="admin"}, new Permission { Url="/webapi02/test2", Name="admin"}, new Permission { Url="/webapi02/test4", Name="admin"}, }; //如果第三个参数,是ClaimTypes.Role,上面集合的每个元素的Name为角色名称,如果ClaimTypes.Name,即上面集合的每个元素的Name为用户名 var permissionRequirement = new PermissionRequirement( "/api/denied", permission, ClaimTypes.Role, audienceConfig["Issuer"], audienceConfig["Audience"], signingCredentials, expiration: TimeSpan.FromSeconds(1000000)//设置Token过期时间 ); services.AddAuthorization(options => { options.AddPolicy("Permission", policy => policy.AddRequirements(permissionRequirement)); }). AddAuthentication(options => { options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; }) .AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, o => { //不使用https o.RequireHttpsMetadata = false; o.TokenValidationParameters = tokenValidationParameters; o.Events = new JwtBearerEvents { OnTokenValidated = context => { if (context.Request.Path.Value.ToString() == "/api/logout") { var token = ((context as TokenValidatedContext).SecurityToken as JwtSecurityToken).RawData; } return Task.CompletedTask; } }; }); //注入授权Handler services.AddSingleton
(); services.AddSingleton(permissionRequirement); } }}

YARP项目实现API聚合appsettings.json

{  "urls": "https://*:6001;http://*:6000",  "Logging": {    "LogLevel": {      "Default": "Information",      "Microsoft": "Warning",      "Microsoft.Hosting.Lifetime": "Information"    }  },  "AllowedHosts": "*",  "Audience": {    "Secret": "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890",    "Issuer": "gsw",    "Audience": "everone"  },  //实现api聚合  "ReverseProxy": {    "Routes": [      //业务服务webapi01      {        "RouteId": "webapi01",        "ClusterId": "webapi01_cluster",        "AuthorizationPolicy": "Permission",        "Match": {          "Path": "/webapi01/{**catch-all}"        }      },      //业务服务webapi02      {        "RouteId": "webapi02",        "ClusterId": "webapi02_cluster",        "AuthorizationPolicy": "Permission",        "Match": {          "Path": "/webapi02/{**catch-all}"        }      },      //验证服务      {        "RouteId": "authservice",        "ClusterId": "auth_cluster",        "Match": {          "Path": "/auth/{**catch-all}"        }      }    ],    "Clusters": {      //业务服务webapi01      "webapi01_cluster": {        "Destinations": {          "webapi01_cluster/destination": {            "Address": "https://localhost:7001/"          }        }      },      //业务服务webapi02      "webapi02_cluster": {        "Destinations": {          "webapi02_cluster/destination": {            "Address": "https://localhost:8001/"          }        }      },      //验证服务      "auth_cluster": {        "Destinations": {          "auth_cluster/destination": {            "Address": "https://localhost:5001/"          }        }      }    }  }}

Auth项目实现登录签名部分

using System;using System.IdentityModel.Tokens.Jwt;using System.Security.Claims;namespace AuthenticationAuthorization_Token{    public class JwtToken    {        ///         /// 获取基于JWT的Token        ///         ///         /// 
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 response = new { Status = true, access_token = encodedJwt, expires_in = permissionRequirement.Expiration.TotalMilliseconds, token_type = "Bearer" }; return response; } }}

看结果:

首先登录获取token,用户名gsw,密码111111

访问webapi01

访问webapi02

转载地址:http://tlkdi.baihongyu.com/

你可能感兴趣的文章
机器学习实战之决策树(一)
查看>>
[LeetCode By Python] 2 Add Two Number
查看>>
机器学习实战之决策树二
查看>>
[LeetCode By Python]7 Reverse Integer
查看>>
[LeetCode By Python]9. Palindrome Number
查看>>
[leetCode By Python] 14. Longest Common Prefix
查看>>
[leetCode By Python]111. Minimum Depth of Binary Tree
查看>>
[LeetCode By Python]118. Pascal's Triangle
查看>>
[LeetCode By Python]121. Best Time to Buy and Sell Stock
查看>>
[LeetCode By Python]122. Best Time to Buy and Sell Stock II
查看>>
[LeetCode By Python]125. Valid Palindrome
查看>>
[LeetCode By Python]136. Single Number
查看>>
[LeetCode By Python]172. Factorial Trailing Zeroes
查看>>
[LeetCode By MYSQL] Combine Two Tables
查看>>
python jieba分词模块的基本用法
查看>>
[CCF BY C++]2017.12 最小差值
查看>>
[CCF BY C++]2017-12 游戏
查看>>
如何打开ipynb文件
查看>>
[Leetcode BY python ]190. Reverse Bits
查看>>
Android下调用收发短信邮件等(转载)
查看>>