绕过 Ocelot API 网关
Bypassing Ocelot API Gateway
我有一个 API 网关,在本例中称为 Gateway.Api。在 Startup
class 我有以下内容:
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices(IServiceCollection services)
{
services.AddOcelot(Configuration);
services.AddMvc();
var appSettingSection = Configuration.GetSection("AppSettings");
services.Configure<AppSettings>(appSettingSection);
var appSettings = appSettingSection.Get<AppSettings>();
var key = Encoding.ASCII.GetBytes(appSettings.Secret);
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.SaveToken = true;
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(key),
ValidateIssuer = false,
ValidateAudience = false
};
});
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseAuthentication();
app.UseOcelot().Wait();
app.UseMvc();
}
如您所见,它定义了身份验证方案。
使用 Ocelot
我的 Gateway.Api
有以下配置文件:
{
"ReRoutes": [
{
"DownstreamPathTemplate": "/api/customer",
"DownstreamScheme": "http",
"DownstreamHostAndPorts": [
{
"Host": "localhost",
"Port": 50366
}
],
"UpstreamPathTemplate": "/api/customer",
"UpstreamHttpMethod": [ "Get" ],
"AuthenticationOptions": {
"AuthenticationProviderKey": "Bearer",
"AllowedScopes": []
}
},
{
"DownstreamPathTemplate": "/api/user/authenticate",
"DownstreamScheme": "http",
"DownstreamHostAndPorts": [
{
"Host": "localhost",
"Port": 50353
}
],
"UpstreamPathTemplate": "/api/user/authenticate",
"UpstreamHttpMethod": [ "Post" ]
}
],
"GlobalConfiguration": {
"UseServiceDiscovery": false
}
}
当我尝试在没有令牌的情况下访问 http://localhost:50333/api/customer(Gateway.Api 的端口为 50333)时,我收到 401 响应,证明配置文件和身份验证有效。
除了客户微服务,我还有一个身份微服务,允许用户使用有效的用户名和密码进行身份验证,然后颁发令牌。然后使用此令牌调用客户服务,我得到成功响应 (200 OK)。
现在由于某种原因,如果我不使用网关直接访问客户服务(所以 http://localhost:50366/api/customer)我能够在没有令牌的情况下获得成功的响应。
下面是客户微服务:
[Route("api/[controller]")]
public class CustomerController : Controller
{
[HttpGet]
public IEnumerable<string> Get()
{
var customers = new string[] {
"test",
"test"
};
return customers;
}
}
这是否意味着我必须为每个微服务添加身份验证方案Startup
class?如果是这样,是不是太过分了?
我尝试的是在客户微服务中的操作上使用 [Authorize]
属性,但这会引发异常,即它们不是默认的身份验证方案。
这是开发环境,因此您可以直接访问 url。您的客户服务不知道网关。在实际生产环境中,您通常只会暴露 API 网关,其余服务位于防火墙(私有子网)之后。只有 API 网关可以访问它们。访问服务的唯一方法是通过网关。但是,如果您想公开服务,则必须进行单独的服务身份验证。
Regardless 为您想要保护的服务添加身份验证始终是个好主意。
这样理解吧,为什么要用API网关?
使用 API 网关的原因有很多,其中之一是:
这样我们就可以在API网关处添加鉴权,而不是在很多微服务中添加鉴权码
在生产服务器机器中,我们只为最终用户打开 API 网关端口,用户不知道其他微服务托管在哪里,也无法通过尝试其他端口访问,因为其他端口未打开!
我们还可以将微服务放在另一台机器上,只有托管 API 网关的机器才能访问,方法是将其 IP 地址列入白名单。
但在这种情况下,您信任您的开发人员和 DevOps 团队,否则您可以对高价值微服务进行进一步的身份验证,并且此身份验证与最终用户使用的身份验证没有区别,在这里您将进行身份验证API 网关。
我有一个 API 网关,在本例中称为 Gateway.Api。在 Startup
class 我有以下内容:
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices(IServiceCollection services)
{
services.AddOcelot(Configuration);
services.AddMvc();
var appSettingSection = Configuration.GetSection("AppSettings");
services.Configure<AppSettings>(appSettingSection);
var appSettings = appSettingSection.Get<AppSettings>();
var key = Encoding.ASCII.GetBytes(appSettings.Secret);
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.SaveToken = true;
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(key),
ValidateIssuer = false,
ValidateAudience = false
};
});
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseAuthentication();
app.UseOcelot().Wait();
app.UseMvc();
}
如您所见,它定义了身份验证方案。
使用 Ocelot
我的 Gateway.Api
有以下配置文件:
{
"ReRoutes": [
{
"DownstreamPathTemplate": "/api/customer",
"DownstreamScheme": "http",
"DownstreamHostAndPorts": [
{
"Host": "localhost",
"Port": 50366
}
],
"UpstreamPathTemplate": "/api/customer",
"UpstreamHttpMethod": [ "Get" ],
"AuthenticationOptions": {
"AuthenticationProviderKey": "Bearer",
"AllowedScopes": []
}
},
{
"DownstreamPathTemplate": "/api/user/authenticate",
"DownstreamScheme": "http",
"DownstreamHostAndPorts": [
{
"Host": "localhost",
"Port": 50353
}
],
"UpstreamPathTemplate": "/api/user/authenticate",
"UpstreamHttpMethod": [ "Post" ]
}
],
"GlobalConfiguration": {
"UseServiceDiscovery": false
}
}
当我尝试在没有令牌的情况下访问 http://localhost:50333/api/customer(Gateway.Api 的端口为 50333)时,我收到 401 响应,证明配置文件和身份验证有效。
除了客户微服务,我还有一个身份微服务,允许用户使用有效的用户名和密码进行身份验证,然后颁发令牌。然后使用此令牌调用客户服务,我得到成功响应 (200 OK)。
现在由于某种原因,如果我不使用网关直接访问客户服务(所以 http://localhost:50366/api/customer)我能够在没有令牌的情况下获得成功的响应。
下面是客户微服务:
[Route("api/[controller]")]
public class CustomerController : Controller
{
[HttpGet]
public IEnumerable<string> Get()
{
var customers = new string[] {
"test",
"test"
};
return customers;
}
}
这是否意味着我必须为每个微服务添加身份验证方案Startup
class?如果是这样,是不是太过分了?
我尝试的是在客户微服务中的操作上使用 [Authorize]
属性,但这会引发异常,即它们不是默认的身份验证方案。
这是开发环境,因此您可以直接访问 url。您的客户服务不知道网关。在实际生产环境中,您通常只会暴露 API 网关,其余服务位于防火墙(私有子网)之后。只有 API 网关可以访问它们。访问服务的唯一方法是通过网关。但是,如果您想公开服务,则必须进行单独的服务身份验证。
Regardless 为您想要保护的服务添加身份验证始终是个好主意。
这样理解吧,为什么要用API网关?
使用 API 网关的原因有很多,其中之一是:
这样我们就可以在API网关处添加鉴权,而不是在很多微服务中添加鉴权码
在生产服务器机器中,我们只为最终用户打开 API 网关端口,用户不知道其他微服务托管在哪里,也无法通过尝试其他端口访问,因为其他端口未打开!
我们还可以将微服务放在另一台机器上,只有托管 API 网关的机器才能访问,方法是将其 IP 地址列入白名单。
但在这种情况下,您信任您的开发人员和 DevOps 团队,否则您可以对高价值微服务进行进一步的身份验证,并且此身份验证与最终用户使用的身份验证没有区别,在这里您将进行身份验证API 网关。