简介原文链接

      .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 == "")
{
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()),
signingCredentials: new SigningCredentials(signingKey, SecurityAlgorithms.HmacSha256)
);
var encodedJwt = new JwtSecurityTokenHandler().WriteToken(jwt);
var responseJson = new
{
access_token = encodedJwt,
expires_in = (int)TimeSpan.FromMinutes().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": ,
"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();
}

运行结果。

  完工。

  源码在此

总结

没啥。

.net core使用ocelot---第二篇 身份验证的更多相关文章

  1. 【asp.net core 系列】13 Identity 身份验证入门

    0. 前言 通过前两篇我们实现了如何在Service层如何访问数据,以及如何运用简单的加密算法对数据加密.这一篇我们将探索如何实现asp.net core的身份验证. 1. 身份验证 asp.net ...

  2. 第二章 身份验证——《跟我学Shiro》

    转发:https://www.iteye.com/blog/jinnianshilongnian-2019547 目录贴:跟我学Shiro目录贴 身份验证,即在应用中谁能证明他就是他本人.一般提供如他 ...

  3. ASP.NET Core 学习笔记 第二篇 依赖注入

    前言 ASP.NET Core 应用在启动过程中会依赖各种组件提供服务,而这些组件会以接口的形式标准化,这些组件这就是我们所说的服务,ASP.NET Core框架建立在一个底层的依赖注入框架之上,它使 ...

  4. .net core使用ocelot---第五篇 服务质量

    简介 .net core使用ocelot---第一篇 简单使用  .net core使用ocelot---第二篇 身份验证使用 .net core使用ocelot---第三篇 日志记录  .net c ...

  5. .net core使用ocelot---第八篇 Consul

    简介 .net core使用ocelot---第一篇 简单使用   .net core使用ocelot---第二篇 身份验证使用  .net core使用ocelot---第三篇 日志记录  .net ...

  6. .net core使用ocelot---第七篇 服务发现

    简介 .net core使用ocelot---第一篇 简单使用   .net core使用ocelot---第二篇 身份验证使用  .net core使用ocelot---第三篇 日志记录  .net ...

  7. .net core使用ocelot---第六篇 负载均衡

    简介 .net core使用ocelot---第一篇 简单使用 .net core使用ocelot---第二篇 身份验证 .net core使用ocelot---第三篇 日志记录  .net core ...

  8. .net core使用ocelot---第四篇 限流熔断

    简介 .net core使用ocelot---第一篇 简单使用 .net core使用ocelot---第二篇 身份验证 .net core使用ocelot---第三篇 日志记录 前几篇文章我们陆续介 ...

  9. .net core使用ocelot---第三篇 日志记录

    简介 .net core使用ocelot---第一篇 简单使用 .net core使用ocelot---第二篇 身份验证使用 上篇介绍使用asp.net core 创建API网关.本文将介绍Ocelo ...

随机推荐

  1. mapping 映射

    es的映射就相当于编程语言中给变量定义类型,定义后的变量使用起来更高效,未定义的变量相较于定义的性能肯定是不如的.所以需要掌握es映射. 未定义映射es会对提供的数据进行类型猜测,如果对自动判断的类型 ...

  2. MySQL事务优化

    ====================事务特性 事务隔离级别 事务控制语句 MySQL优化==================== 事务的概念 事务指逻辑上的一组操作,组成这组操作的各个单元,要么全 ...

  3. AI-数据标注

    目录 素材标注工具 标注可能存在的问题 标注注意事项 如何提高素材标注质量     算力和数据是影响深度学习的两个关键因素.在算力满足的情况下,为了达到更好的效果,我们就需要提供海量优质素材数据给神经 ...

  4. Apache源码编译安装脚本

      Apache是开源的的.最流行的Web服务器软件之一,它快速.可靠并且可通过简单的API扩充,将Perl/Python/PHP等解释器编译到服务器中.Apache的模块超多,以及具有运行稳定,强大 ...

  5. Nios II IDE代码优化,quartus ii 11.0版本IDE

    开发Altera Nios II软件可使用Nios II IDE或 Nios II Software BuildTools for Eclipse(即:Nios II SBT for Eclipse) ...

  6. django 补充 QuerySet数据类型

    1 QuerySet数据类型  特点:      (1) 可切片    Entry.objects.all()[:5]      (2) 可迭代 :                articleLis ...

  7. VMware Xcode真机调试

    原因如下:VMware12默认使用usb3.0 ,先给苹果系统关机,然后打开虚拟机设置,更改usb控制器为USB2.0 就可以成功连接了. 问题提示:could not launch “name” p ...

  8. 张兴盼-201871010131 《面向对象程序设计(java)》第六、七周学习总结

    张兴盼-201871010131 <面向对象程序设计(java)>第六.七周学习总结 项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh ...

  9. 原生PHP+原生ajax批量删除(超简单),ajax删除,ajax即点即改,完整代码,完整实例

    效果图: 建表:company DROP TABLE IF EXISTS `company`;CREATE TABLE `company` ( `id` int(11) NOT NULL AUTO_I ...

  10. awesome-RecSys

    https://github.com/jihoo-kim/awesome-RecSys?fbclid=IwAR1m6OebmqO9mfLV1ta4OTihQc9Phw8WNS4zdr5IeT1X1OL ...