Público JWT (Json Web Token) “aud” versus Client_Id - Qual é a diferença?

103

Estou trabalhando na implementação de OAuth 2.0 JWT access_token em meu servidor de autenticação. Porém, não tenho certeza de quais são as diferenças entre a auddeclaração JWT e o client_idvalor do cabeçalho HTTP. Eles são os mesmos? Se não, você pode explicar a diferença entre os dois?

Minha suspeita é que auddeve se referir ao (s) servidor (es) de recursos, e o client_iddeve se referir a um dos aplicativos cliente reconhecidos pelo servidor de autenticação (ou seja, aplicativo da web ou aplicativo iOS).

No meu caso atual, meu servidor de recursos também é meu cliente de aplicativo da web.

Chris Swain
fonte

Respostas:

132

Acontece que minhas suspeitas estavam certas. A auddeclaração de público em um JWT se refere aos Servidores de Recursos que devem aceitar o token.

Como esta postagem simplesmente coloca:

O público de um token é o destinatário pretendido do token.

O valor do público é uma string - normalmente, o endereço base do recurso que está sendo acessado, como https://contoso.com.

O client_idem OAuth se refere ao aplicativo cliente que solicitará recursos do Servidor de Recursos.

O aplicativo cliente (por exemplo, seu aplicativo iOS) solicitará um JWT de seu servidor de autenticação. Ao fazê-lo, ele passa é client_ide client_secretjunto com todas as credenciais do usuário que podem ser necessárias. O Authorization Server valida o cliente usando o client_ide client_secrete retorna um JWT.

O JWT conterá uma auddeclaração que especifica para quais servidores de recursos o JWT é válido. Se o audcontiver www.myfunwebapp.com, mas o aplicativo cliente tentar usar o JWT www.supersecretwebapp.com, o acesso será negado porque o servidor de recursos verá que o JWT não foi feito para ele.

Chris Swain
fonte
6
Parece que aud pode ser o client_id também. veja tools.ietf.org/id/draft-hunt-oauth-v2-user-a4c-01.txt aud REQUIRED for session_token. Contains the client_id of the client receiving the assertion.
themihai
1
O servidor de recursos não sabe para onde os clientes enviam o JWT. Como o servidor de recursos negará esse tráfego de seu aplicativo iOS para algum outro URL? Eu não acho que você está certo.
John Korsnes
Eu diria "Se o" aud "contiver" www.webapp.com ", mas o aplicativo cliente tenta usar o JWT em" secret.webapp.com ""
catanfetamina
2
A RFC diz que o público (aud) identifica os destinatários. Os destinatários recebem seus tokens JWT. Se você tiver um aplicativo da web, provavelmente pode ser contoso.com, mas se você tiver algum aplicativo de desktop ou móvel (que autentica), o público não tem nenhum URI. O emissor é quem gera os tokens JWT, então provavelmente o endereço do servidor. A RFC diz que o uso desta declaração é OPCIONAL, portanto, use-a apenas quando precisar.
Konrad
1
Na verdade, estou confuso sobre qual seria a diferença entre público e emissor.
Andy
62

A audreivindicação JWT (público)

De acordo com RFC 7519 :

A declaração "aud" (público) identifica os destinatários aos quais o JWT se destina. Cada diretor que pretende processar o JWT DEVE se identificar com um valor na reivindicação do público. Se o responsável pelo processamento da reclamação não se identificar com um valor na reclamação "aud" quando esta reclamação estiver presente, o JWT DEVE ser rejeitado. No caso geral, o valor "aud" é uma matriz de strings com distinção entre maiúsculas e minúsculas, cada uma contendo um valor StringOrURI. No caso especial em que o JWT tem um público, o valor "aud" PODE ser uma única string com distinção entre maiúsculas e minúsculas contendo um valor StringOrURI. A interpretação dos valores do público geralmente é específica da aplicação. O uso desta reivindicação é OPCIONAL.

