Table of Contents
Este documento descreve a visão geral das disposições de segurança definidas em API de nível financeiro - Parte 2: Ler e Escrever Perfil de Segurança da API (doravante chamado “FAPI”) e instruções de configuração da Authlete através de etapas para a construção de um servidor de autorização compatível com FAPI.
É fortemente aconselhável que você tenha conhecimento básico do OpenID Connect e Authlete fazendo o tutorial a seguir.
Neste tutorial, assumimos os seguintes componentes. Observe que apenas os consoles e APIs da Authlete estão funcionando, enquanto um servidor de autorização (provedor de identidade OIDC) e um servidor de recursos realmente não existem.
Em vez disso, você usará o comando curl para simular como esses servidores fazem solicitações de API para Authlete ao receber solicitações de autorização, solicitações de token e solicitações de introspecção de token de clientes (OIDC participante).
As FQDNs de cada componente são as seguintes: O servidor de autorização e o cliente não existem como indicado acima, mas suas FQDNs são pelo menos necessárias para explicar o fluxo OAuth.
Componente | FQDN |
---|---|
API Authlete | api.authlete.com |
Authlete Service Owner console | so.authlete.com |
Authlete Developer console | cd.authlete.com |
Servidor de Autorização (Provedor de Identidade OIDC) | as.example.com |
Cliente (OIDC Relying Party) | client.example.org |
servidor de recursos | N/A |
Neste documento, você configurará o Authlete para habilitar o seguinte processo de concessão de tokens e fluxos de acesso à API de forma compatível com o FAPI.
Um cliente compatível com FAPI tem que empregar um objeto de solicitação para criar uma solicitação de autoração a um servidor de autorização compatível com FAPI.
O objeto de solicitação é passado para o servidor por qualquer valor (usando request
parâmetro) ou referência (request_uri
). Neste documento, o cliente estará usando o antigo.
Além do objeto de solicitação, você tem que cumprir outras disposições de segurança da FAPI, tais como response_type
e claims
Parâmetros. Neste documento, o cliente estará usando code id_token
durante response_type
parâmetro. Outras configurações devem ser explicadas mais tarde.
As disposições de segurança da FAPI não permitem que um servidor de autorização inclua um código de autorização (code
), como uma sequência de consulta em uma resposta de autorização. Neste documento, o servidor estará fazendo uma resposta incluir o code
como um fragmento desde response_type=code id_token
é especificado na etapa anterior.
Um servidor de autorização tem que empregar métodos de chave pública para autenticar clientes ao receber uma solicitação de token. Neste documento, o servidor usará autenticação TLS mútua.
Um servidor de autorização tem que vincular um token de acesso a um certificado de cliente obtido a partir da comunicação TLS mútua no ponto final do token do servidor, e fazer uma resposta de token ao cliente.
Um cliente e um servidor de recursos têm que estabelecer uma comunicação TLS mútua. O servidor de recursos estará verificando a vinculação entre o certificado do cliente e o token de acesso em uma solicitação de API e, em seguida, fazendo uma resposta se a vinculação for válida.
Faça login no console proprietário de serviços da Authlete https://so.authlete.com/
e clique no botão “Criar serviço”. Você verá a página de criação do serviço. Digite nome de serviço e identificador de emissor de tokens da seguinte forma e clique no botão “Criar”.
Pressione “OK” em um diálogo para confirmação.
Item | Valor |
---|---|
Nome de serviço | Um valor arbitrário, por exemplo. FAPI Service |
Identificador de emissor de token | https://as.example.com |
O novo serviço foi criado. Os valores gerados automaticamente de “Chave de API” e “Segredo de API” serão usados como “ID de login” e “Senha” para fazer login no Console do Desenvolvedor, bem como credencial para que seu servidor de autorização faça solicitações a APIs Authlete.
Item | Valor |
---|---|
chave da API | Gerado automaticamente, por exemplo. 174381609020 |
Secretas da API | Gerado automaticamente, por exemplo. LszYEVDLM5Bu4lRjO9Vaj0tMSMVerWiPf_zcdy-vu4k |
Vamos habilitar o suporte fapi do serviço. Clique no botão “Editar” na parte inferior da página para tornar as configurações editáveis e ir para a guia Autorização. Deve haver FAPI com uma caixa de seleção, que não é verificada, em Perfis de Serviço suportados. Verifique a caixa e clique no botão “Atualizar” na parte inferior da página. Pressione “OK” em um diálogo para confirmação.
Clique no botão “Editar” para tornar as configurações editáveis novamente e vá para a guia Token. Deve haver escopos suportados e alguns escopos predefinidos, como address
e openid
.
Clique no botão “Criar escopo” no lado direito para que você possa ver uma caixa de diálogo para definir um escopo.
Adicione um novo escopo com os seguintes parâmetros.
Item | Valor |
---|---|
Nome do escopo | payment |
Entrada Padrão | Escolher Non default |
Description | Um valor arbitrário |
Atributos (Clique no botão “Novo atributo” para adicionar) | Chave: fapi / Valor: rw |
Abra o link para o Console de Desenvolvedores da Authlete para o serviço (https://cd.authlete.com/<API Key>
por exemplo, https://cd.authlete.com/174381609020
) e faça login no console com sua chave de API e segredo de API como ID de login e senha, respectivamente.
Clique no botão “Criar aplicativo” no lado direito e digite/escolha os seguintes valores na página do aplicativo de criação.
Item | Valor |
---|---|
Nome do cliente | Um valor arbitrário, por exemplo. FAPI Client |
do tipo cliente | Escolher CONFIDENTIAL |
Em seguida, clique na guia Autorização ao lado do Básico e digite o seguinte valor para Redirecionar URIs.
Item | Valor |
---|---|
Redirecionar uris | https://client.example.org/cb/example.com |
Clique no botão “Criar” na parte inferior da página. Pressione “OK” em um diálogo para confirmação.
Agora você fez o registro do cliente para o serviço.
Valores gerados automaticamente de “Client ID” e “Client Secret” serão usados como client_id
e client_secret
para que o cliente faça solicitações ao servidor de autorização. Certifique-se também de que outros valores sejam definidos como esperado.
Item | Valor |
---|---|
ID do Cliente | Auto-generetad, por exemplo. 591205987816490 |
Secreto do Cliente | Gerado automaticamente, por exemplo. e7iqzq7WE8Kg00yepYnpMTjvDnAnBlq5nfA9DDQLkiYkPQBV6Lr8sLhn7DhUJd17i0O6TwQ2hKFeDAYuU160Vg |
tipo do cliente | CONFIDENTIAL |
Redirecionar uris | https://client.example.org/cb/example.com |
Vamos verificar como o Authlete funciona com a configuração inicial. Nós usaremos /auth/authorization
API com esse propósito.
Vamos supor que o servidor receba uma solicitação de autorização (scope=openid
), que não inclui nenhum escopo sujeito à FAPI. O servidor fará uma solicitação para /auth/authorization
API. Aqui está uma versão da requisição.
Substitua as chaves API Key
, API Secret
, Client ID
pelos valores gerados no passo anterior.
curl -s -X POST https://api.authlete.com/api/auth/authorization \
-u '<API Key e.g. 174381609020>:<API Secret e.g. LszYEVDLM5Bu4lRjO9Vaj0tMSMVerWiPf_zcdy-vu4k>' \
-H 'Content-Type: application/json' \
-d '{"parameters": "redirect_uri=https://client.example.org/cb/example.com&scope=openid&response_type=code&client_id=<Client ID e.g. 591205987816490>&nonce=n-0S6_WzA2Mj"}' |jq
Substitua as chaves API Key
, API Secret
, Client ID
pelos valores gerados no passo anterior.
Se você estar usando curl.exe via PowerShell no Windows 10's, garanta que o comando utilizado seja curl.exe
ao invés curl
, e verifique o uso correto dos caracter "
e `
.
curl.exe -s -X POST https://api.authlete.com/api/auth/authorization `
-u '<API Key e.g. 174381609020>:<API Secret e.g. LszYEVDLM5Bu4lRjO9Vaj0tMSMVerWiPf_zcdy-vu4k>' `
-H 'Content-Type: application/json' `
-d '{\"parameters\": \"redirect_uri=https://client.example.org/cb/example.com&scope=openid&response_type=code&client_id=<Client ID e.g. 591205987816490>&nonce=n-0S6_WzA2Mj\"}'
Authlete faz a seguinte resposta (dobrada para legibilidade).
{
"type": "authorizationResponse",
"resultCode": "A004001",
"resultMessage": "[A004001] Authlete has successfully issued a ticket
to the service (API Key = 174381609020) for the authorization request
from the client (ID = 591205987816490). [response_type=code, openid=true]",
[...]
De acordo com o valor de resultMessage
, Authlete aceitou o pedido de autorização quando seus escopos não estão relacionados à FAPI. Então, o que acontece se a solicitação incluir escopos FAPI? Vamos tentar na próxima seção.
Vamos supor que o servidor de auhtorização receba uma solicitação de autorização (scope=openid payment
) que inclui um escopo (payment
), sujeito à FAPI. O servidor fará uma solicitação para /auth/authorization
API. Aqui está uma versão enrolada do pedido.
curl -s -X POST https://api.authlete.com/api/auth/authorization \
-u '<API Key e.g. 174381609020>:<API Secret e.g. LszYEVDLM5Bu4lRjO9Vaj0tMSMVerWiPf_zcdy-vu4k>' \
-H 'Content-Type: application/json' \
-d '{"parameters": "redirect_uri=https://client.example.org/cb/example.com&scope=openid+payment&response_type=code&client_id=<Client ID e.g. 591205987816490>&nonce=n-0S6_WzA2Mj"}' |jq
curl.exe -s -X POST https://api.authlete.com/api/auth/authorization `
-u '<API Key e.g. 174381609020>:<API Secret e.g. LszYEVDLM5Bu4lRjO9Vaj0tMSMVerWiPf_zcdy-vu4k>' `
-H 'Content-Type: application/json' `
-d '{\"parameters\": \"redirect_uri=https://client.example.org/cb/example.com&scope=openid+payment&response_type=code&client_id=<Client ID e.g. 591205987816490>&nonce=n-0S6_WzA2Mj\"}'
Authlete faz a seguinte resposta de erro (dobrada para legibilidade).
{
"type": "authorizationResponse",
"resultCode": "A150312",
"resultMessage": "[A150312] The value of 'response_type' (code) is not allowed.",
[...]
De acordo com o valor de resultMessage
, response_type=code
não é permitido.
Isso se deve às disposições de segurança da FAPI. 5.2 Leia e escreva as disposições de segurança da API / 5.2.2. Servidor de autorização estados da seguinte forma.
deve exigir o
response_type
Valorescode id_token
oucode id_token token
;
Assim, você tem que usar qualquer um response_type=code id_token
ou response_type=code id_token token
em um ambiente compatível com FAPI. Em outras palavras, outros tipos, como response_type=code
, response_type=token
são proibidos, ou seja, um servidor de autorização não deve aceitá-los.
Então, que tal um pedido de autorização que inclui response_type=code id_token
Em vez de response_type=code
?
Vamos fazer um pedido para /auth/authorization
API como segue.
curl -s -X POST https://api.authlete.com/api/auth/authorization \
-u '<API Key e.g. 174381609020>:<API Secret e.g. LszYEVDLM5Bu4lRjO9Vaj0tMSMVerWiPf_zcdy-vu4k>' \
-H 'Content-Type: application/json' \
-d '{"parameters": "redirect_uri=https://client.example.org/cb/example.com&scope=openid+payment&response_type=code+id_token&client_id=<Client ID e.g. 591205987816490>&nonce=n-0S6_WzA2Mj"}' |jq
curl.exe -s -X POST https://api.authlete.com/api/auth/authorization `
-u '<API Key e.g. 174381609020>:<API Secret e.g. LszYEVDLM5Bu4lRjO9Vaj0tMSMVerWiPf_zcdy-vu4k>' `
-H 'Content-Type: application/json' `
-d '{\"parameters\": \"redirect_uri=https://client.example.org/cb/example.com&scope=openid+payment&response_type=code+id_token&client_id=<Client ID e.g. 591205987816490>&nonce=n-0S6_WzA2Mj\"}'
Novamente Authlete faz outra resposta de erro.
{
"type": "authorizationResponse",
"resultCode": "A150301",
"resultMessage": "[A150301] A request object is required.",
[...]
De acordo com o valor de resultMessage
, um objeto de solicitação é necessário para prosseguir.
Isso se deve às disposições de segurança da FAPI. Na mesma seção, 5.2 Leia e escreva as disposições de segurança da API / 5.2.2. Servidor de autorização estados da seguinte forma.
deve exigir o
request
ourequest_uri
parâmetro a ser passado como um JWS assinado JWT como na cláusula 6 de [OIDC];
Um servidor de autorização tem que obrigar os clientes a passar um objeto de solicitação por valor (request
) ou por referência (request_uri
).
Então vamos criar uma solicitação de autorização com um objeto de solicitação na próxima seção para tornar a solicitação compatível com FAPI.
Nesta seção, criaremos uma solicitação de autorização usando um objeto de solicitação. Também prepararemos uma reivindicação adicional exigida pela FAPI.
Temos que preparar uma chave para um cliente assinar um objeto de solicitação. Neste documento, usaremos mkjwk para criar um par de chaves ES256 e dois tipos de conjuntos-chave; Uma inclui uma chave privada e outra não.
Os parâmetros para mkjwk são os seguintes.
Item | Valor |
---|---|
Guia | EC (Curva Elíptica) |
Curve | curva P-256 |
Key Use | Signing |
Algorithm | ES256 (ECDSA using P-256 and SHA-256) |
Key ID | Um valor arbitrário, por exemplo. 1 |
Aqui estão exemplos de um conjunto de teclas gerado e um conjunto derivado sem uma chave privada.
es256_keyset.txt
(incluindo uma linha de uma chave privada "d"
){
"keys": [
{
"kty": "EC",
"d": "L6KxA-db4oh5NKYEpO6IulUDSRXP7fqNAmScu6fygIE",
"use": "sig",
"crv": "P-256",
"kid": "1",
"x": "icP8p_AigyTzwSpLRyv_bBQTSGu_NG7pMVXd-RAxwYE",
"y": "06tC0MJeBlZNYlnY8g4bCA9wJ34XN-rWfWlmmlhf-F0",
"alg": "ES256"
}
]
}
es256_keyset_pub.txt
(excluindo uma linha de uma chave privada "d"
De es256_keyset.txt
){
"keys": [
{
"kty": "EC",
"use": "sig",
"crv": "P-256",
"kid": "1",
"x": "icP8p_AigyTzwSpLRyv_bBQTSGu_NG7pMVXd-RAxwYE",
"y": "06tC0MJeBlZNYlnY8g4bCA9wJ34XN-rWfWlmmlhf-F0",
"alg": "ES256"
}
]
}
Para que o serviço Authlete verifique a assinatura de um objeto de solicitação proveniente de um cliente, você tem que registrar sua chave pública para as configurações do cliente e especificar um algoritmo de assinatura que o cliente usa.
Faça login no Console do Desenvolvedor para o serviço (https://cd.authlete.com/<API Key>
por exemplo, https://cd.authlete.com/174381609020
) e configurar as configurações do cliente da seguinte forma.
Item | Valor |
---|---|
Conteúdo JWK | Colar conteúdo de es256_keyset_pub.txt |
Item | Valor |
---|---|
Solicitar algoritmo de assinatura de objeto | ES256 |
Agora terminamos a preparação para que Authlete verifique a assinatura de um objeto de solicitação.
Vamos agir como um cliente gerando um objeto de solicitação e elaborando uma solicitação de autorização com o objeto.
Aqui está uma carga de amostra neste documento. Digite o valor correto de client_id
, que foi gerado automaticamente em seu ambiente.
payload.txt
{
"redirect_uri":"https://client.example.org/cb/example.com",
"response_type":"code id_token",
"client_id":"<client_id> e.g. 591205987816490",
"scope":"openid payment",
"exp":15549730000,
"aud":"https://as.example.com",
"nonce":"n-0S6_WzA2Mj"
}
nbf
and modify exp
.
nbf
claim. Authlete will make the following error response if the request object doesn't contain this claim.
[...]
"resultCode": "A150351",
"resultMessage":
"[A150351] An 'nbf' claim is required but not contained in the request object
passed by the 'request' parameter.",
[...]
In order to avoid the error, get the current Unix time using some method (e.g. date +%s
)
and add it to the payload as a value of nbf
claims.
For example, if you would get a value 1613373232
as a result of date +%s
,
you would add the following line to payload.txt
.
"nbf":1613373232,
exp
claim.
Authlete will make the following error response if the above value (15549730000
) is used as a value of exp
.
[...]
"resultCode": "A150365",
"resultMessage":
"[A150365] The lifetime of the request object passed by the 'request' parameter
exceeds the allowed maximum value (3600 seconds).",
[...]
In order to avoid the error, specify a new value which is a sum of the value of nbf
(as used in 1.)
and 3600
.
For example, if "nbf":1613373232
would be used, the new value would be 1613373232 + 3600 = 1613376832
and the line of the exp
claim in the payload.txt
would be as follows.
"exp":1613376832,
payload.txt
including the modification above.
{
"redirect_uri":"https://client.example.org/cb/example.com",
"response_type":"code id_token",
"client_id":"<Client ID> e.g. 591205987816490",
"scope":"openid payment",
"nbf": <Unix time of the current time> e.g. 1613373232,
"exp": <nbf + 3600> e.g. 1613376832,
"aud":"https://as.example.com",
"nonce":"n-0S6_WzA2Mj"
}
O cliente estará criando um JWT assinado com a chave privada gerada na seção anterior. Neste documento, usamos mkjose por exemplo. Digite/escolha valores para cada item e clique em “Gerar” para que você possa encontrar o JWT assinado na seção Saída.
Item | Valor |
---|---|
Conteudo | Colar de payload.txt |
Algoritmo de signatura | Escolher EC256 |
Chave de assinatura | Remova as duas primeiras linhas ("keys": , [ ) e as duas últimas linhas (] , } ), do conteúdo de es256_keyset.txt (como deve ser um JWK, não um conjunto JWK) e cole-o |
Outro exemplo usando passo CLI é o seguinte.
cat payload.txt | \
step crypto jws sign --jwks=es256_keyset.txt --kid=1
Neste documento, foi feito o seguinte resultado. Isso será usado como um valor de request
parâmetro em uma solicitação autorizada.
eyJhbGciOiJFUzI1NiIsImtpZCI6IjEifQ.ewoicmVkaXJlY3RfdXJpIjoiaHR0cHM6Ly9jbGllbnQuZXhhbXBsZS5vcmcvY2IvZXhhbXBsZS5jb20iLAoicmVzcG9uc2VfdHlwZSI6ImNvZGUgaWRfdG9rZW4iLAoiY2xpZW50X2lkIjoiNTkxMjA1OTg3ODE2NDkwIiwKInNjb3BlIjoib3BlbmlkIHBheW1lbnQiLAoiZXhwIjoxNTU0OTczMDAwMCwKImF1ZCI6Imh0dHBzOi8vYXMuZXhhbXBsZS5jb20iLAoibm9uY2UiOiJuLTBTNl9XekEyTWoiCn0K.q_MbfV5qN-gnB93JaQGVrEXu8WvhDuUzWx6DwC50J8AiQGjXDEpw9satUAMN18rrgnGNciiFztoEFJuJjrJoyA
Vamos supor que o servidor de auhtorização receba uma solicitação de autorização,
incluindo um objeto de solicitação, de um cliente.
O servidor fará uma solicitação para /auth/authorization
API. Aqui está uma versão enrolada do pedido.
curl -s -X POST https://api.authlete.com/api/auth/authorization \
-u '<API Key e.g. 174381609020>:<API Secret e.g. LszYEVDLM5Bu4lRjO9Vaj0tMSMVerWiPf_zcdy-vu4k>' \
-H 'Content-Type: application/json' \
-d '{"parameters": "redirect_uri=https://client.example.org/cb/example.com&scope=openid+payment&response_type=code+id_token&client_id=<Client ID e.g. 591205987816490>&nonce=n-0S6_WzA2Mj&request=<Request Object e.g. eyJhbGciOiJFUzI1NiIsImtpZCI6IjEifQ.ewoicmVkaXJlY3RfdXJpIjoiaHR0cHM6Ly9jbGllbnQuZXhhbXBsZS5vcmcvY2IvZXhhbXBsZS5jb20iLAoicmVzcG9uc2VfdHlwZSI6ImNvZGUgaWRfdG9rZW4iLAoiY2xpZW50X2lkIjoiNTkxMjA1OTg3ODE2NDkwIiwKInNjb3BlIjoib3BlbmlkIHBheW1lbnQiLAoiZXhwIjoxNTU0OTczMDAwMCwKImF1ZCI6Imh0dHBzOi8vYXMuZXhhbXBsZS5jb20iLAoibm9uY2UiOiJuLTBTNl9XekEyTWoiCn0K.q_MbfV5qN-gnB93JaQGVrEXu8WvhDuUzWx6DwC50J8AiQGjXDEpw9satUAMN18rrgnGNciiFztoEFJuJjrJoyA>"}' |jq
curl.exe -s -X POST https://api.authlete.com/api/auth/authorization `
-u '<API Key e.g. 174381609020>:<API Secret e.g. LszYEVDLM5Bu4lRjO9Vaj0tMSMVerWiPf_zcdy-vu4k>' `
-H 'Content-Type: application/json' `
-d '{\"parameters\": \"redirect_uri=https://client.example.org/cb/example.com&scope=openid+payment&response_type=code+id_token&client_id=<Client ID e.g. 591205987816490>&nonce=n-0S6_WzA2Mj&request=<Request Object e.g. eyJhbGciOiJFUzI1NiIsImtpZCI6IjEifQ.ewoicmVkaXJlY3RfdXJpIjoiaHR0cHM6Ly9jbGllbnQuZXhhbXBsZS5vcmcvY2IvZXhhbXBsZS5jb20iLAoicmVzcG9uc2VfdHlwZSI6ImNvZGUgaWRfdG9rZW4iLAoiY2xpZW50X2lkIjoiNTkxMjA1OTg3ODE2NDkwIiwKInNjb3BlIjoib3BlbmlkIHBheW1lbnQiLAoiZXhwIjoxNTU0OTczMDAwMCwKImF1ZCI6Imh0dHBzOi8vYXMuZXhhbXBsZS5jb20iLAoibm9uY2UiOiJuLTBTNl9XekEyTWoiCn0K.q_MbfV5qN-gnB93JaQGVrEXu8WvhDuUzWx6DwC50J8AiQGjXDEpw9satUAMN18rrgnGNciiFztoEFJuJjrJoyA>\"}'
Authlete faz a seguinte resposta de erro, apesar de especificar o objeto de solicitação.
{
"type": "authorizationResponse",
"resultCode": "A150317",
"resultMessage": "[A150317] The 'acr' claim is not contained in the request.",
[...]
De acordo com o valor de resultMessage
, um cliente tem que incluir um acr
(referência de contexto de autenticação) na solicitação.
Isso se deve às disposições de segurança da FAPI. 5.2 Leia e escreva disposições de segurança da API / 5.2.3 Cliente público estados da seguinte forma.
solicitará a autenticação do usuário na LoA 3 ou superior, solicitando a reivindicação acr como uma reivindicação essencial definida na seção 5.5.1.1 de [OIDC];"
Assim, um cliente tem que solicitar um servidor de autorização para autenticar usuários na LoA 3 ou superior. O acr
reivindicação é o paramater para especificar a LoA.
Então vamos tentar novamente configurando acr
suporte no serviço Authlete e atuando como um cliente para incluir o acr
reivindicar em outro pedido de autorização.
Faça login no console proprietário de serviços da Authlete https://so.authlete.com/
, clique no botão “Editar” na parte inferior da página para tornar as configurações editáveis e vá para a guia Autenticação do usuário. Deve haver seção de referências de classe de contexto de autenticação suportada.
Adicione os seguintes valores como um novo acr
. Usamos um exemplo de URN urn:example:psd2:sca
para indicar LoA 3 ou superior.
Verifique a caixa e clique no botão “Atualizar” na parte inferior da página. Pressione “OK” em um diálogo para confirmação.
Item | valor |
---|---|
Supported Authentication Context Class References | urn:example:psd2:sca |
Com as instruções acima, um cliente pode solicitar este servidor de autoração para autenticar os usuários de acordo com o acr
.
Vamos adicionar acr
reivindicações para a carga preparada na seção anterior da seguinte forma.
payload-including-acr.txt
{
"redirect_uri":"https://client.example.org/cb/example.com",
"response_type":"code id_token",
"client_id":"591205987816490",
"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"
}
Gere outro JWT assinado com a nova carga útil. Aqui está um exemplo para gerar o JWT com mkjose. Digite/escolha valores para cada item e clique em “Gerar” para que você possa encontrar o JWT assinado na seção Saída.
Item | Valor |
---|---|
Conteudo | Colar conteúdo de payload-including-acr.txt |
Algoritmo de assinatura | Escolher EC256 |
Chave de assinatura | Remova as duas primeiras linhas ("keys": , [ ) e as duas últimas linhas (] , } ), do conteúdo de es256_keyset.txt (como deve ser um JWK, não um conjunto JWK) e cole-o |
Outro exemplo usando passo CLI é o seguinte.
cat payload-including-acr.txt | \
step crypto jws sign --jwks=es256_keyset.txt --kid=1
Neste documento, foi feito o resultado seguinte. Este novo será usado como um valor de request
parâmetro em uma solicitação autorizada.
eyJhbGciOiJFUzI1NiIsImtpZCI6IjEifQ.ewoicmVkaXJlY3RfdXJpIjoiaHR0cHM6Ly9jbGllbnQuZ
XhhbXBsZS5vcmcvY2IvZXhhbXBsZS5jb20iLAoicmVzcG9uc2VfdHlwZSI6ImNvZGUgaWRfdG9rZW4iL
AoiY2xpZW50X2lkIjoiNTkxMjA1OTg3ODE2NDkwIiwKInNjb3BlIjoib3BlbmlkIHBheW1lbnQiLAoiZ
XhwIjoxNTU0OTczMDAwMCwKImF1ZCI6Imh0dHBzOi8vYXMuZXhhbXBsZS5jb20iLAoiY2xhaW1zIjp7C
iAgImlkX3Rva2VuIjp7CiAgICAiYWNyIjp7CiAgICAgICJlc3NlbnRpYWwiOnRydWUsCiAgICAgICJ2Y
Wx1ZXMiOlsidXJuOmV4YW1wbGU6cHNkMjpzY2EiXQogICAgfQogIH0KfSwKIm5vbmNlIjoibi0wUzZfV
3pBMk1qIgp9Cg.b5rDSqaI3dh8n4A8hK4B5zSpnZNO_8--W-kTU03CNbCq1I_Vuf3w33ZVUhD0A-rla8
cTPlZ25keQBncGWafzOA
Vamos substituir o valor de request
parâmetro na seção anterior com o novo
incluindo o acr
reivindicar e fazer um pedido para /auth/authorization
API outra vez.
curl -s -X POST https://api.authlete.com/api/auth/authorization \
-u '<API Key e.g. 174381609020>:<API Secret e.g. LszYEVDLM5Bu4lRjO9Vaj0tMSMVerWiPf_zcdy-vu4k>' \
-H 'Content-Type: application/json' \
-d '{"parameters": "redirect_uri=https://client.example.org/cb/example.com&scope=openid+payment&response_type=code+id_token&client_id=<Client ID e.g. 591205987816490>&nonce=n-0S6_WzA2Mj&request=<Request Object e.g. eyJhbGciOiJFUzI1NiIsImtpZCI6IjEifQ.ewoicmVkaXJlY3RfdXJpIjoiaHR0cHM6Ly9jbGllbnQuZXhhbXBsZS5vcmcvY2IvZXhhbXBsZS5jb20iLAoicmVzcG9uc2VfdHlwZSI6ImNvZGUgaWRfdG9rZW4iLAoiY2xpZW50X2lkIjoiNTkxMjA1OTg3ODE2NDkwIiwKInNjb3BlIjoib3BlbmlkIHBheW1lbnQiLAoiZXhwIjoxNTU0OTczMDAwMCwKImF1ZCI6Imh0dHBzOi8vYXMuZXhhbXBsZS5jb20iLAoiY2xhaW1zIjp7CiAgImlkX3Rva2VuIjp7CiAgICAiYWNyIjp7CiAgICAgICJlc3NlbnRpYWwiOnRydWUsCiAgICAgICJ2YWx1ZXMiOlsidXJuOmV4YW1wbGU6cHNkMjpzY2EiXQogICAgfQogIH0KfSwKIm5vbmNlIjoibi0wUzZfV3pBMk1qIgp9Cg.b5rDSqaI3dh8n4A8hK4B5zSpnZNO_8--W-kTU03CNbCq1I_Vuf3w33ZVUhD0A-rla8cTPlZ25keQBncGWafzOA>"}' |jq
curl.exe -s -X POST https://api.authlete.com/api/auth/authorization `
-u '<API Key e.g. 174381609020>:<API Secret e.g. LszYEVDLM5Bu4lRjO9Vaj0tMSMVerWiPf_zcdy-vu4k>' `
-H 'Content-Type: application/json' `
-d '{\"parameters\": \"redirect_uri=https://client.example.org/cb/example.com&scope=openid+payment&response_type=code+id_token&client_id=<Client ID e.g. 591205987816490>&nonce=n-0S6_WzA2Mj&request=<Request Object e.g. eyJhbGciOiJFUzI1NiIsImtpZCI6IjEifQ.ewoicmVkaXJlY3RfdXJpIjoiaHR0cHM6Ly9jbGllbnQuZXhhbXBsZS5vcmcvY2IvZXhhbXBsZS5jb20iLAoicmVzcG9uc2VfdHlwZSI6ImNvZGUgaWRfdG9rZW4iLAoiY2xpZW50X2lkIjoiNTkxMjA1OTg3ODE2NDkwIiwKInNjb3BlIjoib3BlbmlkIHBheW1lbnQiLAoiZXhwIjoxNTU0OTczMDAwMCwKImF1ZCI6Imh0dHBzOi8vYXMuZXhhbXBsZS5jb20iLAoiY2xhaW1zIjp7CiAgImlkX3Rva2VuIjp7CiAgICAiYWNyIjp7CiAgICAgICJlc3NlbnRpYWwiOnRydWUsCiAgICAgICJ2YWx1ZXMiOlsidXJuOmV4YW1wbGU6cHNkMjpzY2EiXQogICAgfQogIH0KfSwKIm5vbmNlIjoibi0wUzZfV3pBMk1qIgp9Cg.b5rDSqaI3dh8n4A8hK4B5zSpnZNO_8--W-kTU03CNbCq1I_Vuf3w33ZVUhD0A-rla8cTPlZ25keQBncGWafzOA>\"}'
Authlete fará uma resposta (dobrada para legibilidade) assim.
{
"type": "authorizationResponse",
"resultCode": "A004001",
"resultMessage": "[A004001] Authlete has successfully issued a ticket to the service
(API Key = 174381609020) for the authorization request from the client
(ID = 591205987816490). [response_type=code id_token, openid=true]",
[...]
"ticket": "rjasCNvemUwamKP0G1h9Fh5Uo_3fgBfQsTF1PU4-GiE"
[...]
De acordo com o valor de resultMessage
, Authlete aceitou o pedido de autorização. A resposta inclui ticket
como esperado. Um servidor de autorização é armazenar o valor de ticket
na sessão de login do usuário e tente autenticar o usuário e obter consentimento.
Uma vez concluído, o servidor fará uma solicitação ao Authlete’s /auth/authorization/issue
API para gerar uma resposta de autorização.
Neste documento, a solicitação de autorização mostrada na seção anterior incluiu response_type=code id_token
. Assim, espera-se que Authlete gere uma resposta de autorização que inclua um código de autorização code
e um token de ID id_token
em fragmento.
Vamos supor que o servidor de auhtorização autentica o usuário, obtém consentimento e determina que o identificador exclusivo do usuário (subject
) é testuser01
. O servidor fará uma solicitação ao Authlete’s /auth/authorization/issue
API com o ticket
e o subject
. Aqui está uma versão enrolada do pedido.
curl -s -X POST https://api.authlete.com/api/auth/authorization/issue \
-u '<API Key e.g. 174381609020>:<API Secret e.g. LszYEVDLM5Bu4lRjO9Vaj0tMSMVerWiPf_zcdy-vu4k>' \
-H 'Content-Type: application/json' \
-d '{"subject":"testuser01","ticket":"rjasCNvemUwamKP0G1h9Fh5Uo_3fgBfQsTF1PU4-GiE"}' | jq
curl.exe -s -X POST https://api.authlete.com/api/auth/authorization/issue `
-u '<API Key e.g. 174381609020>:<API Secret e.g. LszYEVDLM5Bu4lRjO9Vaj0tMSMVerWiPf_zcdy-vu4k>' `
-H 'Content-Type: application/json' `
-d '{\"subject\":\"testuser01\",\"ticket\":\"rjasCNvemUwamKP0G1h9Fh5Uo_3fgBfQsTF1PU4-GiE\"}'
Authlete faz a seguinte resposta (dobrada para legibilidade).
{
"type": "authorizationIssueResponse",
"resultCode": "A151301",
"resultMessage": "[A151301] The algorithm
('HS256' for 'id_token_signed_response_alg')
to sign the ID token is not allowed.",
[...]
De acordo com o valor de resultMessage
, Authlete não permite hs256 (configurações padrão da Authlete) como um algoritmo de assinatura para token ID.
Isso se deve às disposições de segurança da FAPI. 8.6. Considerações do algoritmo JWS estados da seguinte forma.
devem utilizar algoritmos PS256 ou ES256;
Assim, um cliente e um servidor de autorização têm que empregar eS256 ou PS256 como algoritmo JWS. Neste documento, estaremos configurando Authlete para usar o ES256 para algoritmo de assinatura de token de ID.
Agora vamos gerar um conjunto de chaves ES256 e registrá-lo na Authlete como uma chave de assinatura para o token ID. Também atualizaremos as configurações do cliente para especificar o ES256 como um algoritmo de assinatura para o cliente. Consulte o artigo a seguir na Base de Conhecimento Authlete para obter instruções.
Os parâmetros para mkjwk são os seguintes.
Item | Valor |
---|---|
Guia | EC (Curva Elíptica) |
Curva | P-256 |
Key usage | Signing |
Algorithm | ES256 (ECDSA using P-256 and SHA-256) |
Key ID | Um valor arbitrário, por exemplo. 1 |
Registre o “keypair set” gerado para o serviço fazendo login no Console proprietário de serviços da Authlete https://so.authlete.com/
, adicionando o conjunto de keypair à seção “JWK Set Content” na guia JWK Set e digite um valor de criança do conjunto de keypair, 1
neste exemplo, para a seção “ID Token Signature Key ID” na mesma página.
Em seguida, faça login no Console do Desenvolvedor para o serviço (https://cd.authlete.com/<API Key>
por exemplo, https://cd.authlete.com/174381609020
), clique em um link para o cliente, clique no botão “Editar” na parte inferior da página para tornar as configurações editáveis e vá para a guia ID Token.
Deve haver seção de algoritmo de assinatura de token de ID.
Escolha ES256 na lista suspensa e clique no botão “Atualizar”.
Essas configurações terão Authlete selecionar ES256 como um algoritmo de assinatura para emitir token de ID para este cliente e usar a chave ES256 registrada.
Vamos verificar se Authlete funciona como esperado. Faça o mesmo pedido novamente para /auth/authorization
API para obter um ticket
inicialmente.
curl -s -X POST https://api.authlete.com/api/auth/authorization \
-u '<API Key e.g. 174381609020>:<API Secret e.g. LszYEVDLM5Bu4lRjO9Vaj0tMSMVerWiPf_zcdy-vu4k>' \
-H 'Content-Type: application/json' \
-d '{"parameters": "redirect_uri=https://client.example.org/cb/example.com&scope=openid+payment&response_type=code+id_token&client_id=<Client ID e.g. 591205987816490>&nonce=n-0S6_WzA2Mj&request=<Request Object e.g. eyJhbGciOiJFUzI1NiIsImtpZCI6IjEifQ.ewoicmVkaXJlY3RfdXJpIjoiaHR0cHM6Ly9jbGllbnQuZXhhbXBsZS5vcmcvY2IvZXhhbXBsZS5jb20iLAoicmVzcG9uc2VfdHlwZSI6ImNvZGUgaWRfdG9rZW4iLAoiY2xpZW50X2lkIjoiNTkxMjA1OTg3ODE2NDkwIiwKInNjb3BlIjoib3BlbmlkIHBheW1lbnQiLAoiZXhwIjoxNTU0OTczMDAwMCwKImF1ZCI6Imh0dHBzOi8vYXMuZXhhbXBsZS5jb20iLAoiY2xhaW1zIjp7CiAgImlkX3Rva2VuIjp7CiAgICAiYWNyIjp7CiAgICAgICJlc3NlbnRpYWwiOnRydWUsCiAgICAgICJ2YWx1ZXMiOlsidXJuOmV4YW1wbGU6cHNkMjpzY2EiXQogICAgfQogIH0KfSwKIm5vbmNlIjoibi0wUzZfV3pBMk1qIgp9Cg.b5rDSqaI3dh8n4A8hK4B5zSpnZNO_8--W-kTU03CNbCq1I_Vuf3w33ZVUhD0A-rla8cTPlZ25keQBncGWafzOA>"}' | jq | grep ticket
curl.exe -s -X POST https://api.authlete.com/api/auth/authorization `
-u '<API Key e.g. 174381609020>:<API Secret e.g. LszYEVDLM5Bu4lRjO9Vaj0tMSMVerWiPf_zcdy-vu4k>' `
-H 'Content-Type: application/json' `
-d '{\"parameters\": \"redirect_uri=https://client.example.org/cb/example.com&scope=openid+payment&response_type=code+id_token&client_id=<Client ID e.g. 591205987816490>&nonce=n-0S6_WzA2Mj&request=<Request Object e.g. eyJhbGciOiJFUzI1NiIsImtpZCI6IjEifQ.ewoicmVkaXJlY3RfdXJpIjoiaHR0cHM6Ly9jbGllbnQuZXhhbXBsZS5vcmcvY2IvZXhhbXBsZS5jb20iLAoicmVzcG9uc2VfdHlwZSI6ImNvZGUgaWRfdG9rZW4iLAoiY2xpZW50X2lkIjoiNTkxMjA1OTg3ODE2NDkwIiwKInNjb3BlIjoib3BlbmlkIHBheW1lbnQiLAoiZXhwIjoxNTU0OTczMDAwMCwKImF1ZCI6Imh0dHBzOi8vYXMuZXhhbXBsZS5jb20iLAoiY2xhaW1zIjp7CiAgImlkX3Rva2VuIjp7CiAgICAiYWNyIjp7CiAgICAgICJlc3NlbnRpYWwiOnRydWUsCiAgICAgICJ2YWx1ZXMiOlsidXJuOmV4YW1wbGU6cHNkMjpzY2EiXQogICAgfQogIH0KfSwKIm5vbmNlIjoibi0wUzZfV3pBMk1qIgp9Cg.b5rDSqaI3dh8n4A8hK4B5zSpnZNO_8--W-kTU03CNbCq1I_Vuf3w33ZVUhD0A-rla8cTPlZ25keQBncGWafzOA>\"}'
Você deve ser capaz de obter uma resposta (dobrada para legibilidade) incluindo ticket
.
{
[...]
"resultMessage": "[A004001] Authlete has successfully issued a ticket to the service
(API Key = 174381609020) for the authorization request from the client
(ID = 591205987816490). [response_type=code id_token, openid=true]",
"ticket": "3TzdZO2t8qXaQXIEUA5LLN106uVk5fpwL8_UDGlcwUQ"
[...]
Faça uma solicitação com o valor do ticket
e um valor arbitrário de subject
(testuser01
neste exemplo) para /auth/authorization/issue
API.
curl -s -X POST https://api.authlete.com/api/auth/authorization/issue \
-u '<API Key e.g. 174381609020>:<API Secret e.g. LszYEVDLM5Bu4lRjO9Vaj0tMSMVerWiPf_zcdy-vu4k>' \
-H 'Content-Type: application/json' \
-d '{"subject":"testuser01","ticket":"3TzdZO2t8qXaQXIEUA5LLN106uVk5fpwL8_UDGlcwUQ"}' | jq
curl.exe -s -X POST https://api.authlete.com/api/auth/authorization/issue `
-u '<API Key e.g. 174381609020>:<API Secret e.g. LszYEVDLM5Bu4lRjO9Vaj0tMSMVerWiPf_zcdy-vu4k>' `
-H 'Content-Type: application/json' `
-d '{\"subject\":\"testuser01\",\"ticket\":\"3TzdZO2t8qXaQXIEUA5LLN106uVk5fpwL8_UDGlcwUQ\"}'
Authlete faz a seguinte resposta (dobrada para legibilidade).
{
"type": "authorizationIssueResponse",
"resultCode": "A040001",
"resultMessage": "[A040001] The authorization request was processed successfully.",
"accessTokenDuration": 0,
"accessTokenExpiresAt": 0,
"action": "LOCATION",
"authorizationCode": "TSRAvPIp6V3RgPOs2O7FpPG1_7t6Xpc_kcIramz8gBQ",
"idToken": "eyJraWQiOiIxIiwiYWxnIjoiRVMyNTYifQ.eyJzdWIiOiJ0ZXN0dXNlcjAxIiwiYXVkIjpbIjU5MTIwN
Tk4NzgxNjQ5MCJdLCJjX2hhc2giOiJZQjloU01CWkJLdnFobnFaWWRWTXJnIiwiaXNzIjoiaHR0cHM6L
y9hcy5leGFtcGxlLmNvbSIsImV4cCI6MTU3MjQxMDUyNiwiaWF0IjoxNTcyMzI0MTI2LCJub25jZSI6I
m4tMFM2X1d6QTJNaiJ9.ZY5XK4TqAfcnLsMhkigNRpyM6CvwD7SdX-f9TQ18pwMUdh7eoGc6ijlfEnc4
I3l0jYhlm22yuEeffV6XZhdL0A",
"responseContent": "https://client.example.org/cb/example.com#
code=TSRAvPIp6V3RgPOs2O7FpPG1_7t6Xpc_kcIramz8gBQ&
id_token=eyJraWQiOiIxIiwiYWxnIjoiRVMyNTYifQ.eyJzdWIiOiJ0ZXN0dXNlcjAxIiwiYXVkIjpbIjU5MTIwN
Tk4NzgxNjQ5MCJdLCJjX2hhc2giOiJZQjloU01CWkJLdnFobnFaWWRWTXJnIiwiaXNzIjoiaHR0cHM6L
y9hcy5leGFtcGxlLmNvbSIsImV4cCI6MTU3MjQxMDUyNiwiaWF0IjoxNTcyMzI0MTI2LCJub25jZSI6I
m4tMFM2X1d6QTJNaiJ9.ZY5XK4TqAfcnLsMhkigNRpyM6CvwD7SdX-f9TQ18pwMUdh7eoGc6ijlfEnc4
I3l0jYhlm22yuEeffV6XZhdL0A"
}
De acordo com o valor de resultMessage
, Authlete processou com sucesso o pedido. Há um token de ID emitido e um código de autorização em idToken
e authorizationCode
respectivamente, e conteúdo de resposta HTTP em responseContent
. O conteúdo inclui esses tokens e códigos como fragmento e destina-se a ser enviado de um servidor de autorização para um cliente como resposta de autorização.
Uma vez que o cliente recebeu a resposta do servidor de autorização, ele verificará o token de ID. Se a verificação for feita com sucesso, ela extrairá c_hash
do token de ID e usá-lo para verificar o código de autorização. Se a segunda verificação também for feita com sucesso, o cliente fará uma solicitação de token com o código para o servidor de autoração.
O servidor de autorização fará uma solicitação, incluindo a solicitação de token, para Authlete /auth/token
API para que a API gere uma resposta de token que deve incluir um token de acesso.
Aqui está uma versão curl do pedido para /auth/token
API.
curl -s -X POST https://api.authlete.com/api/auth/token \
-u '<API Key e.g. 174381609020>:<API Secret e.g. LszYEVDLM5Bu4lRjO9Vaj0tMSMVerWiPf_zcdy-vu4k>' \
-H 'Content-Type: application/json' \
-d '{"clientId":"<Client ID e.g. 591205987816490>","clientSecret":"<Client Secret e7iqzq7WE8Kg00yepYnpMTjvDnAnBlq5nfA9DDQLkiYkPQBV6Lr8sLhn7DhUJd17i0O6TwQ2hKFeDAYuU160Vg>","parameters": "grant_type=authorization_code&redirect_uri=https://client.example.org/cb/example.com&code=<Code e.g. TSRAvPIp6V3RgPOs2O7FpPG1_7t6Xpc_kcIramz8gBQ>"}'|jq
curl.exe -s -X POST https://api.authlete.com/api/auth/token `
-u '<API Key e.g. 174381609020>:<API Secret e.g. LszYEVDLM5Bu4lRjO9Vaj0tMSMVerWiPf_zcdy-vu4k>' `
-H 'Content-Type: application/json' `
-d '{\"clientId\":\"<Client ID e.g. 591205987816490>\",\"clientSecret\":\"<Client Secret e7iqzq7WE8Kg00yepYnpMTjvDnAnBlq5nfA9DDQLkiYkPQBV6Lr8sLhn7DhUJd17i0O6TwQ2hKFeDAYuU160Vg>\",\"parameters\": \"grant_type=authorization_code&redirect_uri=https://client.example.org/cb/example.com&code=<Code e.g. TSRAvPIp6V3RgPOs2O7FpPG1_7t6Xpc_kcIramz8gBQ>\"}'
Authlete faz a seguinte resposta de erro (dobrada para legibilidade).
{
"type": "tokenResponse",
"resultCode": "A157301",
"resultMessage": "[A157301] The client type of the client is 'confidential'
but the client authentication method is 'none'.",
"accessTokenDuration": 0,
"accessTokenExpiresAt": 0,
"action": "INVALID_CLIENT",
"clientId": 591205987816490,
"clientIdAliasUsed": false,
"grantType": "AUTHORIZATION_CODE",
"refreshTokenDuration": 0,
"refreshTokenExpiresAt": 0,
"responseContent": "{\"error_description\":\"[A157301] The client type
of the client is 'confidential' but the client authentication method is 'none'.\",
\"error\":\"invalid_client\",\"error_uri\":\"https://docs.authlete.com/#A157301\"}"
}
De acordo com o valor de resultMessage
, o método de autenticação do cliente de none
, que é o valor padrão da Authlete, não é permitido para clientes confidenciais.
Isso se deve às disposições de segurança da FAPI. 5.2 Leia e escreva as disposições de segurança da API / 5.2.2. Servidor de autorização estados da seguinte forma.
deve autenticar o cliente confidencial no ponto final do token usando um dos seguintes métodos (isso substitui a cláusula 5.2.2.2.4 da FAPI):
TLS mútuo para autenticação de clientes de Aauth conforme especificado na seção 2 de [MTLS];
private_key_jwt conforme especificado na seção 9 de [OIDC];
Assim, você tem que usar o OAuth 2.0 Token Binding [OAUTB] ou OAuth 2.0 Mutual TLS Client Authentication and Certificate Bound Access Tokens [MTLS] em um ambiente compatível com FAPI. Ou seja, outros métodos como none
, client_secret_basic
que é popular para clientes confidenciais, ou seja, um servidor de autorização não deve empregá-los para autenticar clientes.
Neste documento, teremos Authlete usar o último e Método PKI Mutual-TLS (tls_client_auth
) definido no método.
Vamos configurar o serviço e as configurações do cliente para ativar a autenticação do cliente TLS.
Faça login no console proprietário de serviços da Authlete https://so.authlete.com/
, clique no botão “Editar” na parte inferior da página para tornar as configurações editáveis e vá para a guia Autorização. Deve haver seção Token Endpoint.
Verifique a caixa em Métodos de Autenticação de Cliente suportados e clique no botão “Atualizar” na parte inferior da página. Pressione “OK” em um diálogo para confirmação.
Item | Valor |
---|---|
Métodos de autenticação de clientes suportados | TLS_CLIENT_AUTH |
Faça login no Console do Desenvolvedor para o serviço (https://cd.authlete.com/<API Key>
por exemplo, https://cd.authlete.com/174381609020
) e configure as configurações do cliente na seção “Ponto final de token” na guia Autorização da seguinte forma.
Item | Valor |
---|---|
Método de autenticação do cliente | TLS_CLIENT_AUTH |
Item | Valor |
---|---|
Cliente TLS Auth Assunto DN | CN=client.example.org, O=Client, L=Chiyoda-ku, ST=Tokyo, C=JP |
Com essas configurações acima, Authlete suportará a autenticação TLS mútua para autenticação do cliente e aplicará o método para processar solicitações de token do cliente. Assunto DN CN=client.example.org, ...
é usado como o identificador do cliente.
Você tem que preparar um certificado digital para que o cliente seja autenticado pelo servidor de autorização. O assunto DN do certificado deve ser o mesmo que
foi especificado na seção anterior, CN=client.example.org, ...
neste documento.
O exemplo a seguir ilustra que gerar um auto-assinado certificado usando OpenSSL.
$ openssl genrsa 2048 > private_key_nopass.pem
Generating RSA private key, 2048 bit long modulus
...............+++
.......................+++
e is 65537 (0x10001)
CN=client.example.org, O=Client, L=Chiyoda-ku, ST=Tokyo, C=JP
como Sujeito DN$ openssl req -new -key private_key_nopass.pem -out server.csr
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) []:JP
State or Province Name (full name) []:Tokyo
Locality Name (eg, city) []:Chiyoda-ku
Organization Name (eg, company) []:Client
Organizational Unit Name (eg, section) []:
Common Name (eg, fully qualified host name) []:client.example.org
Email Address []:
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
$ cat server.csr
-----BEGIN CERTIFICATE REQUEST-----
MIICpTCCAY0CAQAwYDELMAkGA1UEBhMCSlAxDjAMBgNVBAgMBVRva3lvMRMwEQYD
VQQHDApDaGl5b2RhLWt1MQ8wDQYDVQQKDAZDbGllbnQxGzAZBgNVBAMMEmNsaWVu
[...]
r4MUVOwPNWOM6UGYQZwjvtJ2rmKr8cQrbfvbcFiY4s6lLQGOz5yLzmO8GUdmfzUd
p5BW1iL+SpjS
-----END CERTIFICATE REQUEST-----
$ openssl x509 -days 365 -req -signkey private_key_nopass.pem -in server.csr -out server.crt
Signature ok
subject=/C=JP/ST=Tokyo/L=Chiyoda-ku/O=Client/CN=client.example.org
Getting Private key
O seguinte é um certificado gerado neste exemplo.
server.crt
-----BEGIN CERTIFICATE-----
MIIDPDCCAiQCCQDWNMOIuzwDfzANBgkqhkiG9w0BAQUFADBgMQswCQYDVQQGEwJK
UDEOMAwGA1UECAwFVG9reW8xEzARBgNVBAcMCkNoaXlvZGEta3UxDzANBgNVBAoM
BkNsaWVudDEbMBkGA1UEAwwSY2xpZW50LmV4YW1wbGUub3JnMB4XDTE5MTAyODA3
MjczMFoXDTIwMTAyNzA3MjczMFowYDELMAkGA1UEBhMCSlAxDjAMBgNVBAgMBVRv
a3lvMRMwEQYDVQQHDApDaGl5b2RhLWt1MQ8wDQYDVQQKDAZDbGllbnQxGzAZBgNV
BAMMEmNsaWVudC5leGFtcGxlLm9yZzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
AQoCggEBAK2Oyc+BV4N5pYcp47opUwsb2NaJq4X+d5Itq8whpFlZ9uCCHzF5TWSF
XrpYscOp95veGPF42eT1grfxYyvjFotE76caHhBLCkIbBh6Vf222IGMwwBbSZfO9
J3eURtEADBvsZ117HkPVdjYqvt3Pr4RxdR12zG1TcBAoTLGchyr8nBqRADFhUTCL
msYaz1ADiQ/xbJN7VUNQpKhzRWHCdYS03HpbGjYCtAbl9dJnH2EepNF0emGiSPFq
df6taToyCr7oZjM7ufmKPjiiEDbeSYTf6kbPNmmjtoPNNLeejHjP9p0IYx7l0Gkj
mx4kSMLp4vSDftrFgGfcxzaMmKBsosMCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEA
qzdDYbntFLPBlbwAQlpwIjvmvwzvkQt6qgZ9Y0oMAf7pxq3i9q7W1bDol0UF4pIM
z3urEJCHO8w18JRlfOnOENkcLLLntrjOUXuNkaCDLrnv8pnp0yeTQHkSpsyMtJi9
R6r6JT9V57EJ/pWQBgKlN6qMiBkIvX7U2hEMmhZ00h/E5xMmiKbySBiJV9fBzDRf
mAy1p9YEgLsEMLnGjKHTok+hd0BLvcmXVejdUsKCg84F0zqtXEDXLCiKcpXCeeWv
lmmXxC5PH/GEMkSPiGSR7+b1i0sSotsq+M3hbdwabpJ6nQLLbKkFSGcsQ87yL+gr
So6zun26vAUJTu1o9CIjxw==
-----END CERTIFICATE-----
Vamos verificar se Authlete funciona como esperado. Executar o mesmo procedimento novamente.
/auth/authorization
API e obter um valor de ticket
a partir de uma resposta/auth/authorization/issue
API e obter um valor de authorizationCode
a partir de uma resposta/auth/token
API
* Adicionar clientCertificate
parâmetro com o certificado do cliente como seu valor
* Remover clientSecret
parâmetro (não é mais necessário, pois a autenticação TLS mútua é eficaz)Aqui está uma versão curl do pedido para /auth/token
API.
curl -s -X POST https://api.authlete.com/api/auth/token \
-u '<API Key e.g. 174381609020>:<API Secret e.g. LszYEVDLM5Bu4lRjO9Vaj0tMSMVerWiPf_zcdy-vu4k>' \
-H 'Content-Type: application/json' \
-d '{"clientId":"<Client ID e.g. 591205987816490>","parameters": "grant_type=authorization_code&redirect_uri=https://client.example.org/cb/example.com&code=<Code e.g. TSRAvPIp6V3RgPOs2O7FpPG1_7t6Xpc_kcIramz8gBQ>", "clientCertificate":"-----BEGIN CERTIFICATE-----
MIIDPDCCAiQCCQDWNMOIuzwDfzANBgkqhkiG9w0BAQUFADBgMQswCQYDVQQGEwJK
UDEOMAwGA1UECAwFVG9reW8xEzARBgNVBAcMCkNoaXlvZGEta3UxDzANBgNVBAoM
BkNsaWVudDEbMBkGA1UEAwwSY2xpZW50LmV4YW1wbGUub3JnMB4XDTE5MTAyODA3
MjczMFoXDTIwMTAyNzA3MjczMFowYDELMAkGA1UEBhMCSlAxDjAMBgNVBAgMBVRv
a3lvMRMwEQYDVQQHDApDaGl5b2RhLWt1MQ8wDQYDVQQKDAZDbGllbnQxGzAZBgNV
BAMMEmNsaWVudC5leGFtcGxlLm9yZzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
AQoCggEBAK2Oyc+BV4N5pYcp47opUwsb2NaJq4X+d5Itq8whpFlZ9uCCHzF5TWSF
XrpYscOp95veGPF42eT1grfxYyvjFotE76caHhBLCkIbBh6Vf222IGMwwBbSZfO9
J3eURtEADBvsZ117HkPVdjYqvt3Pr4RxdR12zG1TcBAoTLGchyr8nBqRADFhUTCL
msYaz1ADiQ/xbJN7VUNQpKhzRWHCdYS03HpbGjYCtAbl9dJnH2EepNF0emGiSPFq
df6taToyCr7oZjM7ufmKPjiiEDbeSYTf6kbPNmmjtoPNNLeejHjP9p0IYx7l0Gkj
mx4kSMLp4vSDftrFgGfcxzaMmKBsosMCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEA
qzdDYbntFLPBlbwAQlpwIjvmvwzvkQt6qgZ9Y0oMAf7pxq3i9q7W1bDol0UF4pIM
z3urEJCHO8w18JRlfOnOENkcLLLntrjOUXuNkaCDLrnv8pnp0yeTQHkSpsyMtJi9
R6r6JT9V57EJ/pWQBgKlN6qMiBkIvX7U2hEMmhZ00h/E5xMmiKbySBiJV9fBzDRf
mAy1p9YEgLsEMLnGjKHTok+hd0BLvcmXVejdUsKCg84F0zqtXEDXLCiKcpXCeeWv
lmmXxC5PH/GEMkSPiGSR7+b1i0sSotsq+M3hbdwabpJ6nQLLbKkFSGcsQ87yL+gr
So6zun26vAUJTu1o9CIjxw==
-----END CERTIFICATE-----"}'|jq
curl.exe -s -X POST https://api.authlete.com/api/auth/token `
-u '<API Key e.g. 174381609020>:<API Secret e.g. LszYEVDLM5Bu4lRjO9Vaj0tMSMVerWiPf_zcdy-vu4k>' `
-H 'Content-Type: application/json' `
-d '{\"clientId\":\"<Client ID e.g. 591205987816490>\",\"clientSecret\":\"<Client Secret e7iqzq7WE8Kg00yepYnpMTjvDnAnBlq5nfA9DDQLkiYkPQBV6Lr8sLhn7DhUJd17i0O6TwQ2hKFeDAYuU160Vg>\",\"parameters\": \"grant_type=authorization_code&redirect_uri=https://client.example.org/cb/example.com&code=<Code e.g. TSRAvPIp6V3RgPOs2O7FpPG1_7t6Xpc_kcIramz8gBQ>\",\"clientCertificate\":\"-----BEGIN CERTIFICATE-----
MIIDPDCCAiQCCQDWNMOIuzwDfzANBgkqhkiG9w0BAQUFADBgMQswCQYDVQQGEwJK
UDEOMAwGA1UECAwFVG9reW8xEzARBgNVBAcMCkNoaXlvZGEta3UxDzANBgNVBAoM
BkNsaWVudDEbMBkGA1UEAwwSY2xpZW50LmV4YW1wbGUub3JnMB4XDTE5MTAyODA3
MjczMFoXDTIwMTAyNzA3MjczMFowYDELMAkGA1UEBhMCSlAxDjAMBgNVBAgMBVRv
a3lvMRMwEQYDVQQHDApDaGl5b2RhLWt1MQ8wDQYDVQQKDAZDbGllbnQxGzAZBgNV
BAMMEmNsaWVudC5leGFtcGxlLm9yZzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
AQoCggEBAK2Oyc+BV4N5pYcp47opUwsb2NaJq4X+d5Itq8whpFlZ9uCCHzF5TWSF
XrpYscOp95veGPF42eT1grfxYyvjFotE76caHhBLCkIbBh6Vf222IGMwwBbSZfO9
J3eURtEADBvsZ117HkPVdjYqvt3Pr4RxdR12zG1TcBAoTLGchyr8nBqRADFhUTCL
msYaz1ADiQ/xbJN7VUNQpKhzRWHCdYS03HpbGjYCtAbl9dJnH2EepNF0emGiSPFq
df6taToyCr7oZjM7ufmKPjiiEDbeSYTf6kbPNmmjtoPNNLeejHjP9p0IYx7l0Gkj
mx4kSMLp4vSDftrFgGfcxzaMmKBsosMCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEA
qzdDYbntFLPBlbwAQlpwIjvmvwzvkQt6qgZ9Y0oMAf7pxq3i9q7W1bDol0UF4pIM
z3urEJCHO8w18JRlfOnOENkcLLLntrjOUXuNkaCDLrnv8pnp0yeTQHkSpsyMtJi9
R6r6JT9V57EJ/pWQBgKlN6qMiBkIvX7U2hEMmhZ00h/E5xMmiKbySBiJV9fBzDRf
mAy1p9YEgLsEMLnGjKHTok+hd0BLvcmXVejdUsKCg84F0zqtXEDXLCiKcpXCeeWv
lmmXxC5PH/GEMkSPiGSR7+b1i0sSotsq+M3hbdwabpJ6nQLLbKkFSGcsQ87yL+gr
So6zun26vAUJTu1o9CIjxw==
-----END CERTIFICATE-----\"}'
Authlete faz a seguinte resposta com cautela (dobrada para legibilidade).
{
"type": "tokenResponse",
"resultCode": "A152305",
"resultMessage": "[A152305] The service and the client are not configured
so that the required Holder of Key methods are performed.",
"accessToken": "RCqjF4tlffJ7-n92sAEFQNIwrRm0syOUrBu0cNLAIJU",
"accessTokenDuration": 0,
"accessTokenExpiresAt": 0,
"action": "BAD_REQUEST",
"clientId": 591205987816490,
"clientIdAliasUsed": false,
"grantType": "AUTHORIZATION_CODE",
"idToken": "eyJraWQiOiIxIiwiYWxnIjoiRVMyNTYifQ.eyJzdWIiOiJ0ZXN0dXNlcjAxIiwiYXVkIjpbIjU5MTIwN
Tk4NzgxNjQ5MCJdLCJpc3MiOiJodHRwczovL2FzLmV4YW1wbGUuY29tIiwiZXhwIjoxNTcyNDEyMTcwL
CJpYXQiOjE1NzIzMjU3NzAsIm5vbmNlIjoibi0wUzZfV3pBMk1qIn0.x4XmPTh698AbNEjCaNcD5k54q
S249BSPkc9EkwZuUI17AL8z593GYTg3GVQQdhF9k0HYLRA17c3m39OxYDrx3g",
"refreshToken": "jy5lN7TXZrAlIfgFbOaMMkzDtoJUu4prBtNa3HcoRRE",
"refreshTokenDuration": 0,
"refreshTokenExpiresAt": 0,
"responseContent": "{\"error_description\":\"[A152305] The service and the client are
not configured so that the required Holder of Key methods are performed.\",
\"error\":\"invalid_request\",\"error_uri\":\"https://docs.authlete.com/#A152305\"}"
}
De acordo com o valor de resultMessage
, Authlete não executou o método “Holder of Key”, que é obrigatório para cumprir as disposições de segurança da FAPI, enquanto um token de acesso foi emitido.
Assim, o token de acesso emitido não está vinculado ao certificado de cliente TLS do cliente.
Faça login no console proprietário de serviços da Authlete https://so.authlete.com/
, clique no botão “Editar” na parte inferior da página para tornar as configurações editáveis e vá para a guia Token. Deve haver seção Access Token.
Escolha a seguinte opção para tokens de acesso vinculados ao certificado de cliente TLS.
Item | Valor |
---|---|
Tokens de acesso vinculados ao certificado de cliente TLS | Escolher Supported |
Faça login no Console do Desenvolvedor para o serviço (https://cd.authlete.com/<API Key>
por exemplo, https://cd.authlete.com/174381609020
), clique em um link para o cliente, clique no botão “Editar” na parte inferior da página para tornar as configurações editáveis e vá para a guia Básico.
Escolha a seguinte opção para tokens de acesso vinculados ao certificado de cliente TLS.
Item | Valor |
---|---|
Tokens de acesso vinculados ao certificado de cliente TLS | Escolher Enabled |
Parabéns! Finalmente, você terminou a configuração do Authlete para suportar um servidor de autorização compatível com FAPI.
Uma vez que a configuração é feita, você pode verificar se o Authlete funciona como esperado.
Faça solicitações, que são as mesmas da seção anterior,
Para /auth/authorization
API, /auth/authorization/issue
API e /auth/token
API.
Além dessas três solicitações, faça outra solicitação para /auth/introspection
API para ver se o token de acesso usado para solicitações de API a um servidor de recursos está vinculado ao certificado de cliente TLS do cliente.
/auth/authorization
APIcurl -s -X POST https://api.authlete.com/api/auth/authorization -u '174381609020:LszYEVDLM5Bu4lRjO9Vaj0tMSMVerWiPf_zcdy-vu4k' -H 'Content-Type: application/json' -d '{"parameters": "redirect_uri=https://client.example.org/cb/example.com&scope=openid+payment&response_type=code+id_token&client_id=591205987816490&nonce=n-0S6_WzA2Mj&request=eyJhbGciOiJFUzI1NiIsImtpZCI6IjEifQ.ewoicmVkaXJlY3RfdXJpIjoiaHR0cHM6Ly9jbGllbnQuZXhhbXBsZS5vcmcvY2IvZXhhbXBsZS5jb20iLAoicmVzcG9uc2VfdHlwZSI6ImNvZGUgaWRfdG9rZW4iLAoiY2xpZW50X2lkIjoiNTkxMjA1OTg3ODE2NDkwIiwKInNjb3BlIjoib3BlbmlkIHBheW1lbnQiLAoiZXhwIjoxNTU0OTczMDAwMCwKImF1ZCI6Imh0dHBzOi8vYXMuZXhhbXBsZS5jb20iLAoiY2xhaW1zIjp7CiAgImlkX3Rva2VuIjp7CiAgICAiYWNyIjp7CiAgICAgICJlc3NlbnRpYWwiOnRydWUsCiAgICAgICJ2YWx1ZXMiOlsidXJuOm1hY2U6aW5jb21tb246aWFwOnNpbHZlciJdCiAgICB9CiAgfQp9LAoibm9uY2UiOiJuLTBTNl9XekEyTWoiCn0K.50gewunAqCITD6p2kI52GDXdUgQP-EzLDjjjoDT9C4zY8YCKgLzN7sR2ZvkAQ_pimLpwFh2QYjjyPskvvtnC9g"}' |jq|grep ticket
{
[...]
"resultMessage": "[A004001] Authlete has successfully issued a ticket
to the service (API Key = 174381609020) for the authorization request
from the client (ID = 591205987816490). [response_type=code id_token, openid=true]",
[...]
"ticket": "b0JGD-ZkT8ElBGw2ck-T-t87Z033jXvhqC2omPT1bQ4"
[...]
/auth/authorization/issue
APIcurl -s -X POST https://api.authlete.com/api/auth/authorization/issue -u '174381609020:LszYEVDLM5Bu4lRjO9Vaj0tMSMVerWiPf_zcdy-vu4k' -H 'Content-Type: application/json' -d '{"subject":"testuser01","ticket":"b0JGD-ZkT8ElBGw2ck-T-t87Z033jXvhqC2omPT1bQ4"}' | jq
{
"type": "authorizationIssueResponse",
"resultCode": "A040001",
"resultMessage": "[A040001] The authorization request was processed successfully.",
"accessTokenDuration": 0,
"accessTokenExpiresAt": 0,
"action": "LOCATION",
"authorizationCode": "DxiKC0cOc_46nzVjgr41RWBQtMDrAvc0BUbMJ_v7I70",
"idToken": "eyJraWQiOiIxIiwiYWxnIjoiRVMyNTYifQ.eyJzdWIiOiJ0ZXN0dXNlcjAxIiwiYXVkIjpbIjU5MTIwN
Tk4NzgxNjQ5MCJdLCJjX2hhc2giOiJqR2kyOElvYm5HcjNNQ3Y0UUVQRTNnIiwiaXNzIjoiaHR0cHM6L
y9hcy5leGFtcGxlLmNvbSIsImV4cCI6MTU3MjQxMjY4MiwiaWF0IjoxNTcyMzI2MjgyLCJub25jZSI6I
m4tMFM2X1d6QTJNaiJ9.1PFmc0gAsBWtLBriq3z9a4Tsi_ioEYlOqOYbicGEXWIS1WGX5ffGOyZNSzVB
MamZbltZmSys0jlYmmYYLqgGsg",
"responseContent": "https://client.example.org/cb/example.com#
code=DxiKC0cOc_46nzVjgr41RWBQtMDrAvc0BUbMJ_v7I70&
id_token=eyJraWQiOiIxIiwiYWxnIjoiRVMyNTYifQ.eyJzdWIiOiJ0ZXN0dXNlcjAxIiwiYXVkIjpbIjU5MTIwN
Tk4NzgxNjQ5MCJdLCJjX2hhc2giOiJqR2kyOElvYm5HcjNNQ3Y0UUVQRTNnIiwiaXNzIjoiaHR0cHM6L
y9hcy5leGFtcGxlLmNvbSIsImV4cCI6MTU3MjQxMjY4MiwiaWF0IjoxNTcyMzI2MjgyLCJub25jZSI6I
m4tMFM2X1d6QTJNaiJ9.1PFmc0gAsBWtLBriq3z9a4Tsi_ioEYlOqOYbicGEXWIS1WGX5ffGOyZNSzVB
MamZbltZmSys0jlYmmYYLqgGsg"
}
/auth/token
APIcurl -s -X POST https://api.authlete.com/api/auth/token \
-u '174381609020:LszYEVDLM5Bu4lRjO9Vaj0tMSMVerWiPf_zcdy-vu4k' \
-H 'Content-Type: application/json' \
-d '{"clientId":"591205987816490","parameters": "grant_type=authorization_code&redirect_uri=https://client.example.org/cb/example.com&code=DxiKC0cOc_46nzVjgr41RWBQtMDrAvc0BUbMJ_v7I70","clientCertificate":"-----BEGIN CERTIFICATE-----
MIIDPDCCAiQCCQDWNMOIuzwDfzANBgkqhkiG9w0BAQUFADBgMQswCQYDVQQGEwJK
UDEOMAwGA1UECAwFVG9reW8xEzARBgNVBAcMCkNoaXlvZGEta3UxDzANBgNVBAoM
BkNsaWVudDEbMBkGA1UEAwwSY2xpZW50LmV4YW1wbGUub3JnMB4XDTE5MTAyODA3
MjczMFoXDTIwMTAyNzA3MjczMFowYDELMAkGA1UEBhMCSlAxDjAMBgNVBAgMBVRv
a3lvMRMwEQYDVQQHDApDaGl5b2RhLWt1MQ8wDQYDVQQKDAZDbGllbnQxGzAZBgNV
BAMMEmNsaWVudC5leGFtcGxlLm9yZzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
AQoCggEBAK2Oyc+BV4N5pYcp47opUwsb2NaJq4X+d5Itq8whpFlZ9uCCHzF5TWSF
XrpYscOp95veGPF42eT1grfxYyvjFotE76caHhBLCkIbBh6Vf222IGMwwBbSZfO9
J3eURtEADBvsZ117HkPVdjYqvt3Pr4RxdR12zG1TcBAoTLGchyr8nBqRADFhUTCL
msYaz1ADiQ/xbJN7VUNQpKhzRWHCdYS03HpbGjYCtAbl9dJnH2EepNF0emGiSPFq
df6taToyCr7oZjM7ufmKPjiiEDbeSYTf6kbPNmmjtoPNNLeejHjP9p0IYx7l0Gkj
mx4kSMLp4vSDftrFgGfcxzaMmKBsosMCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEA
qzdDYbntFLPBlbwAQlpwIjvmvwzvkQt6qgZ9Y0oMAf7pxq3i9q7W1bDol0UF4pIM
z3urEJCHO8w18JRlfOnOENkcLLLntrjOUXuNkaCDLrnv8pnp0yeTQHkSpsyMtJi9
R6r6JT9V57EJ/pWQBgKlN6qMiBkIvX7U2hEMmhZ00h/E5xMmiKbySBiJV9fBzDRf
mAy1p9YEgLsEMLnGjKHTok+hd0BLvcmXVejdUsKCg84F0zqtXEDXLCiKcpXCeeWv
lmmXxC5PH/GEMkSPiGSR7+b1i0sSotsq+M3hbdwabpJ6nQLLbKkFSGcsQ87yL+gr
So6zun26vAUJTu1o9CIjxw==
-----END CERTIFICATE-----"}' |jq
{
"type": "tokenResponse",
"resultCode": "A050001",
"resultMessage": "[A050001] The token request (grant_type=authorization_code)
was processed successfully.",
"accessToken": "SUtEVc3Tj3D3xOdysQtssQxe9egAhI4fimexNVMjRyU",
"accessTokenDuration": 86400,
"accessTokenExpiresAt": 1572412769390,
"action": "OK",
"clientId": 591205987816490,
"clientIdAliasUsed": false,
"grantType": "AUTHORIZATION_CODE",
"idToken": "eyJraWQiOiIxIiwiYWxnIjoiRVMyNTYifQ.eyJzdWIiOiJ0ZXN0dXNlcjAxIiwiYXVkIjpbIjU5MTIwN
Tk4NzgxNjQ5MCJdLCJpc3MiOiJodHRwczovL2FzLmV4YW1wbGUuY29tIiwiZXhwIjoxNTcyNDEyNzY5L
CJpYXQiOjE1NzIzMjYzNjksIm5vbmNlIjoibi0wUzZfV3pBMk1qIn0.9EQojck-Cf2hnKAZWR164kr21
o5lPKehvIHyViZgRg4CY_ZGmnyFooG4FCwlZxu-QOTtaDCffCsuCdz4GqknTA",
"refreshToken": "tXZjYfoK35I-djg9V3n6s58zsrVqRIzTNMXKIS_wkj8",
"refreshTokenDuration": 864000,
"refreshTokenExpiresAt": 1573190369390,
"responseContent": "{\"access_token\":\"SUtEVc3Tj3D3xOdysQtssQxe9egAhI4fimexNVMjRyU\",
\"refresh_token\":\"tXZjYfoK35I-djg9V3n6s58zsrVqRIzTNMXKIS_wkj8\",\"scope\":\"openid payment\",
\"id_token\":\"eyJraWQiOiIxIiwiYWxnIjoiRVMyNTYifQ.eyJzdWIiOiJ0ZXN0dXNlcjAxIiwiYXVkIjpbIjU5MTIwN
Tk4NzgxNjQ5MCJdLCJpc3MiOiJodHRwczovL2FzLmV4YW1wbGUuY29tIiwiZXhwIjoxNTcyNDEyNzY5L
CJpYXQiOjE1NzIzMjYzNjksIm5vbmNlIjoibi0wUzZfV3pBMk1qIn0.9EQojck-Cf2hnKAZWR164kr21
o5lPKehvIHyViZgRg4CY_ZGmnyFooG4FCwlZxu-QOTtaDCffCsuCdz4GqknTA\",
\"token_type\":\"Bearer\",\"expires_in\":86400}",
"scopes": [
"openid",
"payment"
],
"subject": "testuser01"
}
Após o procedimento acima, temos um token de acesso cujo valor é SUtEVc3Tj3D3xOdysQtssQxe9egAhI4fimexNVMjRyU
neste exemplo.
Vamos supor que o servidor de recursos receba uma solicitação de API, incluindo
o valor como o token de acesso, do cliente. O token no pedido estaria em Authorization: Bearer
cabeçalho.
O servidor de recursos é para
verificar o token e obter informações relacionadas com ele, fazendo um
solicitação para /auth/introspection
API. O servidor de recursos também incluirá
o certificado do cliente, que deve ser capaz de obter a partir de TLS mútuo
comunicação para a solicitação de API, a pedido à Authlete.
/auth/introspection
APIcurl -s -X POST https://api.authlete.com/api/auth/introspection \
-u '<API Key e.g. 174381609020>:<API Secret e.g. LszYEVDLM5Bu4lRjO9Vaj0tMSMVerWiPf_zcdy-vu4k>' \
-H 'Content-Type: application/json' \
-d '{"token":"SUtEVc3Tj3D3xOdysQtssQxe9egAhI4fimexNVMjRyU","clientCertificate":"-----BEGIN CERTIFICATE-----
MIIDPDCCAiQCCQDWNMOIuzwDfzANBgkqhkiG9w0BAQUFADBgMQswCQYDVQQGEwJK
UDEOMAwGA1UECAwFVG9reW8xEzARBgNVBAcMCkNoaXlvZGEta3UxDzANBgNVBAoM
BkNsaWVudDEbMBkGA1UEAwwSY2xpZW50LmV4YW1wbGUub3JnMB4XDTE5MTAyODA3
MjczMFoXDTIwMTAyNzA3MjczMFowYDELMAkGA1UEBhMCSlAxDjAMBgNVBAgMBVRv
a3lvMRMwEQYDVQQHDApDaGl5b2RhLWt1MQ8wDQYDVQQKDAZDbGllbnQxGzAZBgNV
BAMMEmNsaWVudC5leGFtcGxlLm9yZzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
AQoCggEBAK2Oyc+BV4N5pYcp47opUwsb2NaJq4X+d5Itq8whpFlZ9uCCHzF5TWSF
XrpYscOp95veGPF42eT1grfxYyvjFotE76caHhBLCkIbBh6Vf222IGMwwBbSZfO9
J3eURtEADBvsZ117HkPVdjYqvt3Pr4RxdR12zG1TcBAoTLGchyr8nBqRADFhUTCL
msYaz1ADiQ/xbJN7VUNQpKhzRWHCdYS03HpbGjYCtAbl9dJnH2EepNF0emGiSPFq
df6taToyCr7oZjM7ufmKPjiiEDbeSYTf6kbPNmmjtoPNNLeejHjP9p0IYx7l0Gkj
mx4kSMLp4vSDftrFgGfcxzaMmKBsosMCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEA
qzdDYbntFLPBlbwAQlpwIjvmvwzvkQt6qgZ9Y0oMAf7pxq3i9q7W1bDol0UF4pIM
z3urEJCHO8w18JRlfOnOENkcLLLntrjOUXuNkaCDLrnv8pnp0yeTQHkSpsyMtJi9
R6r6JT9V57EJ/pWQBgKlN6qMiBkIvX7U2hEMmhZ00h/E5xMmiKbySBiJV9fBzDRf
mAy1p9YEgLsEMLnGjKHTok+hd0BLvcmXVejdUsKCg84F0zqtXEDXLCiKcpXCeeWv
lmmXxC5PH/GEMkSPiGSR7+b1i0sSotsq+M3hbdwabpJ6nQLLbKkFSGcsQ87yL+gr
So6zun26vAUJTu1o9CIjxw==
-----END CERTIFICATE-----"}'|jq
curl.exe -s -X POST https://api.authlete.com/api/auth/introspection `
-u '<API Key e.g. 174381609020>:<API Secret e.g. LszYEVDLM5Bu4lRjO9Vaj0tMSMVerWiPf_zcdy-vu4k>' `
-H 'Content-Type: application/json' `
-d '{\"token\":\"SUtEVc3Tj3D3xOdysQtssQxe9egAhI4fimexNVMjRyU\",\"clientCertificate\":\"-----BEGIN CERTIFICATE-----
MIIDPDCCAiQCCQDWNMOIuzwDfzANBgkqhkiG9w0BAQUFADBgMQswCQYDVQQGEwJK
UDEOMAwGA1UECAwFVG9reW8xEzARBgNVBAcMCkNoaXlvZGEta3UxDzANBgNVBAoM
BkNsaWVudDEbMBkGA1UEAwwSY2xpZW50LmV4YW1wbGUub3JnMB4XDTE5MTAyODA3
MjczMFoXDTIwMTAyNzA3MjczMFowYDELMAkGA1UEBhMCSlAxDjAMBgNVBAgMBVRv
a3lvMRMwEQYDVQQHDApDaGl5b2RhLWt1MQ8wDQYDVQQKDAZDbGllbnQxGzAZBgNV
BAMMEmNsaWVudC5leGFtcGxlLm9yZzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
AQoCggEBAK2Oyc+BV4N5pYcp47opUwsb2NaJq4X+d5Itq8whpFlZ9uCCHzF5TWSF
XrpYscOp95veGPF42eT1grfxYyvjFotE76caHhBLCkIbBh6Vf222IGMwwBbSZfO9
J3eURtEADBvsZ117HkPVdjYqvt3Pr4RxdR12zG1TcBAoTLGchyr8nBqRADFhUTCL
msYaz1ADiQ/xbJN7VUNQpKhzRWHCdYS03HpbGjYCtAbl9dJnH2EepNF0emGiSPFq
df6taToyCr7oZjM7ufmKPjiiEDbeSYTf6kbPNmmjtoPNNLeejHjP9p0IYx7l0Gkj
mx4kSMLp4vSDftrFgGfcxzaMmKBsosMCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEA
qzdDYbntFLPBlbwAQlpwIjvmvwzvkQt6qgZ9Y0oMAf7pxq3i9q7W1bDol0UF4pIM
z3urEJCHO8w18JRlfOnOENkcLLLntrjOUXuNkaCDLrnv8pnp0yeTQHkSpsyMtJi9
R6r6JT9V57EJ/pWQBgKlN6qMiBkIvX7U2hEMmhZ00h/E5xMmiKbySBiJV9fBzDRf
mAy1p9YEgLsEMLnGjKHTok+hd0BLvcmXVejdUsKCg84F0zqtXEDXLCiKcpXCeeWv
lmmXxC5PH/GEMkSPiGSR7+b1i0sSotsq+M3hbdwabpJ6nQLLbKkFSGcsQ87yL+gr
So6zun26vAUJTu1o9CIjxw==
-----END CERTIFICATE-----\"}'
{
"type": "introspectionResponse",
"resultCode": "A056001",
"resultMessage": "[A056001] The access token is valid.",
"action": "OK",
"certificateThumbprint": "cBNP0zNH0fkcIQdVHdB8GDQAbaZyIjKXB0EVRTByJMU",
"clientId": 591205987816490,
"clientIdAliasUsed": false,
"existent": true,
"expiresAt": 1572412769000,
"refreshable": true,
"responseContent": "Bearer error=\"invalid_request\"",
"scopes": [
"openid",
"payment"
],
"subject": "testuser01",
"sufficient": true,
"usable": true
}
O servidor de recursos agora é capaz de descobrir que o token de acesso do cliente foi verificado e obter as informações associadas com o token, como assunto e escopos.
Neste tutorial, revisamos as disposições de segurança definidas em API de nível financeiro - Parte 2: Ler e Escrever Perfil de Segurança da API e instruções de configuração da Authlete através de etapas para a construção de um servidor de autorização compatível com FAPI.