Tempo de Vida dos Tokens, Expiração e Renovação

Antes de começares aqui, certifica-te de que compreendes como iniciar sessão e adquirir tokens.

Ao usar MSAL.js, deve compreender as implicações de recuperar tokens para os utilizadores e como gerir a vida útil destes tokens.

Tempo de Vida dos Tokens e Expiração

Pode configurar a vida útil dos tokens de acesso, de ID ou de Security Assertion Markup Language (SAML) emitidos pela plataforma de identidades da Microsoft. Algumas das informações estão resumidas abaixo.

Tokens de Identificação

Os tokens ID estão vinculados a uma combinação específica de conta e cliente, e normalmente contêm informações de perfil sobre o utilizador. Normalmente, a duração da sessão de utilizador de uma aplicação web corresponde à duração da sessão do token ID, que por defeito é de 24 horas. Pode ler mais sobre como configurar a vida útil dos tokens.

Tokens de acesso

Os tokens de acesso no navegador têm uma expiração predefinida recomendada de 1 hora. Após esta 1 hora, quaisquer calls portadores com o token expirado serão rejeitados. Este token pode ser atualizado silenciosamente usando o token de atualização recuperado com este token. Pode ler mais sobre como configurar a vida útil dos tokens.

Atualizar tokens

Os tokens de atualização fornecidos às aplicações de página única são tokens de atualização com duração limitada (normalmente 24 horas a partir do momento em que são obtidos). Esta é uma janela não ajustável nem deslizante, para toda a vida. Sempre que um token de atualização é usado para renovar um token de acesso, um novo token de atualização é obtido juntamente com o token de acesso renovado. Este novo token de atualização terá uma vida útil igual à vida útil restante do token de atualização original. Uma vez que um token de atualização expira, deve ser iniciado um novo fluxo de código de autorização para recuperar um código de autorização e trocá-lo por um novo conjunto de tokens.

Nota: Quando é obtido um novo token de atualização, msal.js substitui o token de atualização em cache pelo novo token de atualização, no entanto, o token de atualização antigo não é invalidado pelo servidor e pode continuar a ser usado para obter tokens de acesso até à sua expiração.

Renovação do Token

O PublicClientApplication objeto expõe uma API chamada acquireTokenSilent que serve para recuperar tokens não expirados silenciosamente. Faz isto em alguns passos:

  1. Verifique se já existe um token na cache de tokens para os dados scopes, client id, authority, e/ou homeAccountIdentifier.
  2. Se existir um token para os parâmetros indicados, garanta que obtemos uma única correspondência e verifique a data de expiração.
  3. Se o token de acesso não estiver expirado, a MSAL devolverá uma resposta com os tokens relevantes.
  4. Se o token de acesso estiver expirado mas o token de atualização continuar válido, a MSAL usará o token de atualização para recuperar um novo conjunto de tokens e depois devolverá uma resposta.
  5. Se o token de atualização estiver expirado, a MSAL tentará recuperar um token de acesso silenciosamente usando um iframe oculto. Isto utilizará o sid ou o nome de utilizador no objeto de declarações da conta para obter uma indicação sobre a sessão do utilizador. Se esta chamada ao iframe oculto falhar, o MSAL propagará um erro do servidor como um InteractionRequiredAuthError, solicitando a obtenção de um código de autorização para obter um novo conjunto de tokens. Pode fazê-lo efetuando uma chamada à API de login ou acquireToken com o objeto PublicClientApplication. Se a sessão ainda estiver ativa, o servidor enviará um código sem qualquer indicação do utilizador. Caso contrário, o utilizador será obrigado a introduzir as suas credenciais.

Consulte o artigo sobre objetos de pedido e resposta para mais informações sobre os parâmetros de configuração que pode definir para o acquireTokenSilent método.

Evitar interrupções interativas no meio da sessão do utilizador

Em alguns casos, pode querer invocar a interação preventivamente, se necessário, no início da sessão do utilizador para garantir que ele pode continuar a adquirir tokens silenciosamente e usar a sua aplicação sem mais interrupções. Pode, naturalmente, conseguir isto invocando a interação sempre que a sua aplicação é carregada pela primeira vez; no entanto, isto proporciona uma má experiência de utilizador e tem pior desempenho quando o utilizador já tem tokens de uma sessão anterior ou de outra janela/separador. Em vez disso, com alguns parâmetros do pedido, pode usar acquireTokenSilent para garantir que a cache tem os tokens necessários disponíveis para serem devolvidos silenciosamente durante um período de tempo arbitrário.

Para garantir que acquireTokenSilent pode devolver tokens válidos durante, pelo menos, 1 hora:

  • Chame acquireTokenSilent ao carregar a página com o parâmetro de pedido forceRefresh definido como true. Isto irá saltar a cache e adquirir um token novo, que poderá ser servido a partir da cache em chamadas subsequentes.
  • Em chamadas subsequentes, deixa forceRefresh sem definir ou explicitamente false para garantir que os tokens podem ser servidos a partir da cache

