Microsoft Dynamics CRM Online Office 365 Authentication Deep Dive
In this blog post I will discuss the authentication mechanism and behind the scene communication that happen for CRM 2011 Online Office 365 provisioned organizations using ADFS.
The default CRM 2011 Online Office 365 provisioned organization uses “Authentication Platform” that provides identity storage (Microsoft Online IDs) and authentication. The directory store holds the users’ credentials.
CRM 2011 Online and other cloud based offering from Microsoft rely and trust on authentication platform for validating that the user is authenticated. You need a valid authentication token to access these services.
When you log in to a CRM 2011 Online Office 365 provisioned organization, it first goes to the CRM Online which redirects it to the login page because the user is not authenticated. The user provides the credentials and is authenticated by the authentication platform.
It provides the user with a token which is used by CRM Online to validate that the user is authenticated.
A very basic level communication pattern is as follows:
- Request goes to orgname.crm.dynamics.com
- Redirect to login.microsoftonline.com
- Submit credentials to login.microsoftonline.com
- Get security token response (Key Identifier and Cipher Values)
- Submit security token response to dynamicscrmna.accesscontrol. windows.net to get asymmetric token with new Key Identifier and Cipher Values
- Use the Key Identifier and Cipher values returned by access control service in CRM Organization Request headers.
The communication pattern for a federated CRM 2011 Online organization is largely the same with the following differences:
- The Identity sources move from authentication platform (Office 365) to local Active Directory
- User provisioning can only be done on local Active Directory
- A trust is established between ADFS and Authentication Platform
The following section visualizes the steps above and provides the behind the scene communication XML.
Platform Setup:
Step 1
User tries to access CRM 2011 Online.
Step 2
User is redirected to authentication platform.
Step 3
Since the identity store is local, the user is redirected to ADFS for SAML token.
Request:
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<s:Header>
<a:Action s:mustUnderstand="1">http://docs.oasis-open.org/ws-sx/ws-trust/200512/RST/Issue</a:Action>
<a:MessageID>urn:uuid:8fa2d6d5-338e-4b32-a140-14a22124bf78</a:MessageID>
<a:ReplyTo>
<a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address>
</a:ReplyTo>
<a:To s:mustUnderstand="1">https://sso.contoso.com/adfs/services/trust/13/usernamemixed</a:To>
<o:Security s:mustUnderstand="1" xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<u:Timestamp u:Id="_0">
<u:Created>2013-09-10T18:14:47.734Z</u:Created>
<u:Expires>2013-09-10T18:19:47.734Z</u:Expires>
</u:Timestamp>
<o:UsernameToken u:Id="uuid-41dd8496-cd49-4858-a763-ef25fe91e77d-1">
<o:Username>username@contoso.com</o:Username>
<o:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">password</o:Password>
</o:UsernameToken>
</o:Security>
</s:Header>
<s:Body>
<trust:RequestSecurityToken xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512">
<wsp:AppliesTo xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy">
<a:EndpointReference>
<a:Address>urn:federation:MicrosoftOnline</a:Address>
</a:EndpointReference>
</wsp:AppliesTo>
<trust:KeyType>http://docs.oasis-open.org/ws-sx/ws-trust/200512/Bearer</trust:KeyType>
<trust:RequestType>http://docs.oasis-open.org/ws-sx/ws-trust/200512/Issue</trust:RequestType>
</trust:RequestSecurityToken>
</s:Body>
</s:Envelope>
Step 4
A SAML token with assertions is issued to the user.
Response:
<saml:Assertion MajorVersion="1" MinorVersion="1" AssertionID="_346a9244-c947-4d1f-8643-5af0eafa79de" Issuer="http://SSO.contoso.com/adfs/services/trust" IssueInstant="2013-09-10T18:14:47.971Z" xmlns:saml="urn:oasis:names:tc:SAML:1.0:assertion">
<saml:Conditions NotBefore="2013-08-21T18:14:47.971Z" NotOnOrAfter="2013-08-21T19:14:47.971Z">
<saml:AudienceRestrictionCondition>
<saml:Audience>urn:federation:MicrosoftOnline</saml:Audience>
</saml:AudienceRestrictionCondition>
</saml:Conditions>
<saml:AttributeStatement>
<saml:Subject>
<saml:NameIdentifier Format="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified">42BgKuVbL...</saml:NameIdentifier>
<saml:SubjectConfirmation>
<saml:ConfirmationMethod>urn:oasis:names:tc:SAML:1.0:cm:bearer</saml:ConfirmationMethod>
</saml:SubjectConfirmation>
</saml:Subject>
<saml:Attribute AttributeName="UPN" AttributeNamespace="http://schemas.xmlsoap.org/claims">
<saml:AttributeValue>username@contoso.com</saml:AttributeValue>
</saml:Attribute>
<saml:Attribute AttributeName="ImmutableID" AttributeNamespace="http://schemas.microsoft.com/LiveID/Federation/2008/05">
<saml:AttributeValue>42BgKuVbL...</saml:AttributeValue>
</saml:Attribute>
</saml:AttributeStatement>
<saml:AuthenticationStatement AuthenticationMethod="urn:oasis:names:tc:SAML:1.0:am:password" AuthenticationInstant="2013-08-21T18:14:47.939Z">
<saml:Subject>
<saml:NameIdentifier Format="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified">42BgKuVbL...</saml:NameIdentifier>
<saml:SubjectConfirmation>
<saml:ConfirmationMethod>urn:oasis:names:tc:SAML:1.0:cm:bearer</saml:ConfirmationMethod>
</saml:SubjectConfirmation>
</saml:Subject>
</saml:AuthenticationStatement>
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:SignedInfo>
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
<ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
<ds:Reference URI="#_346a9244-c947-4d1f-8643-5af0eafa79de">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<ds:DigestValue>ABCKC7F2mJzR...
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>afM2Nrb3bFBSKK01frSuoNIC26f...</ds:SignatureValue>
<KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
<X509Data>
<X509Certificate>MIIC7DCCAdSgAwIBAgIQZJlaNfUE9rRAE...</X509Certificate>
</X509Data>
</KeyInfo>
</ds:Signature>
</saml:Assertion>
Step 5
User sends the SAML token to authentication platform for authentication.
Response:
<wst:RequestedSecurityToken>
<EncryptedData xmlns="http://www.w3.org/2001/04/xmlenc#" Id="Assertion0" Type="http://www.w3.org/2001/04/xmlenc#Element">
<EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#tripledes-cbc"></EncryptionMethod>
<ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<EncryptedKey>
<EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p"></EncryptionMethod>
<ds:KeyInfo Id="keyinfo">
<wsse:SecurityTokenReference>
<wsse:KeyIdentifier EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509SubjectKeyIdentifier">D3xjUG3HGa...</wsse:KeyIdentifier>
</wsse:SecurityTokenReference>
</ds:KeyInfo>
<CipherData>
<CipherValue>Dms1ENvwhR1X5EnaWAM4DjTf9sbo77ugNW8zrDuKhrBoQkVHkCxYbRWWGQu3TRHSizfVyTWzdELXMX1kG8wOTF...</CipherValue>
</CipherData>
</EncryptedKey
</ds:KeyInfo
<CipherData>
<CipherValue>jCmWQXjk2WXvyOVpIXG8EBb+pfsWDc14723uaZ3xrqiGamsovYqtLmwzs6cM6s7iP...</CipherValue>
</CipherData>
</EncryptedData>
</wst:RequestedSecurityToken>
Step 6
Authentication Platform (access control service) authenticates the token based on the SAML assertions and returns the new token with a new Unique ID.
Request:
<EncryptedData Id="Assertion0" Type="http://www.w3.org/2001/04/xmlenc#Element" xmlns="http://www.w3.org/2001/04/xmlenc#">
<EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#tripledes-cbc">
<ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<EncryptedKey>
<EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p">
<ds:KeyInfo Id="keyinfo">
<wsse:SecurityTokenReference xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<wsse:KeyIdentifier EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509SubjectKeyIdentifier">D3xjUG3HGaQu...</wsse:KeyIdentifier>
</wsse:SecurityTokenReference>
</ds:KeyInfo>
<CipherData>
<CipherValue>Dms1ENvwhR1X5EnaWAM4...</CipherValue>
</CipherData>
</EncryptedKey>
</ds:KeyInfo>
<CipherData>
<CipherValue>jCmWQXjk2WXvyOVpIXG8EBb+...</CipherValue>
</CipherData>
</EncryptedData>
Response:
<EncryptedAssertion xmlns="urn:oasis:names:tc:SAML:2.0:assertion">
<xenc:EncryptedData Type="http://www.w3.org/2001/04/xmlenc#Element" xmlns:xenc="http://www.w3.org/2001/04/xmlenc#">
<xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes256-cbc" />
<KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
<e:EncryptedKey xmlns:e="http://www.w3.org/2001/04/xmlenc#">
<e:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p">
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
</e:EncryptionMethod>
<KeyInfo>
<o:SecurityTokenReference xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<o:KeyIdentifier ValueType="http://docs.oasis-open.org/wss/oasis-wss-soap-message-security-1.1#ThumbprintSHA1">awMBGpzu/rq...</o:KeyIdentifier>
</o:SecurityTokenReference>
</KeyInfo>
<e:CipherData>
<e:CipherValue>QZUW5oD7gtbzyG97ZacwJqCmu1hnAFG/...</e:CipherValue>
</e:CipherData>
</e:EncryptedKey>
</KeyInfo>
<xenc:CipherData>
<xenc:CipherValue>x701TxJSesab4iqpLqkZbKdxzTPU0Ej/...</xenc:CipherValue>
</xenc:CipherData>
</xenc:EncryptedData>
</EncryptedAssertion>
Step 7
User sends the new authentication token back to CRM 2011 Online for log-in.
Request:
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<a:Action s:mustUnderstand="1">http://schemas.microsoft.com/xrm/2011/Contracts/Services/IOrganizationService/Create</a:Action>
<a:MessageID>urn:uuid:e6bc5b8f-7aaa-4eaf-b6fd-640607e8352e</a:MessageID>
<a:ReplyTo>
<a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address>
</a:ReplyTo>
<VsDebuggerCausalityData xmlns="http://schemas.microsoft.com/vstudio/diagnostics/servicemodelsink">uIDPo2PvyFt4YVJOrMxf6eNDQJMAAAAA...</VsDebuggerCausalityData>
<a:To s:mustUnderstand="1">https://specproduce.crm.dynamics.com/XRMServices/2011/Organization.svc</a:To>
<o:Security s:mustUnderstand="1" xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<u:Timestamp u:Id="_0">
<u:Created>2013-09-10T18:14:48.654Z</u:Created>
<u:Expires>2013-09-10T18:19:48.654Z</u:Expires>
</u:Timestamp>
<EncryptedAssertion xmlns="urn:oasis:names:tc:SAML:2.0:assertion">
<xenc:EncryptedData Type="http://www.w3.org/2001/04/xmlenc#Element" xmlns:xenc="http://www.w3.org/2001/04/xmlenc#">
<xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes256-cbc"/>
<KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
<e:EncryptedKey xmlns:e="http://www.w3.org/2001/04/xmlenc#">
<e:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p">
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
</e:EncryptionMethod>
<KeyInfo>
<o:SecurityTokenReference>
<o:KeyIdentifier ValueType="http://docs.oasis-open.org/wss/oasis-wss-soap-message-security-1.1#ThumbprintSHA1">awMBGpzu/...</o:KeyIdentifier>
</o:SecurityTokenReference>
</KeyInfo>
<e:CipherData>
<e:CipherValue>QZUW5oD7gtbzyG97ZacwJqCmu1hnAFG/...</e:CipherValue>
</e:CipherData>
</e:EncryptedKey>
</KeyInfo>
<xenc:CipherData>
<xenc:CipherValue>x701TxJSesab4iqpLqkZbKdxzTPU0Ej/...</xenc:CipherValue>
</xenc:CipherData>
</xenc:EncryptedData>
</EncryptedAssertion>
</o:Security>
</s:Header>
<s:Body>
<Create xmlns="http://schemas.microsoft.com/xrm/2011/Contracts/Services">
<entity xmlns:b="http://schemas.microsoft.com/xrm/2011/Contracts" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<b:Attributes xmlns:c="http://schemas.datacontract.org/2004/07/System.Collections.Generic">
<b:KeyValuePairOfstringanyType>
<c:key>subject</c:key>
<c:value i:type="d:string" xmlns:d="http://www.w3.org/2001/XMLSchema">fmt test</c:value>
 </b:KeyValuePairOfstringanyType>
</b:Attributes>
<b:EntityState i:nil="true"/>
<b:FormattedValues xmlns:c="http://schemas.datacontract.org/2004/07/System.Collections.Generic"/>
<b:Id>00000000-0000-0000-0000-000000000000</b:Id>
<b:LogicalName>lead</b:LogicalName>
<b:RelatedEntities xmlns:c="http://schemas.datacontract.org/2004/07/System.Collections.Generic"/>
</entity>
</Create>
</s:Body>
</s:Envelope>
Accessing CRM 2011 Online from a non .NET environment
As demonstrated above there is a lot of back and forth communication between the federated service (CRM Online), authentication platform (access control service) and ADFS.
There are samples available online on how to access a CRM 2011 Online Office 365 provisioned organization, but the problem starts when an organization is using ADFS sync or SSO.
You can easily build an XML SOAP message with user credentials and send to the SSO endpoint and it will return the SAML token with assertions. The next step would be to send the SAML assertions to login.microsoftonline.com, and it would return the Key Identifier and Cipher Values.
As per the communication pattern we need to get Key Identifier and Cipher values from the access control service as CRM 2011 Online won’t accept the initial set.
The issue is that the XML SOAP message that access control service accepts has to be signed and the detail on how to do that is internal to the CRM SDK/Identity Model.
Since you can’t sign the XML message to send to the access control service, integration with CRM 2011 cannot work.
During my research and analysis on this problem, I realized that you can create Microsoft Online Ids in case your SSO goes down (in which case no one can access the federated services). To leave a backdoor open we must have this alternate user and this brings me to the conclusion that for CRM 2011 Online, we can create a non-interactive user using Microsoft Online Id.
This user will use the authentication platform instead of local ADFS/SSO and hence can be used by non .NET environments to access CRM for integrations.
I hope you find this blog helpful.
If you have any questions or need additional information, please do not hesitate to contact me at (760) 930-6457 or at mmirza@fmtconsultants.com
References:
http://channel9.msdn.com/Events/TechEd/NorthAmerica/2011/OSP215
http://maso.dk/2011/06/01/how-does-adfs-work-with-office-365/
Authored by:
Mohsin Mirza
Senior CRM Developer, FMT Consultants
Posted by: Jakob Bechgaard