Saturday 12 January 2013

Authenticating .NET CSOM in SharePoint Online

The process of authenticating the .NET Client Object Model in SharePoint Online has been greatly simplified in the 2013 version. Earlier (2010), you had to go through a lot of steps for doing the exact same thing. You  had to open a web browser instance, force the user to enter the credentials in the browser and then grab that  cookie from Internet Explorer and pass it to the .NET CSOM. If you are interested, the code of the old authentication method can be found here:
http://blogs.msdn.com/b/cjohnson/archive/2011/05/03/authentication-with-sharepoint-online-and-the-client-side-object-model.aspx

Fortunately in the 2013 version, the process is a lot simplified by the introduction of the SharePointOnlineCredentials class. This class is part of the Microsoft.SharePoint.Client.dll itself so you don't have to include an extra assembly in your application. All you have to do is pass an instance of the SharePointOnlineCredentials class to the ClientContext.Credentials property. The SharePointOnlineCredentials takes in two parameters which are your Login Email for your Office 365 SharePoint site and your password in the SecureString format.

You can grab all the required SharePoint 2013 client assemblies from here:
http://www.microsoft.com/en-us/download/details.aspx?id=35585

For this particular demo, you will need to reference the Microsoft.SharePoint.Client.dll and the Microsoft.SharePoint.Client.Runtime.dll assemblies in your project.

 The code is as follows:




39 comments:

Anonymous said...

Great post - I can get it working great on my Windows 8 VS 2012 Development machine but it fails when deploying. msoidclil.dll was missing and once I registered it on the IIS server, some of its dependencies appear missing. Any pointers on what needs installed on the IIS server (2008 R2)?

Thanks!

Vardhaman Deshpande said...

Hi Anonymous,

You will probably need to manually install the O365 Pre-Upgrade software on your Server 2008 R2. Here a is a link which should help you out:
http://community.office365.com/en-us/wikis/manage/562.aspx

The msoidcli.dll is one of libraries which provides the framework for authentication in Office 365. Learn more about it here: http://community.office365.com/en-us/wikis/officeapps/534.aspx

Erik Hoeksma said...

Hi there,

Thanks for this post. this seems to work properly when developing locally, but I tried to push this to azure websites, and there it gives me the "401 - Unauthorized" error, with the exact same code (it does try to connect, just not authorized.

Would you know how I can fix this ?

Unknown said...

This is great but can I authenticate against Office 365 using this? I want to log the person in? How do I get the authcookie?

Unknown said...

Looks promising. However, how do you handle authentication when you use active sync with ADFS? Are there any examples of this? I have really struggled trying to find examples on how to do this.

What about the file size limit. It was previously 3MG, however recently it was closer to 2MG. I have had to change to posting a request, and then updating the fields using CSOM. It really needs to be over 5MG, if not 20+.

Unknown said...

Eric, sorry replying late but I guess you need to use ACS with Azure websites as mentioned here http://blogs.technet.com/b/speschka/archive/2013/01/29/using-acs-with-the-new-azure-web-sites.aspx

Unknown said...

Hi....GREAT POST!!!! I've been struggling to connect a .Net app with Sharepoint online. I tried the code you posted, but I'm getting the follwing error: "The identity has not been authenticated". However I know for sure that the URL, username and password are correct, since I can connect directly from the borwser (open the URL, get the Office365 login screen, enter username and password).

Any ideas?
Kind regards, Ariel

Vardhaman Deshpande said...

Hi Ariel,

Are you sure that you are connecting to a SharePoint Online 2013 version? This authentication method is not supported for SharePoint Online 2010. Also, if you don't mind sending me the URL of your site and the credentials of a test user, I could check out what the problem is exactly.

Unknown said...

Thank you for your response Vardhaman. I'm pretty sure it's a Sharepoint 2013 Online. The url is https://agroprimedemo.sharepoint.com. Username: bloguser@agroprimedemo.onmicrosoft.com
Pass: Chile001
The error I'm receiving is "The identity has not been authenticated."
To stay in touch, my email is aplon@xms.cl.
Best regards, Ariel

Vardhaman Deshpande said...

Hi Ariel,

I have tried your credentials and it works for me. Here is my sample project
https://dl.dropboxusercontent.com/u/21118137/SPOnlineAuth.zip

You can take a look at the code.

Unknown said...

Thank you Vardhaman. Worked like a charm. I used your code, translated to vb.net and....voila: I got sharepoint 2013 integration :)

THANK YOU SO MUCH!!!!
YOU ARE THE MAN :)
Best regards, Ariel

Unknown said...

Worked like a charm!!!
Once again....YOU ARE THE MAN!!!!
Thanks for this

Vardhaman Deshpande said...

Glad it helped you :)

Steven C. Britton said...

I've tried to get this working using Office 2013, and it won't authenticate my client.

I have a @live.com login, so I've tried the following:

live.com#username@live.com (fails)
username@live.com (fails)
live.com#username (doesn't recognize as valid)

