我正在使用密码资源所有者流,我不得不添加一个解决方法来执行此操作,这包含在以下堆栈溢出问题中: –
Swagger/Swashbuckle: OAuth2 with Resource Owner Password Credentials Grant
我已经完成了所有工作,通过javascript将Bearer令牌添加到当前浏览器窗口中的请求标头,但是api调用需要授权的控制器方法仍然返回“401 – 授权失败”.
$('#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 -X GET –header “Accept: application/json” –header
“Authorization: Bearer
NqlSG-WyTx2zkYE8xFklGyZWlQDZdsCKZBHruEXvX47N7PAzw4-jZ4eH5D0yFzQTXj13RwKFFt1rUZt2fzWj1vR5UR87wdlKC3YvsTojYV4-3DsWwY7qYRfiKPuM0j09c3X5lnrtlBVJ1rBRUH0TLjfw_yGxgoLBwOJl9xyC1YWNoPOe2nzL4lMOHodAnMem0IBMJmUo3Rt575tnWAbBsQXWhlImDIxCZXvkZdJtlXfIfBSUdY9gfRWL0ZjKbf7m2-yLzH0gpMAMuKaADmJlIudJc0d4SP1Nn2Kh2HuVH8CX4QgZuu4egl9N6rY2smorP2vBSC4_dC4CpmYYzOTu2wUnUhHDY2Q6NWl377ijDKwZLcW9jtD-2tBiEGmFuRV0mVGnh0zc4w9Ao9jPCdtrbSyGitgloBW-UG2bfyao3eE”
“07001”
我根本看不出任何问题.
然后我使用Postman来调用完全相同的URL调用,使用在javascript调用中生成的相同访问令牌…
猜猜是什么……它运作正常.
编辑
我已经尝试从控制器中删除授权属性,以便我可以检查请求,因为它命中控制器方法.
查看请求标头,Authorization属性为null.
不知道为什么会这样. CURL建议将其放入请求中.
编辑2
我已经包含了我的安全定义: –
"securityDefinitions": { "oauth2": { "type": "oauth2","description": "OAuth2 Password Grant","flow": "password","tokenUrl": "http://localhost:42291/token","scopes": {} } }
编辑3
当通过cURL直接在命令行中公开时,在这个api调用的Swagger UI中显示的cURL可以正常工作.
现在我完全糊涂了.
解决方法
在onComplete.JS中,我需要创建一个与swagger规范中显示的键匹配的键.
如果您检查上面的代码片段,您会看到我创建了一个密钥并将其称为“授权”.但这与命名的安全定义“oauth2”不匹配.
工作代码: –
$('#input_apiKey').change(function () { var key = $('#input_apiKey')[0].value; var credentials = key.split(':'); $.ajax({ url: "http://localhost:42291/token",success: function (response) { var bearerToken = "Bearer " + response.access_token; window.swaggerUi.api.clientAuthorizations.remove('api_key'); var apiKeyAuth = new SwaggerClient.ApiKeyAuthorization("Authorization","header"); window.swaggerUi.api.clientAuthorizations.add('oauth2',apiKeyAuth); alert("Login Succesfull!"); },thrownerror) { alert("Login Failed!"); } }); });
为了进一步解释这一点,您需要创建IOperationFilter的实现,以便swagger可以确定api的哪些方法需要Authorizaion.正确配置后,您应该在swagger规范中看到针对每个api调用的安全定义: –
我的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); } }