VB.net 2010 视频教程 VB.net 2010 视频教程 VB.net 2010 视频教程
SQL Server 2008 视频教程 c#入门经典教程 Visual Basic从门到精通视频教程
当前位置:
首页 > 编程开发 > C#编程 >
  • C#教程之.net core使用ocelot---第二篇 身份验证使用

  • 2019-08-14 15:22 来源:未知
简介原文链接
      .net core使用ocelot---第一篇 简单使用
         接上文,我将继续介绍使用asp.net core 创建API网关,主要介绍身份验证(authentication )相关内容。
         API服务是需要保护的资源,我们应该尽可能的保证他们的安全。
         通常,我们会使用aspnet security 来保证我们项目的安全,aspnet security代码库是为asp.net core 设计的安全和授权中间件。已经让事情变得简单。
         那么我们在项目中引入API网关会不会导致巨大的改变?答案是,不会。我们的修改微乎其微,但是却让安全和授权变得简单。
         先看下面的截图。

  截图显示,当我们访问我们的服务,API网关会让我们首先访问其授权模块。我们必须访问授权服务获得访问令牌(access token),然后用访问令牌访问受保护的服务。
         可能你倾向将授权服务独立,这意味客户端得先访问授权服务获得访问令牌。然后携带令牌访问API网关。毫无疑问这样做没问题,但是我建议将授权服务和其他服务放在一起。
         APIGateway是我们所有服务的入口,对于身份未验证的客户端仅可以访问授权服务。
         OK,开始我们的表演。
         我会使用上一个demo的部分内容,便于理解。
Step1
项目名称 项目类型 描述
APIGateway ASP.NET Core Empty 示例的入口
CustomersAPIServices ASP.NET Core Web API API 服务处理消费者的操作
AuthServer ASP.NET Core Web API API 服务处理授权操作
ClientApp Console App 控制台程序模拟客户端
  APIGateway和CustomerAPIServices和上篇文章的例子一样,你可以在APIGatewayBasicDemo获得。
Step2
         创建AuthServer,AuthServer主要是为request请求生成访问令牌(access token),我们需要添加一个方法处理。
复制代码
[HttpGet] public IActionResult Get(string name, string pwd) { //just hard code here. 
    if (name == "catcher" && pwd == "123") { var now = DateTime.UtcNow; var claims = new Claim[] { new Claim(JwtRegisteredClaimNames.Sub, name), new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()), new Claim(JwtRegisteredClaimNames.Iat, now.ToUniversalTime().ToString(), ClaimValueTypes.Integer64) }; var signingKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(_settings.Value.Secret)); var tokenValidationParameters = new TokenValidationParameters { ValidateIssuerSigningKey = true, IssuerSigningKey = signingKey, ValidateIssuer = true, ValidIssuer = _settings.Value.Iss, ValidateAudience = true, ValidAudience = _settings.Value.Aud, ValidateLifetime = true, ClockSkew = TimeSpan.Zero, RequireExpirationTime = true, }; var jwt = new JwtSecurityToken( issuer: _settings.Value.Iss, audience: _settings.Value.Aud, claims: claims, notBefore: now, expires: now.Add(TimeSpan.FromMinutes(2)), signingCredentials: new SigningCredentials(signingKey, SecurityAlgorithms.HmacSha256) ); var encodedJwt = new JwtSecurityTokenHandler().WriteToken(jwt); var responseJson = new { access_token = encodedJwt, expires_in = (int)TimeSpan.FromMinutes(2).TotalSeconds }; return Json(responseJson); } else { return Json(""); } } 
复制代码
  在验证用户时。我使用硬编码将用户名写死,因为对于本文这个不是那么重要。
  这样我们就完成了授权服务,现在跑起来。

Step3
         回到CustomersAPIServices项目,我们应该保护这个服务。
         修改Startup,我们可以使用授权。在这我用JwtBearer进行授权,我会给TestKey设置默认的授权方案。TestKey我将在下面提到。
