Skip to content

OIDC OpenID Connect

OpenID Connect (OIDC) is a widely adopted identity layer built on top of the OAuth 2.0 protocol. It enables clients (applications) to verify the identity of an end user based on authentication performed by an authorization server (identity provider, or IdP), and to obtain basic profile information about the user. OIDC is crucial for implementing Single Sign-On (SSO) and securely managing user authentication in a standardized manner across web applications and APIs.

Key Concepts of OIDC

  • Authorization Server (IdP): The server responsible for authenticating the user and issuing tokens. Popular examples include Google, Okta, and Keycloak.
  • Client (Relying Party, RP): The application that wants to authenticate the user. It relies on the authorization server for authentication and token issuance.
  • ID Token: A JSON Web Token (JWT) that contains information about the authenticated user, including claims such as their identity.
  • Access Token: A token (typically a JWT) used to access protected resources on behalf of the user, usually for API access.
  • UserInfo Endpoint: An API endpoint provided by the authorization server where additional user details can be retrieved.

OIDC Workflow

  1. Authentication Request: The client redirects the user to the authorization server’s authentication page.
  2. User Authentication: The authorization server authenticates the user using mechanisms like username/password, multi-factor authentication (MFA), etc.
  3. Token Issuance: After successful authentication, the server issues an ID token (and optionally an access token) to the client.
  4. Token Validation: The client verifies the ID token by checking its signature, claims (audience, issuer, etc.), and expiration.
  5. UserInfo Retrieval: The client may call the UserInfo endpoint to obtain additional profile information about the authenticated user.

Python Ecosystem for OIDC

Several Python libraries make it easier to integrate OIDC authentication in your applications. Some of the most prominent options include:

  1. Authlib:
    Authlib is a powerful Python library for OAuth 2.0 and OpenID Connect. It provides an easy-to-use interface for handling OIDC authentication, including managing token exchange and user profile retrieval.

Example using Authlib:
```python
from authlib.integrations.requests_client import OAuth2Session

client = OAuth2Session(client_id, client_secret, scope=’openid profile email’)
uri, state = client.create_authorization_url(authorization_endpoint)
# Redirect the user to the authorization server

# Once redirected back with a code
token = client.fetch_token(token_endpoint, authorization_response=callback_url)
user_info = client.get(userinfo_endpoint).json()
```

  1. Django Integration:
    For Django applications, mozilla-django-oidc is a popular package that simplifies OIDC integration by providing authentication hooks and session management.

Example Django configuration:
python # In settings.py OIDC_RP_CLIENT_ID = 'your-client-id' OIDC_RP_CLIENT_SECRET = 'your-client-secret' OIDC_OP_AUTHORIZATION_ENDPOINT = 'https://your-idp/authorize' OIDC_OP_TOKEN_ENDPOINT = 'https://your-idp/token' OIDC_OP_USER_ENDPOINT = 'https://your-idp/userinfo'

  1. FastAPI Integration:
    FastAPI, known for its asynchronous capabilities, can also be integrated with OIDC using libraries like fastapi-authlib or Authlib. This provides a seamless way to authenticate users in modern API-driven applications.

Example with FastAPI:
```python
from fastapi import FastAPI, Depends
from authlib.integrations.starlette_client import OAuth

app = FastAPI()
oauth = OAuth()
oidc = oauth.register(‘oidc’, client_id=’client-id’, client_secret=’client-secret’, …)

@app.route(‘/login’)
async def login(request: Request):
redirect_uri = url_for(‘auth’, _external=True)
return await oidc.authorize_redirect(request, redirect_uri)
```

Example with Flask and OIDC

Prerequisites

  1. Install Flask and Authlib:
    bash pip install Flask Authlib

  2. Use an OpenID Connect provider (e.g., Google, Keycloak, or Okta) for your client credentials and provider endpoints.

Flask OIDC Example

from flask import Flask, redirect, url_for, session
from authlib.integrations.flask_client import OAuth

app = Flask(__name__)
app.secret_key = 'your_secret_key'
app.config['SESSION_COOKIE_NAME'] = 'flask_oidc_session'

# OIDC provider details
OIDC_CLIENT_ID = 'your-client-id'
OIDC_CLIENT_SECRET = 'your-client-secret'
OIDC_DISCOVERY_URL = 'https://your-oidc-provider/.well-known/openid-configuration'

# Initialize OAuth and configure the OIDC provider
oauth = OAuth(app)
oidc = oauth.register(
    name='oidc',
    client_id=OIDC_CLIENT_ID,
    client_secret=OIDC_CLIENT_SECRET,
    server_metadata_url=OIDC_DISCOVERY_URL,
    client_kwargs={'scope': 'openid profile email'}
)

@app.route('/')
def home():
    user_info = session.get('user')
    if user_info:
        return f"Hello, {user_info['email']}!"
    return '<a href="/login">Login with OIDC</a>'

@app.route('/login')
def login():
    redirect_uri = url_for('auth', _external=True)
    return oidc.authorize_redirect(redirect_uri)

@app.route('/auth')
def auth():
    token = oidc.authorize_access_token()
    user_info = oidc.parse_id_token(token)
    session['user'] = user_info
    return redirect('/')

@app.route('/logout')
def logout():
    session.pop('user', None)
    return redirect('/')

if __name__ == '__main__':
    app.run(debug=True)

Use Cases for OIDC in Python

  1. Single Sign-On (SSO): OIDC is frequently used to implement SSO across different services and applications. Users can log in once via an identity provider and seamlessly access multiple applications without re-authenticating.

  2. API Security: With OIDC, APIs can verify the identity of users using the ID token, ensuring that the users accessing an API are authenticated and authorized.

  3. Multi-Tenant Applications: OIDC allows applications to support multiple identity providers, making it easier to authenticate users from different organizations or systems.

Best Practices and Considerations

  • Token Validation: Always validate the signature and claims in the ID token to ensure its authenticity and integrity.
  • Client Secret Management: Store client secrets securely, and never expose them in client-side code.
  • Scope Minimization: Request only the scopes you need (e.g., openid profile email) to minimize the amount of user information you handle.
  • PKCE for Public Clients: Use Proof Key for Code Exchange (PKCE) in public clients (such as mobile apps) to enhance security during the token exchange process.

Page last modified: 2024-09-25 08:35:47