OneDrive SDK, OAuth, Client Authentication, in Consumer space with C# in a UWP application.

I set out on this example technically to get OneNote access which in turn requires OneDrive access as that is where OneNote documents live. I quickly found myself in a forest surrounded by old documentation and about 95% of it leads to using the deprecated Microsoft Live SDK. There are now OneDrive SDK's for several platforms that employ a new way to connect and authenticate to OneDrive. I will be focusing on C# inside a UWP app as there is little documentation out there on this with almost no code examples for the OneDrive Consumer side for implementation. There are a few on OneDrive for Business and registering your app through Azure Active Directory and they can be found here: OneDrive SDK for CSharp.

Now, I am not going to get into explaining how OAuth works, if you want that then read here: https://oauth.net/2/. This is going to be a straight forward step by step example to get you setup and ready to code your app. So, with that said let's get started.

1. The first thing we need to do is pick a name for our app and then register it to get a clientId, that is done at the Application Registration Portal.

You'll need to click "Add an app" in the Live SDK applications section.

step1a

 

When this completes it will take you to the client application screen where you will see information like your Client Id and Client Secret.

2. Next click "Add Platform" for UWP we are going to choose the "Mobile Application" platform.

Once this is done, you should be viewing a screen like below:

step2

3. Now make note of the Client Id and the Redirect URI as you will need those once we start writing code, for mobile the URI will be: https://login.live.com/oauth20\_desktop.srf

 

4. Now, create your UWP application in Visual Studio and name it as you did on the registration page.

step3

 

5. Next open the NuGet package manager or go to GitHub and install the Microsoft.OneDriveSDK.

step4

 

6. Ok, time for some code!

Here is the simple xaml I am using for the demo, 2 buttons and a textbox (keep it simple and learn).

 

 <Grid>
        <Button x:Name="btn_Login" Content="Sign In" Background="AliceBlue"  
                Foreground="DarkBlue" FontSize="12" FontWeight="Bold" Click="btn_Login_Click"  
                VerticalAlignment="Top" Margin="29,19,0,0" />
        
        <Button x:Name="btn_GetDriveId" Content="Get Drive Id" Background="AliceBlue" 
                Foreground="DarkBlue" FontSize="12" FontWeight="Bold" Click="btn_GetDriveId_Click"  
                VerticalAlignment="Top" HorizontalAlignment="Right" Margin="0,19,29,0" Visibility="Collapsed"/>
        
        <TextBox x:Name="txtBox_Response" Height="500" Width="300" FontSize="12"/>
    </Grid>

 

And here is the C#, again this example is to simply show authentication.

 

 using Microsoft.OneDrive.Sdk;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using System.Text;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;

// The Blank Page item template is documented at https://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409

namespace OneDriveConnectSample
{
    /// <summary>
    /// An empty page that can be used on its own or navigated to within a Frame.
    /// </summary>
    public sealed partial class MainPage : Page
    {
        // Client Apication Id.
        private string clientId = "YourClientIdHere";

        // Return url.
        private string returnUrl = "https://login.live.com/oauth20_desktop.srf";

        // Define the permission scopes.
        private static readonly string[] scopes = new string[] {
            "onedrive.readwrite", "offline_access", "wl.signin", "wl.basic" };

        // Create the OneDriveClient interface.
        private IOneDriveClient oneDriveClient { get; set; }

        public MainPage()
        {
            this.InitializeComponent();
        }

        private async void btn_Login_Click(object sender, RoutedEventArgs e)
        {
            if (this.oneDriveClient == null)
            {
                try
                {
                    // Setting up the client here, passing in our Client Id, Return Url, 
                    // Scopes that we want permission to, and building a Web Broker to 
                    // go do our authentication. 
                    this.oneDriveClient = await OneDriveClient.GetAuthenticatedMicrosoftAccountClient(
                        clientId,
                        returnUrl,
                        scopes,
                        webAuthenticationUi: new WebAuthenticationBrokerWebAuthenticationUi());

                    // Show in text box that we are connected.
                    txtBox_Response.Text = "We are now connected.";

                    // We are either just autheticated and connected or we already connected, 
                    // either way we need the drive button now.
                    btn_GetDriveId.Visibility = Visibility.Visible;
                }
                catch (OneDriveException exception)
                {
                    // Eating the authentication cancelled exceptions and resetting our client. 
                    if (!exception.IsMatch(OneDriveErrorCode.AuthenticationCancelled.ToString()))
                    {
                        if (exception.IsMatch(OneDriveErrorCode.AuthenticationFailure.ToString()))
                        {
                            txtBox_Response.Text = "Authentication failed/cancelled, disposing of the client...";

                            ((OneDriveClient)this.oneDriveClient).Dispose();
                            this.oneDriveClient = null;
                        }
                        else
                        {
                            // Or we failed due to someother reason, let get that exception printed out.
                            txtBox_Response.Text = exception.Error.ToString();
                        }
                    }
                    else
                    {
                        ((OneDriveClient)this.oneDriveClient).Dispose();
                        this.oneDriveClient = null;
                    }
                }
            }
        }

        private async void btn_GetDriveId_Click(object sender, RoutedEventArgs e)
        {
            if (this.oneDriveClient != null && this.oneDriveClient.IsAuthenticated == true)
            {
                var drive = await this.oneDriveClient.Drive.Request().GetAsync();
                txtBox_Response.Text = drive.Id.ToString();
            }
            else
            {
                txtBox_Response.Text = "We should never get here...";
            }
            
        }
    }
}

Once you have the code the app will work just like below:

Start1 Auth1 Auth2 Start2 Start3

 

 

The project is available at GitHub DevPFE / OneDriveConnectSample:

https://github.com/DevPFE/OneDriveConnectSample#onedriveconnectsample

 

Here is reference and good information in this area that are relevant reads:

 

SDKs for OneDrive integration:

https://dev.onedrive.com/SDKs.htm

 

Develop with the OneDrive API:

https://dev.onedrive.com/README.htm

 

OneDrive authentication and sign-in:

https://dev.onedrive.com/auth/msa_oauth.htm

 

OneDrive SDK for CSharp on GitHub:

https://github.com/OneDrive/onedrive-sdk-csharp

 

WebAuthenticationBroker class:

https://msdn.microsoft.com/en-us/library/windows/apps/windows.security.authentication.web.webauthenticationbroker.aspx

 

Happy coding!