OpenId and External Logins

If you're not planning to re-write DWKIt configurator (OptimaJet.DWKit.Application/Configurator.cs) and ASP.NET Core MVC launch class of the DWKit app (OptimaJet.DWKit.StarterApplication/Startup.cs), DWKit will use OpenId by default. You still have an opportunity to authenticate user by login and password which are stored in the database (hash is stored for password). You will also be able to add external external authentication providers you need. To make it all work we use Identity Server 4. Identity Server is launched inside DWKit. Identity Server is configured in the OptimaJet.DWKit.StarterApplication/Startup.cs class. See code lines below, which are responsible for the Identity Server configuration. Learn more about the Identity Server configuration in documentaion.

public class Startup
{
    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        ...
        services.ConfigureIdentityServer(Configuration, Environment, _loggerFactory.CreateLogger<Startup>());

        //TODO: Here you can initialize external authentication providers like as Facebook or OpenID Connect.
        var authBuilder = new AuthenticationBuilder(services);
        authBuilder.AddOpenIdConnect("AAD", "Azure Active Directory", options =>
        {
            //options setup
        });
        authBuilder.AddFacebook(options => {
           //options setup
        });

        services.AddMvc(options => {
            ...
            options.Conventions.Add(new Security.OpenIdConnect.AuthorizationPolicyConvention());
        });
        ...
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        ...
        // UseIdentityServer includes a call to UseAuthentication
        app.UseIdentityServer();
        ...
        //DWKIT Init
        Configurator.Configure(app, Configuration);
        ...
    }
}

Most settings will remain unchanged, but please pat attention to the following two aspect:

  • var authBuilder = new AuthenticationBuilder(services); - in the future you will be able to add external authentication providers in authBuilder. For example for Facebook or AzureAD logins.
  • Configurator.Configure(app, Configuration); - calls DWKit configurator inside which DefaultSecurityProvider is created and configured.

DWKit configurator is OptimaJet.DWKit.Application/Configurator.cs class. See part of its code below, which is responsible for creating and configuring DefaultSecurityProvider.

public static class Configurator
{
    public static void Configure(IApplicationBuilder app, IConfigurationRoot configuration, string connectionStringName = "default")
    {
        ...
        var httpContextAccessor = (IHttpContextAccessor)app.ApplicationServices.GetService(typeof(IHttpContextAccessor));
        var eventService = (IEventService)app.ApplicationServices.GetService(typeof(IEventService));
        var authenticationSchemeProvider = (IAuthenticationSchemeProvider)app.ApplicationServices.GetService(typeof(IAuthenticationSchemeProvider));
        var ldap = configuration.GetSection("LDAPConf").Get<Security.IdentityProvider.LDAPConf>();
        ...

        var security = new DefaultSecurityProvider(httpContextAccessor, eventService, authenticationSchemeProvider, ldap);

        Configure(security, configuration, connectionStringName);
    }

    private static void Configure(ISecurityProvider security, IConfigurationRoot configuration, string connectionstringName = "default")
    {
        ...
        DWKitRuntime.Security = security;
        ...
    }
}

Keep in mind that it is essential to use DefaultSecurityProvider, as only it wil work correctly with Identity Server.

oidc-client-js library is used in DWKit client side. Note that DWKit requires two additional files for correct work on client side:

  • OptimaJet.DWKit.StarterApplication/wwwroot/silentRenew.html file - oidc client requests this file to update authentication token on client.
  • OptimaJet.DWKit.StarterApplication/wwwroot/scripts/oidc-client.min.js file - library required for silentRenew.html.

DWKit additional settings

Identity Server will generate an encryption key to work within the developer environment. However we recommend creating a certificate for the production environment, put it in the app folder and write the following strings in DWKit configuration file for it:

{
    "IdentityServerSettings": {
        "CertificateFile": "IdentityServer4Auth.pfx",
        "CertificatePassword": "password"
    }
}

Authentication of custom requests from client

Custom requests from DWKit client actions are required. You've got three options for them to have authentication token.

  • if you're using $.ajax(), i.e. JQuery AJAX requests, you don't need to do anything, it is all configured correctly.
  • if you're using DWKitApp.API.callUrl(url, parameters, callback) method, you don't need to do anything.
  • if you're using any other server request method, it must have 'Authorization' header which contains token. Here's an example of how it is configured with JQuery.
const bearerHeader = 'Bearer ' + user.access_token;
// for jquery calls
$.ajaxSetup({
    beforeSend: (xhr) => {
        xhr.setRequestHeader('Authorization', bearerHeader);
    }
});

user here is provided by oidc-client-js library.

Adding external authentication providers.

To add external authentication providers follow these simple steps. It is effortless in contrast to configuring these providers.

  • add authentication provider in OptimaJet.DWKit.StarterApplication/Startup.cs class. See example of connecting authentication via Facebook and Azure AD (uses OpenId):

    var authBuilder = new AuthenticationBuilder(services);
    authBuilder.AddOpenIdConnect("AAD", "Azure Active Directory", options =>
    {
      options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;
      options.SignOutScheme = IdentityServerConstants.SignoutScheme;
      options.Authority = "https://login.microsoftonline.com/common";
      options.ClientId = "SPECIFY THE CLIENT ID HERE";
      options.Scope.Add("openid");
      options.Scope.Add("profile");
      options.TokenValidationParameters = new TokenValidationParameters
      {
          ValidateIssuer = false
      };
      options.GetClaimsFromUserInfoEndpoint = true;
    });
    authBuilder.AddFacebook(options => {
      options.ClientId = "SPECIFY THE CLIENT ID HERE";
      options.ClientSecret = "SPECIFY THE CLIENT SECRET HERE";
      options.SignInScheme = IdentityServer4.IdentityServerConstants.ExternalCookieAuthenticationScheme;
    });
  • configure them. Look for configuration settings in relevant provider documentation. For example, for Azure AD see this article.

Setting is complete. You will see buttons in login form which correspond to added external authentication providers.

External authentication providers buttons

User can be authenticated in external apps and work in DWKit. If user has been authenticated, but is missing from DWKit database, he will be created automatically. User search is executed by e-mail. If no user with such e-mail has been found, he will be automatically created in the system. However, you can change this behavior by creating MyExternalCredentialsProcessor class, which is implementing IExternalCredentialsProcessor interface and connecting it in the OptimaJet.DWKit.StarterApplication/Startup.cs class.

public class Startup
{
    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        ...
        services.AddTransient<IExternalCredentialsProcessor, MyExternalCredentialsProcessor>();
        ...
    }
}

If user has external credentials, they will be displayed in user editing interface.

Launching admin panel in a separate app

We should also explain how to launch DWKit admin panel in a separate app. Follow these steps:

  • In <DWKitAdmin/> component properties specify authServerHost property with main app address.

    <DWKitAdmin
      ...
      authServerHost="http://localhost:48800"
      ...
    />
  • In configuration on server specify admin host among available redirects. It's done in the DWKit configuration file.

    {
      "IdentityServerSettings": {
          "RedirectHosts": ["http://localhost:48800", "http://localhost:8091"]
      }
    }
  • Controller methods which admin panel requests (i.e. ConfigAPIController and WorkflowController) must use IdentityServer4.IdentityServerConstants.LocalApi.PolicyName policy for authorization. Relevant attributes are already written in these controllers code, you just need to uncomment them.