Vigencias, expiración y renovación de tokens

Antes de empezar aquí, asegúrese de comprender cómo iniciar sesión y adquirir tokens.

Al usar MSAL.js, debe comprender las implicaciones de obtener tokens para los usuarios y cómo administrar el período de validez de estos tokens.

Vigencia y expiración de tokens

Puede configurar el tiempo de vida de los tokens de acceso, de identificador o SAML (Security Assertion Markup Language) emitidos por la plataforma de identidades de Microsoft. A continuación se resume parte de la información.

Tokens de identificación

Los tokens de identificador están enlazados a una combinación específica de cuenta y cliente, y normalmente contienen información de perfil sobre el usuario. Normalmente, la duración de la sesión de usuario de una aplicación web coincidirá con la de la duración de la sesión del token de identificador, que es de forma predeterminada de 24 horas. Puede obtener más información sobre cómo configurar las duraciones de tokens.

Tokens de acceso

Los tokens de acceso en el explorador tienen una expiración recomendada predeterminada de 1 hora. Después de esta 1 hora, se rechazarán las llamadas de portador con el token expirado. Este token se puede actualizar de forma silenciosa mediante el token de actualización recuperado con este token. Puede obtener más información sobre cómo configurar las duraciones de tokens.

Tokens de actualización

Los tokens de actualización proporcionados a las aplicaciones de página única son tokens de actualización de duración limitada (normalmente, 24 horas desde el momento en que se obtienen). Esta es una ventana no ajustable, no corrediza, de por vida. Cada vez que se usa un token de actualización para renovar un token de acceso, se captura un nuevo token de actualización con el token de acceso renovado. Este nuevo token de actualización tendrá una duración igual a la duración restante del token de actualización original. Una vez que haya expirado un token de actualización, se debe iniciar un nuevo flujo de código de autorización para recuperar un código de autorización y cambiarlo por un nuevo conjunto de tokens.

Nota: Cuando se obtiene un nuevo token de actualización, msal.js reemplaza el token de actualización almacenado en caché por el nuevo token de actualización, pero el servidor no invalida el token de actualización anterior y puede usarse para obtener tokens de acceso hasta su expiración.

Renovación de tokens

El PublicClientApplication objeto expone una API denominada acquireTokenSilent que está pensada para recuperar el token no expirado de forma silenciosa. Esto se realiza en algunos pasos:

  1. Compruebe si ya existe un token en la memoria caché de tokens para el especificado scopes, client id, authority, o homeAccountIdentifier.
  2. Si existe un token para los parámetros especificados, asegúrese de obtener una sola coincidencia y comprobar la expiración.
  3. Si el token de acceso no ha expirado, MSAL devolverá una respuesta con los tokens pertinentes.
  4. Si el token de acceso ha expirado, pero el token de actualización sigue siendo válido, MSAL usará el token de actualización especificado para recuperar un nuevo conjunto de tokens y, a continuación, devolverá una respuesta.
  5. Si el token de actualización ha expirado, MSAL intentará recuperar un token de acceso de forma silenciosa mediante un iframe oculto. Esto utilizará el SID o el nombre de usuario del objeto de reclamaciones de la cuenta para obtener una pista sobre la sesión del usuario. Si se produce un error en la llamada a este iframe oculto, MSAL devolverá un error del servidor en forma de InteractionRequiredAuthError, en el que se solicita recuperar un código de autorización para obtener un nuevo conjunto de tokens. Para ello, realice una llamada a la API de inicio de sesión o de acquireToken con el objeto PublicClientApplication. Si la sesión sigue activa, el servidor enviará un código sin preguntar al usuario. De lo contrario, se le pedirá al usuario que escriba sus credenciales.

Consulte el artículo objetos de solicitud y respuesta para obtener más información sobre los parámetros de configuración que puede establecer para el acquireTokenSilent método .

Evitar interrupciones interactivas en medio de la sesión de un usuario

