Demystifying Asgardeo Console authentication
Have you ever wondered how authentication works in the Asgardeo console? So far we are using the Asgardeo console to register new business applications & define their login flow but have you thought about how the authentication works for the Asgardeo console itself.
Like any business application, we can consider Asgardeo Console as an application but it is used by organization admins or privileged users whom we call Asgardeo Users (For the moment only Asgardeo users can access Asgardeo Console). We can say that this application has a bunch of UIs which call specific APIs to perform Administrative tasks or Identity management tasks eg create new users or enable Recaptcha for the organization. Rather than that in the Asgardeo Identity domain, it is no different from another business application. With this mindset, let's discuss how the authentication works for the Asgardeo console.
Asgardeo console uses OAuth2.0 authorization code grant type with PKCE validation. Here authentication will happen in 2 steps(Multi-step authentication) by using 2 authenticators & 1 flow handler in the following order
- Identifier First: Where we provide our username
- Account lookup handler: Identifies user association with organizations & manipulates authentication context to have the tenanted login
- Basic Authenticator: Where we provide our password
Let's analyze the authentication flow step by step to get a clear idea
- Once you try to access the https://console.asgardeo.io/ endpoint, Console application will send the authorization request to Asagrdeo. The request will look like this
https://api.asgardeo.io/t/a/oauth2/authorize?response_type=code&client_id=CONSOLE&scope=openid+openid+SYSTEM&redirect_uri=https%3A%2F%2Fconsole.asgardeo.io&response_mode=form_post&code_challenge_method=S256&code_challenge={blah!blah!}
Points to take a note
- response_type=code: This indicates the Authorization code grant type
- response_mode=form_post: This will ask the authorization code to be sent in the body of a POST request as opposed to in the URL
- This is a 302 GET request thus response will have a location header to denote the redirection URL (In the upcoming request if it is 302, check the location header)
2. We will be redirected to the login page, the URL will look like
https://accounts.asgardeo.io/authenticationendpoint/login.do?client_id=CONSOLE&code_challenge=&code_challenge_method=S256&commonAuthCallerPath=%2Foauth2%2Fauthorize&forceAuth=false&passiveAuth=false&redirect_uri=https%3A%2F%2Fconsole.asgardeo.io&response_mode=form_post&response_type=code&scope=openid+openid+SYSTEM&t=carbon.super&sessionDataKey=&relyingParty=CONSOLE&type=oidc&sp=Console&isSaaSApp=true&authenticators=GoogleOIDCAuthenticator%3AGoogle%3BGithubAuthenticator%3AGitHub%3BIdentifierExecutor%3ALOCAL
We can see a bunch of authenticators listed here:
- GoogleOIDCAuthenticator:Google
- GithubAuthenticator:GitHub
- IdentifierExecutor:LOCAL
These three represent the 3 options we are getting
From these 3 options (Email-Username&Pwd or Sign in with Google or Sign in with Github) we can use anyone. For this article, I'll use the email(Username&Pwd) one.
3. After the user provides his username, the form will be submitted to Asagardeo
https://stage.api.asgardeo.io/commonauth
Points to take a note
- This is a 302 POST request
- In the request body we can see the usernameUserInput, username, authType, sessionDataKey parameters.
4. Again we will be redirected back to the login page, URL will look like
https://accounts.asgardeo.io/authenticationendpoint/login.do?client_id=CONSOLE&code_challenge=&code_challenge_method=S256&commonAuthCallerPath=%2Foauth2%2Fauthorize&forceAuth=false&passiveAuth=false&redirect_uri=https%3A%2F%2Fconsole.asgardeo.io&response_mode=form_post&response_type=code&scope=openid+openid+SYSTEM&t=carbon.super&sessionDataKey=&relyingParty=CONSOLE&type=oidc&sp=Console&isSaaSApp=true&inputType=idf&authenticators=BasicAuthenticator%3ALOCAL&reCaptcha=true&reCaptchaResend=true
Here we will only get BasicAuthenticator:3ALOCAL, this is for the username& password authenticator (since we are using the Identifier First Authenticator in the first step we don’t need to give the username input & only needed to provide the password)
5. After the user provides his password, the form will be submitted to Asagardeo
https://api.asgardeo.io/commonauth
Points to take a note
- This is also a 302 POST request
- In the request body, we can see the username, password, sessionDataKeyg-recaptcha-response parameters.
- In the response body, we will send the following set-cookie header
set-cookie:commonAuthId={blah!blah!}; Path=/t/a/; Secure; HttpOnly; SameSite=None
This cookie will act as the SSO session identifier. The path is set to /t/a as the session is created in the super Asgardeo organization (super tenant)
6. Now it will send a request to authorize the endpoint to validate the session
https://api.asgardeo.io/t/a/oauth2/authorize?sessionDataKey={blahblah}
Points to take a note
- This is a GET request
- In the response body, we will send
set-cookie:opbs={blah!blah!}; Path=/t/a/; Secure; SameSite=None
This cookie will be used in Session management & SLO.
7. Now we will get a POST request to our redirection URL with the authorization code. This due to the response_mode=form_post in our initial requests.
https://console.asgardeo.io/
In this request body, we can find
- code (authorization code)
- AuthenticatedIdPs: Decoded value for this will contain the following information
{"typ":"JWT","alg":"HS256"}{"iss":"wso2","exp":1648747973840,"iat":1648747970840,"idps":[{"idp":"LOCAL","authenticator":"IdentifierExecutor"},{"idp":"LOCAL","authenticator":"LookUpHandler"},{"idp":"LOCAL","authenticator":"BasicAuthenticator"}]}
- session_state: It is the combination of client_id, redirect_uri (Callback-url) , and opbs cookie value
With this, we can consider ourselves as successfully authenticated and use the code to exchange for the token.
8. A request will be sent to .well-known endpoint to get the token endpoint & other endpoint details
https://api.asgardeo.io/oauth2/token/.well-known/openid-configuration
9. We will use the token endpoint identified in the previous request to get the access token
https://api.asgardeo.io/oauth2/token
Points to take a note
- This is a POST request
- In the response, we will get access_token, expires_in, id_token, refresh_token, scope, token_type
If you observed the network trace while performing console login, there will be some additional network calls in between the above requests like ReCaptcha. But the order of the above requests will be preserved and there are essential for authentication.
I have written this blog based on the current Agardeo console authentication flow. In the future, it could be changed but you can follow the same approach to understand the new flow. Along with understanding the current flow, I hope this article will give a perspective to analyze the login flows using network calls.
Cheers!!!