如何将OAuth与Swagger和NSwagStudio一起使用

如何将OAuth与Swagger和NSwagStudio一起使用,swagger,nswag,Swagger,Nswag,我正试图为一个API生成一个C#客户端,该API向我提供了一个swagger.json文件,位于此链接 https://api.ekm.net/swagger/v1/swagger.json 使用NSwagStudo应用程序,我能够导入配置文件并生成一个名为Client.cs的文件,该文件实现了一个名为Client的类,该类上有与API匹配的方法 然而,当我调用任何一种方法时,我会得到一个“未经授权”的异常,我无法找到任何方法向客户机或任何使用其他身份验证方法进行类似操作的人提供OAuth密钥

我正试图为一个API生成一个C#客户端,该API向我提供了一个swagger.json文件,位于此链接

https://api.ekm.net/swagger/v1/swagger.json
使用NSwagStudo应用程序,我能够导入配置文件并生成一个名为Client.cs的文件,该文件实现了一个名为Client的类,该类上有与API匹配的方法

然而,当我调用任何一种方法时,我会得到一个“未经授权”的异常,我无法找到任何方法向客户机或任何使用其他身份验证方法进行类似操作的人提供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
}
我的测试代码如下

"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
}
客户端
类没有任何明显的方法或属性来设置安全值或任何构造函数参数


有人举过如何实现这一目标的例子吗?

我同意。奇怪的是,它不只是接受某种形式的“在这里插入JWT”

不管怎样,我就是这样修复的:

注入HttpClient 勾选NSwagStudio中名为“通过构造函数注入HttpClient”的框

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);
    }
}
内部类AuthTokenHttpMessageHandler:HttpClientHandler
{
私有只读操作processRequest;
公共AuthTokenHttpMessageHandler(操作processRequest)
{
_processRequest=processRequest;
}
受保护的覆盖任务SendAsync(HttpRequestMessage请求,CancellationToken CancellationToken)
{
_processRequest(请求、取消令牌);
返回base.sendaync(请求、取消令牌);
}
}
此处理程序接受一个委托,您可以在其中提供JWT

与客户整合
使用System.Net.Http;
使用System.Net.Http.Header;
使用System.Threading.Tasks;
公共类MyService:IDisposable
{
私有只读AuthTokenHttpMessageHandler _messageHandler;
私有只读HttpClientu HttpClient;
私有只读MyNSwagClient\u客户端;
公共MyService()
{
_messageHandler=新的AuthTokenHttpMessageHandler((req,))=>
{
req.Headers.Authorization=新的AuthenticationHeaderValue(“承载人”,“您的令牌在这里”);
});
_httpClient=新的httpClient(_messageHandler);
_client=新的MyNSwagClient(_httpClient);
}
公共异步任务GetStuffAsync(字符串参数1)
{
返回wait_client.StuffGetAsync(参数1);
}
公共空间处置()
{
_httpClient?.Dispose();
_messageHandler?.Dispose();
}
}
我希望这对你有帮助