I've also tried both HTTP and HTTPS tags on the url, and ALSO, I've tried both http[s]://subdomain.sharepoint.com (which does not need authentication) as well as http[s]://subdomain.sharepoint.com/Path/ (which does require authentication)

Each and every time, the code fails here: clientContext.Credentials = new SharePointOnlineCredentials("loginname@yourside.onmicrosoft.com",passWord);

with a "The identity has not be authenticated" error.

What am I missing? I've been pounding my head against this for weeks, and I'm getting extremely frustrated with it.

Anonymous said...

Anyone had any luck deploying this in an app to Office365? I get "File Not Found Exception msoidcliL.dll" but works fine locally..

Anonymous said...

Hi,

I getting the "Catastrophic failure (Exception from HRESULT: 0x8000FFFF (E_UNEXPECTED))" error in the SharePointOnlineCredentials. Do you know how I can fix it?

And is it possible to use Active Directory's user in SharePointOnlineCredentials?

Thanks.

Anonymous said...

Hi All,

Bit late but hope someone of you can see this.
I have followed same code lines for SPO 2013 but I am getting an error at clientContext.ExecuteQuery();.

Error says - The remote server returned an error: (403) Forbidden.

Appreciate any help.

Thanks,
vv

Andy said...

Like the 1st commenter, it works great on my PC. It does not work on my Windows Server. I get "FileNotFoundException: msoidcliL.dll" I have msoidcliL.dll (and the 2 Microsoft.SharePoint.Client.dll files) in the bin. VS will not let me add msoidcliL.dll as a reference. Thoughts?

Vardhaman Deshpande said...

@Andy

This might help?

http://tomaszrabinski.pl/wordpress/2013/03/18/sharepointonlinecredentials-and-msoidclil-dll-file-not-found-exception/

Andy said...

Thanks, that contains good info about what the msoidcliL.dll issue may be. However, in my case, I cannot modify the registry on my shared server. And I can't install the "Client Components SDK". I see more people with the same issue, but I don't see a solution yet.

Atul Sureka said...

I found lot of articles on internet about SharePoint authentication. Almost of all of them were pointing to same MSDN codebase that does not work with client service. It really helped me to resolve this issue.

Great post Vardhaman. Thanks

Atul Sureka

bittusrk said...

Works like a charm really! It would just make my day if I can get rid of mentioning the password in this code. Can this be done somehow Vardhaman?

Brett said...

What about if you were trying to authenticate Wordpress using Sharepoint credentials. Could you do that using JS or PHP?

Vardhaman Deshpande said...

@Brett

I have not tested it but you can maybe use the REST API for that.

First get the RequestDigest of the SharePoint Page by following this link:
http://blogs.breeze.net/mickb/2012/11/20/SP2013GettingAFormDigestForUpdateRESTCalls.aspx

and then pass that request digest to your jQuery.ajax call as shown here:

http://msdn.microsoft.com/en-us/library/office/jj164022.aspx

Dylan Nicholson said...

IDCRLException: "Identity Client Runtime Library (IDCRL) could not look up the realm information for a federated sign-in."

This is the error I get just trying to construct a SharePointOnlineCredentials object - it was working fine previously. Any clues?

Unknown said...

I am getting 401 unauthorized error while connecting to the Office365 using your code.
I am able to authenticate using login screen method.
But the requirement is to authenticate without using login screen pop up.
Kindly Help?

Abhishek said...

Hi Vardhaman,

Its working fine for me in my local but currently when I am publishing my site on azure its throwing error "System.IO.FileNotFoundException: msoidcliL.dll". Do you have any idea about the same ?
FYI: we can't install anything on the Azure website.

Abhishek said...

If any get the error for sharepoint-azure-msoidclil-dll please refer below url:
https://stackoverflow.com/questions/18724064/sharepoint-azure-msoidclil-dll-missing/28278700#28278700

Lucky said...

Hi Vardhaman,

I get following error in my service

A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond xxx.xxx.xx.xx:443

Please help me to resolve this issue

Unknown said...

Hi Vardhaman,

How can I authenticate to SharePoint 2013 (On-prem) using ADFS as the authentication provider. In my code, I'm creating the ClientContext object but when I try to execute the query I'm getting a 403 Forbidden error.

Thanks!

ARUN said...

Thanks Vardhaman. This helped me a lot

Unknown said...

Hello Vardhaman,

I am new to sharepoint and trying to read List from sharepoint. But i'm getting exception "Cannot contact site at the specified URL https://xyz". Could you please help me here.

Thanks,
KJ

Unknown said...

Hi I need to create a web service for external apps (other sites from the internet) invoke from my SharePoint site. The thing is that we have SharePoint Online. Can I do what u said in your post in SharePoint Online? If so, how? I'm very newbie in SharePoint.

Eric Schrader said...

If you get a 403 and just created a new user account, try logging in to the site as that user first. Worked right after I did that. Not sure if there was a delay syncing the new licensed AAD user to SPO or what, but it worked right after I signed in the web browser first.

Vimal said...

Hi Vardhaman,

We have a web application hosted on Azure Service which is accessing SharePoint (purchased E3 license) using CSOM 16.0(nuget package "Microsoft.SharePointOnline.CSOM")

Example code :

using (ClientContext clientContext = new ClientContext("https://yoursite.sharepoint..."))
{
SecureString passWord = new SecureString();

foreach (char c in "yourpassword".ToCharArray()) passWord.AppendChar(c);

clientContext.Credentials = new SharePointOnlineCredentials("loginname@yoursite.onmicrosoft.com", passWord);

Web web = clientContext.Web;

clientContext.Load(web);

clientContext.ExecuteQuery();

Console.WriteLine(web.Title);

Console.ReadLine();
}

it keep giving me following error, Please help

'center' is an unexpected token. The expected token is '"' or '''. Line 7, position 12.

Stack Trace for reference :

[XmlException: 'center' is an unexpected token. The expected token is '"' or '''. Line 7, position 12.]
System.Xml.XmlTextReaderImpl.Throw(Exception e) +72
System.Xml.XmlTextReaderImpl.Throw(String res, String[] args) +78
System.Xml.XmlTextReaderImpl.ThrowUnexpectedToken(String expectedToken1, String expectedToken2) +127
System.Xml.XmlTextReaderImpl.ParseAttributes() +5382300
System.Xml.XmlTextReaderImpl.ParseElement() +428
System.Xml.XmlTextReaderImpl.ParseElementContent() +119
System.Xml.XmlTextReaderImpl.Read() +44
System.Xml.Linq.XContainer.ReadContentFrom(XmlReader r) +880
System.Xml.Linq.XContainer.ReadContentFrom(XmlReader r, LoadOptions o) +48
System.Xml.Linq.XDocument.Load(XmlReader reader, LoadOptions options) +283
Microsoft.SharePoint.Client.Idcrl.IdcrlAuth.DoGet(String url) +398
Microsoft.SharePoint.Client.Idcrl.IdcrlAuth.RequestFederationProviderInfo(String domainname) +114
Microsoft.SharePoint.Client.Idcrl.IdcrlAuth.GetFederationProviderInfo(String domainname) +324
Microsoft.SharePoint.Client.Idcrl.IdcrlAuth.InitFederationProviderInfoForUser(String username) +74
Microsoft.SharePoint.Client.Idcrl.IdcrlAuth.GetServiceToken(String username, String password, String serviceTarget, String servicePolicy) +114
Microsoft.SharePoint.Client.Idcrl.SharePointOnlineAuthenticationProvider.GetAuthenticationCookie(Uri url, String username, SecureString password, Boolean alwaysThrowOnFailure, EventHandler`1 executingWebRequest) +302
Microsoft.SharePoint.Client.SharePointOnlineCredentials.GetAuthenticationCookie(Uri url, Boolean refresh, Boolean alwaysThrowOnFailure) +360
Microsoft.SharePoint.Client.ClientRuntimeContext.SetupRequestCredential(ClientRuntimeContext context, HttpWebRequest request) +487
Microsoft.SharePoint.Client.SPWebRequestExecutor.GetRequestStream() +45
Microsoft.SharePoint.Client.ClientContext.GetFormDigestInfoPrivate() +382
Microsoft.SharePoint.Client.ClientContext.EnsureFormDigest() +126
Microsoft.SharePoint.Client.ClientContext.ExecuteQuery() +234

Unknown said...

Hello. When I get to the line of using(ClientContext...) I get an error saying 'ActiveX control '8856f961-340a-11d0-a96b-00c04fd705a2' cannot be instantiated because the current thread is not in a single-threaded apartment.'

The issue is then it instantiate a new WebBrowser in the CLaimsWebAuth method.

Any thoughts?

Unknown said...

hello. I get an error stating 'ActiveX control '8856f961-340a-11d0-a96b-00c04fd705a2' cannot be instantiated because the current thread is not in a single-threaded apartment.'.

It breaks on this.webBrowser = new WebBrowser() in the ClaimsWebAuth method.

I have tried adding the [STAThread] and few other things but no luck. Any thoughts?

Rama said...

I am getting below error when i am running the above sample code

Microsoft.SharePoint.Client.IdcrlException
HResult=0x80048821
Message=The sign-in name or password does not match one in the Microsoft account system.
Source=Microsoft.SharePoint.Client.Runtime

Shaily Shah said...

Hi Vardhaman, Thanks for this Post!!

I've been struggling to connect a .Net app with SharePoint online. I have tried the code you posted, but I'm getting the following error: 'The remote server returned an error: (401) Unauthorized.'

However, I know for sure that the SharePoint URL, username, and password are correct

Please let me know if you have any suggestions.

Kind regards,
Shaily Shah