Read the intro to this series here.
Have you ever tried hitting one of SharePoint’s APIs from your next million dollar phone app prototype and gotten a HTTP Error 403 Forbidden?
Chances are you are requesting something from SharePoint and its just a bog standard site configured with Windows Auth (NTLM).
On Windows Phone NTLM support isn’t baked into the platform for 3rd party apps.
Note: I hope Microsoft adds support for NTLM in a later release. Currently the Office Hub can connect and authenticate with SharePoint so long as the site address doesn’t include a “.” in the address. e.g. http://myserver/ will work, but http://myserver.contoso.com won’t work. Apparently a “.” in the name makes the stack put it in the “Internet” zone which doesn’t support NTLM. Anyway, I digress.
As far as I know NTLM support out of the box on the “other” mobile platforms like iOS and Android is also limited.
All this makes authenticating with SharePoint a bit more painful than you might initially think. However, if you think about it this limitation it is only really a pain if you are building an app that will only ever be used internally on the same network as SharePoint, rather than externally over the internet since NTLM is no good over the internet. I can think of lots of examples of apps that this would be the case, but many many more where you would want them to connect to SharePoint no matter if you were on the network or out on the internet.
So given NTLM is almost immediately off the table what options does that leave you with?
- Unified Access Gateway (UAG) in front of SharePoint
- Basic Authentication (Auth HTTP header based)
- Forms Authentication
UAG has a feature that lets you configure it to translate Forms Auth to NTLM. Its effectively logs in on your behalf using the credentials you provide. Its pretty cool, but unfortunately is another bit of software you need. If it is an option you are interested in you can read more in this whitepaper: http://technet.microsoft.com/en-us/library/hh180841.aspx
Basic Auth makes things a bit easier. You need to base64 encode the username and password and stuff it in the Authorization HTTP header. If you do want to use this method you will need to make sure you connect over SSL so you don’t disclose your username and password.
Forms Authentication. The reason this is my personal preference is that it is typically the option that people use when exposing SharePoint sites for people access over the internet. For example when you want to invite a partner organization to a SharePoint site you host. In this situation, if you already have Forms set up then its pretty straightforward to connect from a phone app.
Note: For a fantastic guide to setting up Forms Auth you should read Mirjam’s excellent blog posts: Configuring claims and forms based authentication for use with a SQL provider in SharePoint 2010 and/or Configuring claims and forms based authentication for use with an LDAP provider in SharePoint 2010
So how do you programmatically authenticate with a Forms Auth secured site?
SharePoint 2007 and 2010 provide an Authentication SOAP webservice called authentication.asmx that lets you pass a username and password and return a set of authentication cookies that you can attach to future requests.
You can find the auth web service at http://<sharepoint site url>/_vti_bin/authentication.asmx
To ensure you keep a handle on the cookies that come back as part of the response there are a couple of things you should do first before issuing the request.
Note: Full code is available via the link at the end of this post. The code contained in the article are only snippets. Please see the full source.
(Windows Phone specific code) 1st, create a new CookieContainer and attach it to your request. When the response comes back your container will be filled with the right authentication cookies:
private CookieContainer cookieJar = new CookieContainer();
2nd, set up the headers to ensure your request is interpreted correctly & attach the CookieContainer your created:
System.Uri authServiceUri = new Uri(AuthenticationServiceURL); HttpWebRequest spAuthReq = HttpWebRequest.Create(authServiceUri) as HttpWebRequest; spAuthReq.CookieContainer = cookieJar; spAuthReq.Headers["SOAPAction"] = "http://schemas.microsoft.com/sharepoint/soap/Login"; spAuthReq.ContentType = "text/xml; charset=utf-8"; spAuthReq.Method = "POST";
Simply POST a SOAP message with your username and password in it. The SOAP message looks like this:
string envelope = @"<?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>{0}</username> <password>{1}</password> </Login> </soap:Body> </soap:Envelope>";
When the response comes back from SharePoint you should see a response returned as follows:
<?xml version=”1.0″ encoding=”utf-8″?><soap:Envelope xmlns:soap=”http://schemas.xmlsoap.org/soap/envelope/” xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance” xmlns:xsd=”http://www.w3.org/2001/XMLSchema”>
<soap:Body>
<LoginResponse xmlns=”http://schemas.microsoft.com/sharepoint/soap/”>
<LoginResult>
<CookieName>FedAuth</CookieName>
<ErrorCode>NoError</ErrorCode>
<TimeoutSeconds>1800</TimeoutSeconds>
</LoginResult>
</LoginResponse>
</soap:Body>
</soap:Envelope>
The LoginResult bits are the interesting parts. The CookieName tells you the name of the authentication cookie that was issued & ErrorCode tells you if everything worked as expected.
Note: On Windows Phone (7 & 7.5 at least) if you look in the CookieContainer you will NOT see any cookies returned. Don’t let this worry you. They are in there, but they are marked HttpOnly and wont show up in the CookieContainer. Don’t belive me? Take a look with Fiddler 🙂
Ok, so now you have authenticated and you want to get/set some data. What next?
The really important part is setting those cookies when you make your next request. Simply take that CookieContainer you attached to the authentication request, and reattach it to your next request to a SharePoint API. e.g.
System.Net.HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url); request.CookieContainer = App.CookieJar; request.Accept = @"application/json"; request.Method = "GET"; request.BeginGetResponse(new AsyncCallback(GetTasksCallBack), request);
The critical line above is:
request.CookieContainer = App.CookieJar;
This will ensure the “FedAuth” cookie from the authentication process is passed to SharePoint when the request for data is made, and SharePoint will know who you are etc…
In the attached sample code I have wrapped up all the authentication code into a helper class called “Authorization”. You can use it like so:
auth = new Authorization(Constants.USER_NAME, Constants.USER_PASSWORD, Constants.AUTHENTICATION_SERVICE_URL);
auth.OnAuthenticated += auth_OnAuthenticated;
auth.Authenticate();
Then in the event handler “auth_OnAuthenticated” you can grab the cookie container like:
void auth_OnAuthenticated(object sender, AuthenticatedEventArgs e) { App.CookieJar = e.CookieJar; }
The sample below is a Windows Phone 7.5 application called “SPMobile”. It contains the Authorization class mentioned above in the /Auth directory. Additionally it requests data from the default Tasks list on a Team site using REST and JSON. The sample illustrates how you can authenticate and then subsequently attach the cookies to your data requests to SharePoint.
The username, password & paths to your SharePoint site should be set in the Constants.cs file accordingly.
In the next part of this series I will post about requesting and interacting with data via SharePoint’s REST services in a mobile friendly manner.
Thanks,
-Chris.
Update: Fixed all the fat finger “NTML” spelling, should have been “NTLM”.
Pingback: NZ/AU SPC slides – Building Mobile SP Apps–Featuring the “#johnsoncam” « looselytyped.net
Pingback: Developing Mobile apps for SharePoint series – Part 2. Show me the data! « looselytyped.net
Where’s the iOS specific examples for authenticating and connecting to SharePoint 2010?
Hi motionpotion,
I don’t do ios development sorry. Having said that the exact same approach applies. You would simply need to make HTTP requests using whatever the iOS calls are instead.
Be sure to post back here with an example if you do this yourself! 🙂
Thanks,
-Chris.
Hi Chris,
Thanks for replying.
Currently working on an iOS app but Kerberos authentication piece is scuppering my progress. All the examples I find verge on saying it’s possible from Xcode to do this but no example that I have found actually gets it completely working.
Will post back if I get something useful working.
SharePoint 2013 provides an interesting chance of designers to develop cellular phone applications that journey with customers, are entertaining and eye-catching, and are available whenever and wherever customers want to work with them.
The information with example provided on Developing Mobile apps for SharePoint series is really useful for the users.