Sitecore Identity Part 2: Identity Client and Resource Authorization


In the previous blog we discussed fundamentals of OAuth 2.0 and Open Id Connect. We discussed the implementation of these two protocols in Sitecore Identity Server using IdentityServer4 framework. We also discussed, how Sitecore Identity will play the role in Sitecore Micro Service Architecture.
In this blog, we will show, how we can create a Sitecore Identity Client that authenticates against Sitecore Identity Server and how this client can authorize via Sitecore Identity Server to use Sitecore Services. For the purpose of demonstration, I have created a ASP.Net Core MVC client that will use hybrid grant type to authenticate and authorize against Sitecore Identity Server. I also created a sample API service that returns data using Sitecore Layout Service and it is scoped using sitecore.profile.api scope. This sample service can be seen as a sitecore resource.
Following diagram shows how different parts of this example fits into the architecture.

Following animation shows my Sitecore Identity Client in action. This shows

  • Client is authenticated by Sitecore Identity Server and displays the identity information.
  • Renewing token from the Identity Server.
  • Calling Sitecore Service to demonstrate authorizing Sitecore Resource via Sitecore Identity.
  • Logging out.

Sitecore Identity Client in Action

Sitecore Identity Configuration

For an Sitecore Identity Client to be recognized by Sitecore Identity Server, we have to provide some information to it. There are two ways to do this, we can use dependency injection or we can register the client in IdentityServer.xml located in <website root>\sitecore\Sitecore.Plugin.IdentityServer\Config. There is a Clients section in IdentityServer.xml, we can either use the DefaultClient, which is used by Sitecore (Sitecore is a Sitecore Identity Client) or we can add a new client. I chose to add a new Client. Let’s go through that and understand important client configuration. Following fields are most important.

  • ClientId: Uniquely identify a client’s behavior. When a Client use this Id, Sitecore Identity Server use this Id to find out the configuration to be used for the client. Same ClientId can be used by more than one client. For example, instead of creating a new client in the config for my Identity Server client, I could have used DefaultClient, which is used by Sitecore.
  • ClientSecret: Client Secret is used to authenticate client against Sitecore Identity Server. This field is optional.
  • AllowOfflineAccess: Sitecore Identity supports offline_access scope, which is used to renew access token. This field in the configuration determines if offline_access scope is supported for client or not. If not supported, client will not be able to renew the token and will have to authenticate again to get a new token after token expires.
  • RequireConsent: This field determines if Identity Server needs to get consent from the resource owner before the client is authorized to get access to the resources. Typically, it is an intermediate page implemented in the Identity Server to show the user a list of scopes she is giving access to the client. Sitecore Identity Server didn’t implement this page yet. So, if you set this field ‘true’, you will get page not found error.
  • AllowedGrantTypes: This field lists the OAuth grant types allowed for the client. Supported grant types for Sitecore Identity can be found in the previous blog.
  • RedirectUris: This field contains list of URIs where Identity Server will redirect this user after login. The OpenId Connect authentication middleware handles /singin-oidc route and populates the user information before redirecting user to the return url. The
    {AllowedCorsOrigin} is replaced with AllowedCorsOrigins field mentioned below. Sitecore uses /identity/signin  for RedirectUris, not the standard oidc route.
  • PostLogoutRedirectUris: This field is similar to RedirectUris, except that this is the URL where Identity Server redirects the client after logging out. Standard oidc route is /signout-callback-oidc
  • AllowedCorsOrigins: This field lists the domain names allowed to use Identity Server for authentication and authorization. In my case I am running the client website at http://localhost:5002.

Sitecore Identity Client

Now we have to create an Identity Client. For this I haven’t reinvented the wheel. I took the same approach as the IdentityServer samples and added a new sample client for Sitecore Identity Server. My samples can be found here. This is a fork out of original IdentityServer4 samples with Sitecore Client and sample Sitecore API (we will discuss in the next section).
I added the following code in Startup.cs. This configures the client. Lines of code we need to pay attentions are, Authority, ClientId, ClientSecret and scopes. Authority is Sitecore Identity server URL. ClientId and ClientSecret are same as in the Sitecore Identity Configuration above. Also, this client wants to authenticate using OpenId Connect, access Sitecore Profile and Profile API and renew the expired access token without logging in as declared in the scopes.

