SwashBuckle/Swagger-OAuth资源所有者密码流 [英] SwashBuckle/Swagger - OAuth Resource Owner Password Flow

查看:113
本文介绍了SwashBuckle/Swagger-OAuth资源所有者密码流的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正试图在我的Asp.Net Web API中实现大张旗鼓,但是我遇到了问题.

I'm trying to implement swagger into my Asp.Net Web API, and i'm running into a problem.

我正在使用密码资源所有者流,并且我必须添加一个解决方案来做到这一点,以下堆栈溢出问题对此进行了介绍:-

I'm using the password resource owner flow, and i'm having to add a work around in order to do this, which is covered in the following stack overflow question :-

Swagger/Swashbuckle:具有资源所有者密码凭据授予的OAuth2

一切正常,将Bearer令牌通过javascript添加到当前浏览器窗口中的请求标头中,但是对需要授权的控制器方法的api调用仍然返回"401-授权失败".

I've got everything working, the Bearer token is added via javascript to the request header in the current browser window, but the api calls to the controller methods requiring authorization are still return "401 - Authorization Failed".

这是获取承载令牌并添加标头的JavaScript:-

Here is the JavaScript that gets the bearer token and adds the header :-

 $('#input_apiKey').change(function () {
    var key = $('#input_apiKey')[0].value;
    var credentials = key.split(':'); //username:password expected
    $.ajax({
        url: "http://localhost:42291/token",
        type: "post",
        contenttype: 'x-www-form-urlencoded',
        data: "grant_type=password&username=" + credentials[0] + "&password=" + credentials[1],
        success: function (response) {
            var bearerToken = 'Bearer ' + response.access_token;

            window.swaggerUi.api.clientAuthorizations.add('Authorization', new window.SwaggerClient.ApiKeyAuthorization('Authorization', bearerToken, 'header'));
            window.swaggerUi.api.clientAuthorizations.remove('api_key');

            alert("Login Succesfull!");
        },
        error: function (xhr, ajaxoptions, thrownerror) {
            alert("Login failed!");
        }
    });
}); 

Swagger响应中的Curl为:-

The Curl in the response in Swagger is :-

curl -X GET --header接受:application/json" --header 授权:不记名 NqlSG-WyTx2zkYE8xFklGyZWlQDZdsCKZBHruEXvX47N7PAzw4-jZ4eH5D0yFzQTXj13RwKFFt1rUZt2fzWj1vR5UR87wdlKC3YvsTojYV4-3DsWwY7qYRfiKPuM0j09c3X5lnrtlBVJ1rBRUH0TLjfw_yGxgoLBwOJl9xyC1YWNoPOe2nzL4lMOHodAnMem0IBMJmUo3Rt575tnWAbBsQXWhlImDIxCZXvkZdJtlXfIfBSUdY9gfRWL0ZjKbf7m2-yLzH0gpMAMuKaADmJlIudJc0d4SP1Nn2Kh2HuVH8CX4QgZuu4egl9N6rY2smorP2vBSC4_dC4CpmYYzOTu2wUnUhHDY2Q6NWl377ijDKwZLcW9jtD-2tBiEGmFuRV0mVGnh0zc4w9Ao9jPCdtrbSyGitgloBW-UG2bfyao3eE" " http://localhost:42291/api/v1/claims "

curl -X GET --header "Accept: application/json" --header "Authorization: Bearer NqlSG-WyTx2zkYE8xFklGyZWlQDZdsCKZBHruEXvX47N7PAzw4-jZ4eH5D0yFzQTXj13RwKFFt1rUZt2fzWj1vR5UR87wdlKC3YvsTojYV4-3DsWwY7qYRfiKPuM0j09c3X5lnrtlBVJ1rBRUH0TLjfw_yGxgoLBwOJl9xyC1YWNoPOe2nzL4lMOHodAnMem0IBMJmUo3Rt575tnWAbBsQXWhlImDIxCZXvkZdJtlXfIfBSUdY9gfRWL0ZjKbf7m2-yLzH0gpMAMuKaADmJlIudJc0d4SP1Nn2Kh2HuVH8CX4QgZuu4egl9N6rY2smorP2vBSC4_dC4CpmYYzOTu2wUnUhHDY2Q6NWl377ijDKwZLcW9jtD-2tBiEGmFuRV0mVGnh0zc4w9Ao9jPCdtrbSyGitgloBW-UG2bfyao3eE" "http://localhost:42291/api/v1/claims"

