Autenticação única com MSAL.js

O login único (SSO) proporciona uma experiência mais fluida ao reduzir o número de vezes que um utilizador é solicitado para obter credenciais. Os utilizadores inserem as suas credenciais uma vez, e a sessão estabelecida pode ser reutilizada por outras aplicações no mesmo dispositivo sem necessidade de mais solicitações.

O Microsoft Entra ID ativa o SSO ao definir um cookie de sessão quando um utilizador se autentica pela primeira vez. MSAL.js também armazena em cache os ID tokens e os tokens de acesso do utilizador no armazenamento do navegador por domínio de aplicação. Os dois mecanismos, o cookie de sessão Microsoft Entra e a cache da Biblioteca de Autenticação da Microsoft (MSAL), são independentes entre si, mas funcionam em conjunto para fornecer comportamento SSO.

SSO entre separadores do navegador para a mesma aplicação

Quando um utilizador tem uma aplicação aberta em vários separadores e inicia sessão num deles, pode iniciar sessão na mesma aplicação aberta noutros separadores sem ser solicitado. Para isso, tem de definir cacheLocation no objeto de configuração do MSAL.js para localStorage, como mostrado no exemplo seguinte:

const config = {
  auth: {
    clientId: "1111-2222-3333-4444-55555555",
  },
  cache: {
    cacheLocation: "localStorage",
  },
};

const msalInstance = new msal.PublicClientApplication(config);

Neste caso, as instâncias da aplicação em diferentes separadores do navegador utilizam a mesma cache da MSAL, partilhando, assim, o estado de autenticação entre elas. Também pode usar eventos MSAL para atualizar instâncias de aplicação quando um utilizador faz login a partir de outro separador ou janela do navegador. Para mais informações, veja: Sincronização do estado logado entre separadores e janelas

SSO entre diferentes aplicações

Quando um utilizador se autentica, é definido um cookie de sessão no domínio Microsoft Entra no navegador. MSAL.js depende deste cookie de sessão para fornecer SSO ao utilizador entre diferentes aplicações. Em particular, MSAL.js oferece o método ssoSilent para iniciar sessão do utilizador e obter tokens sem qualquer interação. No entanto, se o utilizador tiver várias contas de utilizador numa sessão com o Microsoft Entra ID, é então solicitado a escolher uma conta para iniciar sessão. Assim, existem duas formas de obter SSO através do método ssoSilent.

Com sugestão do utilizador

Para melhorar o desempenho e garantir que o servidor de autorização procurará a sessão correta da conta, pode passar uma das seguintes opções no objeto de pedido do ssoSilent método para obter o token silenciosamente.

Recomendamos a utilização da login_hintdeclaração opcional do token de ID fornecida a ssoSilent como loginHint, pois é o indício de conta mais fiável para pedidos silenciosos e interativos.

Usar uma dica de login

A declaração opcional login_hint dá uma indicação ao Microsoft Entra ID sobre a conta de utilizador que está a tentar iniciar sessão. Para contornar o prompt de seleção de conta normalmente mostrado durante pedidos de autenticação interativos, forneça o loginHint seguinte:

const silentRequest = {
    scopes: ["User.Read", "Mail.Read"],
    loginHint: "user@contoso.com"
};

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
    }
}

Neste exemplo, loginHint contém o email ou UPN do utilizador, que é usado como dica durante pedidos interativos de tokens. A indicação pode ser transmitida entre aplicações para facilitar o SSO silencioso, em que a aplicação A pode iniciar a sessão de um utilizador, ler o loginHint, e depois enviar a declaração e o contexto atual do tenant à aplicação B. O Microsoft Entra ID tentará pré-preencher o formulário de início de sessão ou ignorar o pedido de seleção de conta e avançar diretamente para o processo de autenticação do utilizador especificado.

Se a informação na login_hint reclamação não corresponder a nenhum utilizador existente, são redirecionados para passar pela experiência padrão de login, incluindo a seleção da conta.

Utilização de um ID de sessão

Para usar um ID de sessão, adicione sid como uma reivindicação opcional aos tokens ID da sua aplicação. A sid reivindicação permite que uma aplicação identifique a sessão Microsoft Entra de um utilizador independentemente do nome da sua conta ou nome de utilizador. Para saber como adicionar reivindicações opcionais como sid, veja Fornecer reivindicações opcionais à sua aplicação. Utilize o ID de sessão (SID) nos pedidos de autenticação silenciosa que fizer com ssoSilent no MSAL.js.

const request = {
  scopes: ["user.read"],
  sid: sid,
};

 try {
    const loginResponse = await msalInstance.ssoSilent(request);
} catch (err) {
    if (err instanceof InteractionRequiredAuthError) {
        const loginResponse = await msalInstance.loginPopup(request).catch(error => {
            // handle error
        });
    } else {
        // handle error
    }
}

