Aplicando segurança nas API's

Aprenda como integrar o serviço de identidade do Keycloak nas API’s para controle de acesso no microsserviço desenvolvido utilizando a plataforma Devprime. O Keycloak suporta OpenID Connect / OAuth 2.0 / JWT na proteção de páginas web e API’s.

Durante esse cenário nós utilizaremos o adapter de security do Devprime stack para ativar as configurações de segurança e nós recomendamos que tenha implementado o item Aplicando segurança na Web.

Para avançar nesse cenário é fundamental ter uma instância do Keycloak e seguir os passos conforme instruções abaixo:

  1. Crie uma instância do Keycloak seguindo os procimentos indicados.
  2. Instale o Devprime CLI.
  3. Criando um microservico para uso na demonstração “ms-sec-order”
    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. Após a conclusão é possivel executar o microsserviço. Depois finalize.
    .\run.ps1 ou ./run.sh (Linux, macOS)

  2. Alterando a porta padrão do microsserviço
    Nós vamos agora editar o arquivo appsettings.json disponível na pasta ms-payment/src/App para configurar o adapter web e depois o adapter security. Aletre o valor do parâmetro url para evitar conflito de portas.

 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. Abra o arquivo de configurações e inclua no adapter de security os parametros do Keycloak obitidos no item 1 desse passo a passo alterando os itens “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"
    }

Após concluindo esse estágio o controle de segurança de acesso a API já configurado. Localize o arquivo Payment.cs na pasta ms-payment/src/Adapters/Web/ para configurar a restrição de acesso à uma rota na API. No exemplo abaixo aplicaremos no 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. Execute novamente o microsserviço e abra a url https://localhost:5003

  2. Entre no swagger e tente efetuar um “GET”

  3. Como a segurança está ativa a resposta será um 401 indicando falta de permissão
    401 Security

  4. Você também pode realizar o mesmo teste utilizando o 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

Próximos passos:

Você protegeu o acesso a uma API do microsserviço utilizando o Keycloak.
Parabéns🚀

Última modificação September 2, 2023 (c87f0320)