Introduction:
In this article you will learn how to integration a IdentityServer4 with ASP.NET Core 6 to secure our API application. This article will start with of scratch of creating an empty ASP.NET Core application to build it with OpenID Framework.
Prerequisites:
Basic knowledge in building ASP.NET Core web application.
This article cover following topics
- What is Identity Server4?
- Create an ASP.NET Core project with IdetityServer4
- Adding in-Memory Configuration
- Test User
- Identity Resources
- API Scopes
- API Resource
- Clients
- Registering IdentityServer4 in ASP.NET Core
- In Memory configuration store
- Singing Credentials
- Running IdentityServer4
- Fetching Access token with POSTMAN
- Understanding the token
- Build Authentication layer in ASP.NET Core Web API with IdentityServer4
- Fetching the Token
- Accessing the API with Access token
- Summary
1. What is Identity Server4?
Identity Server4 is an open-source authentication provider with OpenID connect and OAuth2.0 framework for ASP.NET Core. It acts as a centralized authentication provider or security token server (STS). It will be ideal to go through layers when you have multiple API/microservices applications and you should have single security token server to handle the authentication so that you really don’t have to define the Authentication in each and every application.
Identity server4 is a simple and straightforward STS. The user uses the clients (ASP.NET MVC or angular or react application and so on) to access the data, these users are authenticated by Identity Server to use the client. After successful authentication, the Identity server will send a token to client. Then client should use this token to access the data from the APIs.
The identityServer4 is the implementation of OpenID Connect and OAuth 2.0 to secure mobile, native and web applications. It acts as a middleware and a single source where you can integrate with multiple application to frame the authentication layer to secure your applications.
2. Create ASP.NET Core Project with IdentityServer 4
Create an empty ASP.NET Core project with .NET 6 framework using Visual Studio.

This project will act as an actual IdentityServer
Install IdentityServer4 Package using below command with Package Manager console in Visual studio.
Install-Package IdentityServer4
3. Adding in-memory configuration
For demo purpose I will be adding all the configuration within the code to make it much easier for understanding
Note: This is not a case when you integrate IdentityServer4 in production. My next article on IdentityServer4 with ASP.NET Core will teach you how to make this project production ready.
Create a Class and name it as IdentityConfiguration.cs
3.1 Test User
Add the following code to the IdentityConfiguration class
public static List<TestUser> TestUsers =>
new List<TestUser>
{
new TestUser
{
SubjectId = "123",
Username = "Gowtham",
Password = "Test@123",
Claims =
{
new Claim(JwtClaimTypes.Name, "Gowtham K"),
new Claim(JwtClaimTypes.GivenName, "Gowtham"),
new Claim(JwtClaimTypes.FamilyName, "Kumar"),
new Claim(JwtClaimTypes.WebSite, "https://gowthamcbe.com/"),
}
}
};
For demo purpose I have defined a test user. This above code will return a TestUser with some specific JWT Claims.
3.2 Identity Resource
The data like UserId, phone number, email which has something unique to a particular identity/user are the Identity Resource. Add the following code to IdentityConfigration class
public static IEnumerable<IdentityResource> IdentityResources =>
new IdentityResource[]
{
new IdentityResources.OpenId(),
new IdentityResources.Profile(),
};
The above code will add OpenId and Profile Identity resources.
3.3 API Scopes
Scopes defines the authorization level for the user. Let’s have two scopes for now name it as api.read and api.write. You will learn more about this scope implementation in my future article on IdentityServer4. Add following code to IdentityConfigration class
public static IEnumerable<ApiScope> ApiScopes =>
new ApiScope[]
{
new ApiScope("api.read"),
new ApiScope("api.write"),
};
3.4 API Resources
Let’s define the API Resource with Scopes and API Secrets. Ensure to hash this secret code. This secret hashed code will be saved internal within IdentityServer4.
public static IEnumerable<ApiResource> ApiResources =>
new ApiResource[]
{
new ApiResource("myApi")
{
Scopes = new List<string>{ "Api.read","Api.write" },
ApiSecrets = new List<Secret>{ new Secret("secret".Sha256()) }
}
};
3.5 Clients
Let’s define the clients by giving proper clientId and name. We also have to define who will be granted access to our protected resource. In our case it is myAPI. Add following code to IdentityConfigration class
public static IEnumerable<Client> Clients =>
new Client[]
{
new Client
{
ClientId = "client",
ClientName = "Client Credentials Client",
AllowedGrantTypes = GrantTypes.ClientCredentials,
ClientSecrets = { new Secret("secret".Sha256()) },
AllowedScopes = { "api.read" }
},
};
4.Registering IdentityServer4 in ASP.NET Core
Let’s register IdentityServer4 in ASP.NET Core application. Open Program.cs file and add the following code.
builder.Services.AddIdentityServer()
.AddInMemoryClients(IdentityConfiguration.Clients)
.AddInMemoryIdentityResources(IdentityConfiguration.IdentityResources)
.AddInMemoryApiResources(IdentityConfiguration.ApiResources)
.AddInMemoryApiScopes(IdentityConfiguration.ApiScopes)
.AddTestUsers(IdentityConfiguration.TestUsers);
.AddDeveloperSigningCredential();
The above configure all the Static Resources, clients, and Users which are defined in IdentiyConfigration.cs class.
4.1 In-Memory Configuration Store
I have hardcoded the configurations of IdentityServer for a demo. All these operational and configurational data are store In-Memory. These configurations are loaded only once the application start-up mostly suitable for development.
4.2 Signing Credentials
IdentityServer needs certificates to verify it’s usage, since we don’t have certificate, we use AddDeveloperSigningCredential() extension.
app.UseIdentityServer();
Complete code
using IdentityServer4.NCache.Options;
using IdentityServerCore;
using Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddIdentityServer()
.AddInMemoryClients(IdentityConfiguration.Clients)
.AddInMemoryIdentityResources(IdentityConfiguration.IdentityResources)
.AddInMemoryApiResources(IdentityConfiguration.ApiResources)
.AddInMemoryApiScopes(IdentityConfiguration.ApiScopes)
.AddTestUsers(IdentityConfiguration.TestUsers)
.AddDeveloperSigningCredential();
var app = builder.Build();
app.MapGet("/", () => "Hello World!");
app.UseRouting();
app.UseIdentityServer();
app.Run();
5. Running IdentityServer4
5.1 Fetching Access token with POSTMAN
Run the application, let’s test the token generation from postman

After successfully authorization, IdentityServer4 will returns an access token that is valid for 3600 seconds.
5.2 Understanding the token
Copy the encoded token and head over to jwt.io to decode the Access Token.
Note: Any JWTokens can be decoded, thus make sure to never add any sensitive data like password, etc on to your tokens.

6. Build Authentication layer in ASP.NET Core Web API with IdentityServer4
Let’s see how to secure the ASP.NET Web API application with IdentityServer4. Add a new ASP.NET Core Web API Project to the solution.

Install “IdentityServer4.AccessTokenValidation” package from package manager console using below command.
Install-Package IdentityServer4.AccessTokenValidation
Open up Program.cs of the Web API Project and add the following code
builder.Services.AddAuthentication("Bearer").AddIdentityServerAuthentication("Bearer", options =>
{
options.ApiName = "myApi";
options.Authority = "https://localhost:7136";
});
This configuration tells the program to use the authentication service(IdentityServer4 project). It act as a Authentication middleware to the pipeline.
app.UseAuthorization();
From the solution -> Set StartUp Project, choose multiple startup project and set the API and Identity server project to start.

In the API project we have default WeatherForecast GET API under WeatherForecastController. Set Authorize attribute to this controller.
[ApiController]
[Route("[controller]")]
[Authorize]
Run the solution and test the WeatherForecast API with POSTMAN

The status code is 401. Since no token was passed this request is unauthorized.
6.2 Accessing the API with Access token
Let’s generate a new token as we did in previous step using https://localhost:7136/connect/token POST API and pass that token with /WeatherForecast GET API in POSTMAN

Now the authorization was successful and we got a proper response from the API.
7. Summary
In this article, we covered the basics of IdentityServer4 like Resources, Test Users, Clients, etc. Finally, we build the API project and secured it by the IdentityServer4 with the token to validate the clients.
Source code – Get here.
I hope this article will help you to get start with IdentityServer4. Please share your queries, suggestions in the comments section below.
Happy Coding!!!
Scopes = new List{ “Api.read”,”Api.write” }
the list should be like { “api.read”,”api.write” } with small case “a”.
With “A” it is causing problem and giving empty audience error.
I tried this on .net core 7.