Connecting to SharePoint Online from console application with ADAL and PnP Core Component

Office 365 Developer Patterns and Practices Core component is designed to increase the productivity of developers when you are developing applications for SharePoint Online or for SharePoint on-premises. It encapsulates numerous complex operations to more streamlined methods and usage, so that developers can more efficiently concentrate on solving business problems. PnP Core component is released as Nuget package and can be used in provider hosted add-ins or from native windows applications, like with console applications. It’s also used by the PnP PowerShell CmdLets, which enables you to take advantage of the Core Component capabilities without the need of using Visual Studio.

There are currently two different versions of the PnP Core Component, one targeted for SharePoint Online and for SharePoint 2013 on-premises. SharePoint 2016 version is coming later 2016. Different versions are released due the differences in supported CSOM operations.

This is a blog post around using the PnP Core Component AuthenticationManager class to gain client context from console application using permissions granted from Azure Active Directory. This nicely demonstrates the abstractions what the PnP Core Component is providing by simplifying the needed code for typical operations with SharePoint. You can also find a video showing the below steps from the PnP Channel 9 video blog.

Video at Channel 9 PnP Video Blog.

Steps to connect to SharePoint Online with ADAL and Office Dev PnP Core Component

First we’ll need to register the application for the Azure Active Directory associated to the Office 365 tenant. This can be done from Azure Portal by moving to https://portal.azure.com and signing in with the account associated to the tenant.

  • Select Active Directory from the main menu

image

  • Move to Application section in the Azure AD

image

  • Click Add to add new application
  • Click “Add an application my organization is developing
  • Provide your application a name and select the type as Native Client Application

image

  • Define redirect URI for your application. Notice that the value does not need to be a physical endpoint, but must be a valid URI.

image

  • Click “Complete” so that your application entry is created to Azure Active Directory
  • Move to Configure section

image

  • Copy Client ID and Redirect URI information, since these will be used when we connect to Office 365 or SharePoint Online from our console application.
  • Scroll down under the permissions to other applications section and click Add application

image

  • Select Office 365 SharePoint Online

image

  • Click Complete
  • Set “Have full control of all site collections” as the delegated permission for the application

image

  • Click Save to complete the registration

Now we are all good from the Azure Active Directory side, so let’s proceed on the Visual Studio side.

  • Open up a Visual Studio and chose the Windows Console application as the project type

image

  • Right click Visual Studio project and choose Manage Nuget Packages

image

  • Install following Nuget packages – notice that Office Dev PnP Core component Nuget package will pull down automatically quite a few dependent Nuget packages as well to ensure that capabilities are working without issues.
    • Microsoft.IdentityModel.Clients.ActiveDirectory – version 2.22.302111727 (at the time of the blog post)
    • OfficeDevPnPCore16 – version 2.1.1602 (at the time of the blog post)

image

  • Move to program.cs and update Main method as follows
  
 static void Main(string[] args)
 {
  
     using (var ctx = new AuthenticationManager().
             GetAzureADNativeApplicationAuthenticatedContext(
             "https://vesaj.sharepoint.com/sites/dev", 
             "clientId", "redirectUrl"))
     {
         // Do your stuff
         Web web = ctx.Web;
         ctx.Load(web);
         ctx.ExecuteQuery();
         string title = web.Title;
     }
 }
  • Update clientId and redirectURL in the GetAzureAdNativeApplicationAuthenticatedContext method call based on the registration you did in Azure Active Directory
  • Add following using statements on the program.cs
  
 using Microsoft.SharePoint.Client;
 using OfficeDevPnP.Core;
  
  • When you are done with the updates, full code should look something like following
  
 using Microsoft.SharePoint.Client;
 using OfficeDevPnP.Core;
 using System;
 using System.Collections.Generic;
 using System.Linq;
 using System.Text;
 using System.Threading.Tasks;
  
 namespace SPO.Console.Test
 {
     class Program
     {
         static void Main(string[] args)
         {
  
             using (var ctx = new AuthenticationManager().
                     GetAzureADNativeApplicationAuthenticatedContext(
                     "https://vesaj.sharepoint.com/sites/dev", 
                     "66eb87c4-b5aa-486b-a763-df52c7b5c1b8", 
                     "https://contoso.com/OfficeDevPnP.Core"))
             {
                 // Do your stuff
                 Web web = ctx.Web;
                 ctx.Load(web);
                 ctx.ExecuteQuery();
                 string title = web.Title;
             }
         }
     }
 }
  
  • Set a break point for example on the ExecuteQuery method call and press F5 in the Visual Studio to start debugging the solution

  • When ExecuteQuery method is called, you will see Sign in prompt to login with needed account to your tenant

    • This way you do not need to store any login information on the caller side, needed information is rather prompted from the user.
  • Provide your user name and password and click Sign in button

image

  • Confirm that you have access on the site collection in your tenant with only one line of code

image

That’s it. With PnP Core Component, you can significantly increase the productivity of your developers. In this case we used PnP Core Component within Console application, but more often it would be used within provider hosted add-ins. In those cases you’d not obviously use the native application option with the login prompt, but conceptually implementation or usage is exactly the same. There’s a separate PnP Core component version for SharePoint Online and for SharePoint 2013 on-premises.

Office 365 Developer Patterns and Practices

Office365PnPLogoRed_thumb1Techniques showed in this blog post are part of the Office 365 Developer Patterns and Practices guidance, which contains guidance and reusable solutions for demonstrating different patterns and practices related  on the development for Office 365 and SharePoint on-premises.

Check the details around PnP from dev.office.com at https://aka.ms/OfficeDevPnP. PnP Core Component is released as part of the monthly releases of PnP and you can find the source code for it from https://github.com/OfficeDev/PnP-sites-core.  Please join us on sharing patterns and practices for the community for the benefit of the community. If you have any questions, comments or feedback related on this sample, blog post or anything on PnP, please use the Office 365 Developer Patterns and Practices Yammer group at https://aka.ms/OfficeDevPnPYammer.

“Sharing is caring”

Comments

  • Anonymous
    August 15, 2016
    Hey Vesku. Thanks for this post. FYI - I tried this step-by-step just now and when downloading "Sharepointpnpcoreonline" (2.6.1608.0) + "Active Directory Authentication Library" (3.13.1) from nuget there seems to be some version conflict. The 3.13.1 version of the ActiveDirectory.AuthenticationResult class does not implement the same methods as the 2.22.302111727 you are using in your example. I receive the following error: An unhandled exception of type 'System.MissingMethodException' occurred in mscorlib.dll. Method not found: 'Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationResult Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext.AcquireToken(System.String, System.String, System.Uri, Microsoft.IdentityModel.Clients.ActiveDirectory.PromptBehavior)'. To resolve this I went to the github project for pnp (https://github.com/OfficeDev/PnP-Sites-Core/tree/master/Core) and downloaded the source. I checked the dependencies of the project. The packages.config contains a reference to version 2.18.206251556 (). I picked up the assemblies from the packages folder and referenced them in my project that uses the nuget "Sharepointpnpcoreonline" package. That works the way you describe.
  • Anonymous
    September 16, 2016
    First, when I go into portal.azure.com to register the application for Azure Active Directory, everything looks different, but I think I got it done. But when I should copy Client ID and Redirect URI information, I have my choice between the Object Id and the Application ID, but no Client ID. So I tried using both of these, but I get the same error either way:An unhandled exception of type 'System.MissingMethodException' occurred in mscorlib.dllAdditional information: Method not found: 'Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationResult Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext.AcquireToken(System.String, System.String, System.Uri, Microsoft.IdentityModel.Clients.ActiveDirectory.PromptBehavior)'.
    • Anonymous
      September 16, 2016
      Note: I do have a reference to Microsoft.IdentityModel.Clients.ActiveDirectory v.3.13.4
      • Anonymous
        September 08, 2017
        Hi I used the same Microsoft.IdentityModel.Clients.ActiveDirectory v.3.13.4 and I have same error as Rick Kushner. I try to use latest versions still the same issue occurs. I just can't connect to my Sharepoint via this sample or access token samples I just running out of ideas. Please help me using (var ctx = new AuthenticationManager().GetAzureADNativeApplicationAuthenticatedContext("https://sp.iedu.sk/sites/eAktovka", "d8939fe0-d7bb-4f29-bca8-dfb0d0cc1aa8", "http://EduProtectionClient")) { // Do your stuff Web web = ctx.Web; ctx.Load(web); ctx.ExecuteQuery(); string title = web.Title; }
  • Anonymous
    August 07, 2017
    For most recent news you have to pay a visit internet and on internet I found this web site as a best web site for hottest updates.
  • Anonymous
    October 21, 2017
    Hi Vesku, this is awesome and worked like a charm !!Practically, I need what you showed using a console (or pure windows, rather than Web API) but instead of having the user prompted for the password, the console application picks up the token from the current user logged on the machine using windows identity (or other) and create a normal SharePoint Online client context. I did find what I believe might be a workaround because it still requires showing the pop and is in effect just automating the password entry using the popup. Is there a better PnP approach or sample which demonstrates this?
    • Anonymous
      October 22, 2017
      If you need to do this without user consent, you should be looking into using app-only options with Azure AD. AuthenticationManager from the PnP CSOM Core provides this easily and that's also demonstrated in following webcast - https://dev.office.com/blogs/Introduction-to-authentication-manager-in-pnp-core-library.
      • Anonymous
        October 24, 2017
        Hi Vesa, thanks for replying :)Had a look at the authentication manager and still not sure which method suits my requirement.If I'm not mistaken, (and apologies if I'm missing something) the app only methods mean that query results will not consider the permissions of the current user running the console application but will return all the results according to the application permissions as registered in Azure AD.If possible I need the permissions of the user running the console application considered as per SharePoint normal security. I want to achieve this without needing the user to put in the password. What I'm thinking is if there is a way to use the current windows identity of the logged in user on the machine which is synchronized with SharePoint Online through Azure AD. Is this possible? Such as this example (https://code.msdn.microsoft.com/Remote-Authentication-in-b7b6f43c) but potentially a newer / better approach.