Índice

 

Objetivo

Esta experiência de uso tem como objetivo principal o uso do Fluig Identity como IDP (Identity Provider) para a linha de produtos TFS - Totvs Financial Services. Consiste em transferir para o Fluig Identity a responsabilidade por autenticar e validar usuários do TFS provendo assim um ponto de acesso único através do Single-Sign-On.

Requisitos mínimos

Um aplicativo no Fluig Identity previamente cadastrado e configurado para se comunicar com o TFS - Totvs Financial Services. Além disso, todos os usuários do TFS deverão ter e-mail cadastrado em sua base de dados.

Single-Sign-On

Single-Sign-On (SSO) é uma propriedade do controle de acesso de sistemas de softwares independentes, porém multi-relacionados. Com esta propriedade um usuário efetua login uma vez e ganha acesso a todos os sistemas sem ser solicitado a efetuar login novamente em cada um deles. Por outro lado, Single-Sign-Off é a propriedade pela qual uma única ação de logout termina o acesso a vários sistemas de software. 

Como diferentes aplicações e recursos suportam diferentes mecanismos de autenticação, Single-Sign-On deve internamente traduzir e armazenar as credenciais para os diversos mecanismos a partir da credencial utilizada para autenticação inicial.

Módulo de Segurança do TFS

A linha de produtos TFS - Core Banking constitui-se de dezenas de módulos que, interligados, fornecem soluções de Core Banking a diversos tipos de Instituições Financeiras. Basicamente, a linha de produtos está dividida em módulos que foram concebidas em duas plataformas: Plataforma Web e plataforma Power Builder.

Os módulos da plataforma Web são todos desenvolvidos em Java e utiliza o Josso, uma solução para Single-Sign-On de aplicações Web.

O Fluig Identity disponibiliza a possibilidade de autenticação tanto para aplicações Web quanto para aplicações Desktop. Durante a configuração da Aplicação no Fluig Identity é possível selecionar o tipo de autenticação (login). A opção SAML é a aplicada as aplicações web-based, enquanto que a opção Executável SAML é o login de aplicações Desktop.

 

Configuração de login de Aplicação

 

Para as experiências de uso do Fluig, o segmento TFS irá configurar duas aplicações:

SAML

Fluxo da autenticação

A autenticação consiste basicamente em identificar o usuário que está acessando a aplicação e atestar que sua identidade é válida. Com o Fluig Identity atuando como o Provedor de Identidade (ID Provider) e a aplicação cadastrada e configurada atuando como o Provedor de Serviço (Service Provider), existe a possibilidade de a aplicação ser iniciada em qualquer um dos lados.

A aplicação pode ser inicializada tanto de através do Fluig Identity (através do lançamento da aplicação cadastrada) quanto através da própria aplicação, ou seja, da mesma forma que era chamada antes do contexto do Single-Sign-On (pela URL no browser no caso de aplicações web, ou pela execução da linha de comando em aplicações desktop).

No Fluig Identity, é possível configurar o tipo de inicialização da aplicação.

 

Configuração de Login

 

Para aplicações Web configurada com IDP_INITIATED, a inicialização funciona tanto pelo IDP (Identity Provider) quanto pelo SP (Service Provider). Em outras palavras, é possível inicializar uma aplicação Web tanto pelo Fluig Identity quanto pelo browser se a aplicação estiver configurada como IDP_INITIATED.

 

IDP_INITIATED

Este tipo de inicialização ocorre quando a chamada da aplicação é feita a partir do IDP (Identity Provider), ou seja, a partir do Fluig Identity.

O usuário acessa o Fluig Identity. Para ter acesso ao Fluig Identity, precisa se logar. Uma vez logado e autenticado, o IDP vai lançar a aplicação invocando o Servlet de Consumidor de Asserções (AssertionConsumerService). Esta Servlet recebe a requisição e repassa para o saml-java-toolkit que irá fazer todas as ações relacionadas a handshake e autoriazação do usuário. Uma vez realizadas as ações, o toolkit devolve um objeto que representa o usuário validado e autenticado. 

O aplicativo, então, estabelece uma relação de confiança com o IDP e assume que o usuário devolvido é de fato válido e autêntico.

Diagrama de Sequência IDP_INITIATED

SP_INITIATED

Este tipo de inicialização ocorre quando a chamada da aplicação é feita a partir do próprio SP (Service Provider).

O usuário acessa o diretamente o aplicativo (URL no browser ou executável). O aplicativo identifica que está sendo acessado diretamente, então, durante as primeiras instruções de inicialização, direciona a requisição para a Servlet RequestGenerator. Esta Servlet redireciona a requisição para o Fluig Identity para que o usuário possa se logar. Uma vez logado, o Fluig Identity invoca o Servlet de Consumidor de Asserções (AssertionConsumerService). A partir daí, o resto do fluxo segue da mesma forma que o fluxo no IDP_INITIATED e resulta na entrega de um objeto que representa o usuário validado e autenticado. 

Então, igualmente o aplicativo estabelece uma relação de confiança com o IDP e assume que o usuário devolvido é de fato válido e autêntico.

Diagrama de Sequência SP_INITIATEDPreparando o TFS para o Single-Sign-On

A aplicação Web do portal de módulos do TFS utiliza um toolkit em java que implementa o SAML, o saml-java-toolkit. O toolkit fica, então, responsável por toda ação relacionada a negociação e hand-shake durante o processo de autenticação e entregará o usuário devidamente identificado e autenticado no Fluig Identity para a aplicação Web. Para utilizar o saml-java-toolkit, foi adicionado a dependência no pom.xml do projeto web:

 

		<!-- DEPENDENCIAS DO SAML TOTVS -->
		<dependency>
			<groupId>com.totvslabs</groupId>
			<artifactId>saml-java-toolkit</artifactId>
			<version>1.2.3</version>
		</dependency>

 

toolkit SAML utiliza um conjunto de propriedades que identifica e configura o toolkit para o Fluig identity. O framework da aplicação Web do portal de módulos do TFS possui o arquivo app.xml e o utiliza para guardar estas propriedades. Deve ser inseridas as propriedades que o toolkit SAML irá utilizar durante sua execução.

 

<appconfig>
    <aplicacaoNome>Sistema TOTVS</aplicacaoNome>
    <!-- 
    Outras propriedades neste nível...
    ...
    ...
    -->
    <parametros>		
        <autenticacaoFluig>true</autenticacaoFluig>
		<autenticacaoLogout>https://tfs.thecloudpass.com/cloudpass/login/logout</autenticacaoLogout>
		<autenticacaoClockSkew>60</autenticacaoClockSkew>
		<autenticacaoSpIssuerName>TotvsLabs</autenticacaoSpIssuerName>
		<autenticacaoSpProtocolBinding>HttpPost</autenticacaoSpProtocolBinding>
		<autenticacaoAcsURL>http://10.51.6.62:8085/jsp_login/ACS</autenticacaoAcsURL>
		<autenticacaoIdpProtocolBinding>HttpPost</autenticacaoIdpProtocolBinding>
		<autenticacaoProviderName>TotvsLabs</autenticacaoProviderName>
		<autenticacaoNameIdFormat>email</autenticacaoNameIdFormat>
		<autenticacaoRelayState>http://10.51.6.62:8085/jsp_login/ACS</autenticacaoRelayState>
		<autenticacaoIdpIssuerName>TotvsLabs</autenticacaoIdpIssuerName>
		<autenticacaoIdpDestination>https://tfs.thecloudpass.com/cloudpass/SPInitPost/receiveSSORequest/lteodrn5ckp9kl181410443016241/get619yn058rezjv1410518461489</autenticacaoIdpDestination>
		<autenticacaoCertificateFile>C:\\Dev\\tfs.thecloudpass.com.crt</autenticacaoCertificateFile>
		<autenticacaoIdpCertIssuerName>Totvslabs</autenticacaoIdpCertIssuerName>
		<autenticacaoExecutavelSAMLTimeout>60</autenticacaoExecutavelSAMLTimeout>
		<!-- 
		Outras propriedades neste nível...
		...
		...
		-->
    </parametros>
</appconfig>

 

Segundo o fluxo acima, ao lançar a aplicação TFS Web, o Fluig Identity dispara um resquest para a URL de Consumidor de Asserções configurada para a aplicação (http://{host:port}/jsp_login/ACS). Este contexto está mapeado no web.xml.


    <!-- CONFIGURACAO DO SAML DO FLUIG DA TOTVS -->
    
    <servlet>
		<servlet-name>ACS</servlet-name>
		<servlet-class>com.totalbanco.framework.josso.web.AssertionConsumerService</servlet-class>
	</servlet>
	<servlet-mapping>
		<servlet-name>ACS</servlet-name>
		<url-pattern>/ACS</url-pattern>
	</servlet-mapping>


De acordo com o mapeamento, o request é direcionado para a Servlet abaixo. Tanto o doPost() quanto o doGet() delegam a chamada para o método privado receiveResponse(). Note que ele faz uso das propriedades gravadas no app.xml descritas acima.

 

package com.totalbanco.framework.josso.web;


import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.totalbanco.framework.orion.TBAppConfig;
import com.totvslabs.idm.protocol.saml2toolkit.common.OpenSAMLInitializer;
import com.totvslabs.idm.protocol.saml2toolkit.common.PropertyObject;
import com.totvslabs.idm.protocol.saml2toolkit.common.User;
import com.totvslabs.idm.protocol.saml2toolkit.responseVerify.ResponseProcessor;


/**
 * This class will receive SAML response from the IDP
 *
 */
public class AssertionConsumerService extends HttpServlet {
	
	private final static Logger logger = LoggerFactory.getLogger(AssertionConsumerService.class);
	
	private static final long serialVersionUID = 1L;
	
	@Override
	public void init() {
		try {
			//initialize the library
			OpenSAMLInitializer initOpenSaml = new OpenSAMLInitializer();
			initOpenSaml.initializeLibrary();						
		}catch (Exception e){
			logger.error("Exception occurred while initializing the OpenSaml library: " + e.getMessage());
		}
	}
	
	@Override
	public void doGet(final HttpServletRequest httpRequest, final HttpServletResponse httpResponse) throws ServletException, IOException {
		logger.debug("received a GET");
		receiveResponse(httpRequest, httpResponse);
	}
	@Override
	public void doPost(final HttpServletRequest request, final HttpServletResponse response) throws ServletException, IOException {	
		logger.debug("received a POST");
		receiveResponse(request, response);
	}	
	
	private void receiveResponse(HttpServletRequest httpRequest, HttpServletResponse httpResponse) {
		logger.debug("receieved a SAML Response");
		
		try {
			final TBAppConfig tbAppConfig = (TBAppConfig) httpRequest.getSession().getServletContext().getAttribute(TBAppConfig.COMPONENT_NAME);
			
			final PropertyObject propObj = new PropertyObject();
		    propObj.setClockSkew(tbAppConfig.getParametros().get("autenticacaoClockSkew"));
		    propObj.setSpIssuerName(tbAppConfig.getParametros().get("autenticacaoSpIssuerName"));
		    propObj.setSpProtocolBinding(tbAppConfig.getParametros().get("autenticacaoSpProtocolBinding"));
		    propObj.setAcsUrl(tbAppConfig.getParametros().get("autenticacaoAcsURL"));
		    propObj.setIdpProtocolBinding(tbAppConfig.getParametros().get("autenticacaoIdpProtocolBinding"));
		    propObj.setProviderName(tbAppConfig.getParametros().get("autenticacaoProviderName"));
		    propObj.setNameIdFormat(tbAppConfig.getParametros().get("autenticacaoNameIdFormat"));
		    propObj.setRelayState(tbAppConfig.getParametros().get("autenticacaoRelayState"));
		    propObj.setIdpIssuerName(tbAppConfig.getParametros().get("autenticacaoIdpIssuerName"));
		    propObj.setIdpDestination(tbAppConfig.getParametros().get("autenticacaoIdpDestination"));
		    propObj.setCertificateFile(tbAppConfig.getParametros().get("autenticacaoCertificateFile"));
		    propObj.setIdpCertIssuerName(tbAppConfig.getParametros().get("autenticacaoIdpCertIssuerName"));
			
		    logger.debug("ResponseProcessor.processResponse() will be executed with properties bellow:");
		    logger.debug("ClockSkew: " + propObj.getClockSkew());
		    logger.debug("SpIssuerName: " + propObj.getSpIssuerName());
		    logger.debug("SpProtocolBinding: " + propObj.getSpProtocolBinding());
		    logger.debug("AcsUrl: " + propObj.getAcsUrl());
		    logger.debug("IdpProtocolBinding: " + propObj.getIdpProtocolBinding());
		    logger.debug("ProviderName: " + propObj.getProviderName());
		    logger.debug("NameIdFormat: " + propObj.getNameIdFormat());
		    logger.debug("RelayState: " + propObj.getRelayState());
		    logger.debug("IdpIssuerName: " + propObj.getIdpIssuerName());
		    logger.debug("IdpDestination: " + propObj.getIdpDestination());
		    logger.debug("CertificateFile: " + propObj.getCertificateFile());
		    
		    final ResponseProcessor responseProcessor = new ResponseProcessor();
		    final User user = responseProcessor.processResponse(httpRequest, httpResponse, propObj);
		
			logger.debug("Usuário autenticado: " + user.getUsername());
			
			httpRequest.getSession(true).setAttribute("userFluig", user);
			httpResponse.sendRedirect(httpRequest.getContextPath() +  "/signon/login.htm");
		
		} catch(Exception e) {
			logger.error("Exception while processing the response: " + e.getMessage());
		}
	}
}

Configurando o TFS como Aplicação no Fluig Identity

Para que o TFS possa usufruir do recurso de Single-Sign-On, é necessário cadastrá-lo e configurá-lo como uma Aplicação no Fluig Identity. Para isso adicione uma nova aplicação:

Adicionando nova aplicação

Entre com as informações básicas:

Informações básicas

Então clique na aba Entrar e configure as informações de Single-Sign-On propriamente dita, conforme imagem abaixo:

Configurações Single-Sign-On

One-Click Configuration

Para que o TFS possa ser acessível atráves do Fluig Identity via Single-Sign-On, é necessário habilitar a opção no Módulo Provisionador Fluig. O One-Click Configuration é uma forma simples de configurar o TFS para usar o Identity com apenas um clique. Basta configurar o contexto do Identity e o Token da Aplicação que o TFS se conecta ao FI e importa todas as configurações necessárias para a iteração entre as partes.

Passo 1: Acesse o Módulo e clique em Provisionador Fluig > Configuração.

Provisionador Fluig

Para buscar o Token da aplicação, acesse o aplicativo que foi cadastrado no Fluig Identity entre em Configurações > Overview > Token de Configuração.

Token da aplicação

Passo 2: Preencha os campos URL do Fluig Identity e Token de Config. da Aplicação e clique no botão One-Click. O módulo Proviisonador Fluig deve buscar e armazenar as configurações do Fluig Indentity.



Executável SAML

Para acessar as aplicações PowerBuilder o Fluig deve chamar o aplicativo Abertura passando alguns parâmetros. O acesso aos aplicativos é sempre através do Abertura.

Parâmetros

O Abertura aguarda 5 parâmetros, separados por espaço, passados no formato chave e valor. Todas as chaves iniciam com sinal de menos (-) e terminam com sinal de igual (=) e em seguida é informado o valor. Caso algum parâmetro não precise ser informado, não deve ser passada nem a chave e nem o valor.

Exemplo da linha de parâmetros: "-sgMdl=EM -sgTrn=GARBOUGA -cdUsu=TB -samlSession=51438757-f6c0-4fb8-8877-489451e672f4 -samlTimeout=60"

            Definição dos parâmetros:

-sgMdl=XX - Módulo ou Aplicação a ser acessada;

-sgTrn=XXXXXXXX – Nome da transação (tela) que deve ser aberta ao entrar na aplicação;

-cdUsu=XX – Nome do usuário para fazer login;

-samlSession=XXXX – Número da sessão que o Fluig grava na tabela T400AUTH do banco SEGURANCA para o usuário. O mesmo número deve ser passado nesse parâmetro para validação no momento do login;

-samlTimeout=99 – Tempo em segundos que a sessão gravada na tabela T400AUTH permanece válida para efetuar o login.

Os parâmetros “-cdUsu=”, “-samlSession=” e “-samlTimeout=” são obrigatórios para Abertura identificar que foi o Fluig que executou o Abertura.

 Aplicação Abertura

O aplicativo Abertura é um centralizador de módulos ou de sistemas da TFS. Abaixo exemplo da tela inicial:


O Abertura aguarda uma string com os parâmetros enviados pelo Fluig. Caso não forem passados os parâmetros obrigatórios, o Abertura vai abrir normalmente e pedir usuário e senha para logar em qualquer módulo TFS, não identificando o login através do Fluig.

Com os parâmetros obrigatórios validados (“-cdUsu=”, “-samlSession=” e “-samlTimeout=”), o Abertura irá identificar que a requisição foi através do Fluig e irá repassá-los ao módulo que o usuário quer entrar. Não sendo necessário informar usuário e senha novamente, já que usuário já está autorizado pelo Fluig.

O Fluig deve gravar uma sessão nova para cada requisição de Módulos PowerBuilder. A sessão é caracterizada por uma linha no banco SEGURANCA, na tabela T400AUTH. A sessão é por usuário. O número da sessão gravada no banco deve ser passado na chave “-samlSession=”, junto com as chaves “-cdUsu=” e “-samlTimeout=. Caso a sessão não estiver gravada no banco, o Abertura irá retornar uma mensagem de erro.

Quando o Abertura encontra uma sessão aberta, verifica se ela ainda é válida. Caso o timeout for “-samlTimeout=60”, a sessão gravada deve ser consumida em 1 minuto, caso contrário irá devolver uma mensagem de erro de tempo de sessão expirado.

Quando o Abertura valida a sessão passada, verifica se existe modulo e transação informada.

Caso o Abertura receber o parâmetro indicando um módulo para acessar (-sgMdl=), ele vai abrir diretamente o módulo pedido não parando na tela inicial.

Exemplo: -sgMdl=EM -cdUsu=TB -samlSession=51438757-f6c0-4fb8-8877-489451e672f4 -samlTimeout=60.

No exemplo, foi validado o usuário, a sessão e o timeout de sessão e o Abertura chamou diretamente o módulo EM (Empréstimos) sem pedir usuário e senha. Caindo na tela de abrangência.

Além do módulo (-sgMdl=) o Fluig pode enviar para o Abertura a transação que deseja abrir. Passando o parâmetro -sgTrn=XXXXXXXX. Assim, o Abertura chama o módulo desejado e abre a transação diretamente, como se estivesse escolhido pelo menu da aplicação PowerBuilder.

Por exemplo, -sgMdl=EM -cdUsu=TB -samlSession=51438757-f6c0-4fb8-8877-489451e672f4 -samlTimeout=60 -sgTrn=GARBPART

No exemplo, foi validado o usuário, a sessão e o timeout de sessão e o Abertura chamou diretamente o módulo EM (Empréstimos) sem pedir usuário e senha. E como recebeu também o parâmetro –sgTrn=GARBPART abriu a tela de Garantias e Bens.

 


Estas instruções devem ser seguidas para que o Executável SAML funcione!

 

As aplicações Power Builder são instaladas através de um instalador do tipo Wizard que, além de copiar todos os arquivos corretamente na pasta de instalação, ainda efetua o registro da aplicação no Registro do Windows (Regedit). Além da informação do executável, é criado um par chave/valor com chave 'Path' e com valor que contém os caminhos dos diretórios onde se encontram as DLL's necessárias para execução da aplicação Power Builder.

 

Regedit do executável Power Builder

 

Na solução Executável SAML, ao efetuar o handshake SAML após o launcher da aplicação, o Fluig Identity invoca o executável Power Builder através do Desktop Launcher, que é uma aplicação utilitária executável (appinvoker.exe), que por sua vez realiza a chamada do executável do Power Builder propriamente dito.

 

Appinvoker

 

O problema é que o executável Power Builder, ao ser invocado pelo appinvoker.exe, herda dele todas as configurações do Registro do Windows. Como o appinvoker não tem a chave 'Path' configurada, também não a repassa para o executável Power Builder que fica sem "saber" onde estão as DLL's e portanto, incapaz de funcionar corretamente.

Para que o executável Power Builder possa ser executado corretamente, deve ser criado o par chave/valor do tipo 'Valor da Cadeia de Caracteres' na configuração Regedit do appinvoker exatamente igual ao configurado para o executável Power Builder.

 

 

Localize o executável Power Builber no Regedit:

Localizando Executável Power Builder

Copie o todo o valor da chave 'Path':

Copiando o valor da chave 'Path'

Localize o executável do appinvoker:

Localizando executável appinvoker

Crie um novo 'Valor da Cadeia de Caracteres' com o nome 'Path':

Criando chave 'Path' em appinvoker

 

Edite e insira o conteúdo criado no Passo 1:

O Windows deve ser reiniciado para que a alteração tenha efeito.

Editando o valor da chave 'Path'

 

 

Provisionamento

O provisionamento permite que todas as operações efetuadas no Fluig Identity referentes a criação e gerenciamento de Usuários, Perfis (Roles) e Autorizações (Entitlements) sejam refletidos no TFS. Para que haja sincronia entra as informações no Fluig Identity e o TFS, o FI invoca serviços RESTful disponibilizadas pelo TFS. Assim sendo, o TFS teve que implementar, disponibilizar expor estes serviços que ficam acessíveis através de uma URL. Esta URL deve estar configurada na aplicação.

Configurando a aplicação para o provisionamento

Para configurar o TFS para o provisionamento, clique na aba Provisionar e preencha os campos conforme imagem abaixo:

O Modelo RAC para o TFS Core Banking deve ser sempre o Modelo Datasul!

Configuração do provisionamento

Particularidades na configuração

Diferenciando TFS Web e TFS Power Builder

Conforme mencionado no início desta página, os módulos do TFS Core Banking são disponibilizados em duas tecnologias, Java e Power Builder. Porém, possui o modelo de permissionamento (bando de dados) compartilhado, ou seja, os mesmo recursos (usuários, perfis, etc) são mantidos na mesma base para as duas tecnologias. Para que seja possível distinguir qual aplicação está chamando os serviços RESTful, incluímos na URL REST o pb ou web juntamente com o ID do app no Fluig Identity. Quando um request chega no serviço, capturamos este a tecnologia e o ID e sabemos quem (qual aplicação) está invocando o método.

 

http://189.89.44.15/jsp_pf_hml/resource/rest/web/3c9vpl81h31zqiz71417183899797

Permitindo acesso externo e diferenciando ambiente

Como o Fluig identity é uma aplicação cloud que precisa acessar serviços dentro da rede do TFS Core Banking, foi disponibilizado uma máquina com IP externo exposto rodando um Apache Server que é responsável por redirecionar os requests para os servidores internos do TFS.

Aproveitando os recursos de redirecionamento do Apache que avalia o destino com base no contexto da URL, aproveitamentos para usar este recurso e criar também redirecionamento para os diversos ambientes da experiência (desenv, homolog, qa, etc).

 

http://189.89.44.15/jsp_pf_hml/resource/rest/web/3c9vpl81h31zqiz71417183899797

 

 

<VirtualHost *:80>
	ProxyPreserveHost On

	ProxyPass /jsp_pf http://10.51.6.115:8080/jsp_pf
	ProxyPassReverse /jsp_pf http://10.51.6.115:8080/jsp_pf

	ProxyPass /jsp_pf_loc http://10.51.6.123:8085/jsp_pf
	ProxyPassReverse /jsp_pf_loc http://10.51.6.123:8085/jsp_pf

	ProxyPass /jsp_pf_dev http://vfluigplatdev:9090/jsp_pf
	ProxyPassReverse /jsp_pf_dev http://vfluigplatdev:9090/jsp_pf

	ProxyPass /jsp_pf_hml http://10.51.2.119:8080/jsp_pf
	ProxyPassReverse /jsp_pf_hml http://10.51.2.119:8080/jsp_pf

	<Location "/jsp_pf">
		Order allow,deny
		Allow from all
	</Location>
	<Location "/TOTVSIntegration">
		Order allow,deny
		Allow from all
	</Location>
</VirtualHost>

Sincronização

A sincronização do módulo de permissionamento é uma operação que deve ser realizada inicialmente para o que todos os dados do modelo de permissionamento do TFS sejam importados para o Fluig Identity. Trata-se de uma carga full inicial e deve ser executado somente uma vez. A partir daí, toda operação referente a permissionamento, deve ser feita no Fluig Identity e não mais no módulo de Segurança do TFS.

Para fazer a sincronização, entre nas configurações da aplicação, aba Recursos e clique no botão Synchronize.