Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
O MSAL Angular fornece uma classe Interceptor que adquire automaticamente tokens para pedidos enviados que utilizam o cliente Angular http para recursos protegidos conhecidos. Este documento fornece mais informações sobre a configuração e utilização do MsalInterceptor.
Embora recomendemos usar diretamente a MsalInterceptor API em vez da acquireTokenSilent API, por favor note que a utilização MsalInterceptor é opcional. Poderá preferir adquirir tokens explicitamente através das APIs acquireToken em vez disso.
Note que o MsalInterceptor é fornecido para sua comodidade e poderá não se adequar a todos os casos de uso. Encorajamo-lo a escrever o seu próprio interceptor se tiver necessidades específicas que não sejam abordadas pelo MsalInterceptor.
Configuração
Configuração do MsalInterceptor em app.module.ts
O MsalInterceptor pode ser adicionado à sua aplicação como provedor no ficheiro app.module.ts, juntamente com a respetiva configuração. A importação inclui uma instância de MSAL, bem como dois objetos de configuração específicos do Angular. O terceiro argumento é um MsalInterceptorConfiguration objeto, que contém os valores para interactionType, a protectedResourceMap, e um opcional authRequest.
A sua configuração pode parecer a que está abaixo. Consulte o nosso documento de configuração sobre outras formas de configurar o MSAL Angular para a sua aplicação.
import { NgModule } from '@angular/core';
import { HTTP_INTERCEPTORS, HttpClientModule } from "@angular/common/http";
import { AppComponent } from './app.component';
import { MsalModule, MsalRedirectComponent, MsalGuard, MsalInterceptor } from '@azure/msal-angular'; // Import MsalInterceptor
import { InteractionType, PublicClientApplication } from '@azure/msal-browser';
@NgModule({
declarations: [
AppComponent,
],
imports: [
MsalModule.forRoot( new PublicClientApplication({
// MSAL Configuration
}), {
// MSAL Guard Configuration
}, {
// MSAL Interceptor Configurations
interactionType: InteractionType.Redirect,
protectedResourceMap: new Map([
['Enter_the_Graph_Endpoint_Here/v1.0/me', ['user.read']]
])
})
],
providers: [
{
provide: HTTP_INTERCEPTORS, // Provides as HTTP Interceptor
useClass: MsalInterceptor,
multi: true
},
MsalGuard
],
bootstrap: [AppComponent, MsalRedirectComponent]
})
export class AppModule { }
Tipo de Interação
Embora o MsalInterceptor tenha sido concebido para obter tokens silenciosamente, se um pedido silencioso falhar, recorrerá à obtenção interativa de tokens. Podem InteractionType ser importados de @azure/msal-browser e definidos para Popup ou Redirect.
{
interactionType: InteractionType.Redirect,
protectedResourceMap: new Map([
['Enter_the_Graph_Endpoint_Here/v1.0/me', ['user.read']]
])
}
Mapa de Recursos Protegidos
Os recursos protegidos e os respetivos escopos são fornecidos como a protectedResourceMap na MsalInterceptor configuração.
Os URL que fornece na coleção protectedResourceMap fazem distinção entre maiúsculas e minúsculas. Para cada recurso, adicione os âmbitos pedidos para serem incluídos no token de acesso.
Por exemplo:
-
["user.read"]para Microsoft Graph -
["<Application ID URL>/scope"]para APIs web personalizadas (isto é,api://<Application ID>/access_as_user)
Os escopos podem ser especificados para um recurso das seguintes formas:
- Um conjunto de âmbitos que será adicionado a cada pedido HTTP para esse recurso, independentemente do método HTTP utilizado.
{
interactionType: InteractionType.Redirect,
protectedResourceMap: new Map<string, Array<string> | null>([
["https://graph.microsoft.com/v1.0/me", ["user.read", "profile"]],
["https://myapplication.com/user/*", ["customscope.read"]]
]),
}
- Um array de
ProtectedResourceScopes, que associará âmbitos apenas a métodos HTTP específicos.
{
interactionType: InteractionType.Redirect,
protectedResourceMap: new Map<string, Array<string|ProtectedResourceScopes> | null>([
["https://graph.microsoft.com/v1.0/me", ["user.read"]],
["http://myapplication.com", [
{
httpMethod: "POST",
scopes: ["write.scope"]
}
]]
])
}
Note-se que os escopos de um recurso podem conter uma combinação de cadeias e ProtectedResourceScopes. No exemplo abaixo, um GET pedido terá os escopos "all.scope" e "read.scope", ao passo que um PUT pedido terá apenas "all.scope".
{
interactionType: InteractionType.Redirect,
protectedResourceMap: new Map<string, Array<string|ProtectedResourceScopes> | null>([
["http://myapplication.com", [
"all.scope",
{
httpMethod: "GET",
scopes: ["read.scope"]
},
{
httpMethod: "POST",
scopes: ["info.scope"]
}
]]
])
}
- Um valor de âmbito de
null, indica que um recurso deve ser desprotegido e não receberá tokens. Recursos não incluídos noprotectedResourceMapnão estão protegidos por defeito. Especificar um determinado recurso como desprotegido pode ser útil quando algumas rotas de um recurso devem ser protegidas e outras não. Note que a ordem emprotectedResourceMapimporta, por isso o recurso nulo deve ser colocado antes de quaisquer URLs de base ou curingas semelhantes.
{
interactionType: InteractionType.Redirect,
protectedResourceMap: new Map<string, Array<string> | null>([
["https://graph.microsoft.com/v1.0/me", ["user.read", "profile"]],
["https://myapplication.com/unprotected", null],
["https://myapplication.com/unprotected/post", [{ httpMethod: 'POST', scopes: null }]],
["https://myapplication.com", ["custom.scope"]]
]),
}
Outras coisas a notar relativamente ao protectedResourceMap:
-
Wildcards:
protectedResourceMapsuporta o uso*para wildcards. Ao usar curingas, se forem encontradas várias entradas coincidentes noprotectedResourceMap, será utilizada a primeira correspondência encontrada (com base na ordem doprotectedResourceMap). -
Caminhos relativos: Se existirem caminhos relativos de recursos na sua aplicação, pode ser necessário fornecer o caminho relativo no
protectedResourceMap. Isto aplica-se também a questões que possam surgir com o ngx-translate. Tenha em atenção que o caminho relativo na suaprotectedResourceMappode ou não precisar de uma barra à esquerda, dependendo da sua aplicação, e poderá ser necessário testar ambas as opções.
Correspondência exata (strictMatching)
No msal-angular v5, a correspondência de padrões de componentes de URL para entradas protectedResourceMap utiliza, por predefinição, semântica de correspondência estrita. O strictMatching campo em MsalInterceptorConfiguration controla este comportamento.
Importante
Se a sua aplicação define dinamicamente as chaves protectedResourceMap (por exemplo, a partir de ficheiros de ambiente, APP_INITIALIZER ou configuração JSON) e essas chaves forem URLs base sem subcaminhos nem carateres universais, a correspondência exata pode impedir silenciosamente que o cabeçalho Authorization seja anexado. Isto resulta em erros 401 sem qualquer erro em tempo de compilação e sem aviso em cada pedido — apenas um único aviso durante a inicialização, se strictMatching não estiver explicitamente configurado. Consulte Resolução de problemas de correspondência estrita para detalhes.
O que muda na correspondência exata
| Comportamento | Legado (strictMatching: false) |
Estrito (padrão na versão 5) |
|---|---|---|
| Metapersonagem a escapar |
. e outros metacaracteres regex não são escapados; atuam como operadores regex |
Todos os metacaracteres (incluindo .) são tratados como literais |
| A ancorar | O padrão pode coincidir em qualquer parte da corda | O padrão deve corresponder à corda completa (^…$) |
Carácter universal do anfitrião (*) |
* corresponde a qualquer sequência de personagens, incluindo . |
* corresponde a qualquer sequência de caracteres que não inclua . (os curingas ficam dentro de um único rótulo DNS) |
Curinga de caminho/pesquisa/hash (*) |
* corresponde a qualquer sequência de caracteres |
* corresponde a qualquer sequência de caracteres (inalterada) |
? Personagem |
Transmitido para o regex subjacente | Tratado como literal? (separador da cadeia de consulta do URL, não um coringa) |
Com correspondência estrita (o padrão da v5):
- Um padrão como
*.contoso.comcorresponde,app.contoso.commas nãoa.b.contoso.com(o coringa não pode abranger separadores de pontos). - Um padrão como
https://graph.microsoft.com/v1.0/mecorresponde apenas a esse URL exato.
Padrões de falha comuns
Os seguintes protectedResourceMap padrões de chave funcionam com a correspondência legada, mas falham silenciosamente com a correspondência estrita:
| Padrão de teclas | URL da solicitação de saída | Resultado com correspondência estrita | Corrigir |
|---|---|---|---|
https://api.example.com |
https://api.example.com/v1/users |
Sem correspondência — a chave é resolvida para o caminho /, a requisição tem o caminho /v1/users |
https://api.example.com/* |
https://api.example.com/ |
https://api.example.com/v1/users |
Sem correspondência — a barra final faz com que o padrão corresponda exatamente a / |
https://api.example.com/* |
environment.apiConfig.uri (por exemplo, https://api.example.com) |
https://api.example.com/v1/users |
Sem correspondência — igual ao anterior | `${environment.apiConfig.uri}/*` |
Comportamento padrão na v5 (sem necessidade de configuração)
A correspondência estrita está ativada por defeito. Não é necessária configuração adicional:
{
interactionType: InteractionType.Redirect,
protectedResourceMap: new Map([
["https://*.contoso.com/api", ["contoso.scope"]],
["https://graph.microsoft.com/v1.0/me", ["user.read"]]
])
// strictMatching defaults to true in v5
}
Optar por não fazer correspondência de legado
Se os seus padrões dependerem da correspondência menos restritiva da versão 4, pode definir strictMatching: false para manter temporariamente o comportamento legado:
Note
A correspondência antiga (strictMatching: false) é disponibilizada para retrocompatibilidade e poderá ser removida numa futura versão principal. Recomendamos atualizar os seus protectedResourceMap padrões para funcionarem com correspondência exata.
{
interactionType: InteractionType.Redirect,
protectedResourceMap: new Map([
["https://*.contoso.com/api", ["contoso.scope"]],
["https://graph.microsoft.com/v1.0/me", ["user.read"]]
]),
strictMatching: false // Use legacy matching for backwards compatibility
}
Orientação para configurações orientadas pelo ambiente
Se as suas protectedResourceMap chaves referenciam valores angulares environment (por exemplo, environment.apiConfig.uri), verifique se esses valores são caminhos exatos (por exemplo, https://graph.microsoft.com/v1.0/me) ou URLs base simples (por exemplo, https://api.example.com). Os caminhos exatos funcionam corretamente com correspondência exata e não precisam de tratamento especial:
export function MSALInterceptorConfigFactory(): MsalInterceptorConfiguration {
const protectedResourceMap = new Map<string, Array<string>>();
// environment.apiConfig.uri is an exact path (e.g. "https://graph.microsoft.com/v1.0/me")
// — strict matching works correctly
protectedResourceMap.set(environment.apiConfig.uri, environment.apiConfig.scopes);
return {
interactionType: InteractionType.Redirect,
protectedResourceMap,
};
}
Se o valor da variável de ambiente for uma URL de base simples e precisares de fazer corresponder subcaminhos, acrescenta um carácter universal /*:
// environment.apiConfig.uri is a base URL (e.g. "https://api.example.com")
// Append /* to match all sub-paths
protectedResourceMap.set(`${environment.apiConfig.uri}/*`, environment.apiConfig.scopes);
Para configurações verdadeiramente dinâmicas onde a forma da chave não é conhecida em tempo de compilação (por exemplo, APP_INITIALIZER, JSON carregado via fetch, ou platformBrowserDynamic), define strictMatching: false como um padrão temporário seguro.
Veja Opções de correção—Opção B para um exemplo de código.
Resolução de problemas de correspondência estrita
Sintomas
- Os pedidos de API retornam 401 Não autorizado após a atualização para
@azure/msal-angulara v5 (ou entre versões menores da v5, como 5.0.x → 5.1.x). - O
Authorization: Bearer <token>cabeçalho está ausente nos pedidos HTTP enviados. - Não são reportados erros em tempo de construção ou de execução — a falha é silenciosa.
- O problema pode aparecer apenas em certos ambientes (por exemplo, staging/produção) onde a URL base da API difere do desenvolvimento.
Opções de correção
Opção A: Atualizar as chaves para funcionar com correspondência rigorosa (recomendado)
Atualize as suas protectedResourceMap chaves para usar caminhos exatos ou curingas que coincidam sob regras rigorosas de correspondência. Esta abordagem é preferida porque o emparelhamento rigoroso é mais seguro e previsível:
{
interactionType: InteractionType.Redirect,
protectedResourceMap: new Map([
// Exact path — matches only this URL
["https://graph.microsoft.com/v1.0/me", ["user.read"]],
// Wildcard — matches all sub-paths of the API
["https://api.example.com/v1/*", ["api.scope"]]
])
// strictMatching defaults to true — no need to set it
}
Opção B: Definir strictMatching: false (alternativa para configurações dinâmicas)
Se as tuas chaves protectedResourceMap forem carregadas dinamicamente em tempo de execução (por exemplo, a partir de APP_INITIALIZER, configuração JSON ou platformBrowserDynamic) e não puderes garantir que contêm caminhos exatos ou carateres universais, define strictMatching: false como valor predefinido temporário seguro:
{
interactionType: InteractionType.Redirect,
protectedResourceMap: new Map([
[config.apiUri, config.apiScopes]
]),
// Dynamic keys may be base URLs without wildcards.
// Remove once keys are migrated to exact paths or wildcard patterns.
strictMatching: false
}
Note
A correspondência antiga (strictMatching: false) é fornecida para compatibilidade com versões anteriores e pode ser removida numa futura versão principal.
Aviso de tempo de execução
MsalInterceptor emite um aviso de execução único através do logger MSAL durante a inicialização quando strictMatching não está explicitamente configurado. Se vir este aviso, siga as opções de correção acima.
AuthRequest opcional
Para mais informações sobre o parâmetro opcional authRequest que pode ser definido em MsalInterceptorConfiguration, consulte a nossa documentação multi-inquilino aqui.
Alterações da versão 1 para a versão 2 do msal-angular
Note
O unprotectedResourceMap no MsalAngularConfiguration do MSAL Angular v1 foi descontinuado e já não funciona.
-
protectedResourceMapfoi movida para oMsalInterceptorConfigurationobjeto, e pode ser passada comoMap<string, Array<string|ProtectedResourceScopes>>.MsalAngularConfigurationfoi descontinuado e já não funciona. - Colocar o domínio raiz no
protectedResourceMappara proteger todas as rotas já não é suportado. Por favor, use a correspondência wildcard em vez disso.
Para mais informações sobre como configurar os telescópios, consulte as nossas Perguntas Frequentes.