Suplemento básico fapi: integração com implementações de referência

Prefácio

Este documento descreve como avaliar o fluxo de autorização compatível com FAPI e a solicitação de API usando um serviço Authlete, que foi configurado com configurações descritas em Noções básicas de API (FAPI) de grau financeiro (doravante “Fapi Basics”), e outros componentes, incluindo as implementações de referência da Authlete.

Components in this tutorial

Pré-requisitos

Antes de fazer isso, espera-se que você tenha conhecimento de OpenID Connect e Authlete, executando o tutorial a seguir.

Você também precisa ter um serviço Authlete configurado com configurações de acordo com o FAPI Basics abaixo. Execute as instruções (Um exemplo completo de caminhar), no documento para garantir que o serviço Authlete funcione corretamente.

Os seguintes componentes de software são usados neste tutorial. Prepare seu ambiente de laboratório que possa executá-los.

  • Necessário para este tutorial
  • Reommended, mas você pode escolher outras ferramentas alternativas
    • Servidor APACHE HTTP (doravante “Apache”): Um proxy reverso para servidor de autorização e servidor de recursos
    • cacho: Um cliente de API
    • OpenSSL: Uma ferramenta para gerar chaves privadas e certificados de chaves públicas

Configuração de um servidor de autorização

Nesta seção, cobriremos as seguintes tarefas:

  • Implantando um pacote java-oauth-server
  • Conexão de teste

O diagrama abaixo ilustra os componentes configurados nesta seção. Um navegador da Web e um curl enviam solicitações para um servidor de autorização (java-oauth-server) cujo ponto final é http://localhost:8080.

Components including a configured authorization server (java-oauth-server)

Configuração do java-oauth-server

Vamos baixar e configurar java-oauth-server. Instruções detalhadas são descritas em seu documento.

Baixando o código fonte

Baixe java-oauth-server usando git comando.

$ git clone https://github.com/authlete/java-oauth-server.git

Configurando

Editar as seguintes entradas em seu arquivo de configuração, authlete.properties. Coloque a chave API e o segredo do seu serviço Authlete que foi configurado de acordo com o FAPI Basics.

service.api_key = <your API key e.g. 1450...0338>
service.api_secret = <your API key e.g. VEIl...0cEs>

Iniciando o servidor

Inicie java-oauth-server usando mvn comando.

$ mvn jetty:run

Testando

Conecte-se a http://localhost:8080 usando um navegador da Web e a seguinte página deve ser exibida.

Top page of java-oauth-server

Execução do fluxo de autorização da FAPI (1)

Gerar um objeto de solicitação de acordo com instruções no Fapi Basics e criar uma solicitação de autorização usando o objeto. Os seguintes valores são usados neste tutorial.

