Open dsmrt opened 4 years ago
One thing we could do is have a config in the config/saml-sp.php
, like requireSsoLogin
(boolean), which enables and disables this feature. That way as simple code push can mitigate issues that may arise.
Update on this. The biggest thing preventing me from adding this feature overriding the functionality with the elevated session manager and auth manager. See https://github.com/craftcms/cms/blob/62b9b99fc78b69a127db2d2c9003fd4072f15d3b/src/web/assets/cp/src/js/ElevatedSessionManager.js
Basically, to add this feature, I'm worried about the amount of work it'd take to get that piece working (without it being hacky) and the upkeep of the feature.
Is there a status update on this? Because having a normal login can look like a tech risk item for corp.
Having the same requirement here. We are in a government context and the only way to login should be SAML. BTW: there is a new command line feature to create impersonating links which could be used as a fallback for admins in cases SAML/IDP is not working: https://github.com/craftcms/cms/pull/9919
The hard part with this is hooking into Craft where there isn’t extendibility in place.
I was hoping to see that would happen with Craft 4.0 due to there being better integration option for third party authentication/authorization.
I can revisit this and see if there is something more temporary (Craft 3.x to 4.0) we can do.
@hiasl Thanks for the link!
What I will try to do is override the default login page. Create a custom login template that will only list the SSO buttons. I think I saw a way to list/fetch all the SSOs but will have to check. Here is a related solution: https://github.com/craftcms/cms/issues/6134#issuecomment-633395451
Another idea I have, but maybe strictly to the corp I work with is: Disable the login page entirely and use the SSO short link provided by IDP which will log you in and redirect you to Craft.\
Will keep the issue updated. Relevant XKCD (Wisdom of the Ancients).
The hard part with this is hooking into Craft where there isn’t extendibility in place.
I was hoping to see that would happen with Craft 4.0 due to there being better integration option for third party authentication/authorization.
I can revisit this and see if there is something more temporary (Craft 3.x to 4.0) we can do.
Maybe a temporary solution would be to add a twig variable that would allow the user to list the buttons. Because a custom login page won't work because we can't query/fetch anything :cry:
@dsmrt, another issue I have is that the session times out and the enter password box reappears (for native Craft login):
I've even set the userSessionDuration
general configuration parameter to 0, but it still pops up periodically.
When logged in via SSO, what's a user expected to do in this case? Sure a user can go back to the login URL, but most users are unlikely to know they would have to do this.
@timeverts this is one of the biggest hurdles in closing this issue. That is controlled by the "Elevated Session".
You may be able to overwrite it. Look here: https://github.com/craftcms/cms/blob/a7b3d1813b92ef489d3566d30daa9a4688b6ec00/src/web/assets/cp/src/js/ElevatedSessionManager.js
Elevated Session is still a problem (the login modal in the cp). There's a lot that'd go into fixing this including ui changes on the user element and overwriting the set password functionality.
Although, it looks like you can get around the modal (asking for the password) by setting the general config item elevatedSessionDuration
to 0 (zero).
<?php
return [
'elevatedSessionDuration' => 0,
];
Hi, what is the roadmap for this? Has any talk with Pixel & Tonic been initiated to make all these password elements configurable?
This should definitely include P&T because it is a major problem/blocker for SSO.
We currently can't generate a GraphQL token because it is requesting a password validation, our headless development has stopped completely. The problem is there is no solution in sight, because even if you want to copy the reset password link and play around with that (idea) you can't, it requires password validation.
cc @brandonkelly @craftcms
Edit:
I did some digging and found that this modal is created as a part of ElevatedSessionManager
which means if I disable the elevated session this won't popup 'elevatedSessionDuration' => 0. This effect both session expiration and password request for changes.
@timeverts this is one of the biggest hurdles in closing this issue. That is controlled by the "Elevated Session".
You may be able to overwrite it. Look here: https://github.com/craftcms/cms/blob/a7b3d1813b92ef489d3566d30daa9a4688b6ec00/src/web/assets/cp/src/js/ElevatedSessionManager.js
The screenshot above ("Your session has ended") is not the elevated session modal, it's <form id="loginmodal">
which is not present in ElevatedSessionManager.js
. So setting elevatedSessionDuration
to 0
doesn't disable this modal.
This is where it's actually handled: https://github.com/craftcms/cms/blob/3c16404560f03b7c63f31cb6e368fb4787e86dd4/src/web/assets/cp/src/js/AuthManager.js
Any updates on this?
Unfortunately, I don't think we are going to be able to fix this.
There are too many areas that need highly customized overrides that will be impossible to support as new Craft versions come out. Also, there are some areas like forgot password which can't be overwritten. At least, not through Craft.
We've (Craft and us) talked before about the future work here but I don't know where that's at. I just reached out to them now but I know they have a lot to support. I'll see what I can find out.
I just wanted to add my work around for this issue. I copied the code directly for the button from view source and input that into a basic Craft login form, as used as an example on their website: https://craftcms.com/knowledge-base/front-end-user-accounts
< form method="post" accept-charset="UTF-8">
{{ csrfInput() }}
{{ actionInput('users/login') }}
<a href="/sso/login/request/<my idp uid, will make env variable>?RelayState=<my website url/userdash>" class="btn submit">
Via Microsoft AD
</a>
</form >
It's a bit goofy and requires me to find the uid information beforehand, but it works. This is for a government intranet site. I don't have the .env file variable working yet, but that's my next step. This way completely bypasses non-admin users from accessing the craft dashboard.
craftcms/cms#1471 (comment)
I use these patches for a Craft4 site (that I register in every CP page):
jQuery(function ($) {
if (document.body.classList.contains('edit-user')) {
// this is an SSO user?
if ($('#fields-fieldUserSamlIdentity-field table tbody tr').length > 0) {
// disabled a bunch of fields the user should not change
['#username', '#fullName', '#email', '#newPassword'].forEach(function (selector) {
$(selector).addClass('disabled').prop('disabled', true).prop('readonly', true);
});
}
}
// Patch the AuthManager, when we cannot use it because the user is an SSO user and does not have a password
if (window.CurrentBackendUser && CurrentBackendUser.isSSO) {
Craft.AuthManager.prototype.showLoginModal = function () {
var quickShow;
if (this.showingLogoutWarningModal) {
this.hideLogoutWarningModal(true);
quickShow = true;
} else {
quickShow = false;
}
this.showingLoginModal = true;
if (!this.loginModal) {
var $form = $('<div id="loginmodal" class="modal alert fitted"/>'),
$body = $(
'<div class="body"><h2>' +
Craft.t('app', 'Your session has ended.') +
'</h2><p>' +
Craft.t('_patch', 'You need to login with you SSO provider in another tab. After successful login, come back to this tab and refresh the login status.') +
'</p></div>'
).appendTo($form),
$inputContainer = $('<div class="inputcontainer">').appendTo($body),
$inputsFlexContainer = $('<div class="flex"/>').appendTo(
$inputContainer
),
$loginButtonContainer = $('<div/>').appendTo($inputsFlexContainer),
$refreshButtonContainer = $('<div/>').appendTo($inputsFlexContainer);
$('<a class="btn submit" target="_blank"/>')
.attr('href', '/' + Craft.cpTrigger + '/login')
.text(Craft.t('_patch', 'Login again'))
.appendTo($loginButtonContainer);
this.$refreshBtn = Craft.ui.createButton({
label: Craft.t('_patch', 'Refresh login status'),
spinner: true,
})
.appendTo($refreshButtonContainer);
this.$loginErrorPara = $('<p class="error"/>').appendTo($body);
// set these to empty jQuery objects to not break other parts of AuthManager
this.$loginBtn = this.$passwordInput = $('#this-is-not-an-ID');
this.loginModal = new Garnish.Modal($form, {
autoShow: false,
closeOtherModals: false,
hideOnEsc: false,
hideOnShadeClick: false,
shadeClass: 'modal-shade dark loginmodalshade',
onFadeIn: () => {
},
onFadeOut: () => {
},
});
this.addListener(this.$refreshBtn, 'click', 'refreshSessionStatus');
}
if (quickShow) {
this.loginModal.quickShow();
} else {
this.loginModal.show();
}
}
Craft.AuthManager.prototype.refreshSessionStatus = function () {
this.$refreshBtn.addClass('loading');
this.doRefreshSessionStatus = true;
this.clearLoginError();
this.checkRemainingSessionTime();
}
var oldUpdateRemainingSessionTime = Craft.AuthManager.prototype.updateRemainingSessionTime;
Craft.AuthManager.prototype.updateRemainingSessionTime = function (remainingSessionTime) {
oldUpdateRemainingSessionTime.apply(this, arguments);
if (this.doRefreshSessionStatus) {
this.$refreshBtn.removeClass('loading');
if (remainingSessionTime < 1) {
this.showLoginError(Craft.t('_patch', 'Login status did not change.'));
}
this.doRefreshSessionStatus = false;
}
}
}
});
@dsmrt, just wondering whether you have had any further discussions about this with @brandonkelly and the Pixel and Tonic team since Craft 5 was released?
I wonder whether there might be some new functionality in Craft 5 that now makes it possible to only permit SSO login.
I wonder whether there might be some new functionality in Craft 5 that now makes it possible to only permit SSO login.
Well, Craft 5 now has native SAML SSO on enterprise plans, so yes, but highly doubt this is going to be accessible to third party plugins for lower plans.
Basically, only allow login through SAML/SSO.
Please Note: This feature may block all admin users from getting into the Control panel and that might create issues if SSO goes down for any reason.