A auddeclaração Audience ( ) conforme definida pela especificação é genérica e específica do aplicativo. O uso pretendido é identificar os destinatários pretendidos do token. O que um destinatário significa é específico do aplicativo. Um valor de público é uma lista de strings ou pode ser uma única string se houver apenas uma auddeclaração. O criador do token não impõe que audseja validado corretamente, a responsabilidade é do destinatário para determinar se o token deve ser usado.

Qualquer que seja o valor, quando um destinatário está validando o JWT e deseja validar que o token foi destinado a ser usado para seus fins, ele DEVE determinar qual valor em se audidentifica, e o token só deve validar se o ID declarado do destinatário for presente na audreivindicação. Não importa se este é um URL ou alguma outra string específica do aplicativo. Por exemplo, se meu sistema decidir se identificar audcom a string: api3.app.comentão, ele só deve aceitar o JWT se a auddeclaração contiver api3.app.comem sua lista de valores de público.

É claro que os destinatários podem escolher ignorar aud, portanto, isso só é útil se um destinatário quiser uma validação positiva de que o token foi criado especificamente para ele.

Minha interpretação com base na especificação é que a audafirmação é útil para criar JWTs construídos com um propósito que são válidos apenas para determinados fins. Para um sistema, isso pode significar que você deseja que um token seja válido para alguns recursos, mas não para outros. Você pode emitir tokens restritos a apenas um determinado "público", enquanto ainda usa as mesmas chaves e algoritmo de validação.

Como, no caso típico, um JWT é gerado por um serviço confiável e usado por outros sistemas confiáveis ​​(sistemas que não desejam usar tokens inválidos), esses sistemas simplesmente precisam coordenar os valores que usarão.

Claro, audé totalmente opcional e pode ser ignorado se seu caso de uso não justificar. Se você não quiser restringir o uso de tokens por públicos específicos, ou nenhum de seus sistemas realmente validará o audtoken, então ele é inútil.

Exemplo: tokens de acesso vs. atualização

Um exemplo inventado (mas simples) em que posso pensar é talvez queiramos usar JWTs para acessar e atualizar tokens sem ter que implementar chaves de criptografia e algoritmos separados, mas simplesmente querer garantir que os tokens de acesso não sejam validados como tokens de atualização ou vice-versa -versa.

Ao usar aud, podemos especificar uma reivindicação de refreshtokens de atualização e uma reivindicação de accesstokens de acesso ao criar esses tokens. Quando uma solicitação é feita para obter um novo token de acesso de um token de atualização, precisamos validar se o token de atualização era um token de atualização genuíno. A audvalidação conforme descrito acima nos dirá se o token era realmente um token de atualização válido, procurando especificamente por uma declaração de refreshem aud.

ID do cliente OAuth x audreivindicação JWT

O ID do cliente OAuth não está relacionado e não tem correlação direta com as auddeclarações do JWT . Da perspectiva do OAuth, os tokens são objetos opacos.

O aplicativo que aceita esses tokens é responsável por analisar e validar o significado desses tokens. Não vejo muito valor em especificar o ID do cliente OAuth em uma auddeclaração JWT .

Kekoa
fonte
3
Estou meio confuso com a parte "deve se identificar". A RFC7519 está cheia de bits inexplicáveis ​​como esse, junto com vagas alusões a outros sistemas de autenticação, que é provavelmente onde a interpretação adequada dos campos de declaração padrão pode ser encontrada. Francamente, a RFC, por mais útil que seja, nunca deveria ter saído do estágio de rascunho em tal estado.
Chuck Adams
1
@ChuckAdams eu editei para esclarecer meus pensamentos. Concordo que a RFC é muito vaga, especialmente em relação às "declarações padrão" e como / quando usá-las.
Kekoa
2
Atualmente, temos a mesma discussão sobre como usar o campo aud e concordo que ele deve conter o destinatário (aquele que valida e aceita o token) e não o client_id (aquele que solicitou a ação do token nome do usuário).
hardysim
4

