Thursday, March 3, 2011

Accessing mixed authentication web app with Client Object Model and Web Serices

I have mixed authentication web app in SharePoint 2010: both Windows (NTLM) and Forms based.
When I tried to access it using Client Object Model with my NTLM credentials I got 401 (Unauthorized) exception. I googled and found this solution

...
clientContext.ExecutingWebRequest += new EventHandler(clientContext_ExecutingWebRequest);
...
}

static void clientContext_ExecutingWebRequest(object sender, WebRequestEventArgs e)
{
e.WebRequestExecutor.WebRequest.Headers.Add("X-FORMS_BASED_AUTH_ACCEPTED", "f");
}


This works well for me.

Then when I tried to access same site using Lists.asmx web service with same NTLM credentials I got exactly same exception.
I added this method to the Web Service wrapper class (it's in Web References > ListWebService > Reference.map > Reference.cs in my case)


protected override System.Net.WebRequest GetWebRequest(Uri uri)
{
System.Net.WebRequest wr = base.GetWebRequest(uri);
wr.Headers.Add("X-FORMS_BASED_AUTH_ACCEPTED", "f");
return wr;
}

That solved the issue as well.

7 comments:

  1. Thanks for posting! This just solved my problem that I had. See http://sharepoint.stackexchange.com/questions/14130/how-do-i-avoid-redirection-for-web-service-authentication-in-sharepoint-2010-when/14132#14132 for details.

    ReplyDelete
  2. Hello, great post and it solves my problem partially.
    I still get the same error when I try to connect from within a SharePoint Custom web service to another SharePoint Custom web service.

    The first web service is called from a Windows Service or from a Windows application. Within the first web service the authentication is working fine and I can get the SPContext.Current.Web.CurrentUser property correctly.
    When I try to access another custom made SharePoint webservice within the ISAPI folder I can not get the SPContext.Current.Web.CurrentUser property while it is NULL.
    Both web services are extended with the GetWebRequest override.

    Do you know what I am missing?
    Thanks in advance!

    ReplyDelete
  3. Problem solved by adding the following piece of code to the initialization of the web service:

    //Check if a HttpContext exists. When calling this from a console app this will be null and settings cookie is not neccessary.
    HttpContext CurrentContext = HttpContext.Current;
    if (CurrentContext != null)
    {
    myPermissionService.CookieContainer = new System.Net.CookieContainer();
    HttpCookie authCookie = CurrentContext.Request.Cookies["FedAuth"];
    if (authCookie != null)
    {
    //when the service is requested anonymously, for example to recover a password, the forms auth cookie will not exist
    myPermissionService.CookieContainer.Add(new Cookie("FedAuth", authCookie.Value, authCookie.Path, CurrentContext.Request.Url.Host));
    }
    }

    ReplyDelete