XYZ LOGIN FOR DUMMIES¶
Intro?
==== IGNORE BELOW THIS LINE ====
¶
THE FLOW IN POSTMAN (mobile to mobile with some kind of interaction with myUnbox)¶
When the login succeeds you get the access token directly instead of a code to exchange for an access token (PKCE etc.). This is deprecated, so instead we use the code
STARTS HERE¶
The end user clicks the login button on the client mobile app or desktop site.
The client sends a PKCE code_challenge and a scope request to the Unbox auth server's /authorize endpoint. Here's the complete list of mandatory query parameters:
{width="6.09375in" height="2.34375in"}
Here's anexample of what that could look like in cURL:
{width="4.5in" height="2.625in"}
The /authorize endpoint sends a login_code_to_sign back to the client.
The auth server sends back something like this:
{width="6.09375in" height="0.8125in"}
Which is really this JSON inside:
{width="6.09375in" height="1.4895833333333333in"}
This is what it looks like, but there's no action to be performed on the content itself. The action to be performed is to take the long base64-encoded string of the login_code_to_sign and to sign it with a private key (which is done on strings, not on JSON).
Client mobile app case: The direct send is all that happens.
Client desktop site case: In addition to the direct send, /authorize also redirects the client site to an auth page. This page displays a QR code with the login_code_to_sign embedded in it so that the end user can scan it with their mobile device.
-
The client passes the login_code_to_sign to the XYZ mobile app (to be signed once the end user consents to the scope the client requests).
-
Mobile client app case: The client sends the login_code_to_sign to XYZ directly (or takes the end user to their mobile app store to download XYZ first).
-
Client desktop site case: The client sends the login_code_to_sign to XYZ by first embedding it in a QR code, then getting the end user to scan it with their mobile device. This either launches XYZ directly, or sends the user to their mobile app store to download XYZ first.
-
-
XYZ asks the end user to consent to the scope request.
-
The user consents to the requested scope of access. Once consent is provided, XYZ uses its private key to generate a public key and signs the login_code_to_sign with the private key. Signing the login_code_to_sign with the private key generates what is called the signature. Sending the public key along with the signature categorically guarantees to the recipient that the message was sent by the owner of the private key from which the public key was derived (and that the message wasn't modified in transit).
-
XYZ sends the triplet of login_code_to_sign, signature, and the public key to the auth server's /authorize/login endpoint.
-
Mobile client app case: XYZ first sends the triplet to the mobile client app, which then passes it to /authorize/login.
-
Client desktop site case: XYZ sends the triplet to /authorize/login directly.
-
POST /authorize/login
{width="6.09375in" height="0.5833333333333334in"}
With XYZ 's private key, read the login_code_to_sign, and generate a signed version.
client app or site call XYZU with a login_code_to_sign and asks for same plus pub key and the signed bersion of the login_code_to_sign.
XYZ signs it with the private key or the identity the user is going to pick.
client MOBILE APP CASE:
XYZ sends TRIPLET to the mobile client app
client mobile app calls /token with signature received from XYZU
client DESKTOP WEBSITE CASE:
XYZ sends TRIPLET to /auth/login which sends code to the desktop client app website
client desktop website calls /token with code received from /auth/login
is provided by XYZ to the client app, and the client app issues the POST request to /token
{width="6.09375in" height="0.34375in"}
client gets this code from /authorize/login
Using this code and code verifier, call POST /token:
{width="6.09375in" height="1.90625in"}
Server replies with a 3000 second bearer access token with openid scope and a refresh token:
{width="6.09375in" height="2.0in"}
It's not important, but the inside of it looks like this:
{width="6.09375in" height="3.875in"}
If you try to sign in more than once, you just get taken to the success part.
However, if you change scope, the whole thing has to be redone.
Sometimes you can have auto-approved scope.
When you configure a client, you can have some scopes that are autoapproved (or understood/implicit).
{width="5.072915573053368in" height="2.7291666666666665in"}
Desktop browser case¶
There are two endpoints that the end-user contacts during the login procedure, an authorization endpoint (Unbox) and a token endpoint (whatever entity the user permits interactions with, such as ).
An end user opens their desktop browser and goes to the LITTER (branded) landing page.
On the LITTER landing page, they click on the Login button.
{width="3.5416666666666665in" height="3.8541666666666665in"}
1. LITTER requests access to MyUnbox (with code verifier and code challenge)¶
The LITTER page creates two strings of numbers and letters used to identify the end user throughout the process:
-
code_verifier (AKA clear value): a random string of 43-128 characters
-
code_challenge (AKA hash value): a transformed/encoded version of the above using a strong encoding method like SHA256 (impractical to reverse-engineer)
The Login page redirects the user to a page with a QR code, which is valid for a brief window of time (currently 3 minutes).
{width="6.35416447944007in" height="2.09375in"}
The QR code is a kind of stamped envelope in the form of a link with a code. Here's an example of what that link might look like:
https://a.nbx.cl/oauth2/authorize/login/A1FP6u4VdTpEBb9QrByJsjKLxnjkbHfDGHfdDoKQYdj3
This envelope contains the code_challenge (above in italics) which says:
"The holder of this piece of code (1 of 2) is the person who clicked on the Login button less than 3 minutes ago."
LITTER asks the user to scan the QR code to give LITTER access to the user's MyUnbox/XYZ app.
The requested access has limited scope (openid).
The user scans the QR with their mobile phone, which opens up their MyUnbox/XYZ app (or gets them to download it).
MyUnbox/XYZ understands this envelope as an instruction to automatically go to the provided URL.
2. Client Sends the Code Challenge with the Authorization Request¶
As part of the initial authorization request, MyUnbox/XYZ sends the code_challenge (the encoded version of the code_verifier) to the authorization server. The request also includes mention of which method was used to encode the code_verifier into the code_challenge.
The authorization server notes these down for a brief time for the purposes of the imminent second step.
It sends the code to be signed to a webpage that gets shown to the end user. Specifically in this case, the returned authorization code appears as
signing the code received from the authorization server using their MyUnbox (or their Cardano private key).
_______________________
-
client: application linked to MyUnbox which is allowed to trigger user authentication and receive a JWT.
-
user: an end user, using the client application and MyUnbox.
A couple discrepancies between the OA2 flow and ours.
JWT is just a way to implement a format of information.
When we say JWT, we mean the bearer token, which is the access token.
You have the access token, its type is bearer.
***
The Auth server presents you with a login_code_to_sign.
You are XYZ. You use your private key to sign it. This generates a signature.
Now you have the signature and the login_code_to_sign (which match?)
From your private key you generate your public key, then you send the three things to the server.
The server says: "Oh, I know the login_code_to_sign, because the one I sent to you (or someone), I can verify that the public key is matching the signature and is matching the login_code_to_sign.
That's how I know you hold the private key of the public key, and I can generate to you a code that you can exchange for the final access token.
***
What we are going to deliver to the website or back end is proof that you are who you say you are.
That
+--------+ +---------------+\ | |--(A)- Authorization Request ->| Resource |\ | | | Owner |\ | |\<-(B)-- Authorization Grant ---| (end-user) |\ | | +---------------+\ | |\ | | +---------------+\ | |--(C)-- Authorization Grant -->| Authorization |\ | Client | | Server |\ |(client app |\<-(D)----- Access Token -------| (Unbox) |\ | or | +---------------+\ | client.org |\ | on | +---------------+\ | desk |--(E)----- Access Token ------>| Resource |\ | top) | | Server |\ | |\<-(F)--- Protected Resource ---| |\ +--------+ +---------------+
OAuth provides a method for clients to access a protected resource on behalf of a resource owner. In the general case, before a client can access a protected resource, it must first obtain an authorization grant from the resource owner and then exchange the authorization grant for an access token. The access token represents the grant\'s scope, duration, and other attributes granted by the authorization grant. The client accesses the protected resource by presenting the access token to the resource server. In some cases, a client can directly present its own credentials to an authorization server to obtain an access token without having to first obtain an authorization grant from a resource owner. The access token provides an abstraction, replacing different authorization constructs (e.g., username and password, assertion) for a single token understood by the resource server. This abstraction enables issuing access tokens valid for a short time period, as well as removing the resource server\'s need to understand a wide range of authentication schemes.
+--------+ +---------------+\ | |--(A)- Authorization Request ->| Resource |\ | | | Owner |\ | |\<-(B)-- Authorization Grant ---| |\ | | +---------------+\ | |\ | | +---------------+\ | |--(C)-- Authorization Grant -->| Authorization |\ | Client | | Server |\ | |\<-(D)----- Access Token -------| |\ | | +---------------+\ | |\ | | +---------------+\ | |--(E)----- Access Token ------>| Resource |\ | | | Server |\ | |\<-(F)--- Protected Resource ---| |\ +--------+ +---------------+\ \ Figure 1: Abstract Protocol Flow
The abstract OAuth 2.0 flow illustrated in Figure 1 describes the\ interaction between the client, resource owner, authorization server,\ and resource server (described in [RFC6749]). The following two\ steps are specified within this document:\ \ (E) The client requests the protected resource from the resource\ server and authenticates by presenting the access token.\ \ (F) The resource server validates the access token, and if valid,\ serves the request.