Implement the Login class

This class is only necessary if you are implementing the Authorization Code grant type.  When using that grant type you need to log-into the authorization server through its Web application and grant access to the registered application.  This class inherits Nemiro.OAuth.LoginForms.Login and handles the calls to the authorization server and provides the user interface for entering your credentials and granting access.  You typically do not need to override any of the base classes when implementing this class.  For more information on the Nemiro.OAuth.LoginForms, see:

https://github.com/alekseynemiro/Nemiro.OAuth.LoginForms

For a standard OAuth provider, the Login class should be as simple as this:


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

There are several examples of implementations of the Login class included with the Nemiro.OAuth.LoginForms source code.

Implement the OAuthProvider class

Open the class file in your solution (i.e. SampleOAuthProvider).  Add these references:

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

You will only need the reference to System.Windows.Forms if you are using the Authorization Code grant type.

Change the class definition to inherit from OAuthProvider and add the DisplayName attribute which is used by Neuron ESB Explorer when listing the available OAuth providers:

[DisplayName("Generic Client Credentials Grant OAuth Provider")]
public class SampleOAuthProvider : OAuthProvider
{
}

Add the public properties required for the grant type you are implementing.  Below are some examples of properties based on the different grant types.  You can find implementations of these in the three generic OAuth samples included with the Neuron ESB installation.

Authorization Code

  • Client ID
  • Client Secret
  • Authorization URL
  • Token URL
  • Redirect URL
  • Scope

Client Credentials

  • Client ID
  • Client Secret
  • Token URL
  • Scope

Resource Owner Credentials

  • Client ID
  • Client Secret
  • Token URL
  • Username
  • Password
  • Scope

When implementing the properties, you can use the same property attributes that are available for custom process steps and adapters:

  • DisplayName
  • Description
  • PropertyOrder
  • EncryptValue

When using the PropertyOrder attribute, you should start with the value of 2.  This is because the inherited class OAuthProvider has two public properties – AccessToken and CredentialType, with the PropertyOrder of 0 and 1, respectively.

The EncryptValue attribute will mask the value of the property when displayed in the UI and also encrypt the property value when it is saved in the solution’s XML file.

Here’s an example of a property for the Client Secret:

[DisplayName("Client Secret")]
[Description("The application secret assigned to your app.")]
[PropertyOrder(3)]
[EncryptValue]

public string ClientSecret
{
  get
  {
    return this.clientSecret;
  }
  set
  {
    this.clientSecret = value;
  }
}

The last thing you need to do is implement the virtual methods GetClient and ClientLogin.  The method GetClient returns an instance of your custom OAuth client that you implemented earlier.  The method ClientLogin is called when the “Test” button is clicked on the OAuth Provider form in Neuron ESB Explorer.  If you are implementing the Authorization Code grant type, this method will show the login form and return the retrieved access token.  The GenericAuthCodeGrantOAuthProvider sample demonstrates how to do this.  For the other two grant types this method should attempt to retrieve an access token using your OAuth client class, and if successfully received it should be returned.  The samples GenericClientCredentialsGrantOAuthProvider and GenericPasswordCredentialsGrantOAuthProvider demonstrate how to do this.

Here is an example of GetClient():

public override OAuthBase GetClient()
{
  return new GenericAuthCodeGrantOAuth2Client(this.authorizationUrl, this.tokenUrl,
    this.redirectUri, this.clientId, this.clientSecret, this.scope);
}

Here is an example of ClientLogin() for the Authorization Code grant.  The first thing this code does is gets an instance of the OAuth client and the OAuth login.  Then the login form is displayed, and if an access token is successfully retrieved, it is returned to the caller.


public override AccessToken ClientLogin(Form mainForm)
{
  GenericAuthCodeGrantLogin login = null;

  try
  {
    var client = this.GetClient();
    login = new GenericAuthCodeGrantLogin(client);

    using (login)
    {
      login.ShowDialog(mainForm);
      if (login.IsSuccessfully)
      {
        return client.AccessToken;
      }
      else
      {
        MessageBox.Show(mainForm, String.Format("Unable to obtain an access token - {0}",
          login.ErrorMessage), "Test Failed");
      }
    }
  }
  catch (Exception ex)
  {
    MessageBox.Show(mainForm, String.Format("Unable to obtain an access token - {0}", ex.Message), "Test Failed");
  }

  return null;
}

Here is an example of ClientLogin() for the Client Credentials grant.  This code does is gets an instance of the OAuth client and its access token.  The get function for AccessTokenValue will make the call to the authorization server to retrieve the access token.  If an access token is retrieved it is returned to the caller.

public override AccessToken ClientLogin(System.Windows.Forms.Form mainForm)
{
  bool success = false;

  try
  {
    var client = this.GetClient();
    var token = client.AccessTokenValue;
    if (!String.IsNullOrEmpty(token))
      success = true;

    if (success)
    {
      MessageBox.Show(mainForm, "Generic Client Credentials OAuth Test Successful", "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;
}

The implementation of ClientLogin() for the Resource Owner Credentials grant would be the same as the Client Credentials grant.

Compile and Deploy

Once you’ve compiled the custom OAuth provider, you will copy the assembly to this folder:

<Neuron Install Location>\<Instance>\OAuthProviders

 

To configure your custom OAuth provider, close and reopen Neuron ESB Explorer and navigate to Security->OAuth Providers.  Click on the “New” button and select the custom OAuth provider from the Provider drop-down list.

 

To debug your provider, you can attach the Visual Studio debugger to NeuronExplorer.exe for design-time debugging and to either ESBService.exe or NeuronProcessHost.exe for runtime debugging.