JWK Set by value added to admin UI, addresses #826
parent
8b81b36e22
commit
79317d5b70
|
@ -631,6 +631,7 @@ var AppRouter = Backbone.Router.extend({
|
||||||
grantTypes: ["authorization_code"],
|
grantTypes: ["authorization_code"],
|
||||||
responseTypes: ["code"],
|
responseTypes: ["code"],
|
||||||
subjectType: "PUBLIC",
|
subjectType: "PUBLIC",
|
||||||
|
jwksType: "URI",
|
||||||
contacts: contacts
|
contacts: contacts
|
||||||
}, { silent: true });
|
}, { silent: true });
|
||||||
|
|
||||||
|
@ -669,6 +670,16 @@ var AppRouter = Backbone.Router.extend({
|
||||||
}, { silent: true });
|
}, { silent: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (client.get("jwks")) {
|
||||||
|
client.set({
|
||||||
|
jwksType: "VAL"
|
||||||
|
}, { silent: true });
|
||||||
|
} else {
|
||||||
|
client.set({
|
||||||
|
jwksType: "URI"
|
||||||
|
}, { silent: true });
|
||||||
|
}
|
||||||
|
|
||||||
client.set({
|
client.set({
|
||||||
generateClientSecret:false,
|
generateClientSecret:false,
|
||||||
displayClientSecret:false
|
displayClientSecret:false
|
||||||
|
|
|
@ -47,7 +47,10 @@ var ClientModel = Backbone.Model.extend({
|
||||||
grantTypes:[],
|
grantTypes:[],
|
||||||
responseTypes:[],
|
responseTypes:[],
|
||||||
policyUri:"",
|
policyUri:"",
|
||||||
|
|
||||||
jwksUri:"",
|
jwksUri:"",
|
||||||
|
jwks:null,
|
||||||
|
jwksType:"URI",
|
||||||
|
|
||||||
applicationType:null,
|
applicationType:null,
|
||||||
sectorIdentifierUri:"",
|
sectorIdentifierUri:"",
|
||||||
|
@ -635,7 +638,8 @@ var ClientFormView = Backbone.View.extend({
|
||||||
"change #tokenEndpointAuthMethod input:radio":"toggleClientCredentials",
|
"change #tokenEndpointAuthMethod input:radio":"toggleClientCredentials",
|
||||||
"change #displayClientSecret":"toggleDisplayClientSecret",
|
"change #displayClientSecret":"toggleDisplayClientSecret",
|
||||||
"change #generateClientSecret":"toggleGenerateClientSecret",
|
"change #generateClientSecret":"toggleGenerateClientSecret",
|
||||||
"change #logoUri input":"previewLogo"
|
"change #logoUri input":"previewLogo",
|
||||||
|
"change #jwkSelector input:radio":"toggleJWKSetType"
|
||||||
},
|
},
|
||||||
|
|
||||||
cancel:function(e) {
|
cancel:function(e) {
|
||||||
|
@ -708,6 +712,25 @@ var ClientFormView = Backbone.View.extend({
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set up the form based on the JWK Set selector
|
||||||
|
*/
|
||||||
|
toggleJWKSetType:function() {
|
||||||
|
var jwkSelector = $('#jwkSelector input:radio', this.el).filter(':checked').val();
|
||||||
|
|
||||||
|
if (jwkSelector == 'URI') {
|
||||||
|
$('#jwksUri', this.el).show();
|
||||||
|
$('#jwks', this.el).hide();
|
||||||
|
} else if (jwkSelector == 'VAL') {
|
||||||
|
$('#jwksUri', this.el).hide();
|
||||||
|
$('#jwks', this.el).show();
|
||||||
|
} else {
|
||||||
|
$('#jwksUri', this.el).hide();
|
||||||
|
$('#jwks', this.el).hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set up the form based on the "Generate" checkbox
|
* Set up the form based on the "Generate" checkbox
|
||||||
* @param event
|
* @param event
|
||||||
|
@ -881,6 +904,40 @@ var ClientFormView = Backbone.View.extend({
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// process the JWKS
|
||||||
|
var jwksUri = null;
|
||||||
|
var jwks = null;
|
||||||
|
var jwkSelector = $('#jwkSelector input:radio', this.el).filter(':checked').val();
|
||||||
|
|
||||||
|
if (jwkSelector == 'URI') {
|
||||||
|
jwksUri = $('#jwksUri input').val();
|
||||||
|
jwks = null;
|
||||||
|
} else if (jwkSelector == 'VAL') {
|
||||||
|
jwksUri = null;
|
||||||
|
try {
|
||||||
|
jwks = JSON.parse($('#jwks textarea').val());
|
||||||
|
} catch (e) {
|
||||||
|
console.log("An error occurred when parsing the JWK Set");
|
||||||
|
|
||||||
|
//Display an alert with an error message
|
||||||
|
$('#modalAlert div.modal-header').html("JWK Set Error");
|
||||||
|
$('#modalAlert div.modal-body').html("There was an error parsing the public key from the JSON Web Key set. Check the value and try again.");
|
||||||
|
|
||||||
|
$("#modalAlert").modal({ // wire up the actual modal functionality and show the dialog
|
||||||
|
"backdrop" : "static",
|
||||||
|
"keyboard" : true,
|
||||||
|
"show" : true // ensure the modal is shown immediately
|
||||||
|
});
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
jwksUri = null;
|
||||||
|
jwks = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
var attrs = {
|
var attrs = {
|
||||||
clientName:$('#clientName input').val(),
|
clientName:$('#clientName input').val(),
|
||||||
clientId:$('#clientId input').val(),
|
clientId:$('#clientId input').val(),
|
||||||
|
@ -900,7 +957,8 @@ var ClientFormView = Backbone.View.extend({
|
||||||
policyUri: $('#policyUri input').val(),
|
policyUri: $('#policyUri input').val(),
|
||||||
clientUri: $('#clientUri input').val(),
|
clientUri: $('#clientUri input').val(),
|
||||||
applicationType: $('#applicationType input').filter(':checked').val(),
|
applicationType: $('#applicationType input').filter(':checked').val(),
|
||||||
jwksUri: $('#jwksUri input').val(),
|
jwksUri: jwksUri,
|
||||||
|
jwks: jwks,
|
||||||
subjectType: $('#subjectType input').filter(':checked').val(),
|
subjectType: $('#subjectType input').filter(':checked').val(),
|
||||||
tokenEndpointAuthMethod: tokenEndpointAuthMethod,
|
tokenEndpointAuthMethod: tokenEndpointAuthMethod,
|
||||||
responseTypes: responseTypes,
|
responseTypes: responseTypes,
|
||||||
|
@ -976,7 +1034,7 @@ var ClientFormView = Backbone.View.extend({
|
||||||
app.navigate('admin/clients', {trigger:true});
|
app.navigate('admin/clients', {trigger:true});
|
||||||
},
|
},
|
||||||
error:function (error, response) {
|
error:function (error, response) {
|
||||||
console.log("An error occurred when deleting from a list widget");
|
console.log("An error occurred when saving a client");
|
||||||
|
|
||||||
//Pull out the response text.
|
//Pull out the response text.
|
||||||
var responseJson = JSON.parse(response.responseText);
|
var responseJson = JSON.parse(response.responseText);
|
||||||
|
@ -1103,6 +1161,7 @@ var ClientFormView = Backbone.View.extend({
|
||||||
// toggle other dynamic fields
|
// toggle other dynamic fields
|
||||||
this.toggleClientCredentials();
|
this.toggleClientCredentials();
|
||||||
this.previewLogo();
|
this.previewLogo();
|
||||||
|
this.toggleJWKSetType();
|
||||||
|
|
||||||
// disable unsupported JOSE algorithms
|
// disable unsupported JOSE algorithms
|
||||||
this.disableUnsupportedJOSEItems(app.serverConfiguration.request_object_signing_alg_values_supported, '#requestObjectSigningAlg option');
|
this.disableUnsupportedJOSEItems(app.serverConfiguration.request_object_signing_alg_values_supported, '#requestObjectSigningAlg option');
|
||||||
|
|
|
@ -276,10 +276,10 @@
|
||||||
<label class="control-label"><span class="label label-default nyi"><i class="icon-road icon-white"></i> NYI </span> <span data-i18n="client.client-form.type">Application Type</span></label>
|
<label class="control-label"><span class="label label-default nyi"><i class="icon-road icon-white"></i> NYI </span> <span data-i18n="client.client-form.type">Application Type</span></label>
|
||||||
<div class="controls">
|
<div class="controls">
|
||||||
<div>
|
<div>
|
||||||
<input type="radio" name="applicationType" value="NATIVE" <%-(applicationType == 'NATIVE' ? 'checked' : '')%>>
|
<input id="app-type-native" type="radio" name="applicationType" value="NATIVE" <%-(applicationType == 'NATIVE' ? 'checked' : '')%>>
|
||||||
<label class="radio inline" data-i18n="client.client-form.type-native">Native</label>
|
<label for="app-type-native" class="radio inline" data-i18n="client.client-form.type-native">Native</label>
|
||||||
<input type="radio" name="applicationType" value="WEB" <%-(applicationType == 'WEB' ? 'checked' : '')%>>
|
<input id="app-type-web" type="radio" name="applicationType" value="WEB" <%-(applicationType == 'WEB' ? 'checked' : '')%>>
|
||||||
<label class="radio inline" data-i18n="client.client-form.type-web">Web</label>
|
<label for="app-type-web" class="radio inline" data-i18n="client.client-form.type-web">Web</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -495,11 +495,23 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="control-group" id="jwksUri">
|
<div class="control-group">
|
||||||
<label class="control-label" data-i18n="client.client-form.jwk-set">JWK Set</label>
|
<label class="control-label" data-i18n="client.client-form.jwk-set">Public Key Set</label>
|
||||||
<div class="controls">
|
<div class="controls" id="jwkSelector">
|
||||||
|
<div>
|
||||||
|
<input id="jwkstype-uri" type="radio" name="jwksType" value="URI" <%-(jwksType == 'URI' ? 'checked' : '')%>>
|
||||||
|
<label for="jwkstype-uri" class="radio inline" data-i18n="client.client-form.jwks-by-uri">By URI</label>
|
||||||
|
<input id="jwkstype-value" type="radio" name="jwksType" value="VAL" <%-(jwksType == 'VAL' ? 'checked' : '')%>>
|
||||||
|
<label for="jwkstype-value" class="radio inline" data-i18n="client.client-form.jwks-by-value">By Value</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="controls" id="jwksUri">
|
||||||
<input placeholder="https://" value="<%-jwksUri%>" maxlength="1000" type="text" class=""/>
|
<input placeholder="https://" value="<%-jwksUri%>" maxlength="1000" type="text" class=""/>
|
||||||
<p class="help-block" data-i18n="client.client-form.jwk-set-help">URL for the client's JSON Web Key set</p>
|
<p class="help-block" data-i18n="client.client-form.jwk-set-help">URL for the client's JSON Web Key set (must be reachable by the server)</p>
|
||||||
|
</div>
|
||||||
|
<div class="controls" id="jwks">
|
||||||
|
<textarea class="input-xlarge" placeholder="{ "keys": [ ] }" maxlength="4000" type="text" rows="8"><%- (jwks != null ? JSON.stringify(jwks, null, ' ') : "") %></textarea>
|
||||||
|
<p class="help-block" data-i18n="client.client-form.jwk-set-value-help">JSON Web Key set</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -215,7 +215,7 @@ public class ClientAPI {
|
||||||
if (Strings.isNullOrEmpty(client.getJwksUri()) && client.getJwks() == null) {
|
if (Strings.isNullOrEmpty(client.getJwksUri()) && client.getJwks() == null) {
|
||||||
logger.error("tried to create client with private key auth but no private key");
|
logger.error("tried to create client with private key auth but no private key");
|
||||||
m.addAttribute(HttpCodeView.CODE, HttpStatus.BAD_REQUEST);
|
m.addAttribute(HttpCodeView.CODE, HttpStatus.BAD_REQUEST);
|
||||||
m.addAttribute(JsonErrorView.ERROR_MESSAGE, "Can not create a client with private key authentication without registering a key via the JWS Set URI.");
|
m.addAttribute(JsonErrorView.ERROR_MESSAGE, "Can not create a client with private key authentication without registering a key via the JWK Set URI or JWK Set Value.");
|
||||||
return JsonErrorView.VIEWNAME;
|
return JsonErrorView.VIEWNAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -315,10 +315,10 @@ public class ClientAPI {
|
||||||
|
|
||||||
} else if (client.getTokenEndpointAuthMethod().equals(AuthMethod.PRIVATE_KEY)) {
|
} else if (client.getTokenEndpointAuthMethod().equals(AuthMethod.PRIVATE_KEY)) {
|
||||||
|
|
||||||
if (Strings.isNullOrEmpty(client.getJwksUri()) && client.getJwks() != null) {
|
if (Strings.isNullOrEmpty(client.getJwksUri()) && client.getJwks() == null) {
|
||||||
logger.error("tried to create client with private key auth but no private key");
|
logger.error("tried to create client with private key auth but no private key");
|
||||||
m.addAttribute(HttpCodeView.CODE, HttpStatus.BAD_REQUEST);
|
m.addAttribute(HttpCodeView.CODE, HttpStatus.BAD_REQUEST);
|
||||||
m.addAttribute(JsonErrorView.ERROR_MESSAGE, "Can not create a client with private key authentication without registering a key via the JWS Set URI.");
|
m.addAttribute(JsonErrorView.ERROR_MESSAGE, "Can not create a client with private key authentication without registering a key via the JWK Set URI or JWK Set Value.");
|
||||||
return JsonErrorView.VIEWNAME;
|
return JsonErrorView.VIEWNAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue