文章目錄
Ocelot
Ocelot
是用 .NET Core 實現的一個開源API網關。包含身份驗證、路由、請求聚合等功能。能夠輕鬆的集成IdentityServer
Ocelot的五種部署方式
-
基本使用
-
集成IdentityServer
-
多實例
-
集成Consul
-
集成 Service Fabric
開始使用
新建網關項目
新建一個Web項目ApiGateways,添加nuget包引用
Install-Package Ocelot
添加ocelot配置文件
- ocelot.json
{
"ReRoutes": [
{
"DownstreamPathTemplate": "/todos/{id}",
"DownstreamScheme": "https",
"DownstreamHostAndPorts": [
{
"Host": "jsonplaceholder.typicode.com",
"Port": 443
}
],
"UpstreamPathTemplate": "/todos/{id}",
"UpstreamHttpMethod": [ "Get" ]
}
],
"GlobalConfiguration": {
"BaseUrl": "https://localhost:5000"
}
}
此配置中,ReRoutes
節點下的Downstream相關節點表示網關下游服務相關配置,以上,我們指定了任意請求都以https請求轉發,其中DownstreamHostAndPorts表示下游服務地址和端口。Upstream
表示上游請求配置
- 配置服務引入oeclot.json
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureAppConfiguration((hostingContext, config) =>
{
config.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath)
.AddJsonFile("ocelot.json")
.AddEnvironmentVariables();
})
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
此配置中,我們的網關服務運行在http://localhost
,其中AuthenticationOptions
是認證服務相關配置,另外有一個下游服務運行在http://localhost:5201
。
將Ocelot服務添加到容器服務
public void ConfigureServices(IServiceCollection services)
{
services.AddOcelot();
}
將Ocelot添加請求管道
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseOcelot();
}
創建身份認證服務
新建一個Identity.API項目
添加nuget
Install-Package IdentityServer4 -Version 3.1.2
添加IdentityServer4
配置
- IdentityServer4 配置
爲便於展示,不做持久化,寫在內存中
public static class Config
{
// Defining an API Resource
public static IEnumerable<ApiResource> Apis => new List<ApiResource>
{
new ApiResource("gateway_api","ApiGateways")
};
// Defining Client
public static IEnumerable<Client> Clients => new List<Client>
{
new Client
{
ClientId="app_test",
// no interactive user, use the clientid/secret for authentication
AllowedGrantTypes=GrantTypes.ClientCredentials,
// secret for authentication
ClientSecrets={
new Secret("123456".Sha256())
},
// scopes that client has access to
AllowedScopes=new List<string>{
"gateway_api",
}
}
};
// Defineing Identity Resource
public static IEnumerable<IdentityResource> IdentityResources => new List<IdentityResource>
{
new IdentityResources.OpenId(),
new IdentityResources.Profile(),
};
}
- 添加IdentityServer4到容器
public void ConfigureDevelopmentServices(IServiceCollection services)
{
var builder = services.AddIdentityServer()
.AddInMemoryApiResources(Config.Apis)
.AddInMemoryClients(Config.Clients)
.AddInMemoryIdentityResources(Config.IdentityResources);
builder.AddDeveloperSigningCredential();
services.AddControllers();
}
- 添加IdentityServer4到請求管道
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseHttpsRedirection();
app.UseRouting();
app.UseIdentityServer();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
創建一個ServiceA
我們將在ServiceA中提供一個簡單服務:爲一個用戶打一個標籤
[Route("[controller]")]
[ApiController]
public class UserController : ControllerBase
{
[HttpPost]
[Route("tag/create")]
public IActionResult CreateTag([FromForm]int userId, [FromForm]string value)
{
// 假設數據庫記錄添加成功,直接返回對象
Tag tagEntity = new Tag();
tagEntity.Id = 1;
tagEntity.UserId = userId;
tagEntity.Value = value;
return Ok(tagEntity);
}
}
public class Tag
{
public int Id { get; set; }
public int UserId { get; set; }
public string Value { get; set; }
}
終章
支持我們三個項目已經建立完成,但要通過網關經身份認證服務請求到創建標籤的服務,我們還需要對網關服務做一些修改。
首先,在ocelot.json新增AuthenticationOptions
配置IdentityServer4身份認證服務中對應的資源
{
"ReRoutes": [
{
"DownstreamPathTemplate": "/{url}",
"DownstreamScheme": "http",
"DownstreamHostAndPorts": [
{
"Host": "localhost",
"Port": 5201
}
],
"UpstreamPathTemplate": "/service-a/{url}",
"UpstreamHttpMethod": [ "Get", "Post" ],
"AuthenticationOptions": {
"AuthenticationProviderKey": "SampleKey",
"AllowedScopes": [ "gateway_api" ]
}
}
],
"GlobalConfiguration": {
"BaseUrl": "http://localhost"
}
}
其中http://localhost:5201
是我們ServiceA運行的地址
然後我們需要注入認證服務到容器
Install-Package IdentityServer4.AccessTokenValidation -Version 3.0.1
public void ConfigureServices(IServiceCollection services)
{
var authenticationProviderKey = "SampleKey";
Action<IdentityServerAuthenticationOptions> options = o =>
{
o.Authority = "http://localhost:5200";
o.ApiName = "gateway_api";
o.SupportedTokens = SupportedTokens.Both;
o.ApiSecret = "123456";
o.RequireHttpsMetadata = false;
};
services.AddAuthentication()
.AddIdentityServerAuthentication(authenticationProviderKey, options);
services.AddOcelot();
}
其中http://localhost:5200
是我們認證服務運行的地址
-
通過網關直接調用
我們發現返回401未授權,這是正常的,因爲我們爲網關服務添加了認證服務。 -
通過token訪問
我們首先要去拿token
,我們現在暫時先通過postman直接獲取token
通過token訪問
我們可以看到已經成功請求到了創建用戶標籤接口