HomeDev GuideAPI Reference
Dev GuideAPI ReferenceUser GuideLegal TermsGitHubNuGetDev CommunitySubmit a ticketLog In

Authenticate the API

Describes how to secure requests to the APIs with OpenID Connect and Bearer Tokens (JWT).

Using the following methods, you should secure requests to the APIs with OpenID Connect and Bearer Tokens (JWT).

  • Configure the application to use an external login provider and enable the JWT Bearer token middleware.
  • Use the implementation based on OpenIddict, ASP.NET Identity, and Entity Framework. The Optimizely implementation gives you the basic OpenID Connect support and the following grant types or flows:
    • Authorization code – For interactive clients.
    • Client Credentials – For machine-to-machine communication.
    • Resource Owner Password – This flow is turned off by default, and you should only use this flow for backward compatibility. This flow is less secure.

Optimizely supports the user info endpoint for retrieving additional user claims.

Install

Install the EPiServer.OpenIDConnect NuGet package from the NuGet feed. You can optionally install EPiServer.OpenIDConnect.UI to get access to a UI where you can revoke authorizations.

Configure

public void ConfigureServices(IServiceCollection services) {
  // ASP.NET Identity needs to be configured before OpenID Connect
  services.AddCmsAspNetIdentity<ApplicationUser>();

  services.AddOpenIDConnect<ApplicationUser>(
    useDevelopmentCertificate: true,
    signingCertificate: null,
    encryptionCertificate: null,
    createSchema: true,
    options => {
      // Sample interactive JavaScript application 
      options.Applications.Add(new OpenIDConnectApplication {
        ClientId = "frontend",
          Scopes = {
            "openid",
            "offline_access",
            "profile",
            "email",
            "roles"
          },
          PostLogoutRedirectUris = {
            new Uri("http://localhost:8080")
          },
          RedirectUris = {
            new Uri("http://localhost:8080/login-callback"),
            new Uri("http://localhost:8080/login-renewal"),
          },
      });

      // Sample application using Client Credentials to make
      // machine-to-machine API calls
      options.Applications.Add(new OpenIDConnectApplication {
        ClientId = "cli",
          ClientSecret = "cli",
          Scopes = {
            ContentDefinitionsApiOptionsDefaults.Scope
          }, // Default scope from Content Definitions API
      });
    });

  // If you have installed EPiServer.OpenIDConnect.UI
  services.AddOpenIDConnectUI();
}

After that, add the Content delivery to the startup.cs file

services.AddContentDeliveryApi(OpenIDConnectOptionsDefaults.AuthenticationScheme, options => {
    options.SiteDefinitionApiEnabled = true;
    options.DisableScopeValidation = false;//default value = true
})
   .WithFriendlyUrl()
   .WithSiteBasedCors();

If DisableScopeValidation = true, the CD will accept the anonymous call.

In production, provide a certificate as an X509Certificate2 for signing and encrypting tokens. During development, OpenIddict provides one automatically if useDevelopmentCertificate is set to true. If the application runs in DXP, Optimizely will provide certificates automatically through the EPiServer.CloudPlatform.Cms package in version 1.3.0 or later. To use the provisioned certificates, use the ICertificateProvider when configuring OpenIddict:

services.AddOpenIDConnect<ApplicationUser>(useDevelopmentCertificate: false, createSchema: true);
services.TryAddEnumerable(ServiceDescriptor.Transient<IConfigureOptions<OpenIddictServerOptions>, CertificateConfigurer>());
internal sealed class CertificateConfigurer: IConfigureOptions < OpenIddictServerOptions > {
  //Names of certificates provisioned by DXP
  internal
  const string SIGNING_CERT_NAME = "oidc-signing";
  internal
  const string ENCRYPTION_CERT_NAME = "oidc-encryption";

  private readonly ICertificateProvider _certificateProvider;

  public CertificateConfigurer(ICertificateProvider certificateProvider) {
    _certificateProvider = certificateProvider;
  }

  public void Configure(OpenIddictServerOptions options) {
    var signingCert = _certificateProvider.Get(SIGNING_CERT_NAME).FirstOrDefault();
    if (signingCert is not null) {
      var signingCredentials = new SigningCredentials(new X509SecurityKey(signingCert), SecurityAlgorithms.RsaSha256);
      options.SigningCredentials.Add(signingCredentials);
    }

    var encryptionCert = _certificateProvider.Get(ENCRYPTION_CERT_NAME).FirstOrDefault();
    if (encryptionCert is not null) {
      var encryptionCredentials = new EncryptingCredentials(new X509SecurityKey(encryptionCert), SecurityAlgorithms.Aes256KW, SecurityAlgorithms.Aes256CbcHmacSha512);
      options.EncryptionCredentials.Add(encryptionCredentials);
    }
  }
}

📘

EPiServer.CloudPlatform.Cms prior to 1.6.1

If you are using EPiServer.CloudPlatform.Cms prior to 1.6.1, ICertificateProvider is not available. In that case, use CertificatesProvider instead.

var certificates = EPiServer.CloudPlatform.Cms.Certificates.CertificatesProvider.Get(_configuration);

services.AddOpenIDConnect<ApplicationUser>(
    useDevelopmentCertificate: false,
    certificates.SigningCertificate,
    certificates.EncryptionCertificate,
    createSchema: true);

You can extend the Entity Framework entities OpenIddict and ASP.NET Identity is used for managing applications and users. If you choose, you should turn off automatic schema creation and rely on migrations directly from Entity Framework.

When configuring Optimizely APIs, use the OpenIDConnectOptionsDefaults.AuthenticationScheme constant as the authentication scheme. The authentication scheme is the first parameter in each method that adds the API.

public void ConfigureServices(IServiceCollection services) {
  services.AddContentDeliveryApi(OpenIDConnectOptionsDefaults.AuthenticationScheme);
}

This scheme can also be used in your web API endpoints.

[Authorize(OpenIDConnectOptionsDefaults.AuthenticationScheme)]
public class MyApiController : ControllerBase {
}