3

I have existing code that makes plain HTTP requests against the REST API's of SharePoint Online (Project Online):

protected object MakeRESTCall(string restRelativeUrl, RestResultType resultType)
{
    var requestUri = GetAbsoluteRESTUri(restRelativeUrl);
    int timeout = 300000; // 300 seconds
    var restRequest = (HttpWebRequest)WebRequest.Create(requestUri);
    restRequest.Method = "GET";
    restRequest.Timeout = timeout;
    restRequest.ReadWriteTimeout = timeout;
    if (resultType == RestResultType.Json)
    {
        restRequest.Accept = "application/json;odata=verbose";
        restRequest.ContentType = "application/json";
    }
    restRequest.Headers.Add("X-FORMS_BASED_AUTH_ACCEPTED", "f");

    var authCookie = GetAuthCookie();
    var cookies = new CookieContainer();
    cookies.SetCookies(new Uri(Settings.ConnectionInfo.Url), authCookie);
    restRequest.CookieContainer = cookies;

    using (var response = (HttpWebResponse)restRequest.GetResponse())
    {
        if (response.StatusCode != HttpStatusCode.OK)
        {
            throw new Exception($"Server error (HTTP {response.StatusCode}: {response.StatusDescription}).");
        }

        var encoding = response.CharacterSet == string.Empty ? Encoding.UTF8 : Encoding.GetEncoding(response.CharacterSet);

        using (var stream = response.GetResponseStream())
        using (var reader = new StreamReader(stream, encoding))
        {
            var responseString = reader.ReadToEnd();
            object result = responseString;

            if (resultType == RestResultType.Json)
            {
                result = JObject.Parse(responseString);
            }
            return result;
        }
    }
}

The GetAuthCookie() method looks like this:

public string GetAuthCookie()
{
    var creds = GetCredentials();
    return creds.GetAuthenticationCookie(<my url>);
}

The GetCredentials() method looks like this:

private ICredentials GetCredentials()
{
    var securePassword = new SecureString();
    foreach (var c in <password>)
    {
        securePassword.AppendChar(c);
    }

    if (IsOnline)
    {
        return new SharePointOnlineCredentials(<login>, securePassword);
    }
    return new NetworkCredential(<login>, securePassword);
}

The original code used to work for Project Online and used the SharePointOnlineCredentials class, but having to support both Project Online and Project Server, I have changed the GetCredentials()-method to return an ICredentials type instead of the original SharePointOnlineCredentials type.

And the ICredentials-interface does not contain a .GetAuthenticationCookie()-method.

The question is:

How do I rewrite my MakeRESTCall method to work for Project Server as well?

Thanks :-)

  • Hey Jesper :) it heavily depends on the type of authentication, which is used by on-prem server. Wether it NTLM or ADFS based? – Sergei Sergeev Oct 19 '18 at 21:37
  • Hi @SergeiSergeev :-) . I hope you are doing well! I am actually not sure - I suspect it to be NTLM. The target server I am working on is a Hyper-V based VM with an "all-in-one" installation of everything, including FE, App server, SQL server, domain controller etc. – Jesper Lund Stocholm Oct 20 '18 at 8:24
0

Apparently a cookie is not needed for NTLM-authentication, so removing those 4 lines handling the cookie magic, made everything work.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.