Implement OAuth2 client authentication for password and application flow
This commit is contained in:
@@ -119,13 +119,13 @@ SwaggerUi.Views.AuthView = Backbone.View.extend({
|
|||||||
else if(auth.get('type') === 'oauth2' && flow && (flow === 'application')) {
|
else if(auth.get('type') === 'oauth2' && flow && (flow === 'application')) {
|
||||||
dets = auth.attributes;
|
dets = auth.attributes;
|
||||||
container.tokenName = dets.tokenName || 'access_token';
|
container.tokenName = dets.tokenName || 'access_token';
|
||||||
this.clientCredentialsFlow(scopes, dets.tokenUrl, container.OAuthSchemeKey);
|
this.clientCredentialsFlow(scopes, dets, container.OAuthSchemeKey);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if(auth.get('type') === 'oauth2' && flow && (flow === 'password')) {
|
else if(auth.get('type') === 'oauth2' && flow && (flow === 'password')) {
|
||||||
dets = auth.attributes;
|
dets = auth.attributes;
|
||||||
window.swaggerUi.tokenName = dets.tokenName || 'access_token';
|
container.tokenName = dets.tokenName || 'access_token';
|
||||||
this.passwordFlow(scopes, dets.tokenUrl, dets.username, dets.password, window.OAuthSchemeKey);
|
this.passwordFlow(scopes, dets, container.OAuthSchemeKey);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if(auth.get('grantTypes')) {
|
else if(auth.get('grantTypes')) {
|
||||||
@@ -162,39 +162,40 @@ SwaggerUi.Views.AuthView = Backbone.View.extend({
|
|||||||
},
|
},
|
||||||
|
|
||||||
// taken from lib/swagger-oauth.js
|
// taken from lib/swagger-oauth.js
|
||||||
clientCredentialsFlow: function (scopes, tokenUrl, OAuthSchemeKey) {
|
clientCredentialsFlow: function (scopes, oauth, OAuthSchemeKey) {
|
||||||
var params = {
|
this.accessTokenRequest(scopes, oauth, OAuthSchemeKey, 'client_credentials');
|
||||||
'client_id': clientId,
|
},
|
||||||
'client_secret': clientSecret,
|
|
||||||
'scope': scopes.join(' '),
|
passwordFlow: function (scopes, oauth, OAuthSchemeKey) {
|
||||||
'grant_type': 'client_credentials'
|
this.accessTokenRequest(scopes, oauth, OAuthSchemeKey, 'password', {
|
||||||
};
|
'username': oauth.username,
|
||||||
$.ajax({
|
'password': oauth.password
|
||||||
url : tokenUrl,
|
|
||||||
type: 'POST',
|
|
||||||
data: params,
|
|
||||||
success: function (data)
|
|
||||||
{
|
|
||||||
onOAuthComplete(data, OAuthSchemeKey);
|
|
||||||
},
|
|
||||||
error: function ()
|
|
||||||
{
|
|
||||||
onOAuthComplete('');
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
passwordFlow: function (scopes, tokenUrl, username, password, OAuthSchemeKey) {
|
accessTokenRequest: function (scopes, oauth, OAuthSchemeKey, grantType, params) {
|
||||||
var params = {
|
params = $.extend({}, {
|
||||||
'scope': scopes.join(' '),
|
'scope': scopes.join(' '),
|
||||||
'username': username,
|
'grant_type': grantType
|
||||||
'password': password,
|
}, params);
|
||||||
'grant_type': 'password'
|
|
||||||
};
|
var headers= {};
|
||||||
|
|
||||||
|
switch (oauth.clientAuthenticationType) {
|
||||||
|
case 'basic':
|
||||||
|
headers.Authorization = 'Basic ' + btoa(oauth.clientId + ':' + oauth.clientSecret);
|
||||||
|
break;
|
||||||
|
case 'request-body':
|
||||||
|
params.client_id = oauth.clientId;
|
||||||
|
params.client_secret = oauth.clientSecret;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url : tokenUrl,
|
url : oauth.tokenUrl,
|
||||||
type: 'POST',
|
type: 'POST',
|
||||||
data: params,
|
data: params,
|
||||||
|
headers: headers,
|
||||||
success: function (data)
|
success: function (data)
|
||||||
{
|
{
|
||||||
onOAuthComplete(data, OAuthSchemeKey);
|
onOAuthComplete(data, OAuthSchemeKey);
|
||||||
|
|||||||
@@ -3,7 +3,8 @@
|
|||||||
SwaggerUi.Models.Oauth2Model = Backbone.Model.extend({
|
SwaggerUi.Models.Oauth2Model = Backbone.Model.extend({
|
||||||
defaults: {
|
defaults: {
|
||||||
scopes: {},
|
scopes: {},
|
||||||
isPasswordFlow: false
|
isPasswordFlow: false,
|
||||||
|
clientAuthenticationType: 'none'
|
||||||
},
|
},
|
||||||
|
|
||||||
initialize: function () {
|
initialize: function () {
|
||||||
@@ -21,7 +22,12 @@ SwaggerUi.Models.Oauth2Model = Backbone.Model.extend({
|
|||||||
this.attributes = attributes;
|
this.attributes = attributes;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.set('isPasswordFlow', attributes.flow && attributes.flow === 'password');
|
if (this.attributes && this.attributes.flow) {
|
||||||
|
var flow = this.attributes.flow;
|
||||||
|
this.set('isPasswordFlow', flow === 'password');
|
||||||
|
this.set('requireClientAuthentication', flow === 'application');
|
||||||
|
this.set('clientAuthentication', flow === 'password' || flow === 'application');
|
||||||
|
}
|
||||||
this.on('change', this.validate);
|
this.on('change', this.validate);
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -43,6 +49,11 @@ SwaggerUi.Models.Oauth2Model = Backbone.Model.extend({
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.get('clientAuthenticationType') in ['basic', 'request-body'] &&
|
||||||
|
(!this.get('clientId'))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
var scp = this.get('scopes');
|
var scp = this.get('scopes');
|
||||||
var idx = _.findIndex(scp, function (o) {
|
var idx = _.findIndex(scp, function (o) {
|
||||||
return o.checked === true;
|
return o.checked === true;
|
||||||
|
|||||||
@@ -4,7 +4,10 @@ SwaggerUi.Views.Oauth2View = Backbone.View.extend({
|
|||||||
events: {
|
events: {
|
||||||
'change .oauth-scope': 'scopeChange',
|
'change .oauth-scope': 'scopeChange',
|
||||||
'change .oauth-username': 'setUsername',
|
'change .oauth-username': 'setUsername',
|
||||||
'change .oauth-password': 'setPassword'
|
'change .oauth-password': 'setPassword',
|
||||||
|
'change .oauth-client-authentication-type': 'setClientAuthenticationType',
|
||||||
|
'change .oauth-client-id': 'setClientId',
|
||||||
|
'change .oauth-client-secret': 'setClientSecret'
|
||||||
},
|
},
|
||||||
|
|
||||||
template: Handlebars.templates.oauth2,
|
template: Handlebars.templates.oauth2,
|
||||||
@@ -38,9 +41,43 @@ SwaggerUi.Views.Oauth2View = Backbone.View.extend({
|
|||||||
this.model.set('password', $(e.target).val());
|
this.model.set('password', $(e.target).val());
|
||||||
},
|
},
|
||||||
|
|
||||||
|
setClientAuthenticationType: function (e) {
|
||||||
|
var type = $(e.target).val();
|
||||||
|
var $el = this.$el;
|
||||||
|
this.model.set('clientAuthenticationType', type);
|
||||||
|
|
||||||
|
switch(type) {
|
||||||
|
case 'none':
|
||||||
|
$el.find('.oauth-client-authentication').hide();
|
||||||
|
break;
|
||||||
|
case 'basic':
|
||||||
|
case 'request-body':
|
||||||
|
$el.find('.oauth-client-id').removeClass(this.cls.error);
|
||||||
|
$el.find('.oauth-client-authentication').show();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
setClientId: function (e) {
|
||||||
|
var val = $(e.target).val();
|
||||||
|
this.model.set('clientId', val);
|
||||||
|
if (val) {
|
||||||
|
$(e.target).removeClass(this.cls.error);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
setClientSecret: function (e) {
|
||||||
|
this.model.set('clientSecret', $(e.target).val());
|
||||||
|
$(e.target).removeClass('error');
|
||||||
|
},
|
||||||
|
|
||||||
highlightInvalid: function () {
|
highlightInvalid: function () {
|
||||||
if (!this.model.get('username')) {
|
if (!this.model.get('username')) {
|
||||||
this.$el.find('.oauth-username').addClass(this.cls.error);
|
this.$el.find('.oauth-username').addClass(this.cls.error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!this.model.get('clientId')) {
|
||||||
|
this.$el.find('.oauth-client-id').addClass(this.cls.error);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -11,6 +11,22 @@
|
|||||||
<div><label>Password: <input class="oauth-password" type="password" name="password"></label></div>
|
<div><label>Password: <input class="oauth-password" type="password" name="password"></label></div>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
{{#if clientAuthentication}}
|
||||||
|
<p>Setup client authentication.{{#if requireClientAuthenticaiton}}(Required){{/if}}</p>
|
||||||
|
<fieldset>
|
||||||
|
<div><label>Type:
|
||||||
|
<select class="oauth-client-authentication-type" name="client-authentication-type">
|
||||||
|
<option value="none" selected>None or other</option>
|
||||||
|
<option value="basic">Basic auth</option>
|
||||||
|
<option value="request-body">Request body</option>
|
||||||
|
</select>
|
||||||
|
</label></div>
|
||||||
|
<div class="oauth-client-authentication" hidden>
|
||||||
|
<div><label>ClientId: <input class="oauth-client-id" type="text" name="client-id"></label></div>
|
||||||
|
<div><label>Secret: <input class="oauth-client-secret" type="text" name="client-secret"></label></div>
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
||||||
|
{{/if}}
|
||||||
<p><strong> {{{escape appName}}} </strong> API requires the following scopes. Select which ones you want to grant to Swagger UI.</p>
|
<p><strong> {{{escape appName}}} </strong> API requires the following scopes. Select which ones you want to grant to Swagger UI.</p>
|
||||||
<p>Scopes are used to grant an application different levels of access to data on behalf of the end user. Each API may declare one or more scopes.
|
<p>Scopes are used to grant an application different levels of access to data on behalf of the end user. Each API may declare one or more scopes.
|
||||||
<a href="#">Learn how to use</a>
|
<a href="#">Learn how to use</a>
|
||||||
|
|||||||
Reference in New Issue
Block a user