Se você veio aqui pesquisando OpenID Connect (OIDC): OAuth 2.0! = OIDC

Eu reconheço que isso é marcado para oauth 2.0 e NÃO OIDC, no entanto, há frequentemente uma conflação entre os 2 padrões, pois ambos os padrões podem usar JWTs e a auddeclaração. E um (OIDC) é basicamente uma extensão do outro (OAUTH 2.0). (Eu mesmo encontrei esta questão procurando o OIDC.)

Tokens de acesso OAuth 2.0 ##

Para tokens de acesso OAuth 2.0 , as respostas existentes cobrem muito bem. Além disso, aqui está uma seção relevante do OAuth 2.0 Framework (RFC 6749)

Para clientes públicos que usam fluxos implícitos, esta especificação não fornece nenhum método para o cliente determinar para qual cliente um token de acesso foi emitido.
...
Autenticar proprietários de recursos para clientes está fora do escopo desta especificação. Qualquer especificação que use o processo de autorização como uma forma de autenticação delegada do usuário final ao cliente (por exemplo, serviço de login de terceiros) NÃO DEVE usar o fluxo implícito sem mecanismos de segurança adicionais que permitiriam ao cliente determinar se o acesso token foi emitido para seu uso (por exemplo, restrição de público do token de acesso).

Tokens de ID OIDC ##

O OIDC tem tokens de ID além de tokens de acesso. A especificação OIDC é explícita no uso da auddeclaração em tokens de ID. ( openid-connect-core-1.0 )

aud
REQUIRED. Público (s) a que este token de ID se destina. Ele DEVE conter o client_id OAuth 2.0 da Parte Confiante como um valor de público. PODE conter também identificadores para outros públicos. No caso geral, o valor aud é uma matriz de strings com distinção entre maiúsculas e minúsculas. No caso especial comum quando há um público, o valor aud PODE ser uma string com distinção entre maiúsculas e minúsculas.

além disso, OIDC especifica a azpdeclaração que é usada em conjunto com audquando audtem mais de um valor.

azp
OPCIONAL. Parte autorizada - a parte para a qual o token de identificação foi emitido. Se estiver presente, DEVE conter o ID do cliente OAuth 2.0 dessa parte. Esta reivindicação só é necessária quando o token de ID tem um único valor de público e esse público é diferente da parte autorizada. PODE ser incluído mesmo quando a parte autorizada é o mesmo público único. O valor azp é uma string com distinção entre maiúsculas e minúsculas que contém um valor StringOrURI.

Joseph A
fonte
1
Apenas para observar uma coisa: Oauth2 não força o uso de JWT.
Zoran
1

Embora seja antigo, acho que a pergunta é válida até hoje

Minha suspeita é que aud deve se referir ao (s) servidor (es) de recursos e o client_id deve referir-se a um dos aplicativos cliente reconhecidos pelo servidor de autenticação

Sim, aud deve se referir à parte consumidora do token. E client_id refere-se à parte que obtém o token.

No meu caso atual, meu servidor de recursos também é meu cliente de aplicativo da web.

No cenário do OP, o aplicativo da web e o servidor de recursos pertencem à mesma parte. Portanto, isso significa que o cliente e o público são iguais. Mas pode haver situações em que esse não seja o caso.

Pense em um SPA que consome um recurso protegido OAuth. Nesse cenário, o SPA é o cliente. O recurso protegido é o público do token de acesso.

Este segundo cenário é interessante. Existe um rascunho de trabalho denominado " Indicadores de recursos para OAuth 2.0 " que explica onde você pode definir o público-alvo em sua solicitação de autorização. Portanto, o token resultante será restrito ao público especificado. Além disso, o Azure OIDC usa uma abordagem semelhante em que permite o registro de recursos e permite que a solicitação de autenticação contenha o parâmetro de recurso para definir o público-alvo do token de acesso. Esses mecanismos permitem que as adpotações OAuth tenham uma separação entre o cliente e a parte consumidora do token (público).

Kavindu Dodanduwa
fonte