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.
Antes de começares aqui, certifica-te de que compreendes como inicializar o objeto da aplicação.
As APIs de início de sessão no MSAL obtêm um authorization code, que pode ser trocado por um token de ID para um utilizador com sessão iniciada, ao mesmo tempo que obtêm os âmbitos consentidos para um recurso adicional e um token de acesso que contém os âmbitos consentidos pelo utilizador para permitir que a sua aplicação chame a API em segurança.
Escolha de um Tipo de Interação
Veja aqui se tiver dúvidas sobre as diferenças entre loginRedirect e loginPopup.
Iniciar sessão com o utilizador
Tem de passar um objeto de pedido para as APIs de início de sessão. Este objeto permite-lhe usar diferentes parâmetros no pedido. Veja aqui para mais informações sobre os parâmetros do objeto de pedido.
Para pedidos de login, todos os parâmetros são opcionais, por isso podes simplesmente enviar um objeto vazio.
- Popup
try {
const loginResponse = await msalInstance.loginPopup({});
} catch (err) {
// handle error
}
- Redirect
try {
msalInstance.loginRedirect({});
} catch (err) {
// handle error
}
Ou pode enviar um conjunto de endoscopos para pré-consentir a:
- Popup
var loginRequest = {
scopes: ["user.read", "mail.send"] // optional Array<string>
};
try {
const loginResponse = await msalInstance.loginPopup(loginRequest);
} catch (err) {
// handle error
}
- Redirect
var loginRequest = {
scopes: ["user.read", "mail.send"] // optional Array<string>
};
try {
msalInstance.loginRedirect(loginRequest);
} catch (err) {
// handle error
}
APIs de contas
Quando uma chamada de início de sessão for bem-sucedida, pode usar a função getAllAccounts() para obter informações sobre os utilizadores atualmente com sessão iniciada.
const myAccounts: AccountInfo[] = msalInstance.getAllAccounts();
Se souber a informação da conta, também pode recuperá-la usando a getAccount() API:
const username = "test@contoso.com";
const myAccount: AccountInfo = msalInstance.getAccount({ username });
const homeAccountId = "userid.hometenantid"; // Best to retrieve the homeAccountId from an account object previously obtained through msal
const myAccount: AccountInfo = msalInstance.getAccount({ homeAccountId });
Note
Filtrar por username é fornecido por conveniência e deve ser considerado menos fiável do que pesquisar com base em homeAccountId. Sempre que possível, utilize homeAccountId.
Em cenários B2C, o seu tenant B2C tem de ser configurado para devolver a declaração emails em idTokens, para poder utilizar o filtro username na API getAccount().
Estas APIs devolverão um objeto de conta ou um array de objetos de conta com a seguinte assinatura:
{
// home account identifier for this account object
homeAccountId: string;
// Entity who issued the token represented as a full host of it (e.g. login.microsoftonline.com)
environment: string;
// Full tenant or organizational id that this account belongs to
tenantId: string;
// preferred_username claim of the id_token that represents this account.
username: string;
};
Login silencioso com ssoSilent()
Se já tiver uma sessão existente com o servidor de autenticação, pode usar a API ssoSilent() para fazer pedidos de tokens sem interação.
Com sugestão do utilizador
Se já tiver a informação de login do utilizador, pode enviá-la para a API para melhorar o desempenho e garantir que o servidor de autorização procurará a sessão correta da conta. Pode passar um dos seguintes elementos no objeto de pedido para obter um token de forma silenciosa com êxito.
Recomenda-se tirar partido da declaração opcional do token de IDlogin_hint (fornecida a ssoSilent como loginHint), pois é a indicação de conta mais fiável para pedidos silenciosos (e interativos).
-
account(que pode ser recuperado usando uma das APIs da conta) -
sid(que pode ser recuperado a partir deidTokenClaimsde um objetoaccount) -
login_hint(pode ser recuperado das seguintes formas)- Como propriedade do
loginHintobjeto da conta (recomendado) - Como a declaração do token de ID do objeto de conta
login_hint(recomendado) - Como propriedade do
usernameobjeto da conta (não recomendado) - Como a reivindicação do ID token do
upnobjeto da conta (não recomendado)
- Como propriedade do
Note
As propriedades username e upn têm suporte parcial em vez da afirmação login_hint propriamente dita, mas não são recomendadas. Utilize as propriedades da conta loginHint ou idTokenClaims.login_hint, se estiverem disponíveis.
Ao passar uma conta, será procurada a declaração opcional do token de ID login_hint (preferencialmente), depois a declaração opcional do token de id sid, recorrendo-se depois a loginHint (se fornecido) ou ao nome de utilizador da conta.
const account = msalInstance.getAllAccounts()[0];
const silentRequest = {
scopes: ["User.Read", "Mail.Read"],
loginHint: account.loginHint, // alternatively, account.idTokenClaims.login_hint
};
try {
const loginResponse = await msalInstance.ssoSilent(silentRequest);
} catch (err) {
if (err instanceof InteractionRequiredAuthError) {
const loginResponse = await msalInstance.loginPopup(silentRequest).catch(error => {
// handle error
});
} else {
// handle error
}
}
Sem Dica do Utilizador
Se não houver informação suficiente disponível sobre o utilizador, pode tentar usar a ssoSilent API sem passar um account, sid ou login_hint.
const silentRequest = {
scopes: ["User.Read", "Mail.Read"]
};
No entanto, tenha em atenção que, se a sua aplicação tiver caminhos de código para vários utilizadores numa única sessão de navegador, ou se o utilizador tiver várias contas para essa única sessão, então há uma maior probabilidade de erros de login silencioso. Pode ver o seguinte erro aparecer no caso de várias sessões de conta serem encontradas pelo servidor de autorização:
InteractionRequiredAuthError: interaction_required: AADSTS16000: Either multiple user identities are available for the current request or selected account is not supported for the scenario.
Isto indica que o servidor não conseguiu determinar em que conta iniciar sessão, e será necessário um dos parâmetros acima (account, login_hint, sid) ou um login interativo para escolher a conta.
Warning
Ao usar ssoSilent, o serviço tenta carregar a sua página de URI de redirecionamento num iframe invisível embutido. As políticas de segurança de conteúdo e os valores de cabeçalho HTTP presentes na resposta da página URI de redirecionamento da sua aplicação, como X-FRAME-OPTIONS: DENY e X-FRAME-OPTIONS: SAMEORIGIN, podem impedir que a sua aplicação carregue no iframe, bloqueando efetivamente o SSO silencioso. Se pretende usar ssoSilent, certifique-se de que o URI de redirecionamento aponta para uma página que não implemente tais políticas.
Considerações sobre RedirectUri
Todos os fluxos de autenticação agora requerem uma página dedicada de redirecionamento que implementa a ponte de redirecionamento MSAL. Isto é necessário para suportar cabeçalhos COOP (Cross-Origin-Opener-Policy) e permitir uma comunicação segura entre janelas popup/iframe e a aplicação principal.
Configuração da página de redirecionamento
O teu redirectUri deve apontar para uma página dedicada que carregue o script de ponte de redirecionamento. Esta página deve:
- Carregue o script de ponte de redirecionamento - Este script gere a comunicação com a janela principal
- Não incluir JavaScript exceto o script bridge - A página de redirecionamento só deve correr o script bridge
- Não incluir lógica de encaminhamento - Evite bibliotecas de routers que possam interferir com o tratamento do hash
- Esteja registado no seu Registo de Aplicações - O URI deve corresponder exatamente ao que está registado no portal do Azure
Exemplo de página de redirecionamento (quando se usa um bundler como Vite ou Webpack):
<!DOCTYPE html>
<html>
<head>
<title>Redirect</title>
</head>
<body>
<p>Processing authentication...</p>
<script type="module">
import { broadcastResponseToMainFrame } from "@azure/msal-browser/redirect-bridge";
broadcastResponseToMainFrame();
</script>
</body>
</html>
Note
O @azure/msal-browser/redirect-bridge especificador deve ser resolvido por um bundler (Vite, Webpack, etc.) — não é um URL que os navegadores possam obter diretamente. Para instruções específicas do framework, consulte o guia de configuração da Redirect Bridge.
Configuração
Pode definir o/a redirectUri globalmente na sua configuração do MSAL ou para cada pedido:
Configuração global:
const msalConfig = {
auth: {
clientId: "your-client-id",
authority: "https://login.microsoftonline.com/common",
redirectUri: "http://localhost:3000/redirect"
}
};
const msalInstance = new PublicClientApplication(msalConfig);
Configuração por pedido:
msalInstance.loginPopup({
scopes: ["user.read"],
redirectUri: "http://localhost:3000/redirect"
});
Para mais informações e implementações completas de exemplo, veja:
Gestão de erros de popup interaction_in_progress
Para fluxos pop-up, podes usar a overrideInteractionInProgress flag para cancelar uma interação pendente e começar uma nova. Isto é útil em cenários de recuperação onde o utilizador cancelou um pop-up ou uma interação falhou.
Note
Esta funcionalidade está disponível apenas para fluxos pop-up e não é suportada para fluxos de redirecionamento. Com o cabeçalho COOP (Cross-Origin-Opener-Policy), a ligação tradicional window.opener é interrompida, permitindo que as janelas pop-up comuniquem com o frame principal apenas através de BroadcastChannel.
Importante
Definir isto como true cancelará forçosamente qualquer pedido pendente de autenticação em janela emergente, mas não fechará nenhuma janela emergente aberta.
Quando definido para true:
- Se outra interação de popup estiver atualmente em curso, é cancelada à força, mas os popups abertos não são fechados
- A interação pendente falha com um erro
interaction_in_progress_cancelled - O novo fluxo popup avança imediatamente
Casos de uso válidos:
- Recuperar de erros em que o utilizador cancelava um popup (o popup era fechado sem completar a autenticação)
- Implementação de fluxos personalizados de recuperação de erros
- Fornecer um mecanismo de "retentativa" após uma interação popup falhada
Predefinição:false
Importante: Usar apenas ao clicar no botão
Não tentes novamente automaticamente quando detetares um interaction_in_progress erro. A substituição só deve ser desencadeada por uma ação explícita do utilizador (como clicar num botão "Tentar novamente"). A anulação automática de interações pode levar a:
- Condições de corrida entre múltiplos fluxos de autenticação
- Cancelamentos inesperados de tentativas legítimas de autenticação
- Fraca experiência de utilizador com fluxos de autenticação a começar e parar inesperadamente
- Muitos pop-ups abertos que não resultam em respostas de autenticação com êxito
Exemplo: Tratamento correto de erros com nova tentativa iniciada pelo utilizador
Para implementações completas com feedback visual, veja:
- Express Sample — Demonstra implementação JavaScript com CSS personalizado
- Exemplo de Router React — Demonstra implementação do React com componentes Material-UI
Ambos os exemplos demonstram:
- Mensagem de aviso apresentada durante a autenticação numa janela de pop-up
- Repetição da janela modal/caixa de diálogo com explicação clara quando ocorrer o erro
interaction_in_progress - Gestão adequada do estado para nova tentativa iniciada pelo utilizador
- Componentes de interface de utilizador prontos para produção
// State to track if user wants to retry
let userWantsRetry = false;
// Button click handler
async function handleLoginClick() {
try {
const loginRequest = {
scopes: ["user.read"]
};
// If user explicitly clicked retry, override the existing interaction
if (userWantsRetry) {
loginRequest.overrideInteractionInProgress = true;
userWantsRetry = false; // Reset flag
}
const response = await msalInstance.loginPopup(loginRequest);
// Handle successful login
} catch (error) {
if (error.errorCode === 'interaction_in_progress') {
// Show retry button to user - DO NOT automatically retry
showRetryButton();
} else {
// Handle other errors
console.error(error);
}
}
}
// Retry button click handler
function handleRetryClick() {
userWantsRetry = true; // Set flag for next login attempt
handleLoginClick(); // User explicitly requested retry
}
Exemplo: componente React com nova tentativa acionada pelo utilizador
function LoginButton() {
const { instance } = useMsal();
const [showRetry, setShowRetry] = useState(false);
const [retryRequested, setRetryRequested] = useState(false);
const handleLogin = async () => {
try {
const loginRequest = {
scopes: ["user.read"],
// Only override if user clicked the retry button
overrideInteractionInProgress: retryRequested
};
setRetryRequested(false); // Reset retry flag
const response = await instance.loginPopup(loginRequest);
setShowRetry(false);
} catch (error) {
if (error.errorCode === 'interaction_in_progress') {
// Show retry button - let user decide whether to retry
setShowRetry(true);
} else {
console.error(error);
}
}
};
const handleRetry = () => {
setRetryRequested(true); // User explicitly requested retry
handleLogin();
};
return (
<div>
<button onClick={handleLogin}>Login</button>
{showRetry && (
<button onClick={handleRetry}>
Retry Login (Cancel Pending)
</button>
)}
</div>
);
}
Próximas Etapas
Aprenda a adquirir e usar um token de acesso!