Para garantir que acquireTokenSilent pode devolver tokens válidos durante um período mínimo de tempo até 24 horas:

  • Chame acquireTokenSilent ao carregar a página com o parâmetro do pedido forceRefresh definido como true & o parâmetro refreshTokenExpirationOffsetSeconds definido para o período de tempo pretendido (em segundos) sem interação
  • Nas chamadas seguintes, deixe forceRefresh e refreshTokenExpirationOffsetSeconds por definir para garantir que os tokens possam ser fornecidos a partir da cache

Por exemplo, se quiser garantir que o utilizador pode adquirir tokens silenciosamente durante as próximas 2 horas:

var request = {
    scopes: ["Mail.Read"],
    account: currentAccount,
    forceRefresh: true,
    refreshTokenExpirationOffsetSeconds: 7200 // 2 hours * 60 minutes * 60 seconds = 7200 seconds
};

const tokenResponse = await msalInstance.acquireTokenSilent(request).catch(async (error) => {
    if (error instanceof InteractionRequiredAuthError) {
        // fallback to interaction when silent call fails
        await msalInstance.acquireTokenRedirect(request);
    }
});

Nota: Nunca há garantia de que um token possa ser adquirido silenciosamente, mesmo que o token de atualização ainda não tenha expirado. Os padrões descritos acima são tentativas de melhor esforço para minimizar a interação em momentos inconvenientes, mas não eliminam a possibilidade de interações necessárias dentro dos prazos desejados. Além disso, nem todos os fornecedores de identidade devolvem a expiração do token de atualização – nesses casos, o refreshTokenExpirationOffsetSeconds parâmetro de pedido não será avaliado.

Política de Pesquisa de Cache

Uma Política de Pesquisa de Cache pode ser fornecida opcionalmente ao pedido. As Políticas de Pesquisa de Cache são:

  • CacheLookupPolicy.Default - acquireTokenSilent Tentará recuperar um token de acesso da cache. Se o token de acesso estiver expirado ou não puder ser encontrado, o token de atualização será usado para adquirir um novo. Finalmente, se o token de atualização estiver expirado, acquireTokenSilent tentará adquirir silenciosamente um novo token de acesso, token id e token de atualização.
  • CacheLookupPolicy.AccessToken - acquireTokenSilent Só vou procurar tokens de acesso na cache. Não tentará renovar o acesso nem atualizar tokens.
  • CacheLookupPolicy.AccessTokenAndRefreshToken - acquireTokenSilent Tentará recuperar um token de acesso da cache. Se o token de acesso estiver expirado ou não puder ser encontrado, o token de atualização será usado para adquirir um novo. Se o token de atualização expirar, não será renovado e acquireTokenSilent falhará.
  • CacheLookupPolicy.RefreshToken - acquireTokenSilent não tentará recuperar os tokens de acesso da cache e, em vez disso, tentará trocar o token de atualização em cache por um novo token de acesso. Se o token de atualização expirar, não será renovado e acquireTokenSilent falhará.
  • CacheLookupPolicy.RefreshTokenAndNetwork - acquireTokenSilent Não vou procurar no cache o token de acesso. Acederá diretamente à rede com o token de atualização armazenado em cache. Se o token de atualização expirar, será feita uma tentativa de renovação. Isso equivale a definir forceRefresh: true.
  • CacheLookupPolicy.Skip - acquireTokenSilent Tentaremos renovar tanto os tokens de acesso como os de atualização. Não vai procurar na cache. Isto falha sempre se os cookies de terceiros forem bloqueados pelo navegador.

Trechos de código

var username = "test@contoso.com";
var currentAccount = msalInstance.getAccount({ username });
var silentRequest = {
    scopes: ["Mail.Read"],
    account: currentAccount,
    forceRefresh: false,
    cacheLookupPolicy: CacheLookupPolicy.Default // will default to CacheLookupPolicy.Default if omitted
};

var request = {
    scopes: ["Mail.Read"],
    loginHint: currentAccount.username // For v1 endpoints, use upn from idToken claims
};

const tokenResponse = await msalInstance.acquireTokenSilent(silentRequest).catch(async (error) => {
    if (error instanceof InteractionRequiredAuthError) {
        // fallback to interaction when silent call fails
        return await msalInstance.acquireTokenPopup(request).catch(error => {
            if (error instanceof InteractionRequiredAuthError) {
                // fallback to interaction when silent call fails
                return msalInstance.acquireTokenRedirect(request)
            }
        });
    }
});

Redirect

var username = "test@contoso.com";
var currentAccount = msalInstance.getAccount({ username });
var silentRequest = {
    scopes: ["Mail.Read"],
    account: currentAccount,
    forceRefresh: false,
    cacheLookupPolicy: CacheLookupPolicy.Default // will default to CacheLookupPolicy.Default if omitted
};

var request = {
    scopes: ["Mail.Read"],
    loginHint: currentAccount.username // For v1 endpoints, use upn from idToken claims
};

const tokenResponse = await msalInstance.acquireTokenSilent(silentRequest).catch(error => {
    if (error instanceof InteractionRequiredAuthError) {
        // fallback to interaction when silent call fails
        return msalInstance.acquireTokenRedirect(request)
    }
});

Próximas Etapas

Aprenda a terminar sessão.