- User clicks Sign In button on site OR navigates to Django Admin unauthenticated
- Call is made to /login/oidc - which initiates LoginRedirectOIDC view
- Backend constructs a URL encoded query string for redirect to Login.gov, which consists of:
- ACR_VALUES - Authentication Context Class Reference, used to determine the identity + authorization assurance level needed (IAL + AAL) (derived from environment variable)
- CLIENT_ID - the ID of our client in Login.gov (derived from environment variable)
- nonce - a 32 byte token hex used only once
- state - a 32 byte token hex used only once
- prompt - always "select_account", defines where they land in Login.gov UI
- redirect_uri - the backend URL to return to after successful auth
- response_type - always "code" - tells Login.gov to return a code that can be used to extract an ID token from the Token endpoint later
- Query string above is then appended to the Login.gov redirect
- In our setup, this all happens on the Login.gov side
- Once user has logged in successfully, Login.gov redirects them back to the
redirect_uri
we specified above - NOTE: Any
redirect_uri
used must be defined in Login.gov or it will be rejected
- User is redirected to /login - which correlates to the TokenAuthorizationOIDC view
- The Authorization Code (
code
), Nonce and State are extracted from the query parameters supplied to the GET request - The expected
nonce
andstate
are pulled from the requestsession
so that they can be compared further in the flow for integrity.
- Using the
code
provided to the view above and theCLIENT_ASSERTION_TYPE
(supplied by environment variable) a request is made to theOIDC_OP_TOKEN_ENDPOINT
(also env var) to retrieve an ID and Access token for the given user. - If the request returns a 200 status code the ID Token will be extracted from the response data.
- This token will come in a decoded form that we must decode using the
OIDC_OP_ISSUER
andCLIENT_ID
environment varaibles, along with theJWKS
provided by Login.gov at theOIDC_OP_JWKS_ENDPOINT
(env var) - Using the decoded payload we will confirm that the nonce and state in the token match the session variables, otherwise raise an exception
- Then the
email_verified
claim will be checked, otherwise an exception will be raised.
- Once the ID token has been decoded and its integrity is verified we will set the
token
value in therequest.session
to the decoded value. - The
sub
(login.gov UUID) andemail
claims will be used to look up the User in our Postgres Database. - If the user is found they will be "logged in" to our system, otherwise a new User record will be created first, then they will be logged in
- "logged in" to our system is achieved by the built-in Django login which sets a session hash so users don't need to login again on further requests while the session is active.