Ok, so leading on from part 1, let's get into some Open ID Connect (OIDC) and JWTs :-)
What is OpenID Connect (OIDC)?
OpenID Connect (OIDC) is an authentication protocol built on top of OAuth 2.0 that allows clients (applications) to verify the identity of users and obtain their basic profile information securely. Unlike OAuth 2.0, which is primarily used for authorization (granting access to resources), OIDC focuses on authentication (confirming who the user is).
Key Components of OIDC
Issuer (Identity Provider, IdP):
- Authenticates users and issues tokens (ID tokens, access tokens, and optionally refresh tokens).
- Examples: Azure AD, Google, Okta, Ping Identity.
Client (Relying Party, RP):
- The application or service that relies on the IdP for user authentication.
Endpoints:
- Authorization Endpoint: Where users are redirected to log in.
- Token Endpoint: Issues tokens after successful authentication.
- UserInfo Endpoint: Provides additional user profile information.
Tokens:
- ID Token: Contains information about the authenticated user (e.g., user ID, email).
- Signed using JSON Web Token (JWT) format.
- Access Token: Grants access to protected resources (optional for SSO).
- Refresh Token: Allows token renewal without requiring user interaction.
Why Use OIDC for SSO?
Modern and Lightweight:
- Designed for modern web and mobile apps with REST/JSON APIs.
- Simpler than legacy protocols like SAML.
Interoperability:
- Widely supported across cloud platforms, mobile apps, and microservices.
Enhanced Security:
- Supports modern security mechanisms like PKCE (Proof Key for Code Exchange) and token introspection.
Flexible User Info:
- Fetch user profile data dynamically via the UserInfo endpoint.
Standardized JWT:
- ID tokens are easy to parse and validate using standard libraries.
How to Use OIDC to Enable SSO
1. Set Up an Identity Provider (IdP)
- Use an IdP that supports OIDC, such as:
- Azure AD
- Google Identity
- Okta
- PingOne
- AWS Cognito
Steps:
- Register your application (Client ID and Client Secret will be generated).
- Configure redirect URIs for your application.
- Set up scopes (e.g.,
openid
, profile
, email
) to define what information to share with the client.
2. Integrate the Client Application
- Configure your application to use the IdP for authentication:
- Use an OIDC-compatible library or SDK (e.g., libraries for Python, Java, .NET, JavaScript).
- Specify the endpoints:
- Authorization Endpoint
- Token Endpoint
- UserInfo Endpoint (optional)
3. Authentication Flow
- Typically, the Authorization Code Flow is used for SSO:
- Initiate Login:
- The user is redirected to the IdP's Authorization Endpoint.
- Include parameters like
response_type=code
, scope=openid profile
, and redirect_uri
.
- Authenticate User:
- The IdP prompts the user to log in.
- Return Authorization Code:
- Upon successful login, the IdP redirects the user back to the client with an authorization code.
- Exchange Code for Tokens:
- The client sends the authorization code to the Token Endpoint and receives:
- ID Token
- Access Token (optional)
- Validate ID Token:
- The client verifies the token’s signature, issuer, and expiration.
4. Authorize Access
- Use the validated ID token to establish a user session in the application.
- Optionally, use the Access Token to call APIs for additional data or functionality.
5. Implement Role-Based Access Control (RBAC)
- Use claims in the ID token (e.g.,
roles
, groups
) to assign permissions in your application.
Example Use Case: Enabling SSO with OIDC
Scenario: SSO for a Web Application
IdP Configuration:
- Register the web application in PingOne or Azure AD.
- Define the redirect URI:
https://example.com/callback
. - Set scopes:
openid profile email
.
Client Application Configuration:
- Integrate an OIDC library (e.g.,
oidc-client
for JavaScript, passport-openidconnect
for Node.js). - Set up endpoints from the IdP:
- Authorization:
https://idp.example.com/authorize
- Token:
https://idp.example.com/token
- UserInfo:
https://idp.example.com/userinfo
.
User Flow:
- User accesses the web app.
- The app redirects the user to the IdP for authentication.
- The user logs in, and the IdP redirects them back with an authorization code.
- The app exchanges the code for tokens and logs the user in.
What is a JWT?
A JWT (JSON Web Token) is a compact, URL-safe, and standardized way to represent claims (statements about an entity, typically the user) in JSON format. It is commonly used for authentication, authorization, and data exchange in modern web applications.
JWTs are widely employed in protocols like OAuth 2.0 and OpenID Connect (OIDC), enabling secure communication between different systems.
Structure of a JWT
A JWT consists of three parts, separated by periods (.
):
1. Header (Base64URL-encoded JSON):
- Contains metadata about the token, including the algorithm used to sign it.
Example:
json {
"alg": "HS256",
"typ": "JWT"
}
2. Payload (Base64URL-encoded JSON):
- Contains the claims, which are statements about the user or other entities.
- Claims can be:
- Registered Claims: Predefined claims like
iss
(issuer), sub
(subject), exp
(expiration time), etc. - Public Claims: Custom claims shared across applications.
- Private Claims: Custom claims specific to your application.
- Example:
3. Signature (Base64URL-encoded string):
- Ensures the integrity and authenticity of the token.
- Created by encoding the header and payload, then signing it with a secret or private key using the specified algorithm.
- Example process (using
HS256
):
Example JWT:
For decoding JWTs https://jwt.io is your friend :-)
Characteristics of JWT
Compact and URL-Safe:
- Can be transmitted via URLs, HTTP headers, or cookies without causing encoding issues.
Stateless:
- Does not require server-side storage, as all data is self-contained within the token.
Secure:
- Signed to prevent tampering.
- Can optionally be encrypted for confidentiality (JWE format).
Self-Contained:
- Includes all the necessary information for authentication or authorization.
Common Use Cases
Authentication:
- OIDC uses JWTs (ID Tokens) to verify a user's identity.
- Example: After a user logs in, the server issues a JWT containing user details, which the client includes in subsequent requests.
Authorization:
- OAuth 2.0 uses JWTs (Access Tokens) to grant clients permission to access resources.
- Example: A JWT with a claim indicating the user's roles or permissions.
Data Exchange:
- JWTs are used to securely transmit information between parties, ensuring integrity and optional confidentiality.
How JWTs Work in Authentication
User Logs In:
- The user submits their credentials to the server.
Server Issues JWT:
- After validating the credentials, the server generates and signs a JWT containing the user's information.
Client Stores JWT:
- The client (e.g., browser or mobile app) stores the JWT in a secure location, such as a cookie or local storage.
Client Sends JWT:
- On subsequent requests, the client includes the JWT (e.g., in the
Authorization
header).
Server Validates JWT:
- The server verifies the JWT's signature and checks claims like expiration time (
exp
) before granting access.
Advantages of JWTs
Scalability:
- Stateless design reduces server-side storage and makes them ideal for distributed systems.
Interoperability:
- Standardized format ensures compatibility across platforms and systems.
Efficiency:
- Compact size reduces overhead for network communication.
Security:
- Signed and optionally encrypted, ensuring integrity and confidentiality.
Challenges and Considerations
Token Revocation:
- Stateless design means JWTs cannot be revoked once issued. Use short expiration times (
exp
) and token refresh mechanisms.
Token Storage:
- Ensure secure storage on the client side to prevent attacks like XSS (cross-site scripting) or CSRF (cross-site request forgery).
Signature Verification:
- Always verify the signature to ensure the token is not tampered with.
Differences Between Access Tokens, Refresh Tokens, and ID Tokens
When working with modern authentication systems, particularly with protocols like OAuth 2.0 and OpenID Connect (OIDC), three types of tokens are commonly used: Access Tokens, Refresh Tokens, and ID Tokens. Each serves a distinct purpose in the authentication and authorization processes.
1. Access Token
Purpose:
- Grants a client application access to a protected resource (e.g., APIs, user data).
- Used for authorization purposes.
Characteristics:
- Issued by an Authorization Server (e.g., an Identity Provider like Azure AD, Okta, Ping Identity).
- Contains information about:
- Scopes/Permissions: Specifies what the client is allowed to do.
- Expiration: Typically short-lived (minutes to hours) to minimize security risks.
- Encoded as a JWT (JSON Web Token) or opaque token, depending on the implementation.
- Sent by the client application in the
Authorization
header of API requests:
Example Use Case:
- A mobile app retrieves an access token after user login and uses it to call a REST API for user data.
2. Refresh Token
Purpose:
- Allows a client application to obtain a new access token without requiring the user to reauthenticate.
- Extends the session duration without storing the user's credentials.
Characteristics:
- Issued alongside the access token (in OAuth 2.0 flows where applicable).
- Typically long-lived, but it can be revoked.
- Sensitive and should never be exposed to the browser or client-side applications directly.
- Used by the client application to call the Token Endpoint and request a new access token:
Example Use Case:
- A user logs into a web application, and after the access token expires, the refresh token is used to silently fetch a new access token without requiring the user to log in again.
3. ID Token
Purpose:
- Provides information about the authenticated user to the client application.
- Used for authentication purposes.
Characteristics:
- Issued by the Identity Provider (IdP) as part of the OpenID Connect (OIDC) flow.
- Encoded as a JWT and contains claims about the user and the authentication event:
sub
: User ID (subject)name
, email
, preferred_username
: User attributesiat
, exp
: Issued-at and expiration timestamps
- Typically consumed by the client application (e.g., a web app or mobile app) to establish a user session.
Example Use Case:
- After a user logs in, the application uses the ID token to display the user's name and email in the UI and to verify the user's identity.
Key Differences
Feature | Access Token | Refresh Token | ID Token |
---|
Purpose | Authorize access to APIs | Obtain new access tokens | Authenticate the user |
Format | JWT or opaque token | Opaque token or JWT | JWT |
Audience | APIs or resource servers | Authorization server | Client application |
Expires Quickly? | Yes | No | Yes |
Contains User Info? | No (only scopes/permissions) | No | Yes (e.g., name, email, roles) |
Usage | Sent with API requests | Exchanged for new tokens | Validates user identity |
Security Risks | Exposure can lead to API misuse | Exposure can allow token theft | Exposure may reveal user info
|
When to Use Each Token
Access Token:
- Use it whenever the application needs to access protected resources or APIs.
- Do not store sensitive user data in access tokens since their primary purpose is authorization.
Refresh Token:
- Use it when the access token expires, and you want to avoid asking the user to log in again.
- Only store refresh tokens in secure server-side environments.
ID Token:
- Use it to validate the user's identity and establish a session in the client application after login.
- Typically used in authentication scenarios (e.g., OpenID Connect).
Example Flow with All Three Tokens
Scenario: A Web Application Using OIDC and OAuth 2.0
User Login:
- The user logs into the web app using their credentials.
- The Identity Provider authenticates the user and issues:
- ID Token: For user authentication and establishing a session.
- Access Token: For accessing APIs (e.g., fetching user profile data).
- Refresh Token: For obtaining new access tokens when the current one expires.
Accessing Protected Resources:
- The web app uses the access token in the
Authorization
header to call APIs.
Access Token Expiration:
- When the access token expires, the refresh token is sent to the Identity Provider's Token Endpoint to request a new access token.
Session Expiration:
- If both the access token and refresh token expire, the user must log in again.
No comments:
Post a Comment