Authentication Strategies - bcgov/common-service-showcase GitHub Wiki
Authentication Strategies
Authentication is the act of confirming that the claim of a single piece of data is true. There are various strategies and protocols in order to authenticate a user such as OAuth, WebADE, JWT Bearer, Kerberos and OpenID Connect. Each strategy has its own means of verifying the truth in claims.
Strategies
Below are some of the commonly used authentication strategies.
OpenID Connect
OpenID Connect, or OIDC, is an authentication layer on top of the OAuth2 authorization framework (RFC 3749). OIDC provides computing clients the ability to verify an identity as well as acquire basic profile information about the user through RESTful network traffic. A relatively quick introduction to OIDC can be found here and the full core specification can be found here.
OIDC/Stateless JWT Authentication Flow
A good strategy for handling authentication is using a combination of OpenID Connect and JWTs as a method of requesting an access token as well as allowing for stateless client authorization to protected API resources (RFC 7523). As such, using an OIDC flow to acquire a JWT access token, and then using the JWT access token for authorized resources is a solid strategy for handling both authentication and authorization. Likewise, using a refresh token to refresh expired JWT access tokens also allows for seamless session refreshing and improves security by minimizing the window of time a JWT access token is valid. The following apps currently use this flow:
Login
For login, we use the standard OIDC flow which strongly resembles OAuth 2 authentication flow. Essentially a user is redirected to the authentication provider. Upon successful authentication, the user will be redirected back to the backend server with an authorization code. The backend server uses that code to authorize the user, and yields a session cookie for the frontend user. The backend then redirects the user back to the root of the frontend, where it will use that session to acquire and store the JWT access token, as well as the refresh token into local storage. An abstract visualization of the flow is shown in Figure 1.
Figure 1 - OpenID Connect Flow with scope openid
Stateless Authorization
Once a user has a JWT and refresh token, they no longer need to concern themselves with the session as that the JWT itself will contain all of the authorization assertions they need to access protected resources if they have permission to do so. As such, the backend endpoint will only need to check that the JWT Bearer token in the Authorization header is valid and contains the correct groups and/or roles. This is shown in Figure 2.
Figure 2 - Accessing protected resources via JWT
Refresh Token Flow
As that a JWT token has a short time window before expiry, a user will frequently need to ask for a new JWT token in order to continue to access protected resources. To do this, the frontend should intercept the protected resource call and check if it failed due to an authorization failure. If it is an authorization failure, it should ask the refresh endpoint to issue a new JWT token, and then reattempt the protected resource call, as shown in Figure 3.
Figure 3 - Refreshing expired JWT with refresh token
Once a user signs out, the frontend will remove both the JWT access token and refresh token from local storage, thus completing the cycle.