{
"redirect_uri":"https://client.example.org/cb/example.com",
"response_type":"code id_token",
"client_id":"1756...3766",
"scope":"openid payment",
"exp":15549730000,
"aud":"https://as.example.com",
"claims":{
  "id_token":{
    "acr":{
      "essential":true,
      "values":["urn:example:psd2:sca"]
    }
  }
},
"nonce":"n-0S6_WzA2Mj"
eyJr...YifQ.ewoi...iCn0.ztl2...tjAA
  • Solicitação de autorização (substituir os valores de client_id (1756...3766) e request (eyJr...YifQ.ewoi...iCn0.ztl2...tjAA) com o seu determinado acima)
http://as.example.com:8080/api/authorization
 ?redirect_uri=https://client.example.org/cb/example.com
 &scope=openid+payment
 &response_type=code+id_token
 &client_id=1756...3766
 &nonce=n-0S6_WzA2Mj
 &request=eyJr...YifQ.ewoi...iCn0.ztl2...tjAA

Digite a sequência de solicitação criada (URL) no campo de localização do seu navegador da Web.

Enter the authorization request URL

Uma página de autorização deve ser exibida. Entrar john / john para os campos de ID de login /Senha e clique em Autorizar o botão Autorizar.

Authorization page of java-oauth-server

Seu navegador da Web tentará (e falhará) se conectar https://client.example.org/cb/example.com/#code=... e mostrar uma página de erro afirmando que o anfitrião client.example.org não existe.

Error stating client.example.org not found

Resposta de Autorização

Copie a URL da página de erro como abaixo.

https://client.example.org/cb/example.com#code=0Io2....sdkQ&id_token=eyJr...YifQ.eyJz...aiJ9.-EPu...Dkkw

Extrair code parâmetro na URL.

code=0Io2...sdkQ

Requisição do Token

Vamos criar um pedido de token que contenha o valor de code (0Io2...sdkQ por exemplo) e enviá-lo para o ponto final de token do java-oauth-server (/api/token).

Nesta seção, tentaremos fazer autenticação do cliente usando client_id / client_secret como segue. Substitua os valores desses parâmetros com os seus que foram gerados automaticamente durante o Fapi Basics.

$ curl -s -X POST http://localhost:8080/api/token \
 -u '1756...3766:EXE7...UxHg' \
  --data-urlencode 'grant_type=authorization_code' \
  --data-urlencode 'redirect_uri=https://client.example.org/cb/example.com' \
  --data-urlencode 'code=0Io2...sdkQ'

Resposta do Token

Você receberá uma resposta de token como esta:

{
  "error_description": "[A244308] Because the feature of certificate-bound
  access tokens is enabled, the client must establish a mutual TLS connection
  to the token endpoint.",
  "error": "invalid_request",
  "error_uri": "https://docs.authlete.com/#A244308"
}

Execution example

Isso significa:

  • java-oauth-server não foi capaz de extrair quaisquer certificados de cliente da solicitação de token, uma vez que nenhuma conexão TLS mútua foi estabelecida entre o cliente (curl comando neste tutorial) e java-oauth-server
  • Assim, java-oauth-server não incluiu nenhum certificado de cliente em uma solicitação para Authlete (API /auth/token)
  • Então Authlete não poderia emitir quaisquer tokens de acesso vinculados a certificados e fez uma resposta com Erro A244308

Na próxima seção, adicionaremos um proxy reverso para aceitar certificados de clientes de clientes para resolver o erro.

Habilitação de TLS para o servidor de autorização

Nesta seção, cobriremos as seguintes tarefas:

  • Configurando um proxy reverso
  • Configuração de um cliente

O diagrama abaixo ilustra os componentes configurados nesta seção. Na seção anterior, tanto navegadores da Web quanto clientes se conectam diretamente ao java-oauth-server (http://localhost:8080). O destino será trocado para Apache (https://as.example.com:8443) que reside na frente do servidor como um proxy reverso. Do lado do cliente, a Curl tentará se conectar ao Apache usando um certificado de cliente para ser autenticado.

Enabling TLS for the authorization server

Configuração de um proxy reverso (1)

Configurando os FQDNs

Adicione a seguinte entrada para /etc/hosts para que tanto navegadores da Web quanto clientes possam encontrar apaches para serem instalados em seu ambiente de laboratório, usando as.example.com como FQDN.

127.0.0.1 as.example.com

Instalando o Apache

Instale o apache no seu ambiente de laboratório.

$ brew install httpd

Este tutorial usa /usr/local/etc/httpd diretório como a localização primária dos arquivos de configuração do Apache.

Preparando os cerficados

Gerando uma chave privada e o certificado

Crie uma chave privada RSA e um certificado de chave pública para apache, usando openssl comando.

$ openssl req -x509 -newkey rsa:2048 \
 -keyout server.key -out server.crt
 -days 3650 -sha256 -nodes \
 -subj '/C=JP/ST=Tokyo/L=Chiyoda-ku/O=Server/CN=as.example.com'
Generating a 2048 bit RSA private key
..........................+++
....+++
writing new private key to 'server.key'
-----

Dois arquivos, server.key (uma chave privada) e server.crt (um certificado de chave pública) são criados.

Fazendo o deploy

Implante esses dois arquivos para localização arbitrária em seu ambiente de laboratório. Este tutorial copia-os sob /usr/local/etc/httpd diretório.

$ sudo cp -p server.key server.crt /usr/local/etc/httpd/.
Password:

Configurando o Apache para TLS

httpd.conf

Vamos configurar configurações básicas do Apache para:

  • Desativar a porta de escuta 8080 (como java-oauth-server usa)
  • Habilitar mod_proxy e mod_ssl módulos relacionados (para obter apache trabalhando como um proxy reverso e aceitando conexão TLS)

Alterações reais no arquivo de configuração, httpd.conf são os seguintes. As configurações relacionadas ao TLS devem ser incluídas a partir de outro arquivo (extra/httpd-ssl.conf).

$ diff /usr/local/etc/httpd/httpd.conf.orig \
/usr/local/etc/httpd/httpd.conf
52c52
< Listen 8080
---
> #Listen 8080
92c92
< #LoadModule socache_shmcb_module lib/httpd/modules/mod_socache_shmcb.so
---
> LoadModule socache_shmcb_module lib/httpd/modules/mod_socache_shmcb.so
131c131
< #LoadModule proxy_module lib/httpd/modules/mod_proxy.so
---
> LoadModule proxy_module lib/httpd/modules/mod_proxy.so
134c134
< #LoadModule proxy_http_module lib/httpd/modules/mod_proxy_http.so
---
> LoadModule proxy_http_module lib/httpd/modules/mod_proxy_http.so
150c150
< #LoadModule ssl_module lib/httpd/modules/mod_ssl.so
---
> LoadModule ssl_module lib/httpd/modules/mod_ssl.so
524c524
< #Include /usr/local/etc/httpd/extra/httpd-ssl.conf
---
> Include /usr/local/etc/httpd/extra/httpd-ssl.conf

extra/httpd-ssl.conf

Neste tutorial, configuramos configurações de TLS e proxy reverso para:

  • Use as.example.com como nome do servidor (enquanto sua porta de escuta (8443) inalterada)
  • Conheça as disposições fapi (usando TLS 1.2 e conjuntos limitados de suítes cifradas)
  • Inclua um certificado de cliente no cabeçalho X-Ssl-Cert (para que o ponto final /api/token do java-oauth-server possa extrair o valor e incluí-lo em uma solicitação à API Authlete (/auth/token API), se ele for definido na solicitação do proxy reverso)
  • Trabalhe como um proxy reverso que encaminha solicitações aceitas em https://as.example.com:8443/ para http://localhost:8080/ (java-oauth-server)

Alterações no arquivo de configuração, extra/httpd-ssl.conf são os seguintes.

$ diff /usr/local/etc/httpd/extra/httpd-ssl.conf.orig \
 /usr/local/etc/httpd/extra/httpd-ssl.conf
125c125
< ServerName www.example.com:8443
---
> ServerName as.example.com:8443
289a290,302
> SSLEngine on
> SSLProtocol TLSv1.2
> SSLCipherSuite -ALL:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES128-GCM-SHA256
> SSLCertificateKeyFile "/usr/local/etc/httpd/server.key"
> SSLCACertificateFile "/usr/local/etc/httpd/server.crt"
> SSLVerifyClient optional_no_ca
> SSLOptions +StdEnvVars +ExportCertData
> SSLCompression off
> RequestHeader set X-Ssl-Cipher "%{SSL_CIPHER}e" env=SSL_CIPHER
> RequestHeader set X-Ssl-Cert "%{SSL_CLIENT_CERT}e" env=SSL_CLIENT_CERT
> ProxyPreserveHost on
> ProxyPass "/" "http://localhost:8080/"
> ProxyPassReverse "/" "http://localhost:8080/"

Iniciando o Apache

Inicie o Apache usando apachectl comando.

$ apachectl start

Uma vez iniciado, conecte-se a https://as.example.com:8443 usando seu navegador da Web e confirme se o conteúdo é o mesmo que http://localhost:8080, a página principal do java-oauth-server.

Na próxima seção, preparamos uma chave privada e um certificado de chave pública para um cliente (curl) que faz uma solicitação de token.

Configurações para um cliente

Preparando o certificado do cliente

Criando uma chave RSA e o respectivo certificado

Executar openssl comando da seguinte forma para criar uma chave privada e um certificado de chave pública.

$ openssl req -x509 -newkey rsa:2048 \
 -keyout client.key -out client.crt
 -days 3650 -sha256 -nodes \
 -subj '/C=JP/ST=Tokyo/L=Chiyoda-ku/O=Server/CN=client.example.org'
Generating a 2048 bit RSA private key
..........................+++
....+++
writing new private key to 'client.key'
-----

Dois arquivos, client.key (uma chave privada) e client.crt (um certificado de chave pública) são criados. Vamos usá-los para fazer solicitações de token com curl.

Requisição e resposta com autorização

Faça uma solicitação de autorização da mesma forma que Execução do fluxo de autorização da FAPI (1).

Extrair um valor de code parâmetro de uma resposta de autorização. O valor neste tutorial é o seguinte.

7Y5h...zp_4

Requisitando o Token

Crie uma solicitação de token e envie-a para o ponto final do token do java-oauth-server (/api/token). As diferentes partes do exemplo anterior (Execução do fluxo de autorização da FAPI (1)) are:

  • URL do ponto final: usando https://as.example.com:8443 Em vez de http://localhost:8080
  • Método de autenticação do cliente: usando a chave privada (client.key) e o certificado de chave pública (client.crt) em vez de client_secret

Assim, o curl comando a ser executado é como abaixo. (substituir os valores de client_id e code com os apropriados em seu ambiente de laboratório)

$ curl --insecure -X POST https://as.example.com:8443/api/token \
--key client.key --cert client.crt \
--data-urlencode 'client_id=1756...3766' \
--data-urlencode 'grant_type=authorization_code' \
--data-urlencode 'redirect_uri=https://client.example.org/cb/example.com' \
--data-urlencode 'code=7Y5h...zp_4'

Resposta com o Token

Você deve receber uma resposta de token como abaixo.

{
  "access_token": "nbN3...LAU8",
  "refresh_token": "SWUu...V8_w",
  "scope": "openid payment",
  "id_token": "eyJr...YifQ.eyJz...qIn0.GPJr...STPQ",
  "token_type": "Bearer",
  "expires_in": 86400
}

Agora você tem um token de acesso com sucesso (nbN3...LAU8 por exemplo) através de conexão TLS mútua. Nos bastidores, Authlete fez o token de acesso vinculado ao certificado do cliente.

Na próxima seção, tentaremos fazer uma solicitação de API com um token de acesso a um servidor de recursos.

Configuração de um servidor de recursos

Nesta seção, cobriremos as seguintes tarefas:

  • Implantando um pacote java-resource-server
  • Conexão de teste

O diagrama abaixo ilustra os componentes configurados nesta seção.

Components including a configured resource server (java-resource-server)

Configuração do java-resource-server

Baixaremos e configuraremos java-resource-server. Instruções são descritas em seu documento.

Downloading the source

Baixe java-resource-server usando git comando.

$ git clone https://github.com/authlete/java-resource-server.git

Configurando o servidor

Editar as seguintes entradas em seu arquivo de configuração, authlete.properties. Coloque a chave da API e o segredo que são os mesmos valores especificados para java-oauth-server.

service.api_key = <your API key e.g. 1450...0338>
service.api_secret = <your API key e.g. VEIl...0cEs>

Iniciando o servidor

Inicie o java-resource-server usando mvn comando.

$ mvn jetty:run

Testando

Conecte-se a http://localhost:8081 usando um navegador da Web e a seguinte página deve ser exibida.

Top page of java-resource-server

Executando um pedido de API (1)

Vamos tentar fazer uma solicitação de API com um token de acesso para “Endpoint do país” do java-resource-server, usando curl comando.

O token de acesso pode ser obtido fazendo o fluxo descrito em Execução do fluxo de autorização da FAPI (2). Neste tutorial, o seguindo o valor é usado.

6Ivp...LiM4

Faça uma solicitação com o token de acesso especificado em Authorization cabeçalho. Os exemplos abaixo mostram a solicitação e a resposta subsequente. -v opção é adicionado a curl comando para que ele possa habilitar saída verbose especialmente informações de cabeçalho.

$ curl -v -X GET http://localhost:8081/api/country/JP \
-H 'Authorization: Bearer 6Ivp...LiM4'
...
> GET /api/country/JP HTTP/1.1
> Host: localhost:8081
> User-Agent: curl/7.64.1
> Accept: */*
> Authorization: Bearer 6Ivp...LiM4
>
< HTTP/1.1 401 Unauthorized
< Date: Mon, 18 May 2020 02:22:32 GMT
< Cache-Control: no-store, no-transform
< Pragma: no-cache
< WWW-Authenticate: Bearer error="invalid_token",
 error_description="[A065304] The client failed to present
 a certificate and the access token is MTLS bound.",
 error_uri="https://docs.authlete.com/#A065304"
< Content-Length: 0
< Server: Jetty(9.3.7.v20160115)
...

Essa resposta significa:

  • java-resource-server não foi capaz de extrair quaisquer certificados de cliente da solicitação de token, uma vez que nenhuma conexão TLS mútua foi estabelecida entre o cliente (curl comando) e java-resource-server
  • Assim, java-resource-server não incluiu nenhum certificado de cliente em uma solicitação ao Authlete API /auth/introspecção
  • Assim, Authlete não pôde verificar a vinculação entre o token de acesso e seu certificado de cliente correspondente e fez uma resposta com Erro A065304

Na próxima seção, configuraremos configurações adicionais para o proxy reverso.

Habilitação de TLS para o servidor de recursos

Nesta seção, cobriremos as seguintes tarefas que são basicamente as mesmas das configurações para java-oauth-server feitas na seção anterior:

Configurações adicionais para o proxy reverso

O diagrama abaixo ilustra os componentes configurados nesta seção. a curl tentará se conectar ao Apache (https://rs.example.com:8443) usando um certificado de cliente para ser autenticado.

Enabling TLS for the resource server

Configuração de um proxy reverso (2)

Configurando os nomes FQDN

Modifique a entrada que foi adicionada /etc/hosts durante Configuração de um proxy reverso (1) para que o cacho possa se conectar ao Apache usando rs.example.com.

127.0.0.1 as.example.com rs.example.com

Configurando o proxy reverso

extra/httpd-ssl.conf

Adicione as seguintes entradas ao extra/httpd-ssl.conf arquivo. Essas configurações, o mesmo que Configuração de um proxy reverso (1) exceto o nome do servidor e os destinos do proxy reverso, são:

  • Declare que essas configurações são aplicadas a rs.example.com:8443
  • Conheça as disposições fapi (usando TLS 1.2 e conjuntos limitados de suítes cifradas)
  • Inclua um certificado de cliente no cabeçalho X-Ssl-Cert (para que /api/país ponto final do java-resource-server possa extrair o valor e incluí-lo em uma solicitação à API Authlete (/Auth/introspection API), se ele for definido na solicitação do proxy reverso)
  • Trabalhe como um proxy reverso que encaminha solicitações aceitas em https://rs.example.com:8443/ para http://localhost:8081/ (java-resource-server)

As entradas adicionais para o arquivo de configuração, extra/httpd-ssl.conf são os seguintes.

<VirtualHost _default_:8443>
DocumentRoot "/usr/local/var/www"
ServerName rs.example.com:8443
ServerAdmin you@example.com
ErrorLog "/usr/local/var/log/httpd/error_log"
TransferLog "/usr/local/var/log/httpd/access_log"
SSLEngine on
SSLProtocol TLSv1.2
SSLCipherSuite -ALL:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES128-GCM-SHA256
SSLCertificateKeyFile "/usr/local/etc/httpd/server.key"
SSLCertificateFile "/usr/local/etc/httpd/server.crt"
SSLCACertificateFile "/usr/local/etc/httpd/server.crt"
SSLVerifyClient optional_no_ca
SSLOptions +StdEnvVars +ExportCertData
SSLCompression off
RequestHeader set X-Ssl-Cipher "%{SSL_CIPHER}e" env=SSL_CIPHER
RequestHeader set X-Ssl-Cert "%{SSL_CLIENT_CERT}e" env=SSL_CLIENT_CERT
ProxyPreserveHost on
ProxyPass "/" "http://localhost:8081/"
ProxyPassReverse "/" "http://localhost:8081/"
</VirtualHost>                                  

Reiniciando o Apache

Pare e inicie o Apache usando apachectl comando.

$ apachectl stop && apachectl start

Após a reinicialização, conecte-se a https://rs.example.com:8443 usando seu navegador da Web e confirme se o conteúdo é o mesmo que http://localhost:8081, a página superior do java-resource-server.

Executando um pedido de API (2)

Faça uma solicitação de API usando curl comando da mesma forma que Executando um pedido de API (1).

O token de acesso pode ser obtido fazendo o fluxo descrito em Execução do fluxo de autorização da FAPI (2). Neste tutorial, o seguindo o valor é usado.

6Ivp...LiM4

Faça uma solicitação com o token de acesso especificado em Authorization cabeçalho. As diferentes partes do exemplo anterior (Executando um pedido de API (1)) são:

  • URL do ponto final: usando https://rs.example.com:8443 Em vez de http://localhost:8081
  • Método de autenticação do cliente: usando a chave privada (client.key) e o certificado de chave pública (client.crt), além do token de acesso

Assim, o curl comando a ser executado é como abaixo.

$ curl -v -X GET http://localhost:8081/api/country/JP \
-H 'Authorization: Bearer 6Ivp...LiM4' \
--key client.key --cert client.crt --insecure
...

Você deve receber uma resposta de API bem sucedida como abaixo.

{
  "name": "Japan",
  "alpha2": "JP",
  "alpha3": "JPN",
  "numeric": 392,
  "currency": "JPY"
}

Execution example

Significa que:

  • java-resource-server extraiu o certificado do cliente da conexão TLS mútua e enviou-o para Authlete,
  • Authlete validou a vinculação entre o certificado do cliente e o token de acesso, e
  • java-resource-server processou a solicitação de API como esperado.

Conclusão

Neste tutorial, confirmamos o fluxo de autorização compatível com FAPI e a solicitação de API usando um serviço Authlete habilitado para FAPI, implementações de referência (java-oauth-server e java-resource-server) e um proxy reverso.