En algunos casos, es posible que desee invocar de forma preventiva la interacción, si es necesario, al principio de la sesión de un usuario para asegurarse de que puede seguir adquirir tokens de forma silenciosa y usar la aplicación sin interrupciones adicionales. Por supuesto, puede lograrlo invocando la interacción cada vez que la aplicación se carga por primera vez, esto es, sin embargo, una experiencia de usuario deficiente y menos eficaz cuando un usuario ya tiene tokens de una sesión anterior u otra ventana o pestaña. En su lugar, con algunos parámetros de solicitud puede usar acquireTokenSilent para asegurarse de que la memoria caché tiene los tokens necesarios disponibles para devolver de forma silenciosa durante un período de tiempo arbitrario.

Para garantizar que acquireTokenSilent pueda devolver tokens válidos durante al menos 1 hora:

  • Llame a acquireTokenSilent al cargar la página con el parámetro de solicitud forceRefresh establecido en true. Esto omitirá la memoria caché y obtendrá un token nuevo, que luego podrá recuperarse de la memoria caché en las llamadas posteriores.
  • En las llamadas posteriores, deje forceRefresh sin establecer o explícitamente false para asegurarse de que los tokens se pueden atender desde la memoria caché.

Para garantizar que acquireTokenSilent pueda devolver tokens válidos durante un período mínimo de cualquier duración de hasta 24 horas:

  • Llama a acquireTokenSilent al cargar la página con el parámetro de solicitud forceRefresh establecido en true & y el parámetro refreshTokenExpirationOffsetSeconds establecido en el tiempo deseado (en segundos) durante el que no debe haber interacción.
  • En las llamadas posteriores, deje forceRefresh y refreshTokenExpirationOffsetSeconds sin establecer para garantizar que los tokens puedan obtenerse desde la caché.

Por ejemplo, si desea asegurarse de que el usuario puede adquirir tokens de forma silenciosa durante las 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 hay una garantía de que se pueda adquirir un token de forma silenciosa incluso si el token de actualización aún no ha expirado. Los patrones descritos anteriormente son los mejores intentos de esfuerzo para minimizar la interacción en momentos inconvenientes, pero no eliminarán la posibilidad de interacciones necesarias dentro de los períodos de tiempo deseados. Además, no todos los proveedores de identidades devuelven la expiración del token de actualización; en esos casos, no se evaluará el refreshTokenExpirationOffsetSeconds parámetro de solicitud.

Política de consulta de caché

Opcionalmente, se puede proporcionar una directiva de búsqueda de caché a la solicitud. Las directivas de búsqueda de caché son:

  • CacheLookupPolicy.Default - acquireTokenSilent intentará recuperar un token de acceso de la memoria caché. Si el token de acceso ha expirado o no se encuentra, el token de actualización se usará para adquirir uno nuevo. Por último, si el token de actualización ha expirado, acquireTokenSilent intentará adquirir de forma silenciosa un nuevo token de acceso, un token de identificador y un token de actualización.
  • CacheLookupPolicy.AccessToken - acquireTokenSilent solo buscará tokens de acceso en la memoria caché. No intentará renovar los tokens de acceso ni los tokens de actualización.
  • CacheLookupPolicy.AccessTokenAndRefreshToken - acquireTokenSilent intentará recuperar un token de acceso de la memoria caché. Si el token de acceso ha expirado o no se encuentra, el token de actualización se usará para adquirir uno nuevo. Si el token de actualización ha expirado, no se renovará y acquireTokenSilent se producirá un error.
  • CacheLookupPolicy.RefreshToken - acquireTokenSilent no intentará recuperar tokens de acceso de la memoria caché y, en su lugar, intentará intercambiar el token de actualización almacenado en caché para un nuevo token de acceso. Si el token de actualización ha expirado, no se renovará y acquireTokenSilent se producirá un error.
  • CacheLookupPolicy.RefreshTokenAndNetwork - acquireTokenSilent no buscará en la memoria caché el token de acceso. Irá directamente a la red con el token de actualización almacenado en caché. Si el token de actualización ha expirado, se intentará renovarlo. Esto equivale a establecer forceRefresh: true.
  • CacheLookupPolicy.Skip - acquireTokenSilent intentará renovar los tokens de acceso y actualización. No buscará en la memoria caché. Esto siempre producirá un error si el explorador bloquea las cookies de terceros.

Fragmentos 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)
            }
        });
    }
});

Redireccionar

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

Pasos siguientes

Obtenga información sobre cómo realizar el cierre de sesión.