Skip to content

Azure Code Grant OAuth Provider Sample

The Azure Code Grant OAuth Provider Sample will show you how to setup a custom OAuth provider for Azure for use in conjunction with Neuron ESB.

Note: It Is recommended that you already be familiar with both Neuron ESB and the Visual Studio before starting this tutorial. You will also need to ensure that both the Visual Studio and Neuron ESB are installed in your environment and configured appropriately.

This sample contains the following artifacts:

  • Visual Studio Project
  • Sample Documentation

While the Visual Studio project is already created for you, in order to execute this sample, you will have to follow along with Sam, and do as he does as he creates a custom OAuth provider.

Overview

There are times when it is necessary to implement custom OAuth providers in order to connect to third party applications such as Azure. While Neuron ESB allows you to import these custom OAuth providers, and use them to facilitate your connections with these applications, they need to be constructed in such a way that Neuron ESB can use. This sample will walk you through constructing a custom OAuth provider and show you how to import it for use into Neuron ESB.

Scenario

Sam Pleuser is hard at work, getting his companies third party applications integrated with their new Neuron ESB platform, when he realizes that he will need to connect to Azure using OAuth to facilitate the transfer of certain data. Not only does he need to connect to Azure, but he needs to do so using Code Grant, which is going to require him to build a custom OAuth provider.

Sam lists out his tasks so that he knows when he has to do in order to achieve his goals, and the order in which he needs to accomplish them.

  • Create a custom OAuth provider for Azure using Code Grant
  • Register the custom OAuth provider with Neuron ESB for use in conjunction with service connectors.

Now that he has an idea of what he needs to do Sam can begin the process.

First Sam opens up his instance of Visual Studio and creates a new class library project. Custom OAuth providers need to be built as class libraries for Neuron ESB to be able to consume them and use them in the Neuron ESB Explorer.

Sam knows that he is going to be integrating with Neuron ESB 3.7.5 and as such will need to ensure that his project is set to compile against .NET Framework 4.7.2. So he selects that as his target frame work when creating his project.

Once the project has been created Sam opens the solution explorer and renames the Class1.cs file to match the name of provider and OAuth type which he is creating. In this case he names the file AzureAuthCodeGrantOAuthProvider.cs

With the file named appropriately Sam now needs to make sure that he has references to the DLLs that he will need in order to complete his task.

As Neuron ESB utilizes the Nemiro.OAuth and Nemiro.OAuth.LoginForms libraries in its implementation of OAuth providers, Sam will need to reference these libraries when creating his own OAuth provider.  These libraries are shipped with Neuron ESB, so he can reference these libraries either by direct reference to the files in the Neuron installation folder or by adding them via NuGet in Visual Studio.

If Sam wants to reference the libraries directly, he simply needs to add references to these files:

  • <Neuron Install Location>\<Instance>\Nemiro.OAuth.dll
  • <Neuron Install Location>\<Instance>\Nemiro.OAuth.LoginForms.dll

If he decides to add them to his solution via NuGet, then he needs to add these libraries:

  • Nemiro.OAuth
  • Nemiro.OAuth.LoginForms

Sam also needs to make sure that he references the Neuron.Esb dll

  • <Neuron Install Location>\<Instance>\Neuron.Esb.dll

As well as System.Windows.Forms.

With the proper references in place Sam opens the AzureAuthCodeGrantOAuthProvider class by double clicking it in the Solution Explorer so that he can begin to add his code. To begin Sam starts by adding a necessary using statements to his class.

using System;
using System.Text;
using System.ComponentModel;
using System.Collections.Specialized;
using System.Windows.Forms;
using Nemiro.OAuth;
using Nemiro.OAuth.LoginForms;
using Neuron.Esb.OAuth;

The first class that Sam needs to construct is a class which inherits Nemiro.OAuth.OAuth2Client. This class will handle all of the interaction between Neuron ESB and the OAuth provider.  Because Sam is going to be using Azure Active Directory which has a requirement for a resource parameter, he will need to override the base class.

For additional information about the Nemiro.OAuth client please visit https://github.com/alekseynemiro/nemiro.oauth.dll or http://oauth.nemiro.net/.

Sam develops the following code in order to ingrate with Azure.

