
Azure Entra ID
Azure Entra ID (formerly Active Directory) is a Microsoft Azure service which provides identity and access management. Cloud CMS supports single sign on with Azure using SAML 2.0.
Set up Azure
Before configuring the Cloud CMS Single Sign-On, you’ll need to set up a few things on Microsoft Azure Entra ID:
Create an Azure Account
If not already present, create an Azure Account using the Azure portal. Log into the portal and go to *Azure Entra ID.

Register your App

From here create your own application,

Enter the Name for the application and select "Integrate any other application..." and create.

Configure your App
Once the Application is created, you will need to copy down the Application ID
from the overview page:

Here, the Application ID
is 654a7083-4259-424d-88b1-cdb71ee64975
but you will have a different value.
Go to Manage -> Single Sign on and select to setup SAML:

From here you will be given the set of steps to set up the SAML configuration.

For Step 1, enter nameId
as the identifier, and for the reply url, set the value to https://{subdomain}.cloudcms.net/saml

Configure Cloud CMS
Next, let's configure Cloud CMS.
- Log in to Cloud CMS as your manager account. You can do this by going to
https://{subdomain}.cloudcms.net/login
.
Then:
- Go to Platform Settings > SSO.
- Select SAML 2.0 from the list as below:
- In the SAML SSO URL field, enter the
Login URL
found in step 4 of the Azure Single Sign On configuration page

- In the SAML Issuer field, enter the
Application ID
of the application created, found on the Overview page - The signing certificate is required, and can be downloaded from step 3 of the SSO configuration, you will want to download the base64 representation. You will want to open the
.cer
file with a text editor and copy its contents out and into the platform configuration.


In the User Field Mappings section, add the following mappings:
- User Property =
name
and Field Value =http://schemas.microsoft.com/identity/claims/displayname
, orhttp://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress
, or another field which you can ensure only contains lowercase alphanumeric and email designated characters, no spaces. - User Property =
email
and Field Value =http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress
- User Property =
firstName
and Field Value =http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname
- User Property =
lastName
and Field Value =http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname

Save your changes.
Try it out
You can now verify that Cloud CMS is configured to use SAML 2.0 with Azure:
- Log out of your current Cloud CMS account
- Log back in
- While Logging in again, you will be re-directed to Microsoft Azure portal.
- Enter the username and password of your account.
- If the credentials match, you will be redirected back to Cloud CMS.
- Cloud CMS will automatically log you in and create your user if it doesn't yet exist.
- Proceed and may the force be with you.
Technical Notes
We've collected some technical notes here to help with integrating to Azure Entra ID.
Redirect URI
When Cloud CMS redirects to Azure Entra ID, it will pass a "redirect URI" to Azure. This must match the value that you have configured for your Redirect URI within Azure. Typically, this will be:
https://{subdomain}.cloudcms.net/saml
SAML Assertion
Once you've authenticated to Azure, Azure will perform a POST back to this URL. The POST will contain a request parameter called SAMLResponse
. This value is a Base64 encoded XML string that contains a SAML assertion. It contains validation of the authenticated user and also contains multiple claims
about the user. These consist of user properties and/or group information.
If you're using a browser, you can open up the Dev Tools of the browser to inspect the assertion POST. Make sure to set logs to persist so that the browser doesn't clear the logging between domain redirects.
The JWT token might look something like:
SAMLResponse: PHNhbWxwOlJlc3BvbnNlIElEPSJfOGZjMzNmMTMtYzI0YS00NzA0LWJlODEtNWRlMmViNDhmZGVhIiBWZXJzaW9uPSIyLjAiIElzc3VlSW5zdGFudD0iMjAyMC0wNi0wMlQxNDo1OTozOC45OTdaIiBEZXN0aW5hdGlvbj0iaHR0cDovL2xvY2FsaG9zdC9zYW1sL2NvbnN1bWUiIEluUmVzcG9uc2VUbz0iX2UyMWViODJhNzVmNDM0ODdmZGYyIiB4bWxuczpzYW1scD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOnByb3RvY29sIj48SXNzdWVyIHhtbG5zPSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6YXNzZXJ0aW9uIj5odHRwczovL3N0cy53aW5kb3dzLm5ldC8zNzcwZjU4NS0xZDliLTQ0ZDQtOTAxNi0yNDI4ZDAwODIxNTQvPC9Jc3N1ZXI+PHNhbWxwOlN0YXR1cz48c2FtbHA6U3RhdHVzQ29kZSBWYWx1ZT0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOnN0YXR1czpTdWNjZXNzIi8+PC9zYW1scDpTdGF0dXM+PEFzc2VydGlvbiBJRD0iXzFjMTA0YTI5LTBiOWUtNDA3ZC05ZjRlLWJhNjExYTcwYzEwMCIgSXNzdWVJbnN0YW50PSIyMDIwLTA2LTAyVDE0OjU5OjM4Ljk4MloiIFZlcnNpb249IjIuMCIgeG1sbnM9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDphc3NlcnRpb24iPjxJc3N1ZXI+aHR0cHM6Ly9zdHMud2luZG93cy5uZXQvMzc3MGY1ODUtMWQ5Yi00NGQ0LTkwMTYtMjQyOGQwMDgyMTU0LzwvSXNzdWVyPjxTaWduYXR1cmUgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvMDkveG1sZHNpZyMiPjxTaWduZWRJbmZvPjxDYW5vbmljYWxpemF0aW9uTWV0aG9kIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS8xMC94bWwtZXhjLWMxNG4jIi8+PFNpZ25hdHVyZU1ldGhvZCBBbGdvcml0aG09Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvMDQveG1sZHNpZy1tb3JlI3JzYS1zaGEyNTYiLz48UmVmZXJlbmNlIFVSST0iI18xYzEwNGEyOS0wYjllLTQwN2QtOWY0ZS1iYTYxMWE3MGMxMDAiPjxUcmFuc2Zvcm1zPjxUcmFuc2Zvcm0gQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwLzA5L3htbGRzaWcjZW52ZWxvcGVkLXNpZ25hdHVyZSIvPjxUcmFuc2Zvcm0gQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxLzEwL3htbC1leGMtYzE0biMiLz48L1RyYW5zZm9ybXM+PERpZ2VzdE1ldGhvZCBBbGdvcml0aG09Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvMDQveG1sZW5jI3NoYTI1NiIvPjxEaWdlc3RWYWx1ZT5uM1VLNlhZcUV5dFpwdjA3R1dxdEt4MkJSekYvRDErcndmMnlrYW5FQzl3PTwvRGlnZXN0VmFsdWU+PC9SZWZlcmVuY2U+PC9TaWduZWRJbmZvPjxTaWduYXR1cmVWYWx1ZT5INGxvdjBMb3FMVk1YS0VPb3ZVSURMSlJTL09LOGx3QlpFclJ5UmJxZXlKUGNjalZucHZ1NVcxcUUvRjhNL2pVam5PZjl5azlrckE1N1d1dkFnUUcxcE5XL3Jsb2J4SWtqd08wRlRvcUJtQm9Ldk1LeWRYT2V6TWRVd3dEcEt0QVNTSDZnNDNDNlBMSmI5TG5yYUVhdEpXNWhIdjZXZ2U4OXMyRjZsWmlpamdTM1NKYlpkRi83OHorUVU1ODhTMk40WVEwbzNEMWdNMFA0S3NJTHZsOVgxWGdIZ3hvaGowMk4zd0k2bjlzSGM4Z1dTQ295WmR4Z3BUM2hqcUNmN2dFcGh1VjdlbFNMMjEyWi9DRU4xa3R5a1NWSG5OMzhteTh2ZTVvbHFRc2pHb1pTSXFuSG40Z3dZOEEyaTRJVFU2WU1PRW93MWdPZFV0RGFtK0tKUm1EZmc9PTwvU2lnbmF0dXJlVmFsdWU+PEtleUluZm8+PFg1MDlEYXRhPjxYNTA5Q2VydGlmaWNhdGU+TUlJREJUQ0NBZTJnQXdJQkFnSVFYVm9najlCQWY0OUlwdU9TSXZ6dE5EQU5CZ2txaGtpRzl3MEJBUXNGQURBdE1Tc3dLUVlEVlFRREV5SmhZMk52ZFc1MGN5NWhZMk5sYzNOamIyNTBjbTlzTG5kcGJtUnZkM011Ym1WME1CNFhEVEl3TURNeE56QXdNREF3TUZvWERUSTFNRE14TnpBd01EQXdNRm93TFRFck1Da0dBMVVFQXhNaVlXTmpiM1Z1ZEhNdVlXTmpaWE56WTI5dWRISnZiQzUzYVc1a2IzZHpMbTVsZERDQ0FTSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQ2dnRUJBTmZMbWR6OXlJRHNrcFp6ck1YaURlVmxDczc1WnVucnp3ekJXNWx6N1V4ZEJqSHU3UTlpVDMyb3RsQnArK0xPd0JjS3NWanVRMEdVYnVsWDBGTHNmTGpFZUNlNThadFNuLy8rNlZSRlNTY2c3aStXdkR3RVVXRUxSK3ZNUHRDR2NYQlRwSUxFblliU016ME5vNCtKcGtjMWx5TUlmRFAvS1NlcW9qbzc0eGZXNFJLdEFndjM5dXdaNVl6MmhaL0ljV092YVFxTVhwMWxxaFhMRklSV2J3akxZWVVibXdHd1lwUTYrK0NtbDB1Y1FvTWtnWVQ4OEhwQS9melhRbExnckhhbXIzZUUvbFZwMjZaV3dmR0xBdmtkTkJhYlFSU3JrOGsvYzZCbVkxbVlwVUZabys3OTVQSTE2bUFkcDFpb0V3SDhJNW9zaXMrL0JSNUdoUHB3aUE4Q0F3RUFBYU1oTUI4d0hRWURWUjBPQkJZRUZGOE1ER2tsT0doR05WSnZzSEhSQ2FxdHpleGNNQTBHQ1NxR1NJYjNEUUVCQ3dVQUE0SUJBUUNLa2Vndy9tZHBDVmwxbE9wZ1U0RzlSVCsxZ3RjUHFaSzlrcGltdURnZ1NKanU2S1VRbE9DaTUvbElINURDenBqRmRtRzE3VGpXVkJOdmU1a293bXJoTHpvdlkwWWtrNys2aFlUQks4ZE5OU21kNFNLN3pZKyswYURJdU96SFAyQ3VyK2tnRkMwZ2V6NTB0UHpvdExEdE1tcDQwZ2tuWHV6bHR3SmZlek5TdzNnTGdsakRzR0djRElYSzNxTFNZaDQ0cVN1Ukd3dWxjTjJFSlVaQkk5dEl4b09EcGFXSElOOCt6MnVadmY4SkJZRmpBMytuOUZSUW41MVgxNkNUY2pxNFFSVGJOVnBnVnVRdXlhWW5FdHgwWm5Edmd1QjNSakdTUElYVFJCa0xsMng3ZTgvNnVBWjZ0Y2h3OHJoY090UHNGZ0p1b0pva0dqdmNVU1IvNkVxZDwvWDUwOUNlcnRpZmljYXRlPjwvWDUwOURhdGE+PC9LZXlJbmZvPjwvU2lnbmF0dXJlPjxTdWJqZWN0PjxOYW1lSUQgRm9ybWF0PSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoxLjE6bmFtZWlkLWZvcm1hdDplbWFpbEFkZHJlc3MiPm1pY2hhZWwudXpxdWlhbm9AY2xvdWRjbXMuY29tPC9OYW1lSUQ+PFN1YmplY3RDb25maXJtYXRpb24gTWV0aG9kPSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6Y206YmVhcmVyIj48U3ViamVjdENvbmZpcm1hdGlvbkRhdGEgSW5SZXNwb25zZVRvPSJfZTIxZWI4MmE3NWY0MzQ4N2ZkZjIiIE5vdE9uT3JBZnRlcj0iMjAyMC0wNi0wMlQxNTo1OTozOC44MDlaIiBSZWNpcGllbnQ9Imh0dHA6Ly9sb2NhbGhvc3Qvc2FtbC9jb25zdW1lIi8+PC9TdWJqZWN0Q29uZmlybWF0aW9uPjwvU3ViamVjdD48Q29uZGl0aW9ucyBOb3RCZWZvcmU9IjIwMjAtMDYtMDJUMTQ6NTQ6MzguODA5WiIgTm90T25PckFmdGVyPSIyMDIwLTA2LTAyVDE1OjU5OjM4LjgwOVoiPjxBdWRpZW5jZVJlc3RyaWN0aW9uPjxBdWRpZW5jZT5zcG46M2VmZDlkOTctMjZlNC00ODM3LWJkNzUtOTFhMzRjMmRhNGVlPC9BdWRpZW5jZT48L0F1ZGllbmNlUmVzdHJpY3Rpb24+PC9Db25kaXRpb25zPjxBdHRyaWJ1dGVTdGF0ZW1lbnQ+PEF0dHJpYnV0ZSBOYW1lPSJodHRwOi8vc2NoZW1hcy5taWNyb3NvZnQuY29tL2lkZW50aXR5L2NsYWltcy90ZW5hbnRpZCI+PEF0dHJpYnV0ZVZhbHVlPjM3NzBmNTg1LTFkOWItNDRkNC05MDE2LTI0MjhkMDA4MjE1NDwvQXR0cmlidXRlVmFsdWU+PC9BdHRyaWJ1dGU+PEF0dHJpYnV0ZSBOYW1lPSJodHRwOi8vc2NoZW1hcy5taWNyb3NvZnQuY29tL2lkZW50aXR5L2NsYWltcy9vYmplY3RpZGVudGlmaWVyIj48QXR0cmlidXRlVmFsdWU+N2E3NmIzNTAtMDAyMS00MDBhLTg3MmItNGRmNzU0MzNmNTEyPC9BdHRyaWJ1dGVWYWx1ZT48L0F0dHJpYnV0ZT48QXR0cmlidXRlIE5hbWU9Imh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3dzLzIwMDUvMDUvaWRlbnRpdHkvY2xhaW1zL3N1cm5hbWUiPjxBdHRyaWJ1dGVWYWx1ZT5mZDI1MWU5Zi1lZGUyLTQ4NjAtYmNiZi00Y2FiYzQxYTc0YjE8L0F0dHJpYnV0ZVZhbHVlPjwvQXR0cmlidXRlPjxBdHRyaWJ1dGUgTmFtZT0iaHR0cDovL3NjaGVtYXMueG1sc29hcC5vcmcvd3MvMjAwNS8wNS9pZGVudGl0eS9jbGFpbXMvZ2l2ZW5uYW1lIj48QXR0cmlidXRlVmFsdWU+NjdlOGY0NjctNmQ2ZS00MWIyLTllZGYtODdhMjU4YWFmMjJiPC9BdHRyaWJ1dGVWYWx1ZT48L0F0dHJpYnV0ZT48QXR0cmlidXRlIE5hbWU9Imh0dHA6Ly9zY2hlbWFzLm1pY3Jvc29mdC5jb20vaWRlbnRpdHkvY2xhaW1zL2Rpc3BsYXluYW1lIj48QXR0cmlidXRlVmFsdWU+NjdlOGY0NjctNmQ2ZS00MWIyLTllZGYtODdhMjU4YWFmMjJiIGZkMjUxZTlmLWVkZTItNDg2MC1iY2JmLTRjYWJjNDFhNzRiMTwvQXR0cmlidXRlVmFsdWU+PC9BdHRyaWJ1dGU+PEF0dHJpYnV0ZSBOYW1lPSJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9lbWFpbGFkZHJlc3MiPjxBdHRyaWJ1dGVWYWx1ZT5taWNoYWVsLnV6cXVpYW5vQGNsb3VkY21zLmNvbTwvQXR0cmlidXRlVmFsdWU+PC9BdHRyaWJ1dGU+PEF0dHJpYnV0ZSBOYW1lPSJodHRwOi8vc2NoZW1hcy5taWNyb3NvZnQuY29tL2lkZW50aXR5L2NsYWltcy9pZGVudGl0eXByb3ZpZGVyIj48QXR0cmlidXRlVmFsdWU+bGl2ZS5jb208L0F0dHJpYnV0ZVZhbHVlPjwvQXR0cmlidXRlPjxBdHRyaWJ1dGUgTmFtZT0iaHR0cDovL3NjaGVtYXMubWljcm9zb2Z0LmNvbS9jbGFpbXMvYXV0aG5tZXRob2RzcmVmZXJlbmNlcyI+PEF0dHJpYnV0ZVZhbHVlPnVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDphYzpjbGFzc2VzOlBhc3N3b3JkUHJvdGVjdGVkVHJhbnNwb3J0PC9BdHRyaWJ1dGVWYWx1ZT48QXR0cmlidXRlVmFsdWU+aHR0cDovL3NjaGVtYXMubWljcm9zb2Z0LmNvbS93cy8yMDA4LzA2L2lkZW50aXR5L2F1dGhlbnRpY2F0aW9ubWV0aG9kL3Vuc3BlY2lmaWVkPC9BdHRyaWJ1dGVWYWx1ZT48L0F0dHJpYnV0ZT48L0F0dHJpYnV0ZVN0YXRlbWVudD48QXV0aG5TdGF0ZW1lbnQgQXV0aG5JbnN0YW50PSIyMDIwLTA2LTAyVDE0OjUwOjA2LjYzNFoiIFNlc3Npb25JbmRleD0iXzFjMTA0YTI5LTBiOWUtNDA3ZC05ZjRlLWJhNjExYTcwYzEwMCI+PEF1dGhuQ29udGV4dD48QXV0aG5Db250ZXh0Q2xhc3NSZWY+dXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOmFjOmNsYXNzZXM6UGFzc3dvcmRQcm90ZWN0ZWRUcmFuc3BvcnQ8L0F1dGhuQ29udGV4dENsYXNzUmVmPjwvQXV0aG5Db250ZXh0PjwvQXV0aG5TdGF0ZW1lbnQ+PC9Bc3NlcnRpb24+PC9zYW1scDpSZXNwb25zZT4=
Not very attractive. That's because it is Base64 encoded. You can use an online tool (such as https://www.base64decode.org/) to decode the Base64 string and you'll get something like this:
<samlp:Response ID="_8fc33f13-c24a-4704-be81-5de2eb48fdea" Version="2.0" IssueInstant="2020-06-02T14:59:38.997Z" Destination="http://mysubdomain.cloudcms.net/saml/consume" InResponseTo="_e21eb82a75f43487fdf2" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol">
<Issuer xmlns="urn:oasis:names:tc:SAML:2.0:assertion">https://sts.windows.net/3770f585-1d9b-44d4-9016-2428d0082154/</Issuer>
<samlp:Status>
<samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success" />
</samlp:Status>
<Assertion ID="_1c104a29-0b9e-407d-9f4e-ba611a70c100" IssueInstant="2020-06-02T14:59:38.982Z" Version="2.0" xmlns="urn:oasis:names:tc:SAML:2.0:assertion">
<Issuer>...</Issuer>
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
...
</Signature>
<Subject>
<NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress">joe.smith@company.com</NameID>
<SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
<SubjectConfirmationData InResponseTo="_e21eb82a75f43487fdf2" NotOnOrAfter="2020-06-02T15:59:38.809Z" Recipient="https://mysubdomain.cloudcms.net/saml/consume" />
</SubjectConfirmation>
</Subject>
<Conditions NotBefore="2020-06-02T14:54:38.809Z" NotOnOrAfter="2020-06-02T15:59:38.809Z">
<AudienceRestriction>
<Audience>...</Audience>
</AudienceRestriction>
</Conditions>
<AttributeStatement>
<Attribute Name="http://schemas.microsoft.com/identity/claims/tenantid">
<AttributeValue>0f583775-1d9b-44d4-9016-008212428d54</AttributeValue>
</Attribute>
<Attribute Name="http://schemas.microsoft.com/identity/claims/objectidentifier">
<AttributeValue>76b37a50-0021-400a-872b-75433f4df512</AttributeValue>
</Attribute>
<Attribute Name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname">
<AttributeValue>Smith</AttributeValue>
</Attribute>
<Attribute Name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname">
<AttributeValue>Joe</AttributeValue>
</Attribute>
<Attribute Name="http://schemas.microsoft.com/identity/claims/displayname">
<AttributeValue>Joe Smith</AttributeValue>
</Attribute>
<Attribute Name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress">
<AttributeValue>joe.smith@company.com</AttributeValue>
</Attribute>
<Attribute Name="http://schemas.microsoft.com/identity/claims/identityprovider">
<AttributeValue>live.com</AttributeValue>
</Attribute>
<Attribute Name="http://schemas.microsoft.com/claims/authnmethodsreferences">
<AttributeValue>urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport</AttributeValue>
<AttributeValue>http://schemas.microsoft.com/ws/2008/06/identity/authenticationmethod/unspecified</AttributeValue>
</Attribute>
</AttributeStatement>
<AuthnStatement AuthnInstant="2020-06-02T14:50:06.634Z" SessionIndex="_14a2c109-b09e-740d-9f4e-611a7ba0c100">
<AuthnContext>
<AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport</AuthnContextClassRef>
</AuthnContext>
</AuthnStatement>
</Assertion>
</samlp:Response>
The attributes that you can use for user and group mappings are listed in the <AttributeStatement>
section.
Note that Azure sends all of its attribute names in a rather lengthy domain-qualified manner. For example, instead of sending displayname
, they send http://schemas.microsoft.com/identity/claims/displayname
.
SAML 2.0 supports namespaces for attribute names but Microsoft has elected to go with the long format.
You can add new attributes within Azure Entra ID by adding new claims. Click on Token Configuration to be taken to a screen where you can add new claims.

After you add claims, they will appear under the <AttributeStatement>
section. Be sure to check your SAMLResponse
after making changes to see the attribute names that come back.
In addition, note that the values you get back will match the entry for the principals as stored in Entra ID. Azure's SAML 2.0 support always sends the attributes listed above and, if it doesn't know a value, you may see a GUID. You'll need to work with Entra ID to make sure that your users have values assigned for:
surname
givenname
displayname
As well as another attributes that you map via SAML assertions.