ClubberLang
ClubberLang

Reputation: 1898

How to protect API (from unexpected calls) with IdentityServer4?

I have a 3 tiers Blazor application, and use IdentyServer 4.1 for authentication.

My current problem is that some API endpoints are not protected, any application can do such call.

My understanding is that IdentityServer only server token for authenticated users, right? Is there a way to ensure that the calls are coming from my applications (web site, mobile, etc...), maybe with a token... but how?

Upvotes: 0

Views: 274

Answers (2)

enet
enet

Reputation: 45764

You'll need to protect your Web-Api end-points with JwtBearer authentication.

Here's a code sample you should have in your Web Api's Startup class:

Startup.ConfigureServices method

    using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.IdentityModel.Tokens;


services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
                .AddJwtBearer(options =>
                {
                    options.Authority = "https://localhost:5000";
                    options.Audience = "weatherapi";
                    options.TokenValidationParameters = new TokenValidationParameters()
                    {
                        NameClaimType = "name"
                    };
                });

Startup.Configure

// Code omitted...

 app.UseCors(config => 
            {
                config.AllowAnyOrigin();
                config.AllowAnyMethod();
                config.AllowAnyHeader();
            });

 app.UseAuthentication();

 app.UseAuthorization();

You'll also need to install the Microsoft.AspNetCore.Authentication.JwtBearer package, which add the ASP.NET Core middleware that enables an application to receive an OpenID Connect bearer token.

You'll also need to annotate your protected end points with the Authorize attribute, or alternatively your controller, like this:

[Authorize]
[ApiController]
[Route("api/[controller]")]
public class WeatherForecastController : ControllerBase
{
}

Note: options.Authority = "https://localhost:5000"; is your IdentityServer project

Note that options.Audience = "weatherapi"; is set up in your IdentityServer project's Config.cs file like this:

public static IEnumerable<ApiResource> Apis =>
            new ApiResource[]
            {
                new ApiResource("weatherapi", "The Weather API")
            };

And

public static IEnumerable<Client> Clients =>
            new Client[]
            {
                new Client
                {
                    ClientId...,
                    
                    AllowedScopes = { "openid", "profile", "email", "weatherapi" } 
                },
            };

Upvotes: 1

Tore Nestenius
Tore Nestenius

Reputation: 19991

If you protect your APIs using the AddJwtBearer handler, it will protect your API and only tokens issued by your IdentityServer will be accepted (comparing the iss claim).

You can also control that the audience of the token is your API. Meaning that your IdentityServer can issue tokens meant for different API's (using the aud claim).

The signature of the tokens can only be accepted if they are signed by the IdentityServer private key. The public part of that key is automatically downloaded by your API at startup.

So, the conclusion is that it is safe.

But this is only dealing with authentication, then you apply authorization checks once you have validated the access token.

The picture from one of mu training classes shows how the pipeline is constructed:

enter image description here

Upvotes: 1

Related Questions