Escrito por

Senior developer at Cysnet
Pregunta Laura Blázquez García · abr 4, 2025

OAuth2: recuperar access_token y evitar login si es válido

Tenemos un servidor OAuth configurado como proveedor de identidades, y tenemos una aplicación externa (de otro proveedor) que se conecta correctamente con el OAuth.

Por necesidades del proyecto, lo que queremos hacer es lo siguiente:

  • Si el usuario no está autenticado, mostrar la página de login del OAuth, que haga el login y que le redirija a la aplicación de terceros --> Esta parte funciona
  • Si el usuario ya está autenticado (ya ha iniciado sesión y ya tiene un access_token válido), que exista una cookie con el access_token generado en el login, y al entrar a la URL de la aplicación de terceros, en lugar de mostrar el login del OAuth, si el access_token es válido, redirigirle directamente a la aplicación de terceros --> Esta parte es la que no conseguimos hacer funcionar

Qué tenemos?

  • Hemos creado una clase custom "test.oauth.server.Authenticate" que extiende de %OAuth2.Server.Authenticate.
  • Hemos añadido el método BeforeAuthenticate. Aquí somos capaces de leer las cookies de la petición, encontrar la que hemos creado, obtener el access_token, validarlo y obtener el token como tal:
Include Ensemble

Class test.oauth.server.Authenticate Extends%OAuth2.Server.Authenticate
{

ClassMethod BeforeAuthenticate(scope As%ArrayOfDataTypes, properties As%OAuth2.Server.Properties) As%Status
{
    $$$LOGINFO("Entrando en BeforeAuthenticate")

	set currentNS = $NamespaceSet httpRequest = %requestSet tokenCookie = httpRequest.GetCookie("SessionToken")

    If tokenCookie '= "" {
        $$$LOGINFO("Token encontrado en Cookie: "_tokenCookie)
        
        // Llamar manualmente a GetAccessToken con el token de la cookieIf..GetAccessToken(tokenCookie) {
            Set isValid = ##class(%SYS.OAuth2.Validation).ValidateJWT("ValidarToken", tokenCookie, , , .jsonObject, .securityParameters, .sc)
            $$$LOGINFO(isValid_" ("_sc_"): "_$System.Status.GetErrorText(sc))
            $$$LOGINFO(jsonObject.%ToJSON())
            
            set$Namespace = "%SYS"Set token=##class(OAuth2.Server.AccessToken).OpenByToken(tokenCookie,.sc)
            set$Namespace = currentNS
            
            $$$LOGINFO(token_" ("_sc_"): "_$System.Status.GetErrorText(sc))
            
            Quit1// Continuar sin mostrar login
        } Else {
            $$$LOGINFO("GetAccessToken rechazó el token")
            Quit$$$OK
        }
    }

    $$$LOGINFO("No se encontró token en Cookie")
    Quit$$$OK
}

ClassMethod GetAccessToken(ByRef AccessToken As%String) As%Boolean
{
    $$$LOGINFO("Entrando en GetAccessToken")
    
    // Si ya recibimos un token desde BeforeAuthenticateIf AccessToken '= "" {
        // Token recibido en GetAccessToken// Llamar a la función de validación de tokenSet sc = ##class(%SYS.OAuth2.Validation).ValidateJWT("ValidarToken", AccessToken, , , .jsonObject, .securityParameters)
        Set user = jsonObject.sub
        $$$LOGINFO("Token válido. Usuario: "_user)
        If user '= "" {
            $$$LOGINFO("Usuario autenticado: "_user)
            Quit$$$OK
        } Else {
            $$$LOGINFO("El usuario está vacío.")
            Quit0// Retorna 0 si el usuario es vacío
        }
    }
    
    Quit0// Asegúrate de retornar 0 si no se obtiene el token
}

}

Pero sea como sea, aunque tengamos el access_token, abramos el objeto Token del OAuth, etc, sigue mostrando el login. Creemos que nos falta algo, pero no sabemos el qué...

Qué podemos hacer? Alguna idea?

Gracias!

Versión del producto: IRIS 2021.1
$ZV: IRIS for Windows (x86-64) 2021.1 (Build 215U) Wed Jun 9 2021 09:39:22 EDT [Health:3.3.0]

Comments

Luis Angel Pérez Ramos · abr 4, 2025

¿Es posible que estéis almacenando la cookie en el explorador de internet pero no la estéis enviando al servidor de OAuth en la request?

0
Laura Blázquez García  abr 4, 2025 to Luis Angel Pérez Ramos

La cookie llega, conseguimos leerla con esta instrucción:

Set tokenCookie = httpRequest.GetCookie("SessionToken")

El nombre es inventado, no sé si quizá esté ahí el problema... O si se debe generar una cabecera o alguna historia para que funcione.

Lo que no sabemos es qué hacer una vez leída la cookie y obtenido el token.

0