Browse Source

Merge pull request #1034 from colinin/api-sign-from-header

feat(open-api): api signature is passed from the request header
pull/1043/head
yx lin 1 year ago
committed by GitHub
parent
commit
913fa7ae3e
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 27
      aspnet-core/framework/open-api/LINGYUN.Abp.OpenApi.Authorization/LINGYUN/Abp/OpenApi/Authorization/OpenApiAuthorizationService.cs
  2. 8
      aspnet-core/framework/open-api/LINGYUN.Abp.OpenApi/LINGYUN/Abp/OpenApi/AbpOpenApiConsts.cs
  3. 7
      gateways/internal/LINGYUN.MicroService.Internal.ApiGateway/src/LINGYUN.MicroService.OpenApi.Gateway/GobalUsings.cs
  4. 2
      gateways/internal/LINGYUN.MicroService.Internal.ApiGateway/src/LINGYUN.MicroService.OpenApi.Gateway/LINGYUN.MicroService.OpenApi.Gateway.csproj
  5. 8
      gateways/internal/LINGYUN.MicroService.Internal.ApiGateway/src/LINGYUN.MicroService.OpenApi.Gateway/OpenApiGatewayModule.cs
  6. 31
      gateways/internal/LINGYUN.MicroService.Internal.ApiGateway/src/LINGYUN.MicroService.OpenApi.Gateway/Program.cs
  7. 4
      gateways/internal/LINGYUN.MicroService.Internal.ApiGateway/src/LINGYUN.MicroService.OpenApi.Gateway/Properties/launchSettings.json
  8. 2
      gateways/internal/LINGYUN.MicroService.Internal.ApiGateway/src/LINGYUN.MicroService.OpenApi.Gateway/appsettings.Development.json
  9. 433
      gateways/internal/LINGYUN.MicroService.Internal.ApiGateway/src/LINGYUN.MicroService.OpenApi.Gateway/yarp.json

27
aspnet-core/framework/open-api/LINGYUN.Abp.OpenApi.Authorization/LINGYUN/Abp/OpenApi/Authorization/OpenApiAuthorizationService.cs

