Árvore de páginas

Versões comparadas

Chave

  • Esta linha foi adicionada.
  • Esta linha foi removida.
  • A formatação mudou.

CONTEÚDO

Informações

Índice
maxLevel34
minLevel2
indent50px
absoluteUrltrue

01. 

VISÃO GERAL

Visão Geral

Disponibilizar um modelo de autenticação e autorização de acesso a recursos (endpoints), que permita abstração e flexibilidade com a utilização de um serviço de login independente (conforme modelo de arquitetura especificado na RFC000010 e RFC000015). 


02.

CONCEITOS APLICADOS

Conceitos Aplicados

OAuth2 é um protocolo que permite aos usuários ter acesso

limitado

a determinados recursos sem precisar expor suas credenciais.

Por isso, serão usados os fluxos de autenticação e autorização baseados no OAuth2.


Como funciona

Ao entrar em uma empresa com controle de acesso, é necessário efetuar previamente o cadastro na portaria (autenticação).

De acordo com a sua visita, a portaria garantirá a autorização de acesso temporária e você receberá um crachá para entrar em determinadas portas

COMO FUNCIONA

Alguns carros de luxo vem com uma chave extra chamada "valet key".

Essa chave pode ser utilizada quando queremos que um manobrista estacione o carro.

Ao utilizar essa chave para ligar o carro, o manobrista não será capaz de dirigir o carro por mais de 2 km.

Independente da restrição que essa chave especial o crachá impõe a seus utilizadores, a ideia é clara: você dá a alguém acesso limitado ao seu carro utilizando uma chave especial e quando quiser acesso ilimitado ao carro, utiliza a chave normal.as portas de acordo com a sua visita.



Para que serve

Análogo ao crachá

PARA QUE SERVE

Análogo a "valet key", para obter acesso limitado a recursos usando o OAuth2, utiliza-se um access token (token de acessoJWT), que permite usufruir recursos de terceiros de forma segura.



Tipos de Concessão de Acesso

A geração e acesso ao endpoint será concedido de acordo com a especificidade do modelo OAuth2

TIPOS DE CONCESSÃO DE ACESSO

A TOTVS utilizará no novo serviço de login um dos fluxos propostos pelo framework Oauth2, abaixo a sua especificidade:

  • O Grant Type para autenticação , autorização e permissionamento entre serviços (M2M). O Client é previamente cadastrado e permissionado e o Resource Server declara por meio de seeds seus recursos.

TIPOS DE GARANTIA DE ACESSO

Para o ERP ficar dentro da especificação e ter o escopo adequado, a TOTVS seguirá a implementação de dois tipos de Grant:

a. Client Credentials

Esse tópico aborda a autorização entre serviços (M2M) onde o Client age em seu próprio nome Resource Server.

Image Removed

Figura 1 - Modelo de acesso com Client Credentials

Abaixo estão listados os componentes do desenho acima:

  • IDM: Solução que garante a autenticidade do Resource Owner

  • Oauth Provider: Solução que assume o papel de Oauth Provider e atua como Authorization Server, esse componente tem a responsabilidade de assinar o access_token com chave assimétrica. O Authorization Server consome uma fila de propagação "Role x ClientId" produzida pelo componente RBAC que persisti para possibilitar a geração do access_token auto-contido com as "Roles" do ClientId. O Authorization Server deve verificar a base para invalidação do clientId de modo que o mesmo ao tentar renovar o access_token utilizando seu refresh_token ou autorizar seja invalidado pelo Oauth Provider;

  • RBAC: Esse componente é responsável por gerir as permissões possibilitando termos uma relação de "Role x Grant". A responsabilidade de verificação desse componente é classificada como extremamente crítica. A solução permite que o RBAC tenha consistência eventual delegando a verificação de "Grant x ClientID" para uma camada na aplicação (Resource Server);

  • Resource Server (APP 2): A aplicação que hospeda o recurso tem a responsabilidade de enviar suas Grants para o RBAC via fila. Esse componente também deve consumir a fila de propagação de "Role x Grant" e gravar os dados recebidos para possibilitar a verificação de permissão das "Roles" que estarão auto-contidas no access_token. O Resource Server tem posse da chave pública para a verificação do access_token. Percebe-se que é necessário a construção de uma abstração para as aplicações;

  • Client (APP 1): O Client é o consumidor do recurso e assume o papel de Resource Owner quando o "grant_type" é client_credentials, com isso, o Client precisa das credenciais client_id e client_secret gerados no momento do registro no Oauth Provider. Assumindo que o Client é o próprio Resource Owner não há a necessidade de delegação de acesso.

  • (Client Credentials ou Resource Owner Password Credentials);
  • Autorização de acesso conforme validade do token de acesso e regras de seguranças interna (certificado, audiência e escopo).