我根本看不出有什么问题.

I cant see anything wrong with this at all.

然后,我使用Postman来调用完全相同的URL调用,并使用与JavaScript调用中生成的访问令牌相同的访问令牌...

I've then used Postman to call the exact same URL call, using the same access token that was generated in the javascript call...

猜猜是什么...它工作正常.

Guess what... it works fine.

编辑

我试图从控制器中删除授​​权属性,以便我可以在请求到达控制器方法时检查请求.

I've tried removing the authorization attribute from the controller, so that i can check the request as it hits the controller method.

在请求标头中查找,授权"属性为空.

looking in the request headers, the Authorization property is null.

不确定为什么会这样. CURL建议将其放置在请求中.

Not sure why this is. the CURL suggests its been placed into the request.

编辑2

我已包含我的安全定义:-

Ive included my Security Definitions:-

"securityDefinitions": {
        "oauth2": {
            "type": "oauth2",
            "description": "OAuth2 Password Grant",
            "flow": "password",
            "tokenUrl": "http://localhost:42291/token",
            "scopes": {}
        }
    }

编辑3 直接在命令行通过cURL公开时,此api调用的Swagger UI中显示的cURL可以正常工作.

EDIT 3 The cURL displayed in the Swagger UI for this api call, when exposed through cURL directly at the command line works without issue.

现在我完全困惑了.

推荐答案

我已经设法解决了这个问题.这是一个简单的类型不匹配,这使我感到悲伤.

I've managed to correct the problem. It was a simple type mismatch that has caused me days of grief.

在onComplete.JS中,我需要创建一个与swagger规范中显示的键匹配的键.

In the onComplete.JS, i needed to create a key that matches the key presented in the swagger specification.

如果您在上面检查我的代码段,您会发现我创建了一个密钥,并将其称为授权".但这与命名的安全定义"oauth2"不匹配.

If you examine my code snippets above you will see that i created a key and called it "Authorization". But that does not match the named security definition "oauth2".

工作代码:-

$('#input_apiKey').change(function () {
    var key = $('#input_apiKey')[0].value;
    var credentials = key.split(':'); 
    $.ajax({
        url: "http://localhost:42291/token",
        type: "post",
        contenttype: 'x-www-form-urlencoded',
        data: "grant_type=password&username=" + credentials[0] + "&password=" + credentials[1],
        success: function (response) {

            var bearerToken = "Bearer " + response.access_token;

            window.swaggerUi.api.clientAuthorizations.remove('api_key');

            var apiKeyAuth = new SwaggerClient.ApiKeyAuthorization("Authorization", bearerToken, "header");

            window.swaggerUi.api.clientAuthorizations.add('oauth2', apiKeyAuth);

            alert("Login Succesfull!");

        },
        error: function (xhr, ajaxoptions, thrownerror) {
            alert("Login failed!");
        }
    });
});

仅对此做进一步解释,您需要创建IOperationFilter的实现,以便大张旗鼓地确定api的哪些方法需要Authorizaion.正确配置后,您应该在swagger规范中看到针对每个api调用的安全性定义:-

Just to explain this a bit further, you need to create an implementation of IOperationFilter so that swagger can determine which methods of the api require Authorizaion. When you have configured this correctly, you should see a security definition against each api call in the swagger specification :-

我的IOperationFilter实现:-

My implementation of IOperationFilter :-

public class AssignOAuth2SecurityRequirements : IOperationFilter
    {
        /// <summary>
        /// Apply Security Measures.
        /// </summary>
        /// <param name="operation"></param>
        /// <param name="schemaRegistry"></param>
        /// <param name="apiDescription"></param>
        /// <exception cref="NotImplementedException"></exception>
        public void Apply(Operation operation, SchemaRegistry schemaRegistry, ApiDescription apiDescription)
        {
            // Determine if the operation has the Authorize attribute
            var authorizeAttributes = apiDescription.ActionDescriptor.GetCustomAttributes<AuthorizeAttribute>();

            if (!authorizeAttributes.Any())
                return;

            // Initialize the operation.security property
            if (operation.security == null)
                operation.security = new List<IDictionary<string, IEnumerable<string>>>();

            // Add the appropriate security definition to the operation
            var oAuthRequirements = new Dictionary<string, IEnumerable<string>>
            {
                { "oauth2", Enumerable.Empty<string>() }
            };

            operation.security.Add(oAuthRequirements);
        }
    }

这篇关于SwashBuckle/Swagger-OAuth资源所有者密码流的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