A comprehensive Python library for implementing OAuth 1.0 and OAuth 2.0 authentication protocols
OpenID Connect identity layer implementation providing ID tokens, UserInfo endpoint, and authentication extensions to OAuth 2.0. Includes JWT token handling, claims processing, and user authentication flows.
Complete OpenID Connect server implementation extending OAuth 2.0 with identity features.
class Server:
def __init__(self, request_validator, token_expires_in=None, token_generator=None, refresh_token_generator=None, **kwargs): ...
def create_userinfo_response(
self,
uri: str,
http_method: str = "GET",
body: str | None = None,
headers: dict[str, str] | None = None,
**kwargs,
) -> tuple[dict[str, str], str, int]:
"""Create UserInfo endpoint response with user claims."""OpenID Connect UserInfo endpoint providing user claims based on access token scope.
class UserInfoEndpoint:
def create_userinfo_response(
self,
uri: str,
http_method: str = "GET",
body: str | None = None,
headers: dict[str, str] | None = None,
**kwargs,
) -> tuple[dict[str, str], str, int]:
"""Create UserInfo response with user claims."""Extended request validator with OpenID Connect specific validation methods.
class RequestValidator: # Extends OAuth2 RequestValidator
def get_id_token(self, token: dict, token_handler, request) -> str:
"""Generate ID token for authenticated user."""
def validate_id_token(self, token: str, scopes: list[str], request) -> bool:
"""Validate ID token."""
def get_userinfo_claims(self, request) -> dict | str:
"""Get user claims for UserInfo endpoint."""
def validate_silent_authorization(self, request) -> bool:
"""Validate silent authorization request."""
def validate_silent_login(self, request) -> bool:
"""Validate silent login request."""
def validate_user_match(self, id_token_hint: str, scopes: list[str], claims: dict, request) -> bool:
"""Validate user matches ID token hint."""
def get_authorization_code_scopes(self, client_id: str, code: str, redirect_uri: str, request) -> list[str]:
"""Get scopes for authorization code."""
def get_authorization_code_nonce(self, client_id: str, code: str, redirect_uri: str, request) -> str:
"""Get nonce for authorization code."""
def finalize_id_token(self, id_token: str, token: dict, token_handler, request) -> str:
"""Finalize ID token before issuance."""
def refresh_id_token(self, request) -> bool:
"""Whether to refresh ID token on token refresh."""from oauthlib.openid import RequestValidator, Server
class OpenIDRequestValidator(RequestValidator):
def get_id_token(self, token, token_handler, request):
user = get_user(request.user_id)
id_token_claims = {
'sub': str(user.id),
'name': user.full_name,
'email': user.email,
'email_verified': user.email_verified,
'picture': user.avatar_url,
'iss': 'https://your-server.com',
'aud': request.client_id,
'iat': int(time.time()),
'exp': int(time.time()) + 3600,
'nonce': getattr(request, 'nonce', None)
}
return create_jwt_token(id_token_claims)
def get_userinfo_claims(self, request):
user = get_user_from_token(request.access_token)
scopes = request.scopes
claims = {'sub': str(user.id)}
if 'profile' in scopes:
claims.update({
'name': user.full_name,
'given_name': user.first_name,
'family_name': user.last_name,
'picture': user.avatar_url
})
if 'email' in scopes:
claims.update({
'email': user.email,
'email_verified': user.email_verified
})
return claims
server = Server(OpenIDRequestValidator())Install with Tessl CLI
npx tessl i tessl/pypi-oauthlib