03. Exemplos de Utilização

Dica

Antes de iniciar a implementação, verifique qual o modelo é o mais adequado para as concessões de acesso, com base no melhor modelo de segurança,

Consulte os links: OAuth2 - Client Credentials e OAuth2 - Resource Owner Password Credentials para mais informações.

a. Configuração


As configurações para utilização dos conceitos de login conforme OAuth2 são realizadas nas telas de Propriedades, disponíveis no produto.

CFG - OAuth2Configura os modelos (Grant Type) de autenticação do usuário propostos nesta documentação.
CFG - JWTConfigura o modelo do Token JWT que será gerado caso a autenticação seja realizada com sucesso.



Informações

A seguir serão demonstrados alguns trechos de códigos em JavaScript e TypeScript que exemplificam os conceitos gerais de Autenticação (para gerar o token) e Autorização (validação do token ao requisitar um endpoint).

Lembrando que o código deve ser alterado de acordo com a linguagem de programação e regras específicas de segurança.

b. Client Credentials


Nota

Este modelo é recomendado quando há a necessidade de comunicações machine-to-machine pois não há um vínculo do usuário do ERP Datasul com a requisição, consequentemente não ocorrerá alguns relacionamentos como o direcionamento do broker, setar um usuário e empresa na memória do PASOE, entre outros. 

Geração do token

De posse com as credenciais de acesso (Id cliente e Senha cliente) cadatradas na tela de Propriedades → OAuth2 → Client Credentials, pode-se efetuar a requisição para a geração dos tokens.

No trecho de código abaixo, caso o token seja gerado com sucesso, seu retorno é armazenado no localStorage (para uso posterior) com a chave token-client.token. 

Bloco de código
languagejs
function token_client_credentials() {
	var http = new XMLHttpRequest();
	var url = '/totvs-login-oauth2/oauth2/token?grant_type=client_credentials';
	http.open('POST', url, true);

	http.setRequestHeader('Authorization', "Basic " + <id_cliente>":"+<senha_cliente>);

	http.onreadystatechange = function() {
		if(http.readyState == 4 && http.status == 200) {
			localStorage.setItem("token-client.token", http.responseText);
		}
	}
}

Utilização dos tokens para acessos aos endpoints

Com o token disponível no localStorage, para efetuar o acesso a determinados endpoints, basta resgatar o valor do access_token e enviá-lo na requisição desejada.

Para acessar os endpoints do ERP Datasul, basta enviar o valor do token como Authorization Bearer na requisição.

Bloco de código
languagejs
public onIntegration(): void {
	let jwtToken = this.getAccessToken();
	... 
	<EFETUA A REQUISIÇÃO AO ENDPOINT, O TOKEN DEVE SER ENVIADO COM BEARER AUTHORIZATION>
	...
}

private getAccessToken(): String {
	let tokenService = localStorage.getItem('token-client.token');
	let jsonTokenService = JSON.parse(tokenService);
	return jsonTokenService['access_token'];
}

Expiração do token

Para limitar o uso indevido em caso de vazamentos, todos os tokens expiram (tempo parametrizável no ERP Datasul), por este motivo é importante que durante a utilização do portal os tokens sejam continuamente revalidados.

