如何将 OAuth 与 Swagger 和 NSwagStudio 结合使用
How to use OAuth with Swagger and NSwagStudio
我正在尝试为 API 生成一个 C# 客户端,它向我提供了一个 swagger.json 文件,位于 link;
https://api.ekm.net/swagger/v1/swagger.json
使用 NSwagStudo 应用程序,我能够导入配置文件并生成一个名为 Client.cs 的文件,该文件实现了一个名为 Client 的 class,它具有与 [=31= 匹配的方法].
然而,当我调用任何方法时,我得到一个 "Unauthorized" 异常,我找不到任何方法来向客户端或任何使用其他身份验证方法进行类似操作的人提供 OAuth 密钥和密码。
检查 swagger 配置文件确实表明 OAuth 被指定为身份验证方法,如下所示;
"securityDefinitions": {
"OAuth": {
"flow": "accessCode",
"authorizationUrl": "https://api.ekm.net/connect/authorize",
"tokenUrl": "https://api.ekm.net/connect/token",
"scopes": {
"tempest.customers.read": "Read a shop's customers.",
"tempest.customers.write": "Modify a shop's customers.",
"tempest.orders.read": "Read a shops orders.",
"tempest.orders.write": "Modify a shop's orders.",
"tempest.products.read": "Read a shop's products.",
"tempest.products.write": "Modify a shop's products.",
"tempest.categories.read": "Read a shop's categories.",
"tempest.categories.write": "Modify a shop's categories.",
"tempest.settings.orderstatuses.read": "Read a shop's order statuses.",
"tempest.settings.domains.read": "Read a shop's domains."
},
"type": "oauth2",
"description": "In order to ensure the safety of our users data, we require all partner applications to register via the [Partner Dashboard](https://partners.ekm.net/). Once registered, partners are provided with an application key, which can be used during an OAuth2 handshake to create a token. This token can then used to make requests on behalf of a merchant."
}
},
我的测试代码如下;
static void Main(string[] args)
{
var swagClient = new Client();
var ords = swagClient.ApiV1OrdersGetAsync(1, 100).Result; // This call throws SwaggerException: Unauthorized
}
Client
class 没有任何明显的方法或属性来设置安全值或任何构造函数参数。
有没有人举例说明如何实现这一点?
我同意。奇怪的是它不只是接受某种 "insert JWT here".
无论如何,我是这样修复它的:
注入 HttpClient
在 NSwagStudio
中勾选名为 "Inject HttpClient via constructor" 的方框
自定义消息处理程序
引入自定义HttpMessageHandler
:
internal class AuthTokenHttpMessageHandler: HttpClientHandler
{
private readonly Action<HttpRequestMessage, CancellationToken> _processRequest;
public AuthTokenHttpMessageHandler(Action<HttpRequestMessage, CancellationToken> processRequest)
{
_processRequest = processRequest;
}
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
_processRequest(request, cancellationToken);
return base.SendAsync(request, cancellationToken);
}
}
此处理程序接受一个委托,您可以在其中提供您的 JWT。
与您的客户集成
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
public class MyService : IDisposable
{
private readonly AuthTokenHttpMessageHandler _messageHandler;
private readonly HttpClient _httpClient;
private readonly MyNSwagClient _client;
public MyService()
{
_messageHandler = new AuthTokenHttpMessageHandler((req, _) =>
{
req.Headers.Authorization = new AuthenticationHeaderValue("bearer", "your token goes here");
});
_httpClient = new HttpClient(_messageHandler);
_client = new MyNSwagClient(_httpClient);
}
public async Task<SomeModel> GetStuffAsync(string paramenter1)
{
return await _client.StuffGetAsync(parameter1);
}
public void Dispose()
{
_httpClient?.Dispose();
_messageHandler?.Dispose();
}
}
希望对你有帮助
我正在尝试为 API 生成一个 C# 客户端,它向我提供了一个 swagger.json 文件,位于 link;
https://api.ekm.net/swagger/v1/swagger.json
使用 NSwagStudo 应用程序,我能够导入配置文件并生成一个名为 Client.cs 的文件,该文件实现了一个名为 Client 的 class,它具有与 [=31= 匹配的方法].
然而,当我调用任何方法时,我得到一个 "Unauthorized" 异常,我找不到任何方法来向客户端或任何使用其他身份验证方法进行类似操作的人提供 OAuth 密钥和密码。
检查 swagger 配置文件确实表明 OAuth 被指定为身份验证方法,如下所示;
"securityDefinitions": {
"OAuth": {
"flow": "accessCode",
"authorizationUrl": "https://api.ekm.net/connect/authorize",
"tokenUrl": "https://api.ekm.net/connect/token",
"scopes": {
"tempest.customers.read": "Read a shop's customers.",
"tempest.customers.write": "Modify a shop's customers.",
"tempest.orders.read": "Read a shops orders.",
"tempest.orders.write": "Modify a shop's orders.",
"tempest.products.read": "Read a shop's products.",
"tempest.products.write": "Modify a shop's products.",
"tempest.categories.read": "Read a shop's categories.",
"tempest.categories.write": "Modify a shop's categories.",
"tempest.settings.orderstatuses.read": "Read a shop's order statuses.",
"tempest.settings.domains.read": "Read a shop's domains."
},
"type": "oauth2",
"description": "In order to ensure the safety of our users data, we require all partner applications to register via the [Partner Dashboard](https://partners.ekm.net/). Once registered, partners are provided with an application key, which can be used during an OAuth2 handshake to create a token. This token can then used to make requests on behalf of a merchant."
}
},
我的测试代码如下;
static void Main(string[] args)
{
var swagClient = new Client();
var ords = swagClient.ApiV1OrdersGetAsync(1, 100).Result; // This call throws SwaggerException: Unauthorized
}
Client
class 没有任何明显的方法或属性来设置安全值或任何构造函数参数。
有没有人举例说明如何实现这一点?
我同意。奇怪的是它不只是接受某种 "insert JWT here".
无论如何,我是这样修复它的:
注入 HttpClient
在 NSwagStudio
中勾选名为 "Inject HttpClient via constructor" 的方框自定义消息处理程序
引入自定义HttpMessageHandler
:
internal class AuthTokenHttpMessageHandler: HttpClientHandler
{
private readonly Action<HttpRequestMessage, CancellationToken> _processRequest;
public AuthTokenHttpMessageHandler(Action<HttpRequestMessage, CancellationToken> processRequest)
{
_processRequest = processRequest;
}
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
_processRequest(request, cancellationToken);
return base.SendAsync(request, cancellationToken);
}
}
此处理程序接受一个委托,您可以在其中提供您的 JWT。
与您的客户集成
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
public class MyService : IDisposable
{
private readonly AuthTokenHttpMessageHandler _messageHandler;
private readonly HttpClient _httpClient;
private readonly MyNSwagClient _client;
public MyService()
{
_messageHandler = new AuthTokenHttpMessageHandler((req, _) =>
{
req.Headers.Authorization = new AuthenticationHeaderValue("bearer", "your token goes here");
});
_httpClient = new HttpClient(_messageHandler);
_client = new MyNSwagClient(_httpClient);
}
public async Task<SomeModel> GetStuffAsync(string paramenter1)
{
return await _client.StuffGetAsync(parameter1);
}
public void Dispose()
{
_httpClient?.Dispose();
_messageHandler?.Dispose();
}
}
希望对你有帮助