Tuesday, January 26, 2021

Authenticate in Sharepoint on-prem FBA site via OTB /_vti_bin/Authentication.asmx web service

Sharepoint contains number of OTB web services which are located inside _vti_bin virtual directory. In this article we will check one of them: authentication.asmx. This is quite interesting web service which allows to authenticate your app in Sharepoint FBA site. I.e. allows to send username and password and get FedAuth authentication cookies if provided credentials are valid (the same cookies which are used by Sharepoint FBA site when you successfully logged in via it’s login page).

Note that you may use this web service in server-side apps or mobile apps but not in client side JavaScript-based solution because FedAuth cookies have HttpOnly flag and thus can’t be used in JavaScript.

In order to use this web service we need to send special SOAP body in HTTP POST request. In order to get example of this SOAP open http://example.com/_vti_bin/authentication.asmx in browser (where instead of http://example.com you should use url of your site). It will show list of available web methods:

  • Login
  • Mode

Click on Login and you will get needed SOAP examples (in this article we will use SOAP 1.1):

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Body>
    <Login xmlns="http://schemas.microsoft.com/sharepoint/soap/">
      <username>string</username>
      <password>string</password>
    </Login>
  </soap:Body>
</soap:Envelope>

In this SOAP body we need to set actual username and password in appropriate xml tags.

Here is example which shows how to send this SOAP body to authentication.asmx web service and get authentication cookies:

var cookies = new CookieContainer();
var handler = new HttpClientHandler();
handler.CookieContainer = cookies;
using (var httpClient = new HttpClient(handler))
{
    string soapBody =
    "<soap:Envelope xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'>" +
    "  <soap:Body>" +
    "    <Login xmlns='http://schemas.microsoft.com/sharepoint/soap/'>" +
    "      <username>" + username + "</username>" +
    "      <password>" + password + "</password>" +
    "    </Login>" +
    "  </soap:Body>" +
    "</soap:Envelope>";
    var req = new HttpRequestMessage(HttpMethod.Post, "http://example.com/_vti_bin/authentication.asmx");
    req.Content = new StringContent(soapBody, Encoding.UTF8, "text/xml")
    var res = httpClient.SendAsync(req).GetAwaiter().GetResult();
    if (res.StatusCode == HttpStatusCode.OK)
    {
        var response = res.Content.ReadAsStringAsync().Result;
        var cookie = cookies.GetCookies(new Uri("http://example.com")).Cast<Cookie>().FirstOrDefault(c => c.Name == "FedAuth");
    }
}

In this example we first create HTTP POST request to authentication.asmx using SOAP body retrieved above and then if authentication was successful read FedAuth cookies returned from server. After that we may use these cookies for making authenticated calls to other web services. In one of the future articles I will show how to do that.

No comments:

Post a Comment