using System;
using System.IdentityModel.Tokens.Jwt;
using System.Net.Http;
using Clients;
using IdentityModel;
using IdentityModel.Client;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.IdentityModel.Tokens;
namespace SitecoreMvcClient
public class Startup
public Startup(IConfiguration configuration)
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
services.AddSingleton<IDiscoveryCache>(r =>
var factory = r.GetRequiredService<IHttpClientFactory>();
return new DiscoveryCache(Constants.SitecoreAuthority, () => factory.CreateClient());
services.AddAuthentication(options =>
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = "oidc";
.AddCookie(options =>
options.ExpireTimeSpan = TimeSpan.FromMinutes(60);
options.Cookie.Name = "sitecoremvcclient";
.AddOpenIdConnect("oidc", options =>
options.Authority = Constants.SitecoreAuthority;
options.RequireHttpsMetadata = false;
options.ClientSecret = "abracadabra";
options.ClientId = "sitecoremvc";
options.ResponseType = "code id_token";
options.ClaimActions.MapAllExcept("iss", "nbf", "exp", "aud", "nonce", "iat", "c_hash");
options.GetClaimsFromUserInfoEndpoint = true;
options.SaveTokens = true;
options.TokenValidationParameters = new TokenValidationParameters
NameClaimType = JwtClaimTypes.Name,
RoleClaimType = JwtClaimTypes.Role,
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)

Following method in the HomController when executes, authentication middleware redirect user to the Authority URL set in the Startup.cs, in this case redirects to Sitecore Identity Server. Once user authenticates, middleware use RedirectUri to collect user information and redirect user to the secure page, where the user, claims and token information are displayed.

public IActionResult Secure()
ViewData["Message"] = "Secure page.";
return View();

There are methods in HomeController to handle Logout and Renewal of token. You can download the code or go to github and explore. I have added the github link at the end of this blog.
Following method is used to make a call to an API which is retrieving data using Sitecore Layout Service API and this API resource is protected by Sitecore Identity Server. The API is like a micro service that the Identity Client is accessing using the access token Identity Server generated on resource owner’s behalf.

public async Task<IActionResult> CallSitecoreApi()
var token = await HttpContext.GetTokenAsync("access_token");
var client = _httpClientFactory.CreateClient();
var response = await client.GetStringAsync(Constants.SitecoreApi + "sitecorelayout");
var obj = JsonConvert.DeserializeObject(response);
ViewBag.Json = JsonConvert.SerializeObject(obj, Formatting.Indented);
return View();

Sitecore Sevice API

I created a sample API project which is using Layout Service API to retrieve data for the root item from my Sitecore 9.1 instance. For this I had to install Sitecore JSS Server package. I provided prerequisite for this API project in the Readme of the github repository.
If you look at the Startup code for this project, the APIs from this project can be accessed using Bearer token generated by the Sitecore Identity Server and APIs are available only to clients who are granted sitecore.profile.api scope. This API project only allow client that is coming from http://localhost:5002.

using Clients;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
namespace SitecoreApi
public class Startup
private readonly ILogger<Startup> _logger;
public Startup(ILogger<Startup> logger)
_logger = logger;
public void ConfigureServices(IServiceCollection services)
.AddJwtBearer("Bearer", options =>
options.Authority = Constants.SitecoreAuthority;
options.RequireHttpsMetadata = false;
options.Audience = "sitecore.profile.api";
public void Configure(IApplicationBuilder app)
app.UseCors(policy =>

There is only one API controller which is returning simply layout data using Sitecore Layout Service as shown below.

using System.Net.Http;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
namespace SitecoreApi
public class SitecoreLayoutController : ControllerBase
public async Task<IActionResult> Get()
var client = new HttpClient();
var content = await client.GetStringAsync("http://sitecore910.sitecore/sitecore/api/layout/render/jss?item=/&sc_apikey={9B8A0FCF-BA5A-483E-9AB0-E263866B9EAF}");
return new JsonResult(JsonConvert.DeserializeObject(content));


In this blog we discussed how we can register a client for Sitecore Identity Server, how to create a Sitecore Identity Client and how to create a resource that can be authorized by Sitecore Identity Server. All the code created for this blog can be downloaded from github link in the reference section below.



About Himadri Chakrabarti (he/him)

I am a solutions architect and technology enthusiast. I am Sitecore and Optimizely MVP. When I am not working with technology I spend time on photography Opinions expressed in my blogs are my own.
This entry was posted in Security, Sitecore, sitecore Identity and tagged , , , , . Bookmark the permalink.

1 Response to Sitecore Identity Part 2: Identity Client and Resource Authorization

  1. Pingback: Sitecore Identity Part 3: Connecting to External Identity Provider | Himadri's Technical Blog

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.