Com o intuito de facilitar a geração do token dentro do produto, é necessário a utilização do refresh_token (grant_type e token):

Image Added

Método: POST

URL: http://{{host}}:{{port}}/totvs-login-oauth2/oauth2/token?grant_type=refresh_token

AuthorizationNão informar pois é considerada somente a validação do token

Body (x-www-form-urlencoded): 

  • refresh_token (Obrigatório): Enviar como x-www-form-urlencoded, o refresh_token gerado no login do produto.
Nota
titleNota
  • O refresh_token não possui atributos de acesso (aud, tenantId, scope), portanto não deve ser utilizado para acessos aos recursos;
  • Todo refresh_token é vinculado a um access_token, sendo deste token os atributos considerados para a nova geração;
  • Por motivos de segurança, após a utilização do refresh_token, o mesmo é automaticamente invalidado;
  • Para considerar um novo ciclo de geração, é necessário considerar os novos tokens gerados a partir do refresh_token.

No trecho de código abaixo é demonstrado a geração contínua de um token (com base no refresh_token), sendo executada em um ciclo contínuo 60 segundos antes de sua expiração:

Bloco de código
$scope.refreshToken = function() {
	var http = new XMLHttpRequest();
	var url = '/totvs-login-oauth2/oauth2/token?grant_type=refresh_token';
	var params = `refresh_token=${$scope.getRefreshToken()}`;
	http.open('POST', url, true);
	http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
   
	http.onreadystatechange = function() {
		if(http.readyState == 4 && http.status == 200) {
			localStorage.setItem("token-client.token", http.responseText);
		}
	}
	http.send(params);
};

$scope.getExpiresInToken = function() {
	const tokenService = localStorage.getItem('token-client.token');
	let jsonTokenService = JSON.parse(tokenService);
	return jsonTokenService['expires_in'];
};

$scope.getRefreshToken = function() {
	const tokenService = localStorage.getItem('token-client.token');
	let jsonTokenService = JSON.parse(tokenService);
	return jsonTokenService['refresh_token'];
};

var expireIn = $scope.getExpiresInToken() * 1000;
/**
 * 1 minuto antes de expirar o token, tenta efetuar a renovacao
 */
setInterval(async() => {
	await $scope.refreshToken()
}, (expireIn - (60 * 1000)));


c. Resource Owner Password Credentials


Nota

Este modelo é recomendado caso o endpoint requisitado necessite de informações do usuário do ERP Datasul.

A utilização do Resource Owner Password Credentials é similar ao Client Credentials, somente difere na geração do token (autenticação), onde são utilizados outros parametros e um usuário e senha do ERP Datasul.

Geração do token

Considere as credenciais de acesso de um usuário do ERP Datasul para a geração do token.

No trecho de código abaixo, caso o token seja gerado com sucesso, seu retorno é armazenado no localStorage com a chave token-service.token. 

Bloco de código
languagejs
function login_oauth2() {
	var http = new XMLHttpRequest();
	var url = '/totvs-login-oauth2/oauth2/token?grant_type=password';
	http.open('POST', url, true);

	http.setRequestHeader('Authorization', "Basic " + btoa($txtUsername.val()+":"+$txtPassword.val()));

	http.onreadystatechange = function() {
		if(http.readyState == 4 && http.status == 200) {
			localStorage.setItem("token-service.token", http.responseText);
		}
	}
}

Utilização dos tokens para acessos aos endpoints

Com o token disponível no localStorage e continuamente validado pelo refresh_token, para efetuar o acesso a determinados recursos, basta resgatar o valor do access_token e enviá-lo na requisição desejada.

O trecho de código abaixo demonstra uma integração com o Smart View (no qual necessita de dados do usuário do ERP Datasul para efetuar o compartilhamento dos layouts por usuário ou grupo).

O token é enviado pela URL devido as características deste endpoint (Smart View), porém este mesmo conceito pode ser adaptado com o modelo Authorization Bearer (recomendado) para efetuar a integração com outros Portais ou Apps.

Bloco de código
languagejs
public onSmartView(smLayout: SmartViewLayout): void {
	let jwtToken = this.getAccessToken();
	let urlView = `${this.urlSmartView}reports/${smLayout["id"]}/view?access_token=${jwtToken}&hidemenus=true&expires_in=0&token_type=bearer`;
	this.link = this.sanitizer.bypassSecurityTrustResourceUrl(urlView);        
	this.poPageSlide.open();
}

private getAccessToken(): String {
	let tokenService = localStorage.getItem('token-service.token');
	let jsonTokenService = JSON.parse(tokenService);
	return jsonTokenService['access_token'];
}

Expiração do token

As etapas de atualização do token são idênticas ao modelo apresentado anteriormente (Client Credentials), no qual deve ser utilizado os mesmos endpoints.


b.Resource Owner Password Credentials

A proposta aborda a autorização entre usuário Resource Owner e Client. Nesse caso o Client assume o papel de Resource Server, com isso, ele hospeda os recursos.

Image Removed

Figura 2 - Modelo de acesso com Resource Owner Password Credentials

Abaixo estão listados os componentes do desenho acima:

03. EXEMPLO DE UTILIZAÇÃO

a. Otimização das Libs do Datasul

Otimização do uso das libs do Datasul no Tomcat

Expedir as libs de forma centralizada

Gerar BuildOfMaterials (BOM) Datasul

  • Descrever o processo que foi efetuado para a centralização das libs.

b. Configuração baseada no OAuth2

A configuração dos dois tipos de Grant será na tela de Propriedades OAuth2 no produto TOTVS.

Informações

Para a implementação dos dois tipos de GRANT será utilizado o Spring Security.

Com o uso do Spring Security para esse controle, ocorrerá a modificação do uso de libs dentro do produto Datasul.

Atualmente as libs estão duplicadas por arquivos .war, o que gera dificuldade em expedições e manutenções.

Essa modificação consiste em criar uma pasta de libs específica para o Datasul, contendo tudo que é necessário para o produto funcionar com o Tomcat.

Para isso será alterado o arquivo catalina.properties, que buscará a nova pasta e modificará o console para gerar as libs conforme o POM Archive.

Esse POM Archive contém a definição de todas as libs utilizadas pelo sistema e ficará armazenado no controle de libs do Maven.

O serviço de login permitirá as autenticações que já existem atualmente no sistema: LDAP, IDENTITY, PRODUCT. Para o RFI não será utilizado este formato.

Como utilizar o Spring Security para atender OAuth2 Client Credentials

  • Analisar se é necessário descrever aqui sobre a utilização do Spring Security.

c. Client Credentials - Autenticação

ClientCredentials - Authorization Server - Engine autenticação

Implementar a Engine de autenticação do client_id e client_secret e retorno do Token JWT devidamente configurado conforme RFC6749 com a utilização do Spring Security:

  • Autenticação conforme cadastro dos Apps;

  • Retorno do token JWT válido para utilização posterior.

  • Descrever o processo que foi efetuado para Client Autenticação.

d. Client Credentials - Autorização

ClientCredentials - Resource Server - Engine autorização acesso

Implementar a Engine de autorização de acesso conforme Token JWT gerado anteriormente na autenticação:

  • Autorização de acesso caso o token JWT esteja válido;

  • Acesso conforme escopo (scope) previamente definidos.

  • Descrever o processo que foi efetuado para Client Autorização.

e. Resource Owner Password Credentials - Autenticação e Autorização

RO Password Credentials - Engine de Autenticação e autorização

Implementar a Engine de autenticação e autorização de acesso para o modelo Resource Owner Password Credentials:

  • Autenticação realizada com o retorno do Token JWT;

  • Autorização de acesso caso o token JWT esteja válido.

  • Descrever o processo que foi efetuado para RO Autenticação e Autorização.

04. ASSUNTOS RELACIONADOS