Question
· Apr 7

OAuth2: Retrieve access_token and prevent login if it's valid

We have an OAuth server configured as an identity provider, and we have an external application (from another provider) that connects correctly with OAuth.

Due to the needs of the project, what we want to do is the following:

  • If the user is not authenticated, show the OAuth login page, have them log in, and redirect them to the third-party app --> This part works
  • If the user is already authenticated (already logged in and already has a valid access_token), we create a cookie with the access_token generated at login, and when entering the third-party application URL, instead of showing the OAuth login, if the access_token is valid, redirect directly to the third-party application --> This is the part we can't get working

What do we have?

  • We have created a custom class "test.oauth.server.Authenticate" that extends from %OAuth2.Server.Authenticate.
  • We've added the BeforeAuthenticate method. Here we're able to read the request cookies, find the one we created, get the access_token, validate it, and then get the token itself:
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
}

}

But no matter what, even if we have the access_token, open the OAuth Token object, etc., it still shows the login. We think we're missing something, but we don't know what...

What can we do? Any ideas?

Thank you!

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]
Discussion (0)0
Log in or sign up to continue