[DisplayName("Azure Authorization Code Grant OAuth Provider")]
public class AzureAuthCodeGrantOAuthProvider : OAuthProvider
{
    private string clientId;
    private string clientSecret;
    private string tenant;
    private string redirectUri;
    private string resource;

Sam starts his code by creating a couple of class variables as the values will be needed in multiple methods within the class.

public AzureAuthCodeGrantOAuth2Client(string authorizeUrl, string accessTokenUrl, string clientId, string clientSecret, string resource, string redirectUri)
    : base(authorizeUrl, accessTokenUrl, clientId, clientSecret)
{
    this.resource = resource;
    this.redirectUri = redirectUri;
    base.ResponseType = ResponseType.Code;
    base.SupportRefreshToken = true;
}

Moving into the meat of the code Sam creates a method for the OAuth2Client called AzureAuthCodeGrantOAuth2Client which sets values for the class level variables as well as the base variable of SupportRefreshToken.

public override string AuthorizationUrl
{
    get
    {
        var result = new StringBuilder();

        result.Append(this.AuthorizeUrl);
        result.Append(this.AuthorizeUrl.Contains("?") ? "&" : "?");
        result.AppendFormat("client_id={0}", OAuthUtility.UrlEncode(base.ApplicationId));
        result.AppendFormat("&response_type={0}", base.ResponseType);
        result.AppendFormat("&redirect_uri={0}", this.redirectUri);
        result.AppendFormat("&response_mode={0}", responseMode);
        result.AppendFormat("&resource={0}", this.resource);
        result.AppendFormat("&state={0}", OAuthUtility.UrlEncode(base.State));

        return result.ToString();
    }
}

Next Sam creates an override for the AuthorizationUrl accessor in the base class, which uses a string builder to build out the AuthorizationURL, inserting the appropriate values into the string as needed.

protected override void GetAccessToken()
{
    if (String.IsNullOrEmpty(this.AuthorizationCode))
    {
        throw new ArgumentNullException("AuthorizationCode");
    }

    var parameters = new NameValueCollection
    {
        { "grant_type", GrantType.AuthorizationCode },
        { "client_id", this.ApplicationId },
        { "code", this.AuthorizationCode },
        { "redirect_uri", this.redirectUri },
        { "resource", this.resource },
    };

    var result = OAuthUtility.Post
    (
        endpoint: this.AccessTokenUrl,
        parameters: parameters,
        authorization: new HttpAuthorization(AuthorizationType.Basic, OAuthUtility.ToBase64String("{0}:{1}", this.ApplicationId, this.ApplicationSecret))
    );

    if (result.ContainsKey("error"))
    {
        this.AccessToken = new OAuth2AccessToken(new ErrorResult(result));
    }
    else
    {
        this.AccessToken = new OAuth2AccessToken(result);
    }
}

Sam then overrides the GetAccessToken method in the base class, so that he can insert the values from his class level variables into the parameters collection before sending the authorization request to Azure for the access token.

public override AccessToken RefreshToken(AccessToken accessToken = null)
{
    var token = (OAuth2AccessToken)base.GetSpecifiedTokenOrCurrent(accessToken, refreshTokenRequired: true);

    var parameters = new NameValueCollection
    {
        { "client_id", this.ApplicationId },
        { "refresh_token", token.RefreshToken },
        { "grant_type", GrantType.RefreshToken },
        { "resource", this.resource }
    };

    var result = OAuthUtility.Post
    (
        this.AccessTokenUrl,
        parameters: parameters,
        accessToken: token
    );

    return new OAuth2AccessToken(result);
}

Finally Sam creates an override for the RefreshToken method in the base class, which again allows him to insert the values of his class level variables into the parameters collection before sending the request to refresh to token to Azure.

With that class complete, Sam moves on to another class, AzureAuthCodeGrantLogin, which inherits from the Login class in Nemiro.

public class AzureAuthCodeGrantLogin : Login
{
    public AzureAuthCodeGrantLogin(OAuthBase client) :
        base(client, responseType: "code")
    {
    }
}

This class only contains a single method and is used solely to specify the responseType as being code, since Sam wants to use Code Grant for this OAuth provider.

With his setup complete Sam next returns to the AzureAuthCodeGrantOAuthProvider class to fill in the two methods that he previously stubbed out.

He starts with the GetClient class, adding the following code

var authorizeUrl = string.Format("https://login.windows.net/{0}/oauth2/authorize", this.tenant);
var accessTokenUrl = string.Format("https://login.windows.net/{0}/oauth2/token", this.tenant);
return new AzureAuthCodeGrantOAuth2Client(authorizeUrl, accessTokenUrl, this.clientId, this.clientSecret, this.resource, this.redirectUri);

This code allows Sam to specify the authorize and access token URLs before creating a new instance of the AzureAuthCodeGrantOAuth2Client class.

Sam then fills out the ClientLogin method with the following code

bool success = false;
AzureAuthCodeGrantLogin login = null;

try
{
    var client = this.GetClient();

    login = new AzureAuthCodeGrantLogin(client);

    using (login)
    {
        login.ShowDialog(mainForm);
        var token = client.AccessTokenValue;

        if (!String.IsNullOrEmpty(token))
            success = true;
    }

    if (success)
    {
        MessageBox.Show(mainForm, "Azure Authorization Code Grant OAuth Test Successfull", "Success");
        return client.AccessToken;
    }
    else
    {
        MessageBox.Show(mainForm, "Unable to obtain an access token - unknown error", "Test Failed");
        return null;
    }
}
catch (Exception ex)
{
    MessageBox.Show(mainForm, String.Format("Unable to obtain an access token - {0}", ex.Message), "Test Failed");
}

return null;

This method creates an instance of the AzureAuthCodeGrantLogin class and then uses that to test Sam’s access to Azure using his OAuth access token.

Once Sam has finished writing his code, he compiles the project to create the project DLL in the bin directory, which he then copies over to his Neuron ESB instance

  • <Neuron Install Location>\<Instance>\OAuthProviders

Doing this will allow Sam to open the Neuron ESB Explorer and leverage his new custom OAuth provider in Security > OAuth section of the Explorer.

Was this article helpful?
Dislike 0
Previous: Azure Client Credentials Grant OAuth Provider Sample
Next: Securing Client Connectors with OAuth Sample