复制代码
public void ConfigureServices(IServiceCollection services) { var audienceConfig = Configuration.GetSection("Audience"); var signingKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(audienceConfig["Secret"])); var tokenValidationParameters = new TokenValidationParameters { ValidateIssuerSigningKey = true, IssuerSigningKey = signingKey, ValidateIssuer = true, ValidIssuer = audienceConfig["Iss"], ValidateAudience = true, ValidAudience = audienceConfig["Aud"], ValidateLifetime = true, ClockSkew = TimeSpan.Zero, RequireExpirationTime = true, }; services.AddAuthentication() .AddJwtBearer("TestKey", x => { x.RequireHttpsMetadata = false; x.TokenValidationParameters = tokenValidationParameters; }); services.AddMvc(); } public void Configure(IApplicationBuilder app) { app.UseAuthentication(); app.UseMvc(); } 
复制代码
  接下来,对需要保护的方法,添加Authorize。
复制代码
[Authorize] [HttpGet] public IEnumerable<string> Get() { return new string[] { "Catcher Wong", "James Li" }; } 
复制代码
注意
         该项目基于asp.net core 2.0. 如果你的项目是1.X,可能有些不同,建议用迁移迁移到2.0.以上。接下来就是见证奇迹的时候了。

Step4
         最重要的步骤来了,在APIGateway中配置授权。
复制代码
public void ConfigureServices(IServiceCollection services) { var audienceConfig = Configuration.GetSection("Audience"); var signingKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(audienceConfig["Secret"])); var tokenValidationParameters = new TokenValidationParameters { ValidateIssuerSigningKey = true, IssuerSigningKey = signingKey, ValidateIssuer = true, ValidIssuer = audienceConfig["Iss"], ValidateAudience = true, ValidAudience = audienceConfig["Aud"], ValidateLifetime = true, ClockSkew = TimeSpan.Zero, RequireExpirationTime = true, }; services.AddAuthentication() .AddJwtBearer("TestKey", x => { x.RequireHttpsMetadata = false; x.TokenValidationParameters = tokenValidationParameters; }); services.AddOcelot(Configuration); } 
复制代码
 
  这个配置的大部分代码和Customer Service一样。
  当Ocelot启动,它会查看ReRoutes 》AuthenticationOptions 》AuthenticationProviderKey 的值,
检查该值是否被授权服务注册,如果没有,Ocelot不会启动,如果有,Ocelot在执行时使用授权服务。
         所以,我们得修改configuration.json,我们需要添加新的节点,并将其值赋为在Startup 类中定义的一样。
复制代码
{ "DownstreamPathTemplate": "/api/customers", "DownstreamScheme": "http", "DownstreamHost": "localhost", "DownstreamPort": 9001, "UpstreamPathTemplate": "/customers", "UpstreamHttpMethod": [ "Get" ], "AuthenticationOptions": { "AuthenticationProviderKey": "TestKey", "AllowedScopes": [] } } 
复制代码
  启动服务。
 

注意
         当你启动项目时遇到下面的错误,你应该检查你的代码,查看AddJwtBearer 方法是否指明授权方案。
        Unhandled Exception: System.InvalidOperationException: Scheme already exists: Bearer
Step5
         我们已经准备完毕,我们用我们的客户端模拟APIGateway的某些请求。
 
         我们先添加获得访问令牌的方法。
复制代码
private static string GetJwt() { HttpClient client = new HttpClient(); client.BaseAddress = new Uri( "http://localhost:9000"); client.DefaultRequestHeaders.Clear(); var res2 = client.GetAsync("/api/auth?name=catcher&pwd=123").Result; dynamic jwt = JsonConvert.DeserializeObject(res2.Content.ReadAsStringAsync().Result); return jwt.access_token; } 
复制代码
 
 接下来,编写通过APIGateway访问Customer Service方法的代码。
复制代码
static void Main(string[] args) { HttpClient client = new HttpClient(); client.DefaultRequestHeaders.Clear(); client.BaseAddress = new Uri("http://localhost:9000"); // 1. without access_token will not access the service // and return 401 . 
    var resWithoutToken = client.GetAsync("/customers").Result; //print something here //2. with access_token will access the service // and return result. 
 client.DefaultRequestHeaders.Clear(); var jwt = GetJwt(); client.DefaultRequestHeaders.Add("Authorization", $"Bearer {jwt}"); var resWithToken = client.GetAsync("/customers").Result; //print something here //3. visit no auth service 
 client.DefaultRequestHeaders.Clear(); var res = client.GetAsync("/customers/1").Result; //print something here 
 Console.Read(); } 
复制代码
 
运行结果。

 
  完工。
  源码在此。
总结
         没啥。
相关教程