Tuesday, September 8, 2015

Using NTLM authentication from Salesforce apex

We had requirement of integrating web-services that used NTML authentication from Salesforce.

The whole process of this integration was very interesting and so I thought of writing article which may help someone on how to tackle this type of integration.

Here are points we will cover:

1) What is NTML authentication and how it works

2) How we can use NTML authentication from Apex?

3) If you face any issues how to resolve them?

Ok, Lets start with point #1



1) What is NTML authentication and how it works: 

In a Windows network, NT LAN Manager (NTLM) is a suite of Microsoft security protocols that provides authentication, integrity, and confidentiality to users. There are various versions of it  NTLMv1, NTLMv2 & NTLM session.  Full details of NTLM is out of scope of this article. you can find more details at https://en.wikipedia.org/wiki/NT_LAN_Manager

How it works: 



A) The client sends an initial message to the server, advertising certain options or capabilities such as cryptographic algorithm support .

B) The server creates a challenge, c, and returns the challenge and the options or capabilities that it can support to the client .

C) The client computes a function on the challenge, resp = f(c, password), and sends the results to the server, along with the user's textual name and domain .

D)The server looks up the user (by the name passed) and computes the same function, f(c, user's password). If the result matches resp (that is, what the client sent in step C), the passwords are presumed to match, and the user is authenticated.

More Details: https://msdn.microsoft.com/en-us/library/cc239684.aspx




2) How we can use NTML authentication from Apex?

Well its dead simple. Nate Wallace have wrote apex classes that takes care of all over heads and you just need to deploy these classes to your org and use them.

Here is sample code on how to use these classes and give a call to NTLM SOAP service.


String body = 'XML_REQUEST_BODY_XXXXXXXXXXXXXXXXXXXX';
String ep = 'END_POINT_URL_XXXXXXXXXXXXXX';

HttpClient httpObj = new HttpClient('DOMIN_XXXX\\USERNAME_XXXXXX','PASSWORD_XXXXXXXX',True);  /* Note two forward slashes between domain and username \\  */
HttpRequest req = new HttpRequest();
req.setBody(body);
req.setMethod('POST');
req.setEndpoint(ep);

req.setHeader('Content-Type','text/xml;charset=UTF-8');

HttpResponse res = httpObj.send(req);
System.debug('Response**:' + res);
System.debug('Response**:' + res.getBody());



This should give you a XML response. Well but what if you did not get valid response... this bring us to next topic


3) If you face any issues how to resolve them?

When working on integration there are generally (at least) two components. First is Server and second is client. In our case our endpoint is server and client is in apex. When we face issue it becomes difficult to identify the issue. To resolve issue we should first decide where the issue is? in client or in server?

To find that out we can use tool like SoapUi to replace our client. SoapUi is tested and trusted tool so when we use it properly we eliminate the possibility of client side issue for ex. incorrect  XML.

To use SoapUI with NTLM authentication you need do following:

a) Import WSDL into SoapUI

b) Click on any service and open Request1

c) On left hand bottom side of Request1 there is authorization tab, click on it.

d)  Select add new authorization and select type As NTLM and provide the credentials

e) Now you can replace the ? in your Request1 with actual values and click submit request button.


If you get positive response when you use SoapUi then it means that there is something wrong in your client:
Examples of client side issues:
1) Invalid XML
2) Incorrect parameter in XML
3) Invalid Header
4) 401 error : authentication failed due to user name/ password / domain
5) 500 Internal server error due to wrong data

If you get negative response when you use SoapUi then it means that there is something wrong in your Server:

1) 500 Internal server error due long processing time
2) 401 error:  network restriction like IP restriction  

Conclusion:While working on integration you need to isolation the issue whether its in client or server and then proceed further. 



9 comments:

  1. Hi AtulR,
    i'm testing integration with Dynamics Nav.
    read about ApexNTLM and looking example for it and then saw this usefull post.
    i still don't get it how to pass body request to the service.
    when i try the wsdl in soapui.
    the request xml is:





    done




    i passing the xml to request body nad got response:
    13:06:31:887 VARIABLE_ASSIGNMENT [148]|resp|"System.HttpResponse[Status=Unsupported Media Type, StatusCode=415]"|0x7ce88b34

    can yu help me to pass the Request body?

    Regards,

    Willy

    ReplyDelete
    Replies
    1. This comment has been removed by the author.

      Delete
    2. Hi HokbenLovers,

      Sorry for very delayed response. I guess you must have solve this by now, but still posting my suggestion here so if some one faces this issue again they will have some pointer.

      To know how the request body should exactly look like, we need to use SOAP UI as descried in point # 3. It will give ux exact request and response.

      It will also give us insight on how NTML is working.

      Hope this helps you.

      Delete
    3. Hi AtuIR,

      My problem was that I set header in request, from which headers doesn't copy. When I set them as map and pass as second parameter to send method everything started working just fine.

      Thank you!

      Delete
    4. Good to know that you were able to fix it!

      Delete
  2. This comment has been removed by the author.

    ReplyDelete
  3. Hi Atul,

    I am facing 401 error. I followed all your steps. I am able to hit the service with SOAP UI. Can you please help? Would appreciate if you could have a look at this - https://salesforce.stackexchange.com/questions/219404/401-error-for-ntlm-authentication-with-sharepoint

    ReplyDelete
  4. Hi Atul, I am using NateWallace code in my org but getting internal server error. I am getting expected response using soap UI and postman. Do you have insight what could go wrong in apex callout .

    ReplyDelete
    Replies
    1. Hi Raj, do you to solve the problem? Can you shrare de resolution? I have the same problem. thanks

      Delete