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
1 namespace Ocelot.JWTAuthorizePolicy 2 { 3 /// <summary> 4 /// 用户或角色或其他凭据实体 5 /// </summary> 6 public class Permission 7 { 8 /// <summary> 9 /// 用户或角色或其他凭据名称 10 /// </summary> 11 public virtual string Name 12 { get; set; } 13 /// <summary> 14 /// 请求Url 15 /// </summary> 16 public virtual string Url 17 { get; set; } 18 } 19 }
PermissionRequirement.cs
1 using Microsoft.AspNetCore.Authorization; 2 using Microsoft.IdentityModel.Tokens; 3 using System; 4 using System.Collections.Generic; 5 6 namespace Ocelot.JWTAuthorizePolicy 7 { 8 /// <summary> 9 /// 必要参数类 10 /// </summary> 11 public class PermissionRequirement : IAuthorizationRequirement 12 { 13 /// <summary> 14 /// 无权限action 15 /// </summary> 16 public string DeniedAction { get; set; } 17 18 /// <summary> 19 /// 认证授权类型 20 /// </summary> 21 public string ClaimType { internal get; set; } 22 /// <summary> 23 /// 请求路径 24 /// </summary> 25 public string LoginPath { get; set; } = "/Api/Login"; 26 /// <summary> 27 /// 发行人 28 /// </summary> 29 public string Issuer { get; set; } 30 /// <summary> 31 /// 订阅人 32 /// </summary> 33 public string Audience { get; set; } 34 /// <summary> 35 /// 过期时间 36 /// </summary> 37 public TimeSpan Expiration { get; set; } 38 /// <summary> 39 /// 签名验证 40 /// </summary> 41 public SigningCredentials SigningCredentials { get; set; } 42 43 /// <summary> 44 /// 构造 45 /// </summary> 46 /// <param name="deniedAction">无权限action</param> 47 /// <param name="userPermissions">用户权限集合</param> 48 49 /// <summary> 50 /// 构造 51 /// </summary> 52 /// <param name="deniedAction">拒约请求的url</param> 53 /// <param name="claimType">声明类型</param> 54 /// <param name="issuer">发行人</param> 55 /// <param name="audience">订阅人</param> 56 /// <param name="signingCredentials">签名验证实体</param> 57 public PermissionRequirement(string deniedAction, string claimType, string issuer, string audience, SigningCredentials signingCredentials, TimeSpan expiration) 58 { 59 ClaimType = claimType; 60 DeniedAction = deniedAction; 61 Issuer = issuer; 62 Audience = audience; 63 Expiration = expiration; 64 SigningCredentials = signingCredentials; 65 } 66 } 67 }
PermissionHandler.cs
1 using Microsoft.AspNetCore.Authentication; 2 using Microsoft.AspNetCore.Authentication.JwtBearer; 3 using Microsoft.AspNetCore.Authorization; 4 using Microsoft.Extensions.DependencyInjection; 5 using System; 6 using System.Collections.Generic; 7 using System.Linq; 8 using System.Security.Claims; 9 using System.Threading.Tasks; 10 11 namespace Ocelot.JWTAuthorizePolicy 12 { 13 /// <summary> 14 /// 权限授权Handler 15 /// </summary> 16 public class PermissionHandler : AuthorizationHandler<PermissionRequirement> 17 { 18 /// <summary> 19 /// 验证方案提供对象 20 /// </summary> 21 public IAuthenticationSchemeProvider Schemes { get; set; } 22 /// <summary> 23 /// 用户权限集合 24 /// </summary> 25 List<Permission> _permissions; 26 /// <summary> 27 /// 构造 28 /// </summary> 29 /// <param name="schemes"></param> 30 public PermissionHandler(IAuthenticationSchemeProvider schemes, List<Permission> permissions=null) 31 { 32 Schemes = schemes; 33 _permissions = permissions; 34 } 35 36 protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context, PermissionRequirement requirement) 37 { 38 //从AuthorizationHandlerContext转成HttpContext,以便取出表求信息 39 var httpContext = (context.Resource as Microsoft.AspNetCore.Mvc.Filters.AuthorizationFilterContext).HttpContext; 40 //请求Url 41 var questUrl = httpContext.Request.Path.Value.ToLower(); 42 //判断请求是否停止 43 var handlers = httpContext.RequestServices.GetRequiredService<IAuthenticationHandlerProvider>(); 44 foreach (var scheme in await Schemes.GetRequestHandlerSchemesAsync()) 45 { 46 var handler = await handlers.GetHandlerAsync(httpContext, scheme.Name) as IAuthenticationRequestHandler; 47 if (handler != null && await handler.HandleRequestAsync()) 48 { 49 context.Fail(); 50 return; 51 } 52 } 53 //判断请求是否拥有凭据,即有没有登录 54 var defaultAuthenticate = await Schemes.GetDefaultAuthenticateSchemeAsync(); 55 if (defaultAuthenticate != null) 56 { 57 var result = await httpContext.AuthenticateAsync(defaultAuthenticate.Name); 58 //result?.Principal不为空即登录成功 59 if (result?.Principal != null) 60 { 61 httpContext.User = result.Principal; 62 //权限中是否存在请求的url 63 if (_permissions!=null&&_permissions.GroupBy(g => g.Url).Where(w => w.Key.ToLower() == questUrl).Count() > 0) 64 { 65 var name = httpContext.User.Claims.SingleOrDefault(s => s.Type == requirement.ClaimType).Value; 66 //验证权限 67 if (_permissions.Where(w => w.Name == name && w.Url.ToLower() == questUrl).Count() == 0) 68 { 69 //无权限跳转到拒绝页面 70 httpContext.Response.Redirect(requirement.DeniedAction); 71 context.Succeed(requirement); 72 return; 73 } 74 } 75 //判断过期时间 76 if (DateTime.Parse(httpContext.User.Claims.SingleOrDefault(s => s.Type == ClaimTypes.Expiration).Value) >= DateTime.Now) 77 { 78 context.Succeed(requirement); 79 } 80 else 81 { 82 context.Fail(); 83 } 84 return; 85 } 86 } 87 //判断没有登录时,是否访问登录的url,并且是Post请求,并且是form表单提交类型,否则为失败 88 if (!questUrl.Equals(requirement.LoginPath.ToLower(), StringComparison.Ordinal) && (!httpContext.Request.Method.Equals("POST") 89 || !httpContext.Request.HasFormContentType)) 90 { 91 context.Fail(); 92 return; 93 } 94 context.Succeed(requirement); 95 } 96 } 97 }
JwtToken.cs
1 using System; 2 using System.IdentityModel.Tokens.Jwt; 3 using System.Security.Claims; 4 5 namespace Ocelot.JWTAuthorizePolicy 6 { 7 /// <summary> 8 /// JWTToken生成类 9 /// </summary> 10 public class JwtToken 11 { 12 /// <summary> 13 /// 获取基于JWT的Token 14 /// </summary> 15 /// <param name="username"></param> 16 /// <returns></returns> 17 public static dynamic BuildJwtToken(Claim[] claims, PermissionRequirement permissionRequirement) 18 { 19 var now = DateTime.UtcNow; 20 var jwt = new JwtSecurityToken( 21 issuer: permissionRequirement.Issuer, 22 audience: permissionRequirement.Audience, 23 claims: claims, 24 notBefore: now, 25 expires: now.Add(permissionRequirement.Expiration), 26 signingCredentials: permissionRequirement.SigningCredentials 27 ); 28 var encodedJwt = new JwtSecurityTokenHandler().WriteToken(jwt); 29 var responseJson = new 30 { 31 Status = true, 32 access_token = encodedJwt, 33 expires_in = permissionRequirement.Expiration.TotalMilliseconds, 34 token_type = "Bearer" 35 }; 36 return responseJson; 37 } 38 } 39 }
OcelotJwtBearerExtension.cs,本类型中的方法分别用于网关,web服务,和验证服务,请参看注释
1 using Microsoft.AspNetCore.Authentication; 2 using Microsoft.AspNetCore.Authorization; 3 using Microsoft.Extensions.DependencyInjection; 4 using Microsoft.IdentityModel.Tokens; 5 using System; 6 using System.Collections.Generic; 7 using System.Security.Claims; 8 using System.Text; 9 10 namespace Ocelot.JWTAuthorizePolicy 11 { 12 /// <summary> 13 /// Ocelot下JwtBearer扩展 14 /// </summary> 15 public static class OcelotJwtBearerExtension 16 { 17 /// <summary> 18 /// 注入Ocelot下JwtBearer,在ocelot网关的Startup的ConfigureServices中调用 19 /// </summary> 20 /// <param name="services">IServiceCollection</param> 21 /// <param name="issuer">发行人</param> 22 /// <param name="audience">订阅人</param> 23 /// <param name="secret">密钥</param> 24 /// <param name="defaultScheme">默认架构</param> 25 /// <param name="isHttps">是否https</param> 26 /// <returns></returns> 27 public static AuthenticationBuilder AddOcelotJwtBearer(this IServiceCollection services, string issuer, string audience, string secret, string defaultScheme, bool isHttps = false) 28 { 29 var keyByteArray = Encoding.ASCII.GetBytes(secret); 30 var signingKey = new SymmetricSecurityKey(keyByteArray); 31 var tokenValidationParameters = new TokenValidationParameters 32 { 33 ValidateIssuerSigningKey = true, 34 IssuerSigningKey = signingKey, 35 ValidateIssuer = true, 36 ValidIssuer = issuer,//发行人 37 ValidateAudience = true, 38 ValidAudience = audience,//订阅人 39 ValidateLifetime = true, 40 ClockSkew = TimeSpan.Zero, 41 RequireExpirationTime = true, 42 }; 43 return services.AddAuthentication(options => 44 { 45 options.DefaultScheme = defaultScheme; 46 }) 47 .AddJwtBearer(defaultScheme, opt => 48 { 49 //不使用https 50 opt.RequireHttpsMetadata = isHttps; 51 opt.TokenValidationParameters = tokenValidationParameters; 52 }); 53 } 54 55 /// <summary> 56 /// 注入Ocelot jwt策略,在业务API应用中的Startup的ConfigureServices调用 57 /// </summary> 58 /// <param name="services">IServiceCollection</param> 59 /// <param name="issuer">发行人</param> 60 /// <param name="audience">订阅人</param> 61 /// <param name="secret">密钥</param> 62 /// <param name="defaultScheme">默认架构</param> 63 /// <param name="policyName">自定义策略名称</param> 64 /// <param name="deniedUrl">拒绝路由</param> 65 /// <param name="isHttps">是否https</param> 66 /// <returns></returns> 67 public static AuthenticationBuilder AddOcelotPolicyJwtBearer(this IServiceCollection services, string issuer, string audience, string secret, string defaultScheme, string policyName, string deniedUrl, bool isHttps = false) 68 { 69 70 var keyByteArray = Encoding.ASCII.GetBytes(secret); 71 var signingKey = new SymmetricSecurityKey(keyByteArray); 72 var tokenValidationParameters = new TokenValidationParameters 73 { 74 ValidateIssuerSigningKey = true, 75 IssuerSigningKey = signingKey, 76 ValidateIssuer = true, 77 ValidIssuer = issuer,//发行人 78 ValidateAudience = true, 79 ValidAudience = audience,//订阅人 80 ValidateLifetime = true, 81 ClockSkew = TimeSpan.Zero, 82 RequireExpirationTime = true, 83 84 }; 85 var signingCredentials = new SigningCredentials(signingKey, SecurityAlgorithms.HmacSha256); 86 //如果第三个参数,是ClaimTypes.Role,上面集合的每个元素的Name为角色名称,如果ClaimTypes.Name,即上面集合的每个元素的Name为用户名 87 var permissionRequirement = new PermissionRequirement( 88 deniedUrl, 89 ClaimTypes.Role, 90 issuer, 91 audience, 92 signingCredentials, 93 expiration: TimeSpan.FromHours(10) 94 ); 95 //注入授权Handler 96 services.AddSingleton<IAuthorizationHandler, PermissionHandler>(); 97 services.AddSingleton(permissionRequirement); 98 return services.AddAuthorization(options => 99 { 100 options.AddPolicy(policyName, 101 policy => policy.Requirements.Add(permissionRequirement)); 102 103 }) 104 .AddAuthentication(options => 105 { 106 options.DefaultScheme = defaultScheme; 107 }) 108 .AddJwtBearer(defaultScheme, o => 109 { 110 //不使用https 111 o.RequireHttpsMetadata = isHttps; 112 o.TokenValidationParameters = tokenValidationParameters; 113 }); 114 } 115 /// <summary> 116 /// 注入Token生成器参数,在token生成项目的Startup的ConfigureServices中使用 117 /// </summary> 118 /// <param name="services">IServiceCollection</param> 119 /// <param name="issuer">发行人</param> 120 /// <param name="audience">订阅人</param> 121 /// <param name="secret">密钥</param> 122 /// <param name="deniedUrl">拒绝路由</param> 123 /// <returns></returns> 124 public static IServiceCollection AddJTokenBuild(this IServiceCollection services, string issuer, string audience, string secret, string deniedUrl) 125 { 126 var signingCredentials = new SigningCredentials(new SymmetricSecurityKey(Encoding.ASCII.GetBytes(secret)), SecurityAlgorithms.HmacSha256); 127 //如果第三个参数,是ClaimTypes.Role,上面集合的每个元素的Name为角色名称,如果ClaimTypes.Name,即上面集合的每个元素的Name为用户名 128 var permissionRequirement = new PermissionRequirement( 129 deniedUrl, 130 ClaimTypes.Role, 131 issuer, 132 audience, 133 signingCredentials, 134 expiration: TimeSpan.FromHours(10) 135 ); 136 return services.AddSingleton(permissionRequirement); 137 138 } 139 140 } 141 }
接下来看AuthenticationAPI项目:
appsettings.json
{
"Logging": {
"IncludeScopes": false,
"Debug": {
"LogLevel": {
"Default": "Information"
}
},
"Console": {
"LogLevel": {
"Default": "Information"
}
}
},
"Audience": {
"Secret": "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890",
"Issuer": "gsw",
"Audience": "everone"
}
}
Startup.cs
1 using Microsoft.AspNetCore.Builder; 2 using Microsoft.AspNetCore.Hosting; 3 using Microsoft.Extensions.Configuration; 4 using Microsoft.Extensions.DependencyInjection; 5 using Ocelot.JWTAuthorizePolicy; 6 7 namespace AuthenticationAPI 8 { 9 public class Startup 10 { 11 public Startup(IConfiguration configuration) 12 { 13 Configuration = configuration; 14 } 15 public IConfiguration Configuration { get; } 16 public void ConfigureServices(IServiceCollection services) 17 { 18 var audienceConfig = Configuration.GetSection("Audience"); 19 //注入OcelotJwtBearer 20 services.AddJTokenBuild(audienceConfig["Issuer"], audienceConfig["Issuer"], audienceConfig["Secret"], "/api/denied"); 21 services.AddMvc(); 22 } 23 public void Configure(IApplicationBuilder app, IHostingEnvironment env) 24 { 25 if (env.IsDevelopment()) 26 { 27 app.UseDeveloperExceptionPage(); 28 } 29 app.UseMvc(); 30 } 31 } 32 }
PermissionController.cs
1 using System; 2 using Microsoft.AspNetCore.Mvc; 3 using Microsoft.AspNetCore.Authorization; 4 using System.Security.Claims; 5 using Microsoft.AspNetCore.Authentication.JwtBearer; 6 using Ocelot.JWTAuthorizePolicy; 7 8 namespace AuthenticationAPI 9 { 10 public class PermissionController : Controller 11 { 12 /// <summary> 13 /// 自定义策略参数 14 /// </summary> 15 PermissionRequirement _requirement; 16 public PermissionController(PermissionRequirement requirement) 17 { 18 _requirement = requirement; 19 } 20 [AllowAnonymous] 21 [HttpPost("/authapi/login")] 22 public IActionResult Login(string username, string password) 23 { 24 var isValidated = (username == "gsw" && password == "111111")|| (username == "ggg" && password == "222222"); 25 var role=username=="gsw"?"admin" :"system"; 26 if (!isValidated) 27 { 28 return new JsonResult(new 29 { 30 Status = false, 31 Message = "认证失败" 32 }); 33 } 34 else 35 { 36 //如果是基于用户的授权策略,这里要添加用户;如果是基于角色的授权策略,这里要添加角色 37 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())}; 38 //用户标识 39 var identity = new ClaimsIdentity(JwtBearerDefaults.AuthenticationScheme); 40 identity.AddClaims(claims); 41 42 var token = JwtToken.BuildJwtToken(claims, _requirement); 43 return new JsonResult(token); 44 } 45 } 46 } 47 }
DemoAAPI项目,DemoBAPI项目类似
appsettings.json与网关,AuthenticationAPI相同
Startup.cs
1 using System.Collections.Generic; 2 using Microsoft.AspNetCore.Builder; 3 using Microsoft.AspNetCore.Hosting; 4 using Microsoft.Extensions.Configuration; 5 using Microsoft.Extensions.DependencyInjection; 6 using Microsoft.Extensions.Logging; 7 using Ocelot.JWTAuthorizePolicy; 8 9 namespace DemoAAPI 10 { 11 public class Startup 12 { 13 public Startup(IConfiguration configuration) 14 { 15 Configuration = configuration; 16 } 17 public IConfiguration Configuration { get; } 18 public void ConfigureServices(IServiceCollection services) 19 { 20 //读取配置文件 21 var audienceConfig = Configuration.GetSection("Audience"); 22 services.AddOcelotPolicyJwtBearer(audienceConfig["Issuer"], audienceConfig["Issuer"], audienceConfig["Secret"], "GSWBearer", "Permission", "/demoaapi/denied"); 23 24 //这个集合模拟用户权限表,可从数据库中查询出来 25 var permission = new List<Permission> { 26 new Permission { Url="/demoaapi/values", Name="system"}, 27 new Permission { Url="/", Name="system"} 28 }; 29 services.AddSingleton(permission); 30 services.AddMvc(); 31 } 32 public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) 33 { 34 loggerFactory.AddConsole(Configuration.GetSection("Logging")); 35 if (env.IsDevelopment()) 36 { 37 app.UseDeveloperExceptionPage(); 38 } 39 app.UseMvc(); 40 } 41 } 42 }
ValuesController.cs
1 using System.Collections.Generic; 2 using Microsoft.AspNetCore.Authorization; 3 using Microsoft.AspNetCore.Mvc; 4 5 namespace DemoAAPI.Controllers 6 { 7 [Authorize("Permission")] 8 [Route("demoaapi/[controller]")] 9 public class ValuesController : Controller 10 { 11 [HttpGet] 12 public IEnumerable<string> Get() 13 { 14 return new string[] { "DemoA服务", "请求" }; 15 } 16 [AllowAnonymous] 17 [HttpGet("/demoaapi/denied")] 18 public IActionResult Denied() 19 { 20 return new JsonResult(new 21 { 22 Status = false, 23 Message = "demoaapi你无权限访问" 24 }); 25 } 26 } 27 }
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
1 using Microsoft.AspNetCore.Builder; 2 using Microsoft.AspNetCore.Hosting; 3 using Microsoft.Extensions.Configuration; 4 using Microsoft.Extensions.DependencyInjection; 5 using Ocelot.DependencyInjection; 6 using Ocelot.Middleware; 7 using Ocelot.JWTAuthorizePolicy; 8 namespace OcelotGateway 9 { 10 public class Startup 11 { 12 public Startup(IConfiguration configuration) 13 { 14 Configuration = configuration; 15 } 16 public IConfiguration Configuration { get; } 17 public void ConfigureServices(IServiceCollection services) 18 { 19 var audienceConfig = Configuration.GetSection("Audience"); 20 //注入OcelotJwtBearer 21 services.AddOcelotJwtBearer(audienceConfig["Issuer"], audienceConfig["Issuer"], audienceConfig["Secret"], "GSWBearer"); 22 //注入配置文件,AddOcelot要求参数是IConfigurationRoot类型,所以要作个转换 23 services.AddOcelot(Configuration as ConfigurationRoot); 24 } 25 public void Configure(IApplicationBuilder app, IHostingEnvironment env) 26 { 27 app.UseOcelot().Wait(); 28 } 29 } 30 }
接下来是测试项目,创建一个控制项目TestClient
Nuget中添加RestSharp包
Program.cs
1 using RestSharp; 2 using System; 3 using System.Diagnostics; 4 5 namespace TestClient 6 { 7 class Program 8 { 9 /// <summary> 10 /// 访问Url 11 /// </summary> 12 static string _url = "http://127.0.0.1:5000"; 13 static void Main(string[] args) 14 { 15 16 Console.Title = "TestClient"; 17 dynamic token = null; 18 while (true) 19 { 20 Console.WriteLine("1、登录【admin】 2、登录【system】 3、登录【错误用户名密码】 4、查询HisUser数据 5、查询LisUser数据 "); 21 var mark = Console.ReadLine(); 22 var stopwatch = new Stopwatch(); 23 stopwatch.Start(); 24 switch (mark) 25 { 26 case "1": 27 token = AdminLogin(); 28 break; 29 case "2": 30 token = SystemLogin(); 31 break; 32 case "3": 33 token = NullLogin(); 34 break; 35 case "4": 36 DemoAAPI(token); 37 break; 38 case "5": 39 DemoBAPI(token); 40 break; 41 } 42 stopwatch.Stop(); 43 TimeSpan timespan = stopwatch.Elapsed; 44 Console.WriteLine($"间隔时间:{timespan.TotalSeconds}"); 45 tokenString = "Bearer " + Convert.ToString(token?.access_token); 46 } 47 } 48 static string tokenString = ""; 49 static dynamic NullLogin() 50 { 51 var loginClient = new RestClient(_url); 52 var loginRequest = new RestRequest("/authapi/login", Method.POST); 53 loginRequest.AddParameter("username", "gswaa"); 54 loginRequest.AddParameter("password", "111111"); 55 //或用用户名密码查询对应角色 56 loginRequest.AddParameter("role", "system"); 57 IRestResponse loginResponse = loginClient.Execute(loginRequest); 58 var loginContent = loginResponse.Content; 59 Console.WriteLine(loginContent); 60 return Newtonsoft.Json.JsonConvert.DeserializeObject(loginContent); 61 } 62 63 static dynamic SystemLogin() 64 { 65 var loginClient = new RestClient(_url); 66 var loginRequest = new RestRequest("/authapi/login", Method.POST); 67 loginRequest.AddParameter("username", "ggg"); 68 loginRequest.AddParameter("password", "222222"); 69 IRestResponse loginResponse = loginClient.Execute(loginRequest); 70 var loginContent = loginResponse.Content; 71 Console.WriteLine(loginContent); 72 return Newtonsoft.Json.JsonConvert.DeserializeObject(loginContent); 73 } 74 static dynamic AdminLogin() 75 { 76 var loginClient = new RestClient(_url); 77 var loginRequest = new RestRequest("/authapi/login", Method.POST); 78 loginRequest.AddParameter("username", "gsw"); 79 loginRequest.AddParameter("password", "111111"); 80 IRestResponse loginResponse = loginClient.Execute(loginRequest); 81 var loginContent = loginResponse.Content; 82 Console.WriteLine(loginContent); 83 return Newtonsoft.Json.JsonConvert.DeserializeObject(loginContent); 84 } 85 static void DemoAAPI(dynamic token) 86 { 87 var client = new RestClient(_url); 88 //这里要在获取的令牌字符串前加Bearer 89 string tk = "Bearer " + Convert.ToString(token?.access_token); 90 client.AddDefaultHeader("Authorization", tk); 91 var request = new RestRequest("/demoaapi/values", Method.GET); 92 IRestResponse response = client.Execute(request); 93 var content = response.Content; 94 Console.WriteLine($"状态码:{(int)response.StatusCode} 状态信息:{response.StatusCode} 返回结果:{content}"); 95 } 96 static void DemoBAPI(dynamic token) 97 { 98 var client = new RestClient(_url); 99 //这里要在获取的令牌字符串前加Bearer 100 string tk = "Bearer " + Convert.ToString(token?.access_token); 101 client.AddDefaultHeader("Authorization", tk); 102 var request = new RestRequest("/demobapi/values", Method.GET); 103 IRestResponse response = client.Execute(request); 104 var content = response.Content; Console.WriteLine($"状态码:{(int)response.StatusCode} 状态信息:{response.StatusCode} 返回结果:{content}"); 105 } 106 } 107 }
《基于.net core微服务架构视频》
http://edu.51cto.com/course/13342.html
《asp.net core精要讲解》 https://ke.qq.com/course/265696
《asp.net core 3.0》 https://ke.qq.com/course/437517
《asp.net core项目实战》 https://ke.qq.com/course/291868
《基于.net core微服务》 https://ke.qq.com/course/299524