0.0.4 • Published 2 years ago

@collabee-tech/collabee-ch-security v0.0.4

Weekly downloads
-
License
MIT
Repository
github
Last release
2 years ago

nodelib-atle-base-security

Biblioteca de segurança para aplicações desenvolvidas com o chassis.

Introdução

A biblioteca de segurança do chassis contém um conjunto de middlewares para immplementar controles de segurança em aplicações baseadas no servidor ExpressJS.

A autenticação e autorização baseia-se no mecanismo JWT (JSON Web Tokens), enviado como um bearer token no header Authorization.

Para determinar se um determinado token é válido, a biblioteca deve ser configurada com a URL de onde serão baixadas as chaves públicas utilizadas para verificação da assinatura.

Após a validação da assinatura, a biblioteca extrai do token a lista de roles do mesmo, os quais são utilizados para implementar os controles de acesso. Opcionalmente, os roles extraidos do token podem passar por um mecanismo de mapeamento, de forma a permitir que a aplicação não tenha que ser alterada nos diferentes ambientes.

Incluindo a biblioteca em seu projeto

$ npm i @collabee-tech/collabee-ch-security

Utilizando o middleware global de segurança

A função authProviderMiddleware cria o middleware de segurança global utilizando configurações padrão:

import { authProviderMiddleware } from '@collabee-tech/collabee-ch-security'
let express = require('express');
let app = express();

app.use(authProviderMiddleware())

NOTA: O middleware deve ser adicionado à aplicação via método use ANTES da mesma ser iniciada

Adicionando restrições de segurança aos endpoints

Utilize a função rolesAllowed para criar um middleware que limita o acesso a determinado endpoint a usuários que tenham determinado role:

import { rolesAllowed } from '@collabee-tech/collabee-ch-security'

app.get("/resource", rolesAllowed("admin"), (req,res,next) => {
    res.send("Só para admins");
})

Configuração da URL das chaves públicas

A biblioteca utiliza a variável de ambiente COLLABEE_SECURITY_JWKS_URL para determinar o local de onde o arquivo padrão JWKS será baixado:

$ export COLLABEE_SECURITY_JWKS_URL=https://collabee.io/openid/connect/jwks.json

NOTA: O gateway utiliza certificados assinados pela CA interna da Collabee. Antes de executar sua aplicação, verifique se os certificados estão instalados no ambiente de execução do nodejs. Uma forma simples de fazer esta verificação é executar o comando curl -v https://endereco-do-jwks.

Configuração do tempo de vida das chaves públicas

A biblioteca mantem as chaves públicas em um cache interno, o qual é renovado em intervalos periódicos. Por padrão, este intervalo é de 5 minutos, mas pode ser ajustado por meio da variável de ambiente COLLABEE_SECURITY_JWKS_MAX_AGE. O valor desta variável corresponde ao tempo em minutos entre atualizações do cache.

Mapeamento de roles físicas em roles lógicas

A biblioteca de segurança permite que o mecanismo de mapeamento das roles extraidas do JWT (roles "físicas") sejam mapeadas em roles "lógicas", as quais são aquelas utilizadas como argumentos na função rolesAllowed.

Para casos simples, a biblioteca provê a classe SimpleRoleMapper, que utiliza um mapa simples em seu construtor. O código abaixo mostra um exemplo de como carregar este mapa a partir de um arquivo de configuração externo:

import { authProviderMiddleware,   SimpleRoleMapper } from '@collabee-tech/collabee-ch-security'

let roles = require(process.cwd() +"/config/roles.json");
let mapper = new SimpleRoleMapper(roles);

let express = require('express');
let app = express();

app.use(authProviderMiddleware(mapper))

O mapa lido arquivo roles.json deve ter como chaves os roles "físicos" e respectivos roles "lógicos":

{
    "ACME_BASE_ADMIN_QA": "admin",
    "ACME_BASE_USER_QA": "user"
}

Caso a aplicação necessite uma lógica mais complexa de mapeamento, ela deve criar suam própria implementação da interface RoleMapper e passá-la para o método authProviderMiddleware:

import { RoleMapper } from '@collabee-tech/collabee-ch-security'

export class CustomRoleMapper implements RoleMapper {

    mapRole(s: string): string[] {
        // ... implementação da lógica de mapeamento

        return myMappedRoles
    }
}

NOTA 1: O método mapRole retorna uma lista de roles lógicos, o que permite que um único role físico seja mapeado para mais de um role lógico.

NOTA 2: Caso o role físico passado como argumento não possua role lógico correspondente, mapRole deve retornar uma lista vazia

Acessando informações do usuário autenticado em um controller

O middleware de segurança adiciona na chave REQUEST_PRINCIPAL_KEY um objeto do tipo Principal, o qual permite aos controllers ter acesso a informações do usuário logado:

import {REQUEST_PRINCIPAL_KEY, Principal } from '@collabee-tech/collabee-ch-security'

app.get('/me', (req, res, next) => {

    let p = req[REQUEST_PRINCIPAL_KEY] as Principal

    // Acesso ao "username"
    let subject = await p.subject();

    // Determina se o usuário corrente possui ou não determinado role
    let isAdmin = await p.isInRole("admin")

    // Determina se o usuário está autenticado
    let isAuthenticated = await p.isAuthenticated();

})

URLs públicas

Por padrão a biblioteca de segurança bloqueia o acesso de qualquer requisição que não tenha um header de autenticação associado. Caso a aplicação tenha URLs públicas, é necessário passar um AuthorizationManager customizado para o middleware global criado pela função authProviderMiddleware().

Para facilitar esta liberação no caso mais comum, onde as URLs públicas são bem conhecidas, utilize a classe SimpleAuthorizationManager:

// Libera acessos aos caminhos indicados
let customAuthManager = new SimpleAuthorizationManager("/docs","/health", "/metrics");

 app.use(authProviderMiddleware(null,null, customAuthManager));