@ -84,18 +84,18 @@ namespace LINGYUN.Abp.OpenApi.Authorization
protected async virtual Task<bool> ValidatAppDescriptor(HttpContext httpContext) protected async virtual Task<bool> ValidatAppDescriptor(HttpContext httpContext)
{ {
httpContext.Request.Headers.TryGetValue(AbpOpenApiConsts.AppKeyFieldName, out var appKey); httpContext.Request.Headers.TryGetValue(AbpOpenApiConsts.HEADER_APP_KEY, out var appKey);
httpContext.Request.Headers.TryGetValue(AbpOpenApiConsts.SignatureFieldName, out var sign); httpContext.Request.Headers.TryGetValue(AbpOpenApiConsts.HEADER_SIGNATURE, out var sign);
httpContext.Request.Headers.TryGetValue(AbpOpenApiConsts.NonceFieldName, out var nonce); httpContext.Request.Headers.TryGetValue(AbpOpenApiConsts.HEADER_NONCE, out var nonce);
httpContext.Request.Headers.TryGetValue(AbpOpenApiConsts.TimeStampFieldName, out var timeStampString); httpContext.Request.Headers.TryGetValue(AbpOpenApiConsts.HEADER_TIMESTAMP, out var timeStampString);
if (StringValues.IsNullOrEmpty(appKey)) if (StringValues.IsNullOrEmpty(appKey))
{ {
var exception = new BusinessException( var exception = new BusinessException(
AbpOpenApiConsts.InvalidAccessWithAppKeyNotFound, AbpOpenApiConsts.InvalidAccessWithAppKeyNotFound,
$"{AbpOpenApiConsts.AppKeyFieldName} Not Found", $"{AbpOpenApiConsts.HEADER_APP_KEY} Not Found",
$"{AbpOpenApiConsts.AppKeyFieldName} Not Found"); $"{AbpOpenApiConsts.HEADER_APP_KEY} Not Found");
await Unauthorized(httpContext, exception); await Unauthorized(httpContext, exception);
return false; return false;
} }
@ -104,8 +104,8 @@ namespace LINGYUN.Abp.OpenApi.Authorization
{ {
var exception = new BusinessException( var exception = new BusinessException(
AbpOpenApiConsts.InvalidAccessWithNonceNotFound, AbpOpenApiConsts.InvalidAccessWithNonceNotFound,
$"{AbpOpenApiConsts.NonceFieldName} Not Found", $"{AbpOpenApiConsts.HEADER_NONCE} Not Found",
$"{AbpOpenApiConsts.NonceFieldName} Not Found"); $"{AbpOpenApiConsts.HEADER_NONCE} Not Found");
await Unauthorized(httpContext, exception); await Unauthorized(httpContext, exception);
return false; return false;
@ -115,8 +115,8 @@ namespace LINGYUN.Abp.OpenApi.Authorization
{ {
var exception = new BusinessException( var exception = new BusinessException(
AbpOpenApiConsts.InvalidAccessWithSignNotFound, AbpOpenApiConsts.InvalidAccessWithSignNotFound,
$"{AbpOpenApiConsts.SignatureFieldName} Not Found", $"{AbpOpenApiConsts.HEADER_SIGNATURE} Not Found",
$"{AbpOpenApiConsts.SignatureFieldName} Not Found"); $"{AbpOpenApiConsts.HEADER_SIGNATURE} Not Found");
await Unauthorized(httpContext, exception); await Unauthorized(httpContext, exception);
return false; return false;
@ -126,8 +126,8 @@ namespace LINGYUN.Abp.OpenApi.Authorization
{ {
var exception = new BusinessException( var exception = new BusinessException(
AbpOpenApiConsts.InvalidAccessWithTimestampNotFound, AbpOpenApiConsts.InvalidAccessWithTimestampNotFound,
$"{AbpOpenApiConsts.TimeStampFieldName} Not Found", $"{AbpOpenApiConsts.HEADER_TIMESTAMP} Not Found",
$"{AbpOpenApiConsts.TimeStampFieldName} Not Found"); $"{AbpOpenApiConsts.HEADER_TIMESTAMP} Not Found");
await Unauthorized(httpContext, exception); await Unauthorized(httpContext, exception);
return false; return false;
@ -264,7 +264,8 @@ namespace LINGYUN.Abp.OpenApi.Authorization
private static string CalculationSignature(string url, IDictionary<string, string> queryDictionary) private static string CalculationSignature(string url, IDictionary<string, string> queryDictionary)
{ {
var queryString = BuildQuery(queryDictionary); var queryString = BuildQuery(queryDictionary);
var encodeUrl = UrlEncode(string.Concat(url, "?", queryString)); // %20 替换 +
var encodeUrl = UrlEncode(string.Concat(url, "?", queryString)).Replace("+", "%20");
return encodeUrl.ToMd5(); return encodeUrl.ToMd5();
} }

8
aspnet-core/framework/open-api/LINGYUN.Abp.OpenApi/LINGYUN/Abp/OpenApi/AbpOpenApiConsts.cs

@ -4,10 +4,10 @@ public static class AbpOpenApiConsts
{ {
public const string SecurityChecking = "_AbpOpenApiSecurityChecking"; public const string SecurityChecking = "_AbpOpenApiSecurityChecking";
public const string AppKeyFieldName = "X-API-APPKEY"; public const string HEADER_APP_KEY = "X-API-APPKEY";
public const string SignatureFieldName = "X-API-SIGN"; public const string HEADER_SIGNATURE = "X-API-SIGN";
public const string NonceFieldName = "X-API-NONCE"; public const string HEADER_NONCE = "X-API-NONCE";
public const string TimeStampFieldName = "X-API-TIMESTAMP"; public const string HEADER_TIMESTAMP = "X-API-TIMESTAMP";
public const string KeyPrefix = "AbpOpenApi"; public const string KeyPrefix = "AbpOpenApi";
/// <summary> /// <summary>

7
gateways/internal/LINGYUN.MicroService.Internal.ApiGateway/src/LINGYUN.MicroService.OpenApi.Gateway/GobalUsings.cs

@ -0,0 +1,7 @@
global using LINGYUN.MicroService.OpenApi.Gateway;
global using Microsoft.AspNetCore.Builder;
global using Microsoft.AspNetCore.Hosting;
global using Microsoft.Extensions.DependencyInjection;
global using Microsoft.Extensions.Hosting;
global using Serilog;
global using System;

2
gateways/internal/LINGYUN.MicroService.Internal.ApiGateway/src/LINGYUN.MicroService.OpenApi.Gateway/LINGYUN.MicroService.OpenApi.Gateway.csproj

@ -4,6 +4,8 @@
<OutputType>Exe</OutputType> <OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework> <TargetFramework>net8.0</TargetFramework>
<RootNamespace>LINGYUN.MicroService.Internal.Gateway</RootNamespace> <RootNamespace>LINGYUN.MicroService.Internal.Gateway</RootNamespace>
<Language>latest</Language>
<ImplicitUsings >enable</ImplicitUsings >
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>

8
gateways/internal/LINGYUN.MicroService.Internal.ApiGateway/src/LINGYUN.MicroService.OpenApi.Gateway/OpenApiGatewayModule.cs

@ -5,20 +5,12 @@ using LINGYUN.Abp.Serilog.Enrichers.Application;
using LINGYUN.Abp.Serilog.Enrichers.UniqueId; using LINGYUN.Abp.Serilog.Enrichers.UniqueId;
using LINGYUN.Abp.Wrapper; using LINGYUN.Abp.Wrapper;
using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Cors; using Microsoft.AspNetCore.Cors;
using Microsoft.AspNetCore.DataProtection; using Microsoft.AspNetCore.DataProtection;
using Microsoft.AspNetCore.WebSockets; using Microsoft.AspNetCore.WebSockets;
using Microsoft.Extensions.Caching.StackExchangeRedis; using Microsoft.Extensions.Caching.StackExchangeRedis;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.OpenApi.Models; using Microsoft.OpenApi.Models;
using StackExchange.Redis; using StackExchange.Redis;
using System;
using System.Collections.Generic;
using System.Linq;
using Volo.Abp; using Volo.Abp;
using Volo.Abp.AspNetCore.Mvc; using Volo.Abp.AspNetCore.Mvc;
using Volo.Abp.AspNetCore.Mvc.ApiExploring; using Volo.Abp.AspNetCore.Mvc.ApiExploring;

31
gateways/internal/LINGYUN.MicroService.Internal.ApiGateway/src/LINGYUN.MicroService.OpenApi.Gateway/Program.cs

@ -1,20 +1,5 @@
using Microsoft.AspNetCore.Builder; try
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Serilog;
using System;
using System.Threading.Tasks;
namespace LINGYUN.MicroService.OpenApi.Gateway;
public class Program
{ {
public static async Task<int> Main(string[] args)
{
try
{
Log.Information("Starting OpenApi ApiGateway."); Log.Information("Starting OpenApi ApiGateway.");
var builder = WebApplication.CreateBuilder(args); var builder = WebApplication.CreateBuilder(args);
builder.Host.AddAppSettingsSecretsJson() builder.Host.AddAppSettingsSecretsJson()
@ -45,15 +30,13 @@ public class Program
await app.RunAsync(); await app.RunAsync();
return 0; return 0;
} }
catch (Exception ex) catch (Exception ex)
{ {
Log.Fatal(ex, "Starting OpenApi ApiGateway terminated unexpectedly!"); Log.Fatal(ex, "Starting OpenApi ApiGateway terminated unexpectedly!");
return 1; return 1;
} }
finally finally
{ {
Log.CloseAndFlush(); Log.CloseAndFlush();
}
}
} }

4
gateways/internal/LINGYUN.MicroService.Internal.ApiGateway/src/LINGYUN.MicroService.OpenApi.Gateway/Properties/launchSettings.json

@ -5,9 +5,9 @@
"launchBrowser": false, "launchBrowser": false,
"dotnetRunMessages": true, "dotnetRunMessages": true,
"environmentVariables": { "environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development" "ASPNETCORE_ENVIRONMENT": "Production"
}, },
"applicationUrl": "http://localhost:30000" "applicationUrl": "http://0.0.0.0:30000"
} }
} }
} }

2
gateways/internal/LINGYUN.MicroService.Internal.ApiGateway/src/LINGYUN.MicroService.OpenApi.Gateway/appsettings.Development.json

@ -9,7 +9,7 @@
"tag": "BackendAdmin" "tag": "BackendAdmin"
}, },
"App": { "App": {
"CorsOrigins": "http://127.0.0.1:3100", "CorsOrigins": "http://127.0.0.1:3100,http://localhost:9010",
"ShowPii": true "ShowPii": true
}, },
"ConnectionStrings": { "ConnectionStrings": {

433
gateways/internal/LINGYUN.MicroService.Internal.ApiGateway/src/LINGYUN.MicroService.OpenApi.Gateway/yarp.json

@ -1,434 +1,3 @@
{ {
"ReverseProxy": { "ReverseProxy": {}
"Routes": {
"abp-route": {
"ClusterId": "admin-api-cluster",
"Match": {
"Path": "/api/abp/{**everything}"
},
"Transforms": [
{
"HeaderPrefix": "X-Forwarded-",
"X-Forwarded": "Append"
},
{
"ResponseHeadersAllowed": "_AbpWrapResult;_AbpDontWrapResult;_AbpErrorFormat"
}
]
},
"auth-server-route": {
"ClusterId": "auth-server-cluster",
"Match": {
"Path": "/connect/{**everything}"
},
"Transforms": [
{
"HeaderPrefix": "X-Forwarded-",
"X-Forwarded": "Append"
},
{
"ResponseHeadersAllowed": "_AbpWrapResult;_AbpDontWrapResult;_AbpErrorFormat"
}
]
},
"account-route": {
"ClusterId": "auth-server-api-cluster",
"Match": {
"Path": "/api/account/{**everything}"
},
"Transforms": [
{
"HeaderPrefix": "X-Forwarded-",
"X-Forwarded": "Append"
},
{
"ResponseHeadersAllowed": "_AbpWrapResult;_AbpDontWrapResult;_AbpErrorFormat"
}
]
},
"identity-route": {
"ClusterId": "auth-server-api-cluster",
"Match": {
"Path": "/api/identity/{**everything}"
},
"Transforms": [
{
"HeaderPrefix": "X-Forwarded-",
"X-Forwarded": "Append"
},
{
"ResponseHeadersAllowed": "_AbpWrapResult;_AbpDontWrapResult;_AbpErrorFormat"
}
]
},
"identity-server-route": {
"ClusterId": "auth-server-api-cluster",
"Match": {
"Path": "/api/identity-server/{**everything}"
},
"Transforms": [
{
"HeaderPrefix": "X-Forwarded-",
"X-Forwarded": "Append"
},
{
"ResponseHeadersAllowed": "_AbpWrapResult;_AbpDontWrapResult;_AbpErrorFormat"
}
]
},
"cache-management-route": {
"ClusterId": "admin-api-cluster",
"Match": {
"Path": "/api/caching-management/{**everything}"
},
"Transforms": [
{
"HeaderPrefix": "X-Forwarded-",
"X-Forwarded": "Append"
},
{
"ResponseHeadersAllowed": "_AbpWrapResult;_AbpDontWrapResult;_AbpErrorFormat"
}
]
},
"saas-route": {
"ClusterId": "admin-api-cluster",
"Match": {
"Path": "/api/saas/{**everything}"
},
"Transforms": [
{
"HeaderPrefix": "X-Forwarded-",
"X-Forwarded": "Append"
},
{
"ResponseHeadersAllowed": "_AbpWrapResult;_AbpDontWrapResult;_AbpErrorFormat"
}
]
},
"auditing-route": {
"ClusterId": "admin-api-cluster",
"Match": {
"Path": "/api/auditing/{**everything}"
},
"Transforms": [
{
"HeaderPrefix": "X-Forwarded-",
"X-Forwarded": "Append"
},
{
"ResponseHeadersAllowed": "_AbpWrapResult;_AbpDontWrapResult;_AbpErrorFormat"
}
]
},
"data-protected-route": {
"ClusterId": "admin-api-cluster",
"Match": {
"Path": "/api/data-protection-management/{**everything}"
},
"Transforms": [
{
"HeaderPrefix": "X-Forwarded-",
"X-Forwarded": "Append"
},
{
"ResponseHeadersAllowed": "_AbpWrapResult;_AbpDontWrapResult;_AbpErrorFormat"
}
]
},
"text-template-route": {
"ClusterId": "admin-api-cluster",
"Match": {
"Path": "/api/text-templating/{**everything}"
},
"Transforms": [
{
"HeaderPrefix": "X-Forwarded-",
"X-Forwarded": "Append"
},
{
"ResponseHeadersAllowed": "_AbpWrapResult;_AbpDontWrapResult;_AbpErrorFormat"
}
]
},
"feature-management-route": {
"ClusterId": "admin-api-cluster",
"Match": {
"Path": "/api/feature-management/{**everything}"
},
"Transforms": [
{
"HeaderPrefix": "X-Forwarded-",
"X-Forwarded": "Append"
},
{
"ResponseHeadersAllowed": "_AbpWrapResult;_AbpDontWrapResult;_AbpErrorFormat"
}
]
},
"permission-management-route": {
"ClusterId": "admin-api-cluster",
"Match": {
"Path": "/api/permission-management/{**everything}"
},
"Transforms": [
{
"HeaderPrefix": "X-Forwarded-",
"X-Forwarded": "Append"
},
{
"ResponseHeadersAllowed": "_AbpWrapResult;_AbpDontWrapResult;_AbpErrorFormat"
}
]
},
"setting-management-route": {
"ClusterId": "admin-api-cluster",
"Match": {
"Path": "/api/setting-management/{**everything}"
},
"Transforms": [
{
"HeaderPrefix": "X-Forwarded-",
"X-Forwarded": "Append"
},
{
"ResponseHeadersAllowed": "_AbpWrapResult;_AbpDontWrapResult;_AbpErrorFormat"
}
]
},
"localization-management-route": {
"ClusterId": "localization-api-cluster",
"Match": {
"Path": "/api/localization/{**everything}"
},
"Transforms": [
{
"HeaderPrefix": "X-Forwarded-",
"X-Forwarded": "Append"
},
{
"ResponseHeadersAllowed": "_AbpWrapResult;_AbpDontWrapResult;_AbpErrorFormat"
}
]
},
"im-route": {
"ClusterId": "messages-api-cluster",
"Match": {
"Path": "/api/im/{**everything}"
},
"Transforms": [
{
"HeaderPrefix": "X-Forwarded-",
"X-Forwarded": "Append"
},
{
"ResponseHeadersAllowed": "_AbpWrapResult;_AbpDontWrapResult;_AbpErrorFormat"
}
]
},
"notifications-route": {
"ClusterId": "messages-api-cluster",
"Match": {
"Path": "/api/notifications/{**everything}"
},
"Transforms": [
{
"HeaderPrefix": "X-Forwarded-",
"X-Forwarded": "Append"
},
{
"ResponseHeadersAllowed": "_AbpWrapResult;_AbpDontWrapResult;_AbpErrorFormat"
}
]
},
"signalr-route": {
"ClusterId": "messages-api-cluster",
"Match": {
"Path": "/signalr-hubs/{**everything}"
},
"Transforms": [
{
"HeaderPrefix": "X-Forwarded-",
"X-Forwarded": "Append"
},
{
"ResponseHeadersAllowed": "_AbpWrapResult;_AbpDontWrapResult;_AbpErrorFormat"
},
{
"RequestHeadersCopy": true
},
{
"ResponseHeadersCopy": true
}
]
},
"webhooks-management-route": {
"ClusterId": "webhooks-api-cluster",
"Match": {
"Path": "/api/webhooks/{**everything}"
},
"Transforms": [
{
"HeaderPrefix": "X-Forwarded-",
"X-Forwarded": "Append"
},
{
"ResponseHeadersAllowed": "_AbpWrapResult;_AbpDontWrapResult;_AbpErrorFormat"
}
]
},
"task-management-route": {
"ClusterId": "tasks-api-cluster",
"Match": {
"Path": "/api/task-management/{**everything}"
},
"Transforms": [
{
"HeaderPrefix": "X-Forwarded-",
"X-Forwarded": "Append"
},
{
"ResponseHeadersAllowed": "_AbpWrapResult;_AbpDontWrapResult;_AbpErrorFormat"
}
]
},
"platform-route": {
"ClusterId": "platform-api-cluster",
"Match": {
"Path": "/api/platform/{**everything}"
},
"Transforms": [
{
"HeaderPrefix": "X-Forwarded-",
"X-Forwarded": "Append"
},
{
"ResponseHeadersAllowed": "_AbpWrapResult;_AbpDontWrapResult;_AbpErrorFormat"
}
]
},
"oss-route": {
"ClusterId": "platform-api-cluster",
"Match": {
"Path": "/api/oss-management/{**everything}"
},
"Transforms": [
{
"HeaderPrefix": "X-Forwarded-",
"X-Forwarded": "Append"
},
{
"ResponseHeadersAllowed": "_AbpWrapResult;_AbpDontWrapResult;_AbpErrorFormat"
}
]
},
"files-route": {
"ClusterId": "platform-api-cluster",
"Match": {
"Path": "/api/files/{**everything}"
},
"Transforms": [
{
"HeaderPrefix": "X-Forwarded-",
"X-Forwarded": "Append"
},
{
"ResponseHeadersAllowed": "_AbpWrapResult;_AbpDontWrapResult;_AbpErrorFormat"
}
]
}
},
"Clusters": {
"auth-server-cluster": {
"Destinations": {
"destination1": {
"Address": "http://auth-server:44385",
"Metadata": {
"SwaggerEndpoint": "http://127.0.0.1:44385"
}
}
}
},
"auth-server-api-cluster": {
"Destinations": {
"destination1": {
"Address": "http://auth-server-api:30015",
"Metadata": {
"SwaggerEndpoint": "http://127.0.0.1:30015"
}
}
}
},
"admin-api-cluster": {
"Destinations": {
"destination1": {
"Address": "http://admin-api:30010",
"Metadata": {
"SwaggerEndpoint": "http://127.0.0.1:30010"
}
}
}
},
"localization-api-cluster": {
"Destinations": {
"destination1": {
"Address": "http://localization-api:30030",
"Metadata": {
"SwaggerEndpoint": "http://127.0.0.1:30030"
}
}
}
},
"messages-api-cluster": {
"Destinations": {
"destination1": {
"Address": "http://messages-api:30020",
"Metadata": {
"SwaggerEndpoint": "http://127.0.0.1:30020"
}
}
}
},
"webhooks-api-cluster": {
"Destinations": {
"destination1": {
"Address": "http://webhooks-api:30045",
"Metadata": {
"SwaggerEndpoint": "http://127.0.0.1:30045"
}
}
}
},
"tasks-api-cluster": {
"Destinations": {
"destination1": {
"Address": "http://tasks-api:30040",
"Metadata": {
"SwaggerEndpoint": "http://127.0.0.1:30040"
}
}
}
},
"platform-api-cluster": {
"Destinations": {
"destination1": {
"Address": "http://platform-api:30025",
"Metadata": {
"SwaggerEndpoint": "http://127.0.0.1:30025"
}
}
}
},
"workflow-api-cluster": {
"Destinations": {
"destination1": {
"Address": "http://workflow-api:30050",
"Metadata": {
"SwaggerEndpoint": "http://127.0.0.1:30050"
}
}
}
}
}
}
} }
Loading…
Cancel
Save