Reputation: 8679
I'm trying to use Swashbuckle 5.0.x with OAuth2. I want to use OAuth2's Resource Owner Password Credentials Grant. I basically only want to ask for a token first and include this token in each request (e.g. no need for scopes).
Can anyone help with this? How do I have to configure swagger/swashbuckle?
Upvotes: 13
Views: 6977
Reputation: 4530
Similar answers to @rui-estreito and @prime-z, but this prompts for a username and password when 'exploring' the API for the first time.
c.InjectJavaScript(thisAssembly, "<project namespace>.CustomContent.apikey.js")
(function () {
$(function () {
console.log("loaded custom auth");
$('#input_apiKey').off();
$('#explore').off();
$('#explore').click(function () {
var credentials_un = prompt("Username");
var credentials_password = prompt("Password");
var client_id = $('#input_apiKey')[0].value;
$.ajax({
url: document.location.origin + "/token",
type: "post",
contenttype: 'x-www-form-urlencoded',
data: "grant_type=password&username=" + credentials_un + "&password=" + credentials_password + "&client_id=" + client_id,
success: function (response) {
var bearerToken = 'Bearer ' + response.access_token;
window.swaggerUi.api.clientAuthorizations.add('Authorization', new SwaggerClient.ApiKeyAuthorization('Authorization', bearerToken, 'header'));
alert("Login successfull");
},
error: function (xhr, ajaxoptions, thrownerror) {
alert("Login failed!");
}
});
});
/*
*/
});
})();
BuildAction change to 'Embedded Resource'
Upvotes: 1
Reputation: 270
i had a problem where the solution .InjectJavaScript() resolved my problem, the diference is that i have a custom grant type, since the base code of swagger-ui-min.js have the grant password hardcoded for the flow password, the solution was override their code:
$(function () {
window.SwaggerUi.Views.AuthView = Backbone.View.extend({
events: (...),
tpls: (...),
selectors: {
innerEl: ".auth_inner",
authBtn: ".auth_submit__button"
},
initialize: function (e)(...),
render: function ()(...),
authorizeClick: function (e)(...),
authorize: function ()(...),
logoutClick: function (e)(...),
handleOauth2Login: function (e)(...),
clientCredentialsFlow: function (e, t, n)(...),
passwordFlow: function (e, t, n) {
this.accessTokenRequest(e, t, n, "mygrant", {
username: t.username,
password: t.password
})
},
accessTokenRequest: function (e, t, n, r, i) {
i = $.extend({}, {
scope: e.join(" "),
grant_type: r
}, i);
var a = {};
switch (t.clientAuthenticationType) {
case "basic":
a.Authorization = "Basic " + btoa(t.clientId + ":" + t.clientSecret);
break;
case "request-body":
i.client_id = t.clientId,
i.client_secret = t.clientSecret
}
$.ajax(...)
}
});
});
The (...) have the original code that i copy from the swagger-ui-min.js.
Upvotes: 0
Reputation: 544
Thank you @Dunken. Your answer almost solve my problem, but to make it work with latest Swashbuckle version I had to change it a bit like this
$('#explore').off();
$('#explore').click(function () {
var key = $('#input_apiKey')[0].value;
var credentials = key.split(':'); //username:password expected
$.ajax({
url: "yourAuthEndpoint",
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 SwaggerClient.ApiKeyAuthorization('Authorization', bearerToken, 'header'));
window.swaggerUi.api.clientAuthorizations.remove("api_key");
alert("Login successfull");
},
error: function (xhr, ajaxoptions, thrownerror) {
alert("Login failed!");
}
});
});
Upvotes: 15
Reputation: 8679
OK, I solved it like this:
Add a JavaScript completion-handler to swagger:
config
.EnableSwagger(c => {
//do stuff
})
.EnableSwaggerUi(c => {
c.InjectJavaScript(typeof(Startup).Assembly, "MyNamespace.SwaggerExtensions.onComplete.js");
});
Take username:password from the API_KEY textbox:
$('#input_apiKey').change(function () {
var key = $('#input_apiKey')[0].value;
var credentials = key.split(':'); //username:password expected
$.ajax({
url: "myURL",
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.authorizations.add('key', new ApiKeyAuthorization('Authorization', bearerToken, 'header'));
},
error: function (xhr, ajaxoptions, thrownerror) {
alert("Login failed!");
}
});
});
Upvotes: 11