Pregunta
· 4 abr, 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 = $Namespace
    Set httpRequest = %request
    Set tokenCookie = httpRequest.GetCookie("SessionToken")

    If tokenCookie '= "" {
        $$$LOGINFO("Token encontrado en Cookie: "_tokenCookie)
        
        // Llamar manualmente a GetAccessToken con el token de la cookie
        If ..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))
            
            Quit 1 // 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 BeforeAuthenticate
    If AccessToken '= "" {
        // Token recibido en GetAccessToken

        // Llamar a la función de validación de token
        Set 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.")
            Quit 0  // Retorna 0 si el usuario es vacío
        }
    }
    
    Quit 0  // 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!

Product version: 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]
Comentarios (2)1
Inicie sesión o regístrese para continuar