CLOUDSTACK-8457: SAML UI enhancements

Add option to authorize SAML SSO for user when adding user. Appends a domain to
user/account name if global setting is enabled, useful in case of multiple IDP
server. By default the setting is set to false (keep as it is).

Signed-off-by: Rohit Yadav <rohit.yadav@shapeblue.com>

This closes #575

(cherry picked from commit 7d11c7bc70)
Signed-off-by: Rohit Yadav <rohit.yadav@shapeblue.com>
This commit is contained in:
Rohit Yadav 2015-07-10 02:26:51 +05:30
parent 63688e70a0
commit 76a10351a5
5 changed files with 132 additions and 3 deletions

View File

@ -64,6 +64,9 @@ public interface SAML2AuthManager extends PluggableAPIAuthenticator, PluggableSe
public static final ConfigKey<String> SAMLSignatureAlgorithm = new ConfigKey<String>("Advanced", String.class, "saml2.sigalg", "SHA1",
"The algorithm to use to when signing a SAML request. Default is SHA1, allowed algorithms: SHA1, SHA256, SHA384, SHA512", true);
public static final ConfigKey<Boolean> SAMLAppendDomainSuffix = new ConfigKey<Boolean>("Advanced", Boolean.class, "saml2.append.idpdomain", "false",
"If enabled, create account/user dialog with SAML SSO enabled will append the IdP domain to the user or account name in the UI dialog", true);
public static final ConfigKey<Integer> SAMLTimeout = new ConfigKey<Integer>("Advanced", Integer.class, "saml2.timeout", "1800",
"SAML2 IDP Metadata refresh interval in seconds, minimum value is set to 300", true);

View File

@ -514,6 +514,6 @@ public class SAML2AuthManagerImpl extends AdapterBase implements SAML2AuthManage
SAMLServiceProviderSingleSignOnURL, SAMLServiceProviderSingleLogOutURL,
SAMLCloudStackRedirectionUrl, SAMLUserAttributeName,
SAMLIdentityProviderMetadataURL, SAMLDefaultIdentityProviderId,
SAMLSignatureAlgorithm, SAMLTimeout};
SAMLSignatureAlgorithm, SAMLAppendDomainSuffix, SAMLTimeout};
}
}

View File

@ -148,6 +148,23 @@
});
}
});
// SAML: Check Append Domain Setting
if (g_idpList) {
$.ajax({
type: 'GET',
url: createURL('listConfigurations&name=saml2.append.idpdomain'),
dataType: 'json',
async: false,
success: function(data, textStatus, xhr) {
if (data && data.listconfigurationsresponse && data.listconfigurationsresponse.configuration) {
g_appendIdpDomain = (data.listconfigurationsresponse.configuration[0].value === 'true');
}
},
error: function(xhr) {
},
});
}
},
detailView: {
@ -1061,6 +1078,68 @@
data: items
});
}
},
samlEnable: {
label: 'label.saml.enable',
docID: 'helpSamlEnable',
isBoolean: true,
validation: {
required: false
},
isHidden: function (args) {
if (g_idpList) return false;
return true;
}
},
samlEntity: {
label: 'label.saml.entity',
docID: 'helpSamlEntity',
validation: {
required: false
},
select: function(args) {
var samlChecked = false;
var idpUrl = "";
var appendDomainToUsername = function() {
if (!g_appendIdpDomain) {
return;
}
var username = $('input[name=username]').val();
if (username) {
username = username.split('@')[0];
}
if (samlChecked) {
var link = document.createElement('a');
link.setAttribute('href', idpUrl);
$('input[name=username]').val(username + "@" + link.host.split('.').splice(-2).join('.'));
} else {
$('input[name=username]').val(username);
}
};
args.$form.find('select[name=samlEntity]').change(function() {
idpUrl = $(this).children(':selected').val();
appendDomainToUsername();
});
args.$form.find('input[name=samlEnable]').change(function() {
samlChecked = $(this).context.checked;
appendDomainToUsername();
});
var items = [];
$(g_idpList).each(function() {
items.push({
id: this.id,
description: this.orgName
});
});
args.response.success({
data: items
});
},
isHidden: function (args) {
if (g_idpList) return false;
return true;
}
}
}
},
@ -1098,12 +1177,30 @@
accounttype: accountObj.accounttype
});
var authorizeUsersForSamlSSO = function (users, entity) {
for (var i = 0; i < users.length; i++) {
$.ajax({
url: createURL('authorizeSamlSso&enable=true&userid=' + users[i].id + "&entityid=" + entity),
error: function(XMLHttpResponse) {
args.response.error(parseXMLHttpResponse(XMLHttpResponse));
}
});
}
return;
};
$.ajax({
url: createURL('createUser'),
type: "POST",
data: data,
success: function(json) {
var item = json.createuserresponse.user;
if (args.data.samlEnable && args.data.samlEnable === 'on') {
var entity = args.data.samlEntity;
if (item && entity)
authorizeUsersForSamlSSO([item], entity);
}
args.response.success({
data: item
});

View File

@ -16,8 +16,9 @@
// under the License.
(function(cloudStack, $) {
var rootDomainId;
var rootDomainId;
cloudStack.accountsWizard = {
informationWithinLdap: {
@ -178,6 +179,33 @@
required: false
},
select: function(args) {
var samlChecked = false;
var idpUrl = "";
var appendDomainToUsername = function() {
if (!g_appendIdpDomain) {
return;
}
var username = $('input[name=username]').val();
if (username) {
username = username.split('@')[0];
}
if (samlChecked) {
var link = document.createElement('a');
link.setAttribute('href', idpUrl);
$('input[name=username]').val(username + "@" + link.host.split('.').splice(-2).join('.'));
} else {
$('input[name=username]').val(username);
}
};
args.$form.find('select[name=samlEntity]').change(function() {
idpUrl = $(this).children(':selected').val();
appendDomainToUsername();
});
args.$form.find('input[name=samlEnable]').change(function() {
samlChecked = $(this).context.checked;
appendDomainToUsername();
});
var items = [];
$(g_idpList).each(function() {
items.push({

View File

@ -33,6 +33,7 @@ var g_userPublicTemplateEnabled = "true";
var g_cloudstackversion = null;
var g_queryAsyncJobResultInterval = 3000;
var g_idpList = null;
var g_appendIdpDomain = false;
//keyboard keycode
var keycode_Enter = 13;