Как использовать OAuth с Swagger и NSwagStudio - PullRequest
0 голосов
/ 29 августа 2018

Я пытаюсь сгенерировать клиент C # для API, который предоставил мне файл swagger.json, расположенный по этой ссылке;

https://api.ekm.net/swagger/v1/swagger.json

Используя приложение NSwagStudo, я могу импортировать файл конфигурации и сгенерировать файл с именем Client.cs, который реализует класс с именем Client, и в нем есть методы, соответствующие API.

Однако, когда я вызываю какой-либо из методов, я получаю исключение «Несанкционировано» и не могу найти способ предоставить ключ и секретный ключ OAuth клиенту или любому, кто делает аналогичные с другими методами аутентификации.

Проверка файлов конфигурации сваггера показывает, что 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 не имеет каких-либо очевидных методов или свойств для установки значений безопасности или каких-либо параметров конструктора.

У кого-нибудь есть пример, как этого добиться?

1 Ответ

0 голосов
/ 12 ноября 2018

Я согласен. Странно, что он не просто принимает "вставить сюда JWT".

Во всяком случае, вот как я это исправил:

Внедрить HttpClient

Установите флажок «Ввести HttpClient через конструктор» в NSwagStudio

CustomMessageHandler

Введите пользовательский 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();
    }
}

Надеюсь, это поможет вам

...