Skip to main content

An async Python client for Keycloak authentication

Project description

IdP Async Client Documentation

Table of Contents

Overview

IdP Async Client is a Python library that provides a unified interface for interacting with Identity Providers (IdPs). It currently supports Keycloak with plans to expand to other IdP solutions.

Key Features

  • Async/await support
  • Token verification & management
  • Session handling
  • Role-based access control
  • Web framework integration
  • Extensible IdP support

Installation

pip install idp-async-client

Getting Started

Basic Setup

from idp_async_client import IdPClient, IdPConfig

# Configure the client
config = IdPConfig(
    provider="keycloak",
    server_url="http://localhost:8080",
    realm_name="my-realm",
    client_id="my-client",
    client_secret="my-secret"
)

# Create client instance
client = IdPClient(config)

Initial Test

# Test connection
async def test_connection():
    is_available = await client.test_connection()
    print(f"IdP server is {'available' if is_available else 'unavailable'}")

Authentication

Password-Based Login

# Login with username and password
async def login():
    try:
        tokens = await client.login_with_password(
            username="user@example.com",
            password="secure_password"
        )
        return tokens
    except AuthenticationError as e:
        print(f"Login failed: {e}")

Social Login

# Login with social provider
async def social_login():
    tokens = await client.login_with_social(
        subject_token="social-provider-token",
        subject_issuer="google"
    )
    return tokens

Token Management

Token Verification

# Verify token
async def verify_token(token: str):
    try:
        user_data = await client.verify_token(token)
        print(f"Token valid for user: {user_data['username']}")
        return user_data
    except TokenError as e:
        print(f"Token invalid: {e}")

Token Refresh

# Refresh access token
async def refresh_token(refresh_token: str):
    try:
        new_tokens = await client.refresh_token(refresh_token)
        return new_tokens
    except TokenError as e:
        print(f"Token refresh failed: {e}")

Role-Based Access

Role Verification

# Check user roles
async def verify_user_access(token: str, required_roles: list):
    try:
        user_data = await client.verify_token(
            token=token,
            verify_roles=required_roles
        )
        return True
    except AuthenticationError:
        return False

Protected Route Decorator

from idp_async_client.auth import require_auth

@require_auth(roles=['admin'])
async def protected_route(request):
    return {"status": "accessed by admin"}

Session Management

Managing User Sessions

# Get user sessions
async def get_sessions(user_id: str):
    sessions = await client.get_user_sessions(user_id)
    return sessions

# Revoke session
async def revoke_session(session_id: str):
    await client.revoke_session(session_id)

Logout

# Logout user
async def logout(refresh_token: str):
    try:
        await client.logout(refresh_token)
        return {"status": "logged out"}
    except Exception as e:
        print(f"Logout failed: {e}")

Web Integration

Middleware Setup

from idp_async_client.middleware import IdPMiddleware

# FastAPI example
app = FastAPI()
app.add_middleware(
    IdPMiddleware,
    idp_client=client,
    required_roles=['user']
)

# Django example
MIDDLEWARE = [
    'idp_async_client.middleware.DjangoIdPMiddleware',
]

Custom Cache Implementation

from idp_async_client.cache import BaseCache

class RedisCache(BaseCache):
    def __init__(self, redis_client):
        self.redis = redis_client

    async def get(self, key: str):
        return await self.redis.get(key)

    async def set(self, key: str, value: str, timeout: int = None):
        await self.redis.set(key, value, ex=timeout)

Configuration

Configuration Options

config = IdPConfig(
    # Required settings
    provider="keycloak",
    server_url="http://localhost:8080",
    realm_name="my-realm",
    client_id="my-client",
    client_secret="my-secret",
    
    # Optional settings
    verify_ssl=True,
    timeout=30,
    token_expires_in=300,
    refresh_expires_in=1800,
    cache_timeout=86400
)

Environment Variables

export IDP_SERVER_URL="http://localhost:8080"
export IDP_REALM_NAME="my-realm"
export IDP_CLIENT_ID="my-client"
export IDP_CLIENT_SECRET="my-secret"

Error Handling

Exception Types

from idp_async_client.exceptions import (
    IdPError,
    AuthenticationError,
    TokenError,
    ConfigError
)

async def handle_auth():
    try:
        tokens = await client.login_with_password(
            "username",
            "password"
        )
    except AuthenticationError as e:
        # Handle authentication failure
        print(f"Authentication failed: {e}")
    except TokenError as e:
        # Handle token-related errors
        print(f"Token error: {e}")
    except ConfigError as e:
        # Handle configuration issues
        print(f"Configuration error: {e}")
    except IdPError as e:
        # Handle general IdP errors
        print(f"IdP error: {e}")

API Reference

Main Classes

  • IdPClient: Main client interface
  • IdPConfig: Configuration class
  • TokenVerifier: Token verification utilities
  • SessionManager: Session management utilities

Utilities

  • token_utils: Token handling utilities
  • cache_utils: Caching utilities
  • crypto_utils: Cryptographic utilities

FAQ

Common Issues

Q: Why am I getting token verification errors? A: Ensure your server's clock is synchronized and the token hasn't expired.

Q: How do I handle token expiration? A: Use the refresh token to get a new access token before it expires.

Q: Can I use multiple IdP providers? A: Yes, create separate client instances with different configurations.

Best Practices

  1. Always use HTTPS in production
  2. Implement proper error handling
  3. Use role-based access control
  4. Regularly rotate client secrets
  5. Implement token refresh logic
  6. Use secure session storage

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

idp_async_client-0.1.0.tar.gz (11.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

idp_async_client-0.1.0-py3-none-any.whl (7.5 kB view details)

Uploaded Python 3

File details

Details for the file idp_async_client-0.1.0.tar.gz.

File metadata

  • Download URL: idp_async_client-0.1.0.tar.gz
  • Upload date:
  • Size: 11.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.0.1 CPython/3.12.8

File hashes

Hashes for idp_async_client-0.1.0.tar.gz
Algorithm Hash digest
SHA256 c2aa72aa5a5dee3ffbdd97d4675b12c30e049ec56f955a93b279c7f63e9ca477
MD5 c8fec4dd59f2208d226c71020672686a
BLAKE2b-256 87cb35d6985589178fabf5d70db33ab19a79bd6a33679d71e02ca06c9dcad345

See more details on using hashes here.

File details

Details for the file idp_async_client-0.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for idp_async_client-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 ec8027fc1fcfeae8f4bf28276e1a41f52d783a4ec4fc43d72139eb752791b384
MD5 0fd758f19e0217adce4cb43115228181
BLAKE2b-256 e751d1aa8b3b9be2fc79ccf5ba42533123f236fb051f7e697acbb2cc1ebd8583

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page