Utilizar um objeto de conta

Se souber as informações da conta de utilizador, também pode recuperar a conta de utilizador ao utilizar os métodos getAccountByUsername() ou getAccountByHomeId():

const username = "test@contoso.com";
const myAccount  = msalInstance.getAccountByUsername(username);

const request = {
    scopes: ["User.Read"],
    account: myAccount
};

try {
    const loginResponse = await msalInstance.ssoSilent(request);
} catch (err) {
    if (err instanceof InteractionRequiredAuthError) {
        const loginResponse = await msalInstance.loginPopup(request).catch(error => {
            // handle error
        });
    } else {
        // handle error
    }
}

Sem indicação do utilizador

Pode tentar usar o ssoSilent método sem passar nenhum account, sid ou login_hint como mostrado no seguinte código:

const request = {
    scopes: ["User.Read"]
};

try {
    const loginResponse = await msalInstance.ssoSilent(request);
} catch (err) {
    if (err instanceof InteractionRequiredAuthError) {
        const loginResponse = await msalInstance.loginPopup(request).catch(error => {
            // handle error
        });
    } else {
        // handle error
    }
}

No entanto, há probabilidade de erros de login silencioso se a aplicação tiver vários utilizadores numa única sessão de navegador ou se o utilizador tiver várias contas nessa mesma sessão. O seguinte erro pode ser apresentado se existirem várias contas disponíveis:

InteractionRequiredAuthError: interaction_required: AADSTS16000: Either multiple user identities are available for the current request or selected account is not supported for the scenario.

O erro indica que o servidor não conseguiu determinar em que conta deve iniciar sessão, e será necessário um dos parâmetros do exemplo anterior (account, login_hint, sid) ou um login interativo para escolher a conta.

Considerações ao utilizar ssoSilent

URI de redirecionamento (URL de resposta)

Para melhor desempenho e para evitar problemas, define-o redirectUri para uma página em branco ou outra página que não use MSAL.

  • Se os utilizadores da aplicação utilizarem apenas os métodos pop-up e silencioso, defina o redirectUri no objeto de configuração PublicClientApplication.
  • Se a aplicação também utilizar métodos de redirecionamento, defina a redirectUri para cada pedido.

Cookies de terceiros

ssoSilenttenta abrir um iframe oculto e reutilizar uma sessão existente com o Microsoft Entra ID. Isto não funciona em navegadores que bloqueiam cookies de terceiros como o Safari, e pode causar um erro de interação:

InteractionRequiredAuthError: login_required: AADSTS50058: A silent sign-in request was sent but no user is signed in. The cookies used to represent the user's session were not sent in the request to Azure AD

Para resolver o erro, o utilizador deve criar um pedido de autenticação interativa utilizando o loginPopup() ou loginRedirect(). Em alguns casos, o valor do prompt none pode ser usado em conjunto com um método de MSAL.js interativo para alcançar SSO. Consulte Solicitações interativas com prompt=none para mais informações. Se já tiver as informações de início de sessão do utilizador, pode passar o parâmetro opcional loginHint ou sid para iniciar sessão numa conta específica.

Desativar o SSO com prompt=login

Se preferir que o Microsoft Entra ID solicite ao utilizador que introduza as suas credenciais, apesar de existir uma sessão ativa com o servidor de autorização, pode utilizar o parâmetro login em pedidos com o MSAL.js. Veja o comportamento do pedido no MSAL.js para saber mais.

Partilha do estado de autenticação entre ADAL.js e MSAL.js

MSAL.js oferece paridade funcional com o ADAL.js nos cenários de autenticação do Microsoft Entra. Para facilitar a migração de ADAL.js para MSAL.js e partilhar o estado de autenticação entre aplicações, a biblioteca lê o ID token que representa a sessão do utilizador na cache ADAL.js. Para tirar partido disto ao migrar de ADAL.js, terá de garantir que as bibliotecas utilizam localStorage para a colocação em cache dos tokens. Defina o cacheLocation para localStorage tanto na configuração MSAL.js como na ADAL.js na inicialização da seguinte forma:


// In ADAL.js
window.config = {
  clientId: "1111-2222-3333-4444-55555555",
  cacheLocation: "localStorage",
};

var authContext = new AuthenticationContext(config);

// In latest MSAL.js version
const config = {
  auth: {
    clientId: "1111-2222-3333-4444-55555555",
  },
  cache: {
    cacheLocation: "localStorage",
  },
};

const msalInstance = new msal.PublicClientApplication(config);

Passos seguintes

Para mais informações sobre SSO, veja: