Closed benjaminkohl closed 5 years ago
Great question! Going to pin this because I've got a lot of AD questions lately.
I'm not sure what they mean by identity
but here's what I found after some quick testing.
There are a few things you need to pass along:
https://my-sp.domain.com/sso/login
https://my-sp.domain.com/sso/logout
Once they create the App, ask them to send you the metadata (like normal) but also the Application ID. The application ID needs to be your entity id now. You can overwrite that system-wide by setting it here: /admin/saml-sp/settings
(it can be an environmental variable). Once you set that, you need to recreate "My Provider" so the new entity id is picked up and saved in the plugin correctly.
I think that is it but let me know if you run into any issues.
Side note on mappings....
You can view the metadata to identify the attributes passed on to you. They will look like these:
http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname
http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname
http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress
You can configure the IdP like so:
Great, thank you! We will definitely need to store some of the attributes to the user profile so that will be helpful as well. I'll get back to the client and see what they say and go from there.
The person responsible for our client's Azure AD SSO got back to me with an application ID (uuid), a client secret and a link to the XML metadata. I think all I need is that XML metadata, right? Otherwise I am not sure where that UUID or client secret play into SAML.
Application ID is important here. You need to make the Application ID your Entity ID now. Currently, the best way to overwrite this is to set it system wide here: /admin/saml-sp/settings
. Note that you can set that as an environmental variable. Once that is set make sure to either resave or delete and save a new "My Provider".
I am unable to save the provided application ID to that entity field. I copy and paste it in then click the "Save" button to update the plugin settings and I get the following exception and stack trace:
2019-10-14 09:46:07 [-][9][e8c528f73c65c856b36b93190d958eeb][error][yii\base\InvalidConfigException] yii\base\InvalidConfigException: Object configuration must be an array containing a "class" element. in /home/user/site.com/hub/prod/vendor/yiisoft/yii2/BaseYii.php:353
Stack trace:
#0 /home/user/site.com/hub/prod/vendor/yiisoft/yii2/base/Component.php(750): yii\BaseYii::createObject(Array)
#1 /home/user/site.com/hub/prod/vendor/yiisoft/yii2/base/Component.php(734): yii\base\Component->attachBehaviorInternal('error', Array)
#2 /home/user/site.com/hub/prod/vendor/yiisoft/yii2/base/Component.php(603): yii\base\Component->ensureBehaviors()
#3 /home/user/site.com/hub/prod/vendor/yiisoft/yii2/base/Controller.php(274): yii\base\Component->trigger('beforeAction', Object(yii\base\ActionEvent))
#4 /home/user/site.com/hub/prod/vendor/yiisoft/yii2/web/Controller.php(164): yii\base\Controller->beforeAction(Object(yii\base\InlineAction))
#5 /home/user/site.com/hub/prod/vendor/craftcms/cms/src/web/Controller.php(143): yii\web\Controller->beforeAction(Object(yii\base\InlineAction))
#6 /home/user/site.com/hub/prod/vendor/yiisoft/yii2/base/Controller.php(155): craft\web\Controller->beforeAction(Object(yii\base\InlineAction))
#7 /home/user/site.com/hub/prod/vendor/craftcms/cms/src/web/Controller.php(187): yii\base\Controller->runAction('save', Array)
#8 /home/user/site.com/hub/prod/vendor/yiisoft/yii2/base/Module.php(528): craft\web\Controller->runAction('save', Array)
#9 /home/user/site.com/hub/prod/vendor/craftcms/cms/src/web/Application.php(299): yii\base\Module->runAction('saml-sp/setting...', Array)
#10 /home/user/site.com/hub/prod/vendor/craftcms/cms/src/web/Application.php(566): craft\web\Application->runAction('saml-sp/setting...', Array)
#11 /home/user/site.com/hub/prod/vendor/craftcms/cms/src/web/Application.php(278): craft\web\Application->_processActionRequest(Object(craft\web\Request))
#12 /home/user/site.com/hub/prod/vendor/yiisoft/yii2/base/Application.php(386): craft\web\Application->handleRequest(Object(craft\web\Request))
#13 /home/user/site.com/hub/prod/public/index.php(26): yii\base\Application->run()
#14 {main}
2019-10-14 09:46:07 [-][9][e8c528f73c65c856b36b93190d958eeb][info][application] $_GET = [
'p' => 'admin/saml-sp/settings'
]
This is version 2.0.9 of the plugin and version 3.3.9 of Craft.
Working on a patch for this now.
@benjaminkohl Should be good now. Try running a composer update flipboxfactory/saml-sp
. The core lib should update as well.
Ok, it let me save the settings and per these instructions (WARNING: If this value is changed, you must recreate "My Provider" and exchange the metadata or values with the other provider (IdP or SP).), I went into my provider and re-saved so now I have two providers in the Service Provider List on the Provider List page.
So now I need to grab the metadata XML provided by our client managing the IDP again and paste it into that box for this newly created service provider?
Nope. Just recreate the SP (your provider). So go back to my provider (here: /admin/saml-sp/metadata/my-provider) and save a new one. You'll probably see 2 now. You can delete the one that doesn't match the new entity id/azure AD application id which should be the old one.
Hopefully all of that makes a little sense. Azure wants the Entity ID to be the application id and currently the only way to do that is to set it system wide. When you set that value system-wide, you have to recreate you metadata and save (what happens when you save from /admin/saml-sp/metadata/my-provider) so everything in the craft db is updated.
There is a read-only field for Login Path and it instructed me to place that value as the loginPath item in the general config file. I grabbed the relative URI from that value and placed it in there. When I try to access the site and it redirects to that login path, I just see the 404 page.
The URL it told me to use looks like: sso/login/{uuid}
Ok ... try adding request
into the path like so: /sso/login/request/{uid}
I'll push a patch for that readonly field.
Ok, thanks. Now I see it performing some redirects but I end up at the Craft error screen for "Bad Request" with the following message:
Identity Provider is not found. Possibly a configuration problem. Issuer/EntityId: https://sts.windows.net/{different uuid that came from provider metadata xml}/
Do you see that entity id in the provider list under IdPs? If not, create the idp in the craft plugin with the Azure AD metadata. You should see the entity id there:
I think I needed to recreate the IDP because now the Entity ID changed and I updated the loginPath accordingly and I also recreated the SAML assertion attribute mappings on the IDP like you outlined in a previous comment. It appears to be authenticating now but I am getting the following exception while it attempts to save the user to Craft which results in a 500 error on the site:
2019-10-16 11:03:49 [-][-][c4ad7e583eff0d8d7cd98a1206f39f8e][error][saml-sp] User save failed: {"email":["Email cannot be blank."]} 2019-10-16 11:03:49 [-][-][c4ad7e583eff0d8d7cd98a1206f39f8e][error][yii\base\UserException] yii\base\UserException: User save failed: {"email":["Email cannot be blank."]} in /home/user/domain/hub/prod/vendor/flipboxfactory/saml-sp/src/services/login/User.php:124 Stack trace:
0 /home/user/domain/hub/prod/vendor/flipboxfactory/saml-sp/src/services/login/User.php(99): flipbox\saml\sp\services\login\User->save(Object(craft\elements\User))
1 /home/user/domain/hub/prod/vendor/flipboxfactory/saml-sp/src/services/Login.php(62): flipbox\saml\sp\services\login\User->sync(Object(craft\elements\User), Object(SAML2\Response))
2 /home/user/domain/hub/prod/vendor/flipboxfactory/saml-sp/src/controllers/LoginController.php(85): flipbox\saml\sp\services\Login->login(Object(SAML2\Response))
3 [internal function]: flipbox\saml\sp\controllers\LoginController->actionIndex()
4 /home/user/domain/hub/prod/vendor/yiisoft/yii2/base/InlineAction.php(57): call_user_func_array(Array, Array)
5 /home/user/domain/hub/prod/vendor/yiisoft/yii2/base/Controller.php(157): yii\base\InlineAction->runWithParams(Array)
6 /home/user/domain/hub/prod/vendor/craftcms/cms/src/web/Controller.php(187): yii\base\Controller->runAction('', Array)
7 /home/user/domain/hub/prod/vendor/yiisoft/yii2/base/Module.php(528): craft\web\Controller->runAction('', Array)
8 /home/user/domain/hub/prod/vendor/craftcms/cms/src/web/Application.php(299): yii\base\Module->runAction('saml-sp/login', Array)
9 /home/user/domain/hub/prod/vendor/yiisoft/yii2/web/Application.php(103): craft\web\Application->runAction('saml-sp/login', Array)
10 /home/user/domain/hub/prod/vendor/craftcms/cms/src/web/Application.php(284): yii\web\Application->handleRequest(Object(craft\web\Request))
11 /home/user/domain/hub/prod/vendor/yiisoft/yii2/base/Application.php(386): craft\web\Application->handleRequest(Object(craft\web\Request))
12 /home/user/domain/hub/prod/public/index.php(26): yii\base\Application->run()
13 {main}
Are you sure the fields are configured correctly? Is the email address point to Email
in the craft property column like so? I've made the mistake of not setting that correctly and seeing this error.
Yes, that is set correctly. I've also proofread the Attribute Name a few times to make sure I typed it correctly. I'm not spotting any inconsistencies but just in case, here it is:
http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress
I am currently looking at this documentation. Perhaps the people managing the account haven't configured it to provide the email address. I'll get in touch with them and see what they say.
Ok cool ... Also try using this tail grep command. You should be able to see the attributes or the plugin debug looking for the attributes in there.
tail -f storage/logs/web.log | grep -A 10 -n '\[saml-'
I found that they are sending the email address in the "name" attribute so I updated the plugin settings and I was able to successfully log in. Thanks for all the help with this! It has been very much appreciated.
I'm going to close this but feel free to reopen if needed, on AD specific stuff.
Hi @dsmrt
I am following some of the steps mentioned here in regards to Integration with Azure AD.
I have a question regarding the possibility of mapping Groups via a Role claim - https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-enterprise-app-role-management
The desired result would be to fetch the role of the SSO user in AD and then map it to a Craft group id/name, so the user would be assigned to a Craft group by default, but the one which it would be mapped to depending on the role.
For example :
adRole1 => craftGroup1 adRole2 => craftGroup2 adRole3 => craftGroup3
A new SSO user with an AD role of "adRole1" would get assigned to Craft group "craftGroup1" by default.
I hope this sounds clear enough.
Hi @dsmrt
I am following some of the steps mentioned here in regards to Integration with Azure AD.
I have a question regarding the possibility of mapping Groups via a Role claim - https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-enterprise-app-role-management
The desired result would be to fetch the role of the SSO user in AD and then map it to a Craft group id/name, so the user would be assigned to a Craft group by default, but the one which it would be mapped to depending on the role.
For example :
adRole1 => craftGroup1 adRole2 => craftGroup2 adRole3 => craftGroup3
A new SSO user with an AD role of "adRole1" would get assigned to Craft group "craftGroup1" by default.
I hope this sounds clear enough.
:wave: @tonyclemmey ,
Quick note: The Craft User group must already exist in Craft for any this mapping to work. We used to create groups automatically (if the implementer wanted) but since that breaks with the project config, we can no longer do this.
Thanks for the link. I'm not too familiar with AD role claims but it looks like they come through Assertion Attributes, which should work.
Another thing I notice with your example is the naming from AD roles should map to a Craft group with a different name/handle (ie, adRole1 => craftGroup1). Unfortunately the plugin doesn't have support for this.
The logic is pretty simple:
BUT, you can hook into the plugin using a Yii Event: https://saml-sp.flipboxfactory.com/configure/events.html#examples
If the mapping needed is as described, feel free to put in an enhancement issue in for this feature request. Just be warned, feature requests these days take some time to push out (up to a few months).
We have a setup with Craft as a admin backend, with multisite, that acts like an api for generated static Nuxt as frontend.
All of the sites (1 backend and 2 frontend) have different domains and the users should only login to the backend.
How do i setup so the loginPath
goes to the backend?
When i have tried to set it up it goes to the frontend domain with /sso/login.
My first time adding an SSO, and the costumer haven't used Azure that much either :flushed:
@espensgr moved your question to it's own issue. I think this is more of a static site issue to tackle than an Azure AD issue.
See #101
This issue is no longer the best "instructions" when configuring Azure AD. I've updated the docs based on updates to the plugin here 👉 Azure AD. Please follow those instructions moving forward.
I still think the steps and documentation is a bit confusing for someone that hasen't setup SSO before. Is it possible to make a video click-walkthrough/screencast on how to setup this with Azure AD, or maybe other ones too? It may just be my peanut sized brain though 🤣
That would be nice. I think i could get something like that going.
Also, lack of understanding has nothing to do with size of brain. SAML was built by alien’s to confuse humans and hinder progress. It’s confusing.
I’ll look into the video thing. I think it’d be nice to have a resource like that. Especially with Azure AD.
Nice!
Yeah, i actually think that SAML stands for Sampling Alien Management Licence, so you are correct.
This might be an issue with me not being a SAML expert, but the people that are responsible for managing our client's Azure AD SSO are asking me for redirect URIs for: identity, callback and logout. They said once they get that, they can provide the application ID, client secrets, metadata and token endpoint.
Unless I am mistaken, these sound more like OAuth terms rather than SAML terms. But what do I know? I specifically mentioned SAML in my email to them so I am feeling a bit lost. Are there instructions online for configuring the plugin's settings with Azure AD?
Edit (by @dsmrt): For configuring Azure AD, follow these instructions 👉 Azure AD