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:

  1. 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!

    ReplyDelete
  2. 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

    ReplyDelete
  3. 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 ?

    ReplyDelete
  4. 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?

    ReplyDelete
  5. 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+.

    ReplyDelete
  6. 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

    ReplyDelete
  7. 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

    ReplyDelete
  8. 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.

    ReplyDelete
  9. 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

    ReplyDelete
  10. 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.

    ReplyDelete
  11. 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

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

    ReplyDelete
  13. 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.

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

    ReplyDelete
  15. 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.

    ReplyDelete
  16. 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

    ReplyDelete
  17. 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?

    ReplyDelete
  18. 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.

    ReplyDelete
  19. 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

    ReplyDelete
  20. 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?

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

    ReplyDelete
  22. @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

    ReplyDelete
  23. 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?

    ReplyDelete
  24. 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?

    ReplyDelete
  25. 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.

    ReplyDelete
  26. 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

    ReplyDelete
  27. 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

    ReplyDelete
  28. 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!

    ReplyDelete
  29. Thanks Vardhaman. This helped me a lot

    ReplyDelete
  30. 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

    ReplyDelete
  31. 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.

    ReplyDelete
  32. 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.

    ReplyDelete
  33. 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

    ReplyDelete
  34. 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?

    ReplyDelete
  35. 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?

    ReplyDelete
  36. 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

    ReplyDelete
  37. 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

    ReplyDelete

Comments moderation is turned ON. Your comment might not appear immediately after posting.