Appendix C. More about authentication and authorization

This appendix covers

  • Basics of authentication and authorization
  • OAuth 2.0 flow
  • JSON Web Tokens

This appendix serves as a short refresher on authentication and authorization. It describes the OAuth 2.0 flow process, the OpenID Connect protocol, and the inner workings of JSON Web Tokens.

C.1. Basics of authentication and authorization

In simple web and mobile applications, the back-end server is usually responsible for the authentication and authorization of users. A password authentication scheme may work as follows (figure C.1):

  1. A user enters a username and password in a mobile application or a website.
  2. The user’s credentials are sent to the server. The application looks up the user in a database and validates the submitted password.
  3. If validation succeeds, the server returns a cookie or a token with, optionally, embedded claims about the user. Claims are assertions about a user, which may include the user’s unique identifier, role, email address, or any other useful or relevant information. If validation fails, the user is notified and prompted to reenter credentials.
  4. Subsequent requests to the server are sent with the cookie or token provided by the server earlier. The system may inspect the cookie or the token for embedded claims, which can include the user’s role or arbitrary information needed to decide whether the user can perform an action. Alternatively, the system can look up the user’s role in a database to grant authorization to perform an action.
Figure C.1. This simple cookie/token forms authentication flow is familiar to all developers.

In more complex scenarios additional systems or steps may be involved. OpenID, for example, is an open standard authentication protocol designed to allow users to authenticate via a third-party service (an OpenID identity provider) instead of having to develop a custom sign-in system. OpenID Connect adds an authentication layer on top of OAuth 2.0. A protocol like OpenID Connect is needed to enforce security and bridge the gap between authentication and authorization. Although it might seem that OAuth 2.0 could be used for authorization as well as authentication, it would be a mistake to assume that. Having an authorization system without an authentication component could lead to attackers gaining improper access to resources. Figure C.2 shows what an OpenID Connect flow looks like.

Figure C.2. OpenID Connect is an authentication protocol based on OAuth 2.0. It’s widely supported in the industry and is used by services such as Auth0.

Authentication vs. authorization

What’s the difference between authentication and authorization? Authentication is the process of verifying who the user is; for example, confirming that user Bob is who he represents himself to be. Authorization is about verifying what the user is allowed to do. Is Bob allowed to view this page? Is Bob allowed to delete a database record? Authentication and authorization are independent concepts (authenticated and non-authenticated users can be authorized to do different things) but are often linked in discussions about security.

OpenID is mainly concerned with authentication. OAuth is mainly about authorization. OpenID Connect is an extension of OAuth 2.0 designed to bring authentication and authorization together. For a more detailed explanation, see https://oauth.net/articles/authentication/.

OAuth 2.0 grant types

The OAuth 2.0 specification (https://tools.ietf.org/html/rfc6749), which is used by OpenID Connect, defines four different grant types for different authorization scenarios:

  • Authorization code for applications running on a web server including server-side rendered web apps: This is a common grant type that implements three-legged OAuth. If you’ve used GitHub, Google, Facebook, or another identity provider to sign in to a website or application, then you’ve experienced it. In an authorization code grant, an authorization server—or the IdP—acts as an intermediary between the client (that is, the website or application that the user wants to log on to) and the resource owner (that is, the user). When the user signs in to the authorization server, they’re redirected to the client with an authorization code, which the client captures and exchanges with the authorization server for an access token. A client can then access a resource server with the access token and retrieve protected resources.
  • Implicit for mobile or browser-based JavaScript-only apps that can’t be trusted with maintaining client secrets: The implicit grant type is a simplified variation of the authorization code flow. As before, the user is redirected to the authorization server to sign in, but instead of the server returning an authentication code, the client is immediately sent an access token. The implicit grant type is needed for the class of applications where the client is unable to store secrets. But there are security implications to using the implicit grant type. It should be used as a second choice when the authorization code grant type is unavailable.
  • Resource owner credentials for directly logging in to a client with a username and password: This is similar to the type of authentication shown in figure C.1. A resource owner provides credentials directly to the client, which exchanges them for an access token.
  • Client credentials for accessing resources outside any user’s specific context: This grant type is useful for machine-to-machine authorization where the client uses its own credentials as an authorization grant.

C.2. JSON Web Token

JSON Web Token (https://tools.ietf.org/html/rfc7519) is an open standard used to transport claims between parties. These tokens have properties that make them useful in serverless systems:

  • JWT is URL-safe by design. Tokens can be passed in the body of the request or in the URL query.
  • JWT is compact and self-contained.
  • JWT can be digitally signed to guarantee integrity and encrypted to guarantee confidentiality.
  • JWT is an open standard and the tokens are easy to create and parse. Libraries are available for JavaScript and other languages.

Claims are encoded in JWT as a JSON object and are sent as a JSON Web Signature (JWS) or JSON Web Encryption (JWE) structure. The JWS payload is digitally signed by the entity creating the token to prevent tampering. The JWT spec defines support for symmetric and asymmetric signing algorithms. Tokens created with an asymmetric signing algorithm can be verified using a public key on a client. Naturally, JWT signed with a symmetric algorithm requires the secret signing key to validate the signature. These can’t be exposed to clients, but you can use them in a Lambda function to validate the token.

It’s also important to note that in JWS the claims (payload) portion is not encrypted in any way. It’s only Base64-encoded so it can be trivially inspected and read. Do not send any sensitive information in it. JWE, on the other hand, encrypts the content of the message instead of digitally signing it. It’s possible to encrypt the JWT claims and then embed them in a JWS if you want to enforce confidentiality and integrity at the same time.

JWT consists of three segments: header, body, and signature. Figure C.3 shows what a JWT token looks like and points out how to identify each segment.

Figure C.3. The JWT structure is composed of three segments separated by a period.

The header of JWT is composed of two parts: the declaring type (JWT) and the hashing algorithm. The payload consists of JWT claims. There’s a set of reserved claims that, although not mandatory, is useful to have. Auth0, for example, includes the following minimum subset of claims in every token:

  • iss— Issuer of the token
  • sub— Subject of the token
  • aud— Audience expected to consume the token
  • exp— Expiration time
  • iat— Issued-at timestamp

Finally, the signature is used to verify the integrity of the token. Typical JWT implementations support signature computation using HMAC with the SHA-256 cryptographic hash function (HS256) or RSA with SHA-256 (RS256).

The website jwt.io has an interactive debugger (figure C.4) for testing whether you have correctly generated your symmetric or asymmetric JWT. It also lists available libraries for token signing/verification for different languages and platforms.

Figure C.4. The jwt.io debugger allows you to test your JSON Web Tokens. You can change the payload and the header to see how the token changes.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.138.110.105