Search code examples
phpauthenticationoauth-2.0dynamics-crmadfs

Access Microsoft Dynamics CRM 2016 REST WEB API


I need to access CRM odata REST API for Integration. I have a php cron job for syncing data from CRM. When I hit the endpoint of CRM WEB API https://internal.crm.org.com:5443/appname/api/data/v8.0/ from browser I redirect to the following link : https://adfs.crm.org.com/adfs/ls/?wa=wsignin1.0&wtrealm=https://internal.crm.org.com:5443/&wctx=rm=1&id=4d65271b-682e-44bb-80ce-ed44b5370ed7&ru=%2forgTechnicalTraining%2fdefault.aspx&wct=2016-11-02T07:15:47Z&wauth=urn:federation:authentication:windows and a window is shown to authenticate using username, and password.

So my question is how to authenticate with the resources server? Microsoft point me to this page https://msdn.microsoft.com/library/mt622431.aspx?cs-save-lang=1&cs-lang=csharp#code-snippet-1 and this guy explain how to authenticate using oauth2 http://www.powerobjects.com/2016/01/22/start-your-engines-getting-started-with-the-crm-2016-web-api/#collapse2

Microsoft said dynamics 365 is using three different security models (claims, active dirctory, and auth2 authentications)


Solution

  • I have successfully integrated with CRM web api 2016 using the ws-trust protocol.

    This lib are do the heavy work for you and implment the ws-trust protocol messages. Steps To authenticate with CRM that is protoected by ADFS 3.0 1- Get the samel security token (the endpoint for ws-trust for active authenticate need to be configured on adfs server) 2- Include that token per http request within the header as earer token Code:

    <?php
    
    include_once dirname(dirname(__FILE__)) . '/http.php';
    include_once dirname(dirname(__FILE__)) . '/wstrust.php';
    
    // username/password of a user in the LDAP directory
    // LDAP as configured in the PingFederate Username Token WS-Trust connection settings for Salesforce
    $username = 'username';
    $password = 'password';
    
    // RST appliesTo
    $appliesTo = 'crmservice/api/data/v8.0/';
    
    //STS service
    $IPSTS = 'org/adfs/services/trust/13/UsernameMixed';
    
    // special token type (needs to be enabled in run.properties)
    $tokenType = WSTRUST::TOKENTYPE_SAML20;
    
    // call to IP-STS, authenticate with uname/pwd, retrieve RSTR with generated token
    //get security token
    $result = HTTP::doSOAP(
            $IPSTS,
            WSTRUST::getRSTHeader(
                    WSTRUST::getUserNameToken($username, $password),
                    WSTRUST::getTimestampHeader(), $IPSTS),
            WSTRUST::getRST($tokenType, $appliesTo)
    );
    
    // parse the RSTR that is returned
    list($dom, $xpath, $token, $proofKey) = WSTRUST::parseRSTR($result);
    
    $xpath->registerNamespace('saml', 'urn:oasis:names:tc:SAML:2.0:assertion');
    $token =  $xpath->query('saml:EncryptedAssertion', $token);
    $token = $token->item(0);
    
    // now pass the encrypted assertion to the RP
    $ts = WSTRUST::getTimestampHeader('_0');
    $token = $dom->saveXML($token);
    
    //include the token with the http header per request  like this Authorization: Bearer $token