enforce clients using a redirect flow have at least one redirect uri registered when using dynamic registration, made error handling more consistent across all APIs

closes #596
pull/604/head
Justin Richer 2014-05-21 18:29:51 -04:00
parent c38761cc23
commit 4e890a4d7d
9 changed files with 69 additions and 34 deletions

View File

@ -98,7 +98,8 @@ var ListWidgetChildView = Backbone.View.extend({
var responseJson = JSON.parse(response.responseText);
//Display an alert with an error message
$('#modalAlert div.modal-body').html(responseJson.errorMessage);
$('#modalAlert div.modal-header').html(responseJson.error);
$('#modalAlert div.modal-body').html(responseJson.error_description);
$("#modalAlert").modal({ // wire up the actual modal functionality and show the dialog
"backdrop" : "static",
@ -351,7 +352,8 @@ var BlackListWidgetView = ListWidgetView.extend({
var responseJson = JSON.parse(response.responseText);
//Display an alert with an error message
$('#modalAlert div.modal-body').html(responseJson.errorMessage);
$('#modalAlert div.modal-header').html(responseJson.error);
$('#modalAlert div.modal-body').html(responseJson.error_description);
$("#modalAlert").modal({ // wire up the actual modal functionality and show the dialog
"backdrop" : "static",

View File

@ -245,7 +245,8 @@ var ClientView = Backbone.View.extend({
var responseJson = JSON.parse(response.responseText);
//Display an alert with an error message
$('#modalAlert div.modal-body').html(responseJson.errorMessage);
$('#modalAlert div.modal-header').html(responseJson.error);
$('#modalAlert div.modal-body').html(responseJson.error_description);
$("#modalAlert").modal({ // wire up the actual modal functionality and show the dialog
"backdrop" : "static",
@ -772,7 +773,8 @@ var ClientFormView = Backbone.View.extend({
var responseJson = JSON.parse(response.responseText);
//Display an alert with an error message
$('#modalAlert div.modal-body').html(responseJson.errorMessage);
$('#modalAlert div.modal-header').html(responseJson.error);
$('#modalAlert div.modal-body').html(responseJson.error_description);
$("#modalAlert").modal({ // wire up the actual modal functionality and show the dialog
"backdrop" : "static",

View File

@ -178,7 +178,8 @@ var DynRegEditView = Backbone.View.extend({
var responseJson = JSON.parse(response.responseText);
//Display an alert with an error message
$('#modalAlert div.modal-body').html(responseJson.errorMessage);
$('#modalAlert div.modal-header').html(responseJson.error);
$('#modalAlert div.modal-body').html(responseJson.error_description);
$("#modalAlert").modal({ // wire up the actual modal functionality and show the dialog
"backdrop" : "static",
@ -343,7 +344,8 @@ var DynRegEditView = Backbone.View.extend({
var responseJson = JSON.parse(response.responseText);
//Display an alert with an error message
$('#modalAlert div.modal-body').html(responseJson.errorMessage);
$('#modalAlert div.modal-header').html(responseJson.error);
$('#modalAlert div.modal-body').html(responseJson.error_description);
$("#modalAlert").modal({ // wire up the actual modal functionality and show the dialog
"backdrop" : "static",

View File

@ -250,7 +250,8 @@ var ApprovedSiteView = Backbone.View.extend({
var responseJson = JSON.parse(response.responseText);
//Display an alert with an error message
$('#modalAlert div.modal-body').html(responseJson.errorMessage);
$('#modalAlert div.modal-header').html(responseJson.error);
$('#modalAlert div.modal-body').html(responseJson.error_description);
$("#modalAlert").modal({ // wire up the actual modal functionality and show the dialog
"backdrop" : "static",

View File

@ -111,7 +111,8 @@ var SystemScopeView = Backbone.View.extend({
var responseJson = JSON.parse(response.responseText);
//Display an alert with an error message
$('#modalAlert div.modal-body').html(responseJson.errorMessage);
$('#modalAlert div.modal-header').html(responseJson.error);
$('#modalAlert div.modal-body').html(responseJson.error_description);
$("#modalAlert").modal({ // wire up the actual modal functionality and show the dialog
"backdrop" : "static",
@ -295,27 +296,15 @@ var SystemScopeFormView = Backbone.View.extend({
//Pull out the response text.
var responseJson = JSON.parse(response.responseText);
if (response.status == 409) {
//Conflict, scope already exists
$('#value.control-group input').addClass('inputError');
$('#value.control-group').before('<div class="alert alert-error"><button type="button" class="close" data-dismiss="alert">&times;</button>' + responseText + '</div>');
$('#value.control-group').bind('click.error', function() {
$('#value.control-group input').removeClass('inputError');
$('#value.control-group').unbind('click.error');
});
}
else {
//Display an alert with an error message
$('#modalAlert div.modal-body').html(responseJson.errorMessage);
$("#modalAlert").modal({ // wire up the actual modal functionality and show the dialog
"backdrop" : "static",
"keyboard" : true,
"show" : true // ensure the modal is shown immediately
});
}
//Display an alert with an error message
$('#modalAlert div.modal-header').html(responseJson.error);
$('#modalAlert div.modal-body').html(responseJson.error_description);
$("#modalAlert").modal({ // wire up the actual modal functionality and show the dialog
"backdrop" : "static",
"keyboard" : true,
"show" : true // ensure the modal is shown immediately
});
}
});
}

View File

@ -120,7 +120,8 @@ var AccessTokenView = Backbone.View.extend({
var responseJson = JSON.parse(response.responseText);
//Display an alert with an error message
$('#modalAlert div.modal-body').html(responseJson.errorMessage);
$('#modalAlert div.modal-header').html(responseJson.error);
$('#modalAlert div.modal-body').html(responseJson.error_description);
$("#modalAlert").modal({ // wire up the actual modal functionality and show the dialog
"backdrop" : "static",
@ -268,7 +269,8 @@ var RefreshTokenView = Backbone.View.extend({
var responseJson = JSON.parse(response.responseText);
//Display an alert with an error message
$('#modalAlert div.modal-body').html(responseJson.errorMessage);
$('#modalAlert div.modal-header').html(responseJson.error);
$('#modalAlert div.modal-body').html(responseJson.error_description);
$("#modalAlert").modal({ // wire up the actual modal functionality and show the dialog
"backdrop" : "static",

View File

@ -194,7 +194,8 @@ var WhiteListView = Backbone.View.extend({
var responseJson = JSON.parse(response.responseText);
//Display an alert with an error message
$('#modalAlert div.modal-body').html(responseJson.errorMessage);
$('#modalAlert div.modal-header').html(responseJson.error);
$('#modalAlert div.modal-body').html(responseJson.error_description);
$("#modalAlert").modal({ // wire up the actual modal functionality and show the dialog
"backdrop" : "static",
@ -278,7 +279,8 @@ var WhiteListFormView = Backbone.View.extend({
var responseJson = JSON.parse(response.responseText);
//Display an alert with an error message
$('#modalAlert div.modal-body').html(responseJson.errorMessage);
$('#modalAlert div.modal-header').html(responseJson.error);
$('#modalAlert div.modal-body').html(responseJson.error_description);
$("#modalAlert").modal({ // wire up the actual modal functionality and show the dialog
"backdrop" : "static",

View File

@ -30,6 +30,7 @@ import org.springframework.stereotype.Component;
import org.springframework.validation.BeanPropertyBindingResult;
import org.springframework.web.servlet.view.AbstractView;
import com.google.common.base.Strings;
import com.google.gson.ExclusionStrategy;
import com.google.gson.FieldAttributes;
import com.google.gson.Gson;
@ -85,9 +86,14 @@ public class JsonErrorView extends AbstractView {
Writer out = response.getWriter();
String errorTitle = (String) model.get("error");
if (Strings.isNullOrEmpty(errorTitle)) {
errorTitle = "Error";
}
String errorMessage = (String) model.get("errorMessage");
JsonObject obj = new JsonObject();
obj.addProperty("error_message", errorMessage);
obj.addProperty("error", errorTitle);
obj.addProperty("error_description", errorMessage);
gson.toJson(obj, out);
} catch (IOException e) {

View File

@ -17,6 +17,7 @@
package org.mitre.openid.connect.web;
import java.io.UnsupportedEncodingException;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
@ -31,6 +32,7 @@ import org.mitre.oauth2.service.OAuth2TokenEntityService;
import org.mitre.oauth2.service.SystemScopeService;
import org.mitre.openid.connect.ClientDetailsEntityJsonProcessor;
import org.mitre.openid.connect.config.ConfigurationPropertiesBean;
import org.mitre.openid.connect.service.BlacklistedSiteService;
import org.mitre.openid.connect.service.OIDCTokenService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -47,6 +49,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.util.UriUtils;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Sets;
@Controller
@ -64,6 +67,9 @@ public class ClientDynamicRegistrationEndpoint {
@Autowired
private SystemScopeService scopeService;
@Autowired
private BlacklistedSiteService blacklistService;
@Autowired
private ConfigurationPropertiesBean config;
@ -121,10 +127,33 @@ public class ClientDynamicRegistrationEndpoint {
newClient.setGrantTypes(Sets.newHashSet("authorization_code")); // allow authorization code grant type by default
}
}
// check to make sure this client registered a redirect URI if using a redirect flow
if (newClient.getGrantTypes().contains("authorization_code") || newClient.getGrantTypes().contains("implicit")) {
if (newClient.getRedirectUris() == null || newClient.getRedirectUris().isEmpty()) {
// return an error
m.addAttribute("error", "invalid_client_uri");
m.addAttribute("errorMessage", "Clients using a redirect-based grant type must register at least one redirect URI.");
m.addAttribute("code", HttpStatus.BAD_REQUEST);
return "jsonErrorView";
}
for (String uri : newClient.getRedirectUris()) {
if (blacklistService.isBlacklisted(uri)) {
// return an error
m.addAttribute("error", "invalid_client_uri");
m.addAttribute("errorMessage", "Redirect URI is not allowed: " + uri);
m.addAttribute("code", HttpStatus.BAD_REQUEST);
return "jsonErrorView";
}
}
}
// set default response types if needed
// TODO: these aren't checked by SECOAUTH
// TODO: the consistency between the response_type and grant_type needs to be checked by the client service, most likely
if (newClient.getResponseTypes() == null || newClient.getResponseTypes().isEmpty()) {
newClient.setResponseTypes(Sets.newHashSet("code")); // default to allowing only the auth code flow
}