# Como autenticar vários usuários de aplicações utilizando o A.D

No post [anterior](https://diogofernandes.com.br/oracle-autenticando-no-windows-addo-windows-ad-diogo-fernandes/) fiz uma breve introdução de como conectar no Oracle autenticando pelo Windows A.D.

Mas de fato o que são tokens? Como carregar vários tokens manualmente na estação? É isso que vamos ver neste post.

De forma macro, como tudo isso funciona? Vamos la!

![No alt text provided for this image](https://media.licdn.com/dms/image/v2/D4D12AQFPjLxGgvNKxg/article-inline_image-shrink_1500_2232/article-inline_image-shrink_1500_2232/0/1690186889613?e=1752105600&v=beta&t=2An0xshRGNx_KSP9E90K2VixaUErYIHaLNNfiLJkf9w align="left")

Assim como descrito no [artigo anterior](https://diogofernandes.com.br/oracle-autenticando-no-windows-ad), nos geramos um arquivo chamado databasenode1.keytab com o comando ktpass, do qual foi executado no A.D.

Posteriormente, transferimos esse arquivo para o servidor de banco de dados e referenciamos esse arquivo la no sqlnet.ora com o arquivo krb5.conf que contém as informações do A.D, ou seja, neste momento criamos uma ponte entre o Oracle e o A.D para se comunicarem através do protocolo kerberos.

```bash
SQLNET.KERBEROS5_CONF=/u01/app/oracle/product/19.0/dbhome_1/network/admin/krb5.conf
SQLNET.KERBEROS5_KEYTAB=/u01/app/oracle/product/19.0/dbhome_1/network/admin/databasenode1.keytab
```

Uma vez isso pronto, agora vamos para a parte de como a maquina cliente carregar o token.

![No alt text provided for this image](https://media.licdn.com/dms/image/v2/D4D12AQEkswrlPHc9Tw/article-inline_image-shrink_1500_2232/article-inline_image-shrink_1500_2232/0/1690188328632?e=1752105600&v=beta&t=C-P8AmtcrGJl6BxwZJhZcy5CJbPx5v__o8F2USgKi28 align="left")

Como a imagem acima demostra, a maquina client vai fazer uma requisição de "Credential Cache" essa credential cache é uma autorização que o A.D concederá a máquina client depois que o comando okinit for executado com sucesso, vamos ver como isso funciona na prática.

![No alt text provided for this image](https://media.licdn.com/dms/image/v2/D4D12AQEplvgZwyBJxw/article-inline_image-shrink_1500_2232/article-inline_image-shrink_1500_2232/0/1690189171055?e=1752105600&v=beta&t=HaXcuAyZxh8QRISYQgne5c_chEWxAnzFqCjx6OoHMV4 align="left")

Acima, executamos o comando okinit para o usuário prodapp01, podemos ver que logo abaixo foi requisitado a senha do usuário, ou seja, nesse momento ele foi até o A.D para validar o usuário, uma vez a senha correta digitada, ele retorna para você uma Credential Cache.

![No alt text provided for this image](https://media.licdn.com/dms/image/v2/D4D12AQFAbE7yDkbM2Q/article-inline_image-shrink_1500_2232/article-inline_image-shrink_1500_2232/0/1690189579194?e=1752105600&v=beta&t=QMeeZIcX_zy3ycRztSOamEwaaenDnfO9RsJ2HtgL9_w align="left")

O comando "oklist" sempre será utilizado para verificar o status da credential cache, na imagem acima podemos ver o local onde ela esta "armazenada" na linha "**Ticket cache: File**", a quem pertence "prodapp01@DATACOSMOS.COM.BR" e a validade "**07/24/23 15:58:04**". O local de armazenamento pode ser definido pelo sintaxe "-c" no comando "okinit" ou definir um local padrão no sqlnet.ora.

PS: O arquivo é criptografado.

```bash
SQLNET.KERBEROS5_CC_NAME=C:\temp\cc_name
```

Agora que a credential cache está na nossa máquina client, vamos fazer a conexão com o Oracle, esse passo, como funciona? Vamos la!!!

![No alt text provided for this image](https://media.licdn.com/dms/image/v2/D4D12AQEoqg_gAHmC9w/article-inline_image-shrink_1500_2232/article-inline_image-shrink_1500_2232/0/1690285270424?e=1752105600&v=beta&t=vmEpMyihNiiBL_Yacm-Oo2XC0nzbZVnXUBJ7-V6R7ms align="left")

A maquina client, se apresenta ao Oracle com a seguinte apresentação:

\- E ai Oracle! Blz? Tenho uma Credential Cache aqui, e gostaria de conectar.

Oracle:

\- E ai jovem! blz? Espera aí que vou verificar com o AD...

![No alt text provided for this image](https://media.licdn.com/dms/image/v2/D4D12AQEVo4EHknzsNg/article-inline_image-shrink_1500_2232/article-inline_image-shrink_1500_2232/0/1690285540357?e=1752105600&v=beta&t=D5K-ukqp1MUgdfl21A5s-jtVervgn78bUHdmKS0Bf8Y align="left")

\- A.D, blz? Tem uma máquina client aqui com a credential cache do usuário "prodapp01" posso liberar a conexão?

A.D:

\- Oracle, essa credencial que você me informou é valida, pode liberar o acesso.

Oracle:

\- Blz! Vou liberar o acesso

![No alt text provided for this image](https://media.licdn.com/dms/image/v2/D4D12AQGSgzj2rp-WLg/article-inline_image-shrink_1500_2232/article-inline_image-shrink_1500_2232/0/1690285923052?e=1752105600&v=beta&t=ykS2UgR82wssHpsBgqomAmgrFpR2ybY0hxE_tzGJpjc align="left")

Acabamos de ver a parte "gráfica", agora vamos para o "bash".

Na prática, é isso que acontece:

> PS: Não façam isso em PRODUÇÃO hehe.

No banco:

```bash
[oracle@databasenode1 admin]$ sqlplus / as sysdba 


SQL*Plus: Release 19.0.0.0.0 - Production on Tue Jul 25 15:08:03 2023
Version 19.17.0.0.0


Copyright (c) 1982, 2022, Oracle.  All rights reserved.




Connected to:
Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
Version 19.17.0.0.0


SQL> alter user prodapp01 identified externally as 'prodapp01@DATACOSMOS.COM.BR' ; 


User altered.

PS: Esse alter user só precisa ser feito na primeira vez.
```

Na máquina de aplicação:

![No alt text provided for this image](https://media.licdn.com/dms/image/v2/D4D12AQGAInW4WmboSA/article-inline_image-shrink_1500_2232/article-inline_image-shrink_1500_2232/0/1690308632829?e=1752105600&v=beta&t=Kw7gIKZlsWXl-j50x6Q3bC2ark9acPPSQB-n2XEjjBQ align="left")

Agora que compreendemos como acontece a negociação com a credential cache adquirida pelo A.D vamos para a parte de como conectar mais de um usuário de aplicação.

Mas antes vamos a uma breve história, até na versão 19.9, não era possível utilizar mais de uma conexão partindo da mesma sessão, mas qual era a limitação?

Não existia a possibilidade do tnsnames ler várias credential cache ao mesmo tempo, porém, a partir da versão 19.10 do Oracle Client, possibilitou carregar mais de um token/credential cache e apontá-los diretamente no tnsnames para a conexão correta. Mas de fato como isso funciona na prática e como fazer?

Utilizaremos como exemplo o usuário prodapp01 e prodapp02.

Antes de carregar os tokens dos usuários, vamos destruir o que está no caminho "default"

![No alt text provided for this image](https://media.licdn.com/dms/image/v2/D4D12AQHpTfSgrlsg4A/article-inline_image-shrink_1500_2232/article-inline_image-shrink_1500_2232/0/1690316316824?e=1752105600&v=beta&t=yIW7nE2GoeVGitN1bbFMgB-h47WcEFwMcijy3kv27Fw align="left")

Agora vamos carregar o token o usuário prodapp01 e prodapp02.

![No alt text provided for this image](https://media.licdn.com/dms/image/v2/D4D12AQG30QnIUV3zvA/article-inline_image-shrink_1500_2232/article-inline_image-shrink_1500_2232/0/1690321607060?e=1752105600&v=beta&t=PCoDTYor3SyZNAAyXCuS_DWvHDjAAgJUBygHbMcb4ck align="left")

Verificando o status dos 2 tokens:

![No alt text provided for this image](https://media.licdn.com/dms/image/v2/D4D12AQFflmrhe94sMA/article-inline_image-shrink_1500_2232/article-inline_image-shrink_1500_2232/0/1690321818462?e=1752105600&v=beta&t=ERn_j_84-knap7zsNvr_cqCX-Xc9QXWynwsgth67WX4 align="left")

Pronto, uma vez os tokens devidamente carregados, vamos montar um novo tnsnames, mas porque fazer isso?

![No alt text provided for this image](https://media.licdn.com/dms/image/v2/D4D12AQG7q8VqeT3mJw/article-inline_image-shrink_1500_2232/article-inline_image-shrink_1500_2232/0/1690322823111?e=1752105600&v=beta&t=jBvFyA9tkSFKR8FeTcWi1cAJpBBOnkhZ5O6u9ieBbNc align="left")

Quando temos que acessar via "strong authentication" com um tnsnames normal, ele sempre vai procurar a credential default e não é esse nosso objetivo, para realizarmos a conexão com as credential's que carregamos anteriormente vamos montar o seguinte tnsnames.ora.

```bash
PRODAPP01_KERB =
  (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=databaseno1.host)(PORT=1521)) 
    (CONNECT_DATA=
    (SERVICE_NAME=KERB)) 
      (SECURITY=(KERBEROS5_CC_NAME = c:\temp\cc_prodapp01) 
      (KERBEROS5_PRINCIPAL = prodapp01@DATACOSMOS.COM.BR)
    )
  )
  
 
PRODAPP02_KERB = 
  (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=databaseno1.host)(PORT=1521)) 
    (CONNECT_DATA=
    (SERVICE_NAME=KERB)) 
      (SECURITY=(KERBEROS5_CC_NAME = c:\temp\cc_prodapp02) 
      (KERBEROS5_PRINCIPAL = prodapp02@DATACOSMOS.COM.BR)
    )
  )
```

Neste novo tnsnames temos 2 campos adicionais:

```bash
SECURITY=(KERBEROS5_CC_NAME = c:\temp\cc_prodapp02)
      (KERBEROS5_PRINCIPAL = prodapp02@DATACOSMOS.COM.BR)
```

Esses 2 parâmetros permite que utilizemos a credential cache correta que nos carregamos anteriormente:

![No alt text provided for this image](https://media.licdn.com/dms/image/v2/D4D12AQFqawFKdFO_gQ/article-inline_image-shrink_1500_2232/article-inline_image-shrink_1500_2232/0/1690335570893?e=1752105600&v=beta&t=EiwJc7OUb0KvdJ18jEKmIL4D41k7bwYtpfXdPocMiGI align="left")

Agora vamos fazer a conexão com os 2 usuários para ver se tudo está ok.

![No alt text provided for this image](https://media.licdn.com/dms/image/v2/D4D12AQHFnBGi_b1gTA/article-inline_image-shrink_1500_2232/article-inline_image-shrink_1500_2232/0/1690335739885?e=1752105600&v=beta&t=xqFsffKs54EYDzqCcsQYH82fZlkdTkzcYx9xelXYndA align="left")

Podemos ver que agora as aplicações podem utilizar vários usuários "strong authentication" oriundo da mesma sessão do windows.

Sqlnet utilizado nesta configuração:

```bash
NAMES.DIRECTORY_PATH= (TNSNAMES, EZCONNECT
SQLNET.AUTHENTICATION_SERVICES= (KERBEROS5,KERBEROS5PRE,BEQ)
SQLNET.FALLBACK_AUTHENTICATION=TRUE
SQLNET.AUTHENTICATION_KERBEROS5_SERVICE=ORACLE
SQLNET.KERBEROS5_CONF=C:\Oracle\CLIENT19C\network\admin\krb5.conf
SQLNET.KERBEROS5_CLOCKSKEW=6000
SQLNET.KERBEROS5_CONF_MIT=TRUE
SQLNET.KERBEROS5_CC_NAME=C:\temp\cc_name)
```

Espero que este artigo contribua para aumentar a segurança do seu banco de dados e de suas aplicações.

> Grande abraço!
