1. Client Credentials instance
① Preparation
To install the template, open a console window and type the following command:
dotnet new -i IdentityServer4.Templates
After installation, there will be so few identityserver templates
We choose the In-Memory Stores and Test Users template to put the information in memory
②Create In-Memory Stores and Test Users template project
dotnet new is4inmem name--myService
Several Client categories will be generated in the config file, this case will try
Then we set the service start port to 5000
③ Create a client
Write a client requesting an access token, create a console application and set the startup port to 5002
Add IdentityModel package
Read the actual endpoint address from the metadata
// discover endpoints from metadata var client = new HttpClient(); var disco = await client.GetDiscoveryDocumentAsync("http://localhost:5000"); if (disco.IsError) { Console.WriteLine(disco.Error); return; }
Next, you can use the information in the discovery document to request a token from IdentityServer to accessapi1
// request token var tokenResponse = await client.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest { Address = disco.TokenEndpoint, ClientId = "client", ClientSecret = "secret", Scope = "api1" }); if (tokenResponse.IsError) { Console.WriteLine(tokenResponse.Error); return; } Console.WriteLine(tokenResponse.Json);
Send access token to API, access api
// call api var apiClient = new HttpClient(); apiClient.SetBearerToken(tokenResponse.AccessToken); var response = await apiClient.GetAsync("http://localhost:5001/identity"); if (!response.IsSuccessStatusCode) { Console.WriteLine(response.StatusCode); } else { var content = await response.Content.ReadAsStringAsync(); Console.WriteLine(JArray.Parse(content)); }
④Define API resources
Create an api project and set the startup port to 5001
Add a new class namedIdentityController
[Route("identity")] [Authorize] public class IdentityController: ControllerBase { [HttpGet] public IActionResult Get() { return new JsonResult(from c in User.Claims select new { c.Type, c.Value }); } }
Then add permission access [Authorize] on the controller
The final step is to add the authentication service to DI (Dependency Injection) and add the authentication middleware to the pipeline. These will:
- Verify incoming token to ensure it comes from a trusted issuer
- Verify that the token can be used with this API (also called audience)
public class Startup { public void ConfigureServices(IServiceCollection services) { services.AddControllers(); services.AddAuthentication("Bearer") .AddJwtBearer("Bearer", options => { options.Authority = "http://localhost:5000"; options.RequireHttpsMetadata = false; options.Audience = "api1"; }); } public void Configure(IApplicationBuilder app) { app.UseRouting(); app.UseAuthentication(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); } }
AddAuthentication
Add the authentication service to DI and configure itBearer
as the default scheme.UseAuthentication
Add authentication middleware to the pipeline so that every call to the host will automatically perform authentication.UseAuthorization
Authorization middleware was added to ensure that anonymous clients cannot access our API endpoints.
http://localhost:5001/identity
Navigating to the controller on the browser should return a 401 status code. This means that your API requires credentials and is now protected by IdentityServer.
References: https://identityserver4.readthedocs.io/en/latest/quickstarts/1_client_credentials.html