Applying security to API's

Learn how to integrate Keycloak’s identity service into the APIs for access control in the microservice developed using the Devprime platform. Keycloak supports OpenID Connect / OAuth 2.0 / JWT in the protection of web pages and API’s.

During this scenario, we’ll use the Devprime stack’s security adapter to enable security settings, and we recommend that you implement Applying Web Security.

To move forward in this scenario, it is essential to have an instance of Keycloak and follow the steps as instructed below:

  1. Create an instance of Keycloak following the indicated procedures.
  2. Install the Devprime CLI.
  3. Creating a microservice for use in the ms-sec-order demo
    dp new ms-order-payment --state mongodb --stream rabbitmq --marketplace payment --init

dp new ms-order-delivery –state mongoDB –stream rabbitmq –marketplace delivery –init

  1. After completion, you can run the microservice. Then finish.
    .\run.ps1 or ./run.sh (Linux, macOS)

  2. Changing the Default Microservice Port
    We will now edit the appsettings.json file available in the ms-payment/src/App folder to configure the web adapter and then the security adapter. Assign the value of the url parameter to avoid port conflict.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
  "Devprime_Web": {
    "url": "https://localhost:5003;http://localhost:5002",
    "enable": "true",
    "enableswagger": "true",
    "PostSuccess": "201",
    "PostFailure": "500",
    "GetSuccess": "200",
    "GetFailure": "500",
    "PatchSuccess": "200",
    "PatchFailure": "500",
    "PutSuccess": "200",
    "PutFailure": "500",
    "DeleteSuccess": "200",
    "DeleteFailure": "500",
    "EnableWebLegacy": "false",
    "EnableStaticFiles": "true",
    "ShowHttpRequests": "false"
  },
  1. Open the settings file and include in the security adapter the Keycloak parameters obtained in item 1 of this walkthrough by changing the items “Domain, ClientID / ClientSecret / LogoutUri / Audience”
    code ./src/App/appsettings.json
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
  "Devprime_Security": {
    "Enable": "true",
    "Identity": {
      "Enable": "true",
      "Type": "keycloak",
      "Domain": "http://localhost:8080/realms/devprime",
      "ClientId": "Your-app-name",
      "ClientSecret": "Your-secret",
      "EnableOIDC": "false",
      "Audience":"Your-app-name",
      "AuthenticationScheme": "OpenIdConnect",
      "LogoutUri": "http://localhost:8080/auth/realms/devprime/protocol/
      openid-connect/logout?redirect_uri=https%3A%2F%2Flocalhost%3A5001",
      "Scopes": "openid;email"
    }

After completing this stage, the API access security control is already configured. Locate the Payment.cs file in the ms-payment/src/Adapters/Web/ folder to configure access restriction to a route in the API. In the example below, we will apply it to the item “app. MapPost /v1/payment”.

    public override void Endpoints(WebApplication app)
    {
        //Automatically returns 404 when no result  
        app.MapGet("/v1/payment" ,[Authorize] async (HttpContext http, IPaymentService Service, int? limit, int? offset, string ordering, string ascdesc, string filter) => await Dp(http).Pipeline(() => Service.GetAll(new Application.Services.Payment.Model.Payment(limit, offset, ordering, ascdesc, filter)), 404));
        //Automatically returns 404 when no result 
        app.MapGet("/v1/payment/{id}", async (HttpContext http, IPaymentService Service, Guid id) => await Dp(http).Pipeline(() => Service.Get(new Application.Services.Payment.Model.Payment(id)), 404));
        app.MapPost("/v1/payment", async (HttpContext http, IPaymentService Service, Devprime.Web.Models.Payment.Payment command) => await Dp(http).Pipeline(() => Service.Add(command.ToApplication())));
        app.MapPut("/v1/payment", async (HttpContext http, IPaymentService Service, Application.Services.Payment.Model.Payment command) => await Dp(http).Pipeline(() => Service.Update(command)));
        app.MapDelete("/v1/payment/{id}", async (HttpContext http, IPaymentService Service, Guid id) => await Dp(http).Pipeline(() => Service.Delete(new Application.Services.Payment.Model.Payment(id))));
    }
  1. Rerun the microservice and open the url https://localhost:5003

  2. Log in to swagger and try to perform a “GET”

  3. Since security is active, the response will be a 401 indicating lack of permission
    401 Security

  4. You can also perform the same test using curl
    curl https://localhost:5003/v1/payment -i

HTTP/1.1 401 Unauthorized
Content-Length: 0
Date: Fri, 20 Jan 2023 23:49:26 GMT
Server: Kestrel
WWW-Authenticate: Bearer

Next Steps:

You’ve secured access to a microservice API using Keycloak.
Congratulations🚀

Last modified April 11, 2024 (cc33f7e6)