Beefy Boxes and Bandwidth Generously Provided by pair Networks
good chemistry is complicated,
and a little bit messy -LW
 
PerlMonks  

Re: Authenticating to Microsoft Dynamic CRM

by rdfield (Priest)
on Mar 05, 2014 at 17:55 UTC ( #1077118=note: print w/replies, xml ) Need Help??


in reply to Authenticating to Microsoft Dynamic CRM

Having looked at various pieces of code in other languages (e.g. http://crmtroubleshoot.blogspot.co.uk/2013/07/dynamics-crm-2011-php-and-soap-using.html with http://crmtroubleshoot.blogspot.co.uk/2013/07/dynamics-crm-2011-php-and-soap-calls.html and http://blogs.msdn.com/b/girishr/archive/2011/02/04/connecting-to-crm-online-2011-web-services-using-soap-requests-only.aspx), I've cobbled this together, which logs into CRM Dynamics from Perl:
use strict; use warnings; use WWW::Curl::Easy; use Data::GUID; use Date::Manip; use XML::Simple; use Data::Dumper; sub make_guid { my $guidobj = Data::GUID->new; return $guidobj->as_string; } sub curl_request { my ($url,$data) = @_; my $headers = [ 'Connection: Keep-Alive', "Content-type: application/soap+xml; charset=UTF-8", "Content-length: " . length($data), ]; my $curl = WWW::Curl::Easy->new; $curl->setopt(CURLOPT_URL, $url); $curl->setopt(CURLOPT_TIMEOUT, 60); $curl->setopt(CURLOPT_SSL_VERIFYPEER, 0); $curl->setopt(CURLOPT_FOLLOWLOCATION, 1); $curl->setopt(CURLOPT_SSLVERSION, 3); $curl->setopt(CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1); $curl->setopt(CURLOPT_HTTPHEADER, $headers); $curl->setopt(CURLOPT_POST, 1); $curl->setopt(CURLOPT_POSTFIELDS, $data); my $response_body; $curl->setopt(CURLOPT_WRITEDATA,\$response_body); my $retcode = $curl->perform; return $retcode, $response_body; } my $guid = make_guid; my $reqguid = make_guid; my $region = 'urn:crmemea:dynamics.com'; # use your region my $username = 'youremailaddress'; my $password = 'yourpassword'; my $host = "yourhost.crm4.dynamics.com"; # use crm5 etc depending on r +egion my $loginurl = 'https://login.microsoftonline.com/RST2.srf'; my $serviceurl = "https://$host/XRMServices/2011/Organization.svc"; my $OCPRequest = '<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap- +envelope" xmlns:a="http://www.w3.org/2005/08/addressing" xmlns:u="htt +p://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utili +ty-1.0.xsd"> <s:Header> <a:Action s:mustUnderstand="1">http://schemas.xmlsoap.org/ws/200 +5/02/trust/RST/Issue</a:Action> <a:MessageID>urn:uuid:' . $guid . '</a:MessageID> <a:ReplyTo> <a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:A +ddress> </a:ReplyTo> <a:To s:mustUnderstand="1">https://login.microsoftonline.com/RST +2.srf</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>'. UnixDate(ParseDate("now"), "%Y-%m-%dT%H:%M:%S").' +Z</u:Created> <u:Expires>' . UnixDate(ParseDate("24 hours"), "%Y-%m-%dT%H:%M +:%S") . 'Z</u:Expires> </u:Timestamp> <o:UsernameToken u:Id="uuid-cdb639e6-f9b0-4c01-b454-0fe244de73 +af-1"> <o:Username>' . $username . '</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> <t:RequestSecurityToken xmlns:t="http://schemas.xmlsoap.org/ws/2 +005/02/trust"> <wsp:AppliesTo xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/0 +9/policy"> <a:EndpointReference> <a:Address>'. $region .'</a:Address> </a:EndpointReference> </wsp:AppliesTo> <t:RequestType>http://schemas.xmlsoap.org/ws/2005/02/trust/Iss +ue</t:RequestType> </t:RequestSecurityToken> </s:Body> </s:Envelope>'; my ($retcode, $response); ($retcode, $response) = curl_request($loginurl, $OCPRequest); if ($retcode) { die("An error logging in\n"); } my $xml = XMLin($response); my $cipher1 = $xml->{"S:Body"}{'wst:RequestSecurityTokenResponse'}{'ws +t:RequestedSecurityToken'}{'EncryptedData'}{'ds:KeyInfo'}{'EncryptedK +ey'}{'CipherData' }{'CipherValue'}; my $cipher2 = $xml->{"S:Body"}{'wst:RequestSecurityTokenResponse'}{'ws +t:RequestedSecurityToken'}{'EncryptedData'}{ 'CipherData'}{'CipherVal +ue'}; my $keyidentifier = $xml->{"S:Body"}{'wst:RequestSecurityTokenResponse +'}{'wst:RequestedSecurityToken'}{'EncryptedData'}{ 'ds:KeyInfo'}{'Enc +ryptedKey'}{'ds:KeyInfo'}{'wsse:SecurityTokenReference'}{'wsse:KeyIde +ntifier'}{'content'}; my $action = "Execute"; # or Retrieve, Create etc my $envelope_start = ' <s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-en +velope" 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">'; my $crmSoapRequestHeader = ' <s:Header> <a:Action s:mustUnderstand="1"> http://schemas.microsoft.com/xrm/2011/Contracts/Se +rvices/IOrganizationService/' . $action . '</a:Action> <a:MessageID> urn:uuid:' . $reqguid . '</a:MessageID> <a:ReplyTo> <a:Address> http://www.w3.org/2005/08/addressing/anonymous</ +a:Address> </a:ReplyTo> <a:To s:mustUnderstand="1"> ' . $serviceurl . '</a:To> <o:Security s:mustUnderstand="1" xmlns:o="http://docs.oasis-open.org/wss/2004/01/oa +sis-200401-wss-wssecurity-secext-1.0.xsd"> <u:Timestamp u:Id="_0"> <u:Created>' .UnixDate(ParseDate("now"), "%Y-% +m-%dT%H:%M:%S") . 'Z</u:Created> <u:Expires>' . UnixDate(ParseDate("24 hours"), + "%Y-%m-%dT%H:%M:%S") . 'Z</u:Expires> </u:Timestamp> <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"> </EncryptionMethod> <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/0 +9/xmldsig#"> <EncryptedKey> <EncryptionMethod Algorithm="http://www.w3 +.org/2001/04/xmlenc#rsa-oaep-mgf1p"> </EncryptionMethod> <ds:KeyInfo Id="keyinfo"> <wsse:SecurityTokenReference xmlns:wsse= +"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-s +ecext-1.0.xsd"> <wsse:KeyIdentifier EncodingType="http +://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-secu +rity-1.0#Base64Binary" ValueType="http://docs.oasis-open.org/ +wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509SubjectKeyIde +ntifier"> ' . $keyidentifier . ' </wsse:KeyIdentifier> </wsse:SecurityTokenReference> </ds:KeyInfo> <CipherData> <CipherValue> ' . $cipher1 . ' </CipherValue> </CipherData> </EncryptedKey> </ds:KeyInfo> <CipherData> <CipherValue> ' . $cipher2 . ' </CipherValue> </CipherData> </EncryptedData> </o:Security> </s:Header> '; my $retrieveMultipleRequestBodyTemplate =' <s:Body> <Execute xmlns="http://schemas.microsoft.com/xrm/2011/Contracts/Ser +vices" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"> <request i:type="b:WhoAmIRequest" xmlns:a="http://schemas.microsof +t.com/xrm/2011/Contracts" xmlns:b="http://schemas.microsoft.com/crm/2 +011/Contracts"> <a:Parameters xmlns:c="http://schemas.datacontract.org/2004/07/Sy +stem.Collections.Generic" /> <a:RequestId i:nil="true" /> <a:RequestName>WhoAmI</a:RequestName> </request> </Execute> </s:Body> '; my $envelope_end = ' </s:Envelope>'; ($retcode, $response) = curl_request($serviceurl,$envelope_start . $cr +mSoapRequestHeader . $retrieveMultipleRequestBodyTemplate . $envelope +_end); if ($retcode == 0) { print("Transfer went ok\n"); print("Received response: $response\n"); } else { print("An error happened: $retcode \n"); print $envelope_start . $crmSoapRequestHeader . $retrieveMultipleRe +questBodyTemplate . $envelope_end }

rdfield

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://1077118]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others exploiting the Monastery: (7)
As of 2018-11-13 18:21 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    My code is most likely broken because:
















    Results (158 votes). Check out past polls.

    Notices?