Click here to Skip to main content
15,887,214 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I need OAuth2 implementation in C# Windows Form application.
I have ClientID as "abc" and
client secret as "xyz".

Further, Auth Url = "https://login.windows.net/{TenentID}/oauth2/authorize?resource=https://api.businesscentral.dynamics.com",

Redirect URI = "https://businesscentral.dynamics.com/",

Access Token URL = "https://login.windows.net/TenentID/oauth2/token?resource=https://api.businesscentral.dynamics.com".

My use case is as follows:
I have a Windows Form native application. We are using Microsoft dynamics application for the finance department. A Windows native app has been used for the core business. My requirement is to integrate two applications to communicate with each other via web API. From MS Dynamics, they have given OAuth2 authorization to access their API endpoints.

I created an access token generating application using C#, but the generated token doesn't allow me to update the resource and said that Unauthorize.

I think I have done something wrong with the implementation. I tried to get the Auth code, but all the efforts fail. I need help to solve the issue.
Further, I will explain how my Auth application works according to the below code sample.

Step 1 - Once the program loads, it asks me to enter a valid Microsoft Email Id and password.

Step 2 - After login process succeeds, it redirect me to Dynamics Login Page.

Step 3 - I can enter DY user credentials as well and log in to the application as well.

Step 4 - Meanwhile, I tried to trigger Authorization code to pass to the method Call (GetAccessTokenAsync). It returned null.

What I have tried:

C#
using Microsoft.AspNetCore.WebUtilities;
using Microsoft.Identity.Client;
using Microsoft.Web.WebView2.Core;
using Microsoft.Web.WebView2.WinForms;
using Microsoft.Web.WebView2.Wpf;
using System;
using System.Security.AccessControl;
using System.Security.Policy;
using System.Web;
using System.Windows.Forms;

namespace OAuthAuth
{
    public partial class Form1 : Form
    {
        private const string clientId = "ABC"; // 
        private const string clientSecret = "XYZ";

        private const string AuthUrl = 
        "https://login.windows.net/{TenentID}/oauth2/authorize";
        private const string redirectUri = 
        "https://businesscentral.dynamics.com/";
        readonly string[] Scope = { ".default " };

        private string authorizationCode;
        public Form1()
        {
            InitializeComponent();
            webBrowser.NavigationCompleted += WebView_NavigationCompleted;
            webBrowser.Source = new Uri(AuthUrl);
        }

        private  void button1_Click(object sender, EventArgs e)
        {
           
        }

        private void button2_Click(object sender, EventArgs e)
        {
            var tokenParams = new Dictionary<string, string>
            {
                { "grant_type", "authorization_code" },
                { "client_id", clientId },
                { "client_secret", clientSecret },
                { "code", authorizationCode },
                { "redirect_uri", redirectUri }
            };
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            string authUri = $"{AuthUrl}?response_type=code&
             client_id={clientId}&redirect_uri={redirectUri}& 
             resource=https://api.businesscentral.dynamics.com";

            webBrowser.Source = new Uri(authUri);
        }
      
        private  void WebView_NavigationCompleted
        (object sender, CoreWebView2NavigationCompletedEventArgs e)
        {
            string currentUrl = webBrowser.Source.AbsoluteUri;

            Uri uri = new Uri(currentUrl);

            if (currentUrl.StartsWith(redirectUri))
            {
                string code = QueryHelpers.ParseNullableQuery(uri.Query).
                              GetValueOrDefault("code");
                string authorizationCode = currentUrl.Split('?') 
                [1].Split('&').FirstOrDefault(q => 
                q.StartsWith("code="))?.Replace("code=", "");
                
                // Implement token exchange logic here
            }
        }        
    }
}
Posted
Updated 15-Aug-23 6:02am
v3

1 solution

For my usage from winform, I use the following code to get the token.

C#
using (HttpClient httpClient = new HttpClient())
{
     HttpClient client = new HttpClient();
     client.BaseAddress = new Uri(url);
     var login = new Dictionary<string, string>
     {
          {"grant_type", "password"},
          {"username", txtOauthUser.Text},
          {"password", txtOauthPassword.Text},
          { "client-id", txtClientId.Text },
          { "client-secret", txtClientSecret.Text }
     };
     var response = client.PostAsync("Token", new FormUrlEncodedContent(login)).Result;
     token = JsonConvert.DeserializeObject<Dictionary<string, string>>(response.Content.ReadAsStringAsync().Result)["access_token"];
}


Once I have the token, I add it to the header for the request I care about.
C#
string headerName = "Authorization";
string headerValue = "Bearer " + GetOAuthToken();
AddHeader(headerName, headerValue);


Not all of the code is here, but its what I can safely copy/paste quickly.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900