Guide

Implementing OAuth 2.0 Authorization Code Flow and Secure Token Storage

IntroductionCopied!

In today's digital landscape, secure authentication and authorization are vital for protecting user data and providing a seamless user experience. This documentation guides you through integrating the OAuth 2.0 Authorization Code Flow into your application and outlines best practices for securely storing access and refresh tokens.

Understanding OAuth 2.0Copied!

What is OAuth 2.0?

OAuth 2.0 is an industry-standard authorization framework that enables applications to obtain limited access to user accounts on an HTTP service. It allows users to grant third-party applications access to their resources without sharing their credentials.

OAuth 2.0 Grant Types

OAuth 2.0 defines several grant types for different scenarios:

  • Authorization Code Grant: Ideal for server-side applications where the client secret can be securely stored.

  • Implicit Grant: Used in client-side applications like mobile apps and web applications running in a browser.

  • Resource Owner Password Credentials Grant: Direct exchange of user credentials (less secure, generally discouraged).

  • Client Credentials Grant: Used for application-level access without user involvement.

  • Refresh Token Grant: Used to obtain a new access token when the current one expires.

Authorization Code FlowCopied!

Flow Overview

The Authorization Code Flow is a secure method for obtaining access and refresh tokens necessary for accessing protected resources on behalf of a user. This flow is suitable for applications where the client secret can be securely stored.

Key Characteristics:

  • User Interaction: The user explicitly authorizes the application by clicking a button like "I authorize this application."

  • Exchange of Authorization Code: An authorization code is exchanged for access and refresh tokens.

  • Long-Term Access: Tokens can be stored long-term to maintain access until the user revokes permissions.

Implementing the Flow with Provided Endpoints

This section provides specific URLs and endpoints based on our authentication server configuration. We will use shell commands to demonstrate the requests.

1. Application Registration

  • Client ID: YOUR_CLIENT_ID

  • Client Secret: YOUR_CLIENT_SECRET

  • Authorization Server URL: https://auth.janebunn.website/realms/janesweather

2. Set your rediredt URL

  • Redirect URI: http://localhost:8000/callback

Ensure that this URI is registered with the authorization server (contact us).

3. Initiate Authorization Request

Construct the authorization URL to redirect the user to the authorization server.

Authorization Endpoint:

https://auth.janebunn.website/realms/janesweather/protocol/openid-connect/auth

Parameters:

  • response_type=code

  • client_id=YOUR_CLIENT_ID

  • redirect_uri=http://localhost:8000/callback

Example Authorization URL:

https://auth.janebunn.website/realms/janesweather/protocol/openid-connect/auth?response_type=code&client_id=YOUR_CLIENT_ID&redirect_uri=http://localhost:8000/callback

4. User Authorization

  • User Action: The user clicks "I authorize this application" on the authorization server's login and consent page.

  • Authorization Server Response: The user is redirected back to your application at http://localhost:8000/callback with the code and state parameters.

5. Handle Authorization Response

In your /callback endpoint, extract the code and state from the query parameters.

6. Exchange Authorization Code for Tokens

Make a POST request to the token endpoint to exchange the authorization code for access and refresh tokens.

Token Endpoint:

https://auth.janebunn.website/realms/janesweather/protocol/openid-connect/token

Example Token Request:
curl -X POST "https://auth.janebunn.website/realms/janesweather/protocol/openid-connect/token" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=authorization_code" \
  -d "client_id=YOUR_CLIENT_ID" \
  -d "client_secret=YOUR_CLIENT_SECRET" \
  -d "code=AUTHORIZATION_CODE" \
  -d "redirect_uri=http://localhost:8000/callback"

Replace:

  • YOUR_CLIENT_ID with your actual client id.

  • YOUR_CLIENT_SECRET with your actual client secret.

  • AUTHORIZATION_CODE with the code received from the authorization response.

7. Receive Access and Refresh Tokens

The response will be in JSON format and contain:

  • access_token

  • refresh_token

  • expires_in

  • refresh_expires_in

  • token_type

  • Other OpenID Connect tokens if applicable

Example Response:

"access_token": "ACCESS_TOKEN", 
"refresh_token": "REFRESH_TOKEN", 
"expires_in": 300, 
"refresh_expires_in": 1800, 
"token_type": "Bearer", 
"id_token": "ID_TOKEN", 
"not-before-policy": 0, 
"session_state": "SESSION_STATE", 
"scope": "openid profile email" 

8. Store Tokens for Long-Term Use

Securely store the access_token and refresh_token for long-term use.

9. Access Protected Resources

Use the access_token to access protected resources by including it in the Authorization header.

Example API Request:

curl -X GET "https://api.janebunn.website/forecast/ecmwf.0p1?lat=-37.840935&lng=144.946457&pid=ChIJ90260rVG1moRkM" \ -H "Authorization: Bearer ACCESS_TOKEN"

Replace ACCESS_TOKEN with your actual access token.

10. Refresh the Access Token

When the access_token expires, use the refresh_token to obtain a new access_token.

Refresh Token Request:

curl -X POST "https://auth.janebunn.website/realms/janesweather/protocol/openid-connect/token"
-H "Content-Type: application/x-www-form-urlencoded"
-d "grant_type=refresh_token"
-d "client_id=YOUR_CLIENT_ID"
-d "client_secret=YOUR_CLIENT_SECRET"
-d "refresh_token=REFRESH_TOKEN"

Replace:

  • YOUR_CLIENT_ID with your actual client id.

  • YOUR_CLIENT_SECRET with your actual client secret.

  • REFRESH_TOKEN with your stored refresh token.

11. Revoke Tokens (Logout)

To revoke the refresh token when a user decides to uninstall or disconnect your app.

Revocation Endpoint:

https://auth.janebunn.website/realms/janesweather/protocol/openid-connect/logout

Logout Request:

curl -X POST "https://auth.janebunn.website/realms/janesweather/protocol/openid-connect/logout"
-H "Content-Type: application/x-www-form-urlencoded"
-d "client_id=YOUR_CLIENT_ID"
-d "client_secret=YOUR_CLIENT_SECRET"
-d "refresh_token=REFRESH_TOKEN"

Note: After revoking the token, remove it from your storage.

Long-Term Token StorageCopied!

Importance of Long-Term Storage

Storing tokens long-term allows your application to maintain access to user resources without requiring the user to re-authenticate frequently. This is essential for providing seamless user experiences, such as background data synchronization, notifications, or any functionality that requires ongoing access.

Best Practices for Secure Storage

  • Secure Databases: Use databases with robust security features.

  • Encryption: Encrypt tokens before storing them to prevent unauthorized access.

  • Access Controls: Implement strict access controls to limit who and what can access the tokens.

  • Regular Audits: Monitor access patterns and audit logs regularly.

  • Token Lifecycle Management: Keep track of token expiry and refresh them proactively.

  • Key Management: Securely manage encryption keys, preferably using a Key Management Service (KMS).

Token Revocation Handling

  • User-Initiated Revocation: Provide users with an option to revoke access (e.g., "Uninstall" or "Disconnect" the app).

  • Revoke Tokens: Use the revocation endpoint to invalidate tokens.

Implementation GuidelinesCopied!

Database Storage Strategies

1. Use a Secure Database

  • Recommendations: Use databases like PostgreSQL, MySQL, or secure NoSQL databases.

  • Encryption at Rest: Enable database encryption features to protect data on disk.

  • Backups: Ensure that backups are also encrypted and securely stored.

2. Token Storage Schema

Store tokens in a table associated with the user’s account.

Example Table Structure:

Column

Type

Description

user_id

VARCHAR

Identifier for the user

access_token

TEXT

Encrypted access token

refresh_token

TEXT

Encrypted refresh token

access_token_expiry

TIMESTAMP

Access token expiration time

refresh_token_expiry

TIMESTAMP

Refresh token expiration time

scopes

VARCHAR

Scopes associated with the tokens

created_at

TIMESTAMP

Timestamp when tokens were stored

updated_at

TIMESTAMP

Timestamp when tokens were last updated

Encryption and Key Management

1. Encrypt Tokens

  • Symmetric Encryption: Use strong algorithms like AES-256.

  • Encryption Libraries: Utilize well-established libraries (e.g., OpenSSL, libsodium).

2. Secure Key Storage

  • Key Management Services (KMS): Use services like AWS KMS, Azure Key Vault, or Google Cloud KMS.

  • Key Rotation: Implement key rotation policies.

  • Access Controls: Restrict access to encryption keys to essential services and personnel.

Access Control and Monitoring

1. Implement Least Privilege

  • Database Users: Create database users with minimal required permissions.

  • Application Access: Ensure that only the necessary parts of your application can access the tokens.

2. Monitoring and Logging

  • Audit Logs: Keep detailed logs of access and modifications to token data.

  • Anomaly Detection: Set up alerts for unusual access patterns or failed access attempts.

3. Secure Application Code

  • Input Validation: Sanitize all inputs to prevent SQL injection and other injection attacks.

  • Secure Coding Practices: Follow best practices like those outlined in the OWASP Top Ten.

ConclusionCopied!

By integrating the OAuth 2.0 Authorization Code Flow using the provided URLs and endpoints, and securely storing tokens for long-term use, your application can provide a seamless and secure user experience. Proper token management ensures that users remain authenticated over extended periods without frequent re-authorization, enhancing usability while maintaining security.

Key Takeaways:

  • User Consent: Users authorize your application once, and you maintain access until they revoke it.

  • Secure Storage: Long-term token storage must be handled with robust security measures to protect user data.

  • Token Lifecycle: Proactively manage token expiry and refresh cycles to ensure uninterrupted access.

  • Revocation Handling: Implement mechanisms for users to revoke access and handle token invalidation accordingly.

ReferencesCopied!