or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

association-management.mdconsumer-auth.mddiscovery.mdextensions.mdindex.mdmessage-processing.mdserver-implementation.mdstorage-backends.mdutilities.md
tile.json

tessl/pypi-python3-openid

OpenID support for modern servers and consumers with comprehensive authentication functionality.

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
pypipkg:pypi/python3-openid@3.2.x

To install, run

npx @tessl/cli install tessl/pypi-python3-openid@3.2.0

index.mddocs/

Python3-OpenID

A comprehensive Python library implementing the OpenID authentication protocol for both consumers (relying parties) and servers (identity providers). This library provides complete OpenID 1.0, 1.1, and 2.0 support, enabling decentralized identity authentication for web applications with multiple storage backends and extension support.

Package Information

  • Package Name: python3-openid
  • Language: Python
  • Installation: pip install python3-openid
  • Optional Dependencies: pip install python3-openid[mysql] or pip install python3-openid[postgresql]

Core Imports

import openid

For consumer (relying party) implementations:

from openid.consumer import consumer
from openid.consumer.discover import discover
from openid.store.filestore import FileOpenIDStore

For server (identity provider) implementations:

from openid.server import server
from openid.store.filestore import FileOpenIDStore

For extensions:

from openid.extensions import sreg, ax

Basic Usage

Consumer Implementation

from openid.consumer import consumer
from openid.store.filestore import FileOpenIDStore
from openid.consumer.discover import discover

# Initialize consumer with session and store
store = FileOpenIDStore('/tmp/openid_store')
openid_consumer = consumer.Consumer({}, store)

# Start authentication
user_url = "https://example.com/user"
auth_request = openid_consumer.begin(user_url)

# Redirect user to identity provider
redirect_url = auth_request.redirectURL(
    realm="https://mysite.com",
    return_to="https://mysite.com/openid/complete"
)

# Handle return from identity provider
query = request.GET  # From your web framework
current_url = "https://mysite.com/openid/complete"
response = openid_consumer.complete(query, current_url)

if response.status == consumer.SUCCESS:
    print(f"Authentication successful for {response.identity_url}")
elif response.status == consumer.FAILURE:
    print(f"Authentication failed: {response.message}")

Server Implementation

from openid.server import server
from openid.store.filestore import FileOpenIDStore

# Initialize server with store
store = FileOpenIDStore('/tmp/openid_store')
openid_server = server.Server(store, op_endpoint="https://myop.com/openid")

# Handle incoming request
query = request.GET  # From your web framework
openid_request = openid_server.decodeRequest(query)

if openid_request.mode == "checkid_setup":
    # Authenticate user and create response
    if user_authenticated:
        openid_response = openid_request.answer(
            allow=True,
            server_url="https://myop.com/openid",
            identity=user_identity_url,
            claimed_id=user_claimed_id
        )
    else:
        # Redirect to login page
        pass

Architecture

The library follows a modular architecture with clear separation between consumer and server functionality:

  • Consumer Package: Handles relying party operations including discovery, authentication requests, and response processing
  • Server Package: Manages identity provider operations including request handling, user authentication, and response generation
  • Store Layer: Provides pluggable storage backends for associations and nonces (file, memory, SQL databases)
  • Extensions: Implements OpenID extensions like Simple Registration (SREG) and Attribute Exchange (AX)
  • Message Layer: Handles OpenID protocol message parsing, namespace management, and encoding
  • Discovery: Implements Yadis and HTML-based OpenID discovery protocols
  • Cryptographic Utilities: Provides association management, Diffie-Hellman key exchange, and message signing

Capabilities

Consumer Authentication

Complete OpenID consumer implementation for web applications acting as relying parties. Handles the full authentication flow from discovery through response processing with support for immediate and setup modes.

class Consumer:
    def __init__(self, session, store, consumer_class=None): ...
    def begin(self, user_url, anonymous=False): ...
    def complete(self, query, current_url): ...

class AuthRequest:
    def redirectURL(self, realm, return_to=None, immediate=False): ...
    def formMarkup(self, realm, return_to=None, immediate=False, form_tag_attrs=None): ...
    def addExtension(self, extension_request): ...

Consumer Authentication

OpenID Discovery

Comprehensive OpenID discovery system implementing Yadis, XRDS, and HTML-based discovery protocols. Handles service endpoint detection, URL normalization, and service type preference ordering for reliable identity provider discovery.

class OpenIDServiceEndpoint:
    def usesExtension(self, extension_uri): ...
    def preferredNamespace(self): ...
    def supportsType(self, type_uri): ...
    def compatibilityMode(self): ...
    def isOPIdentifier(self): ...

def discoverURI(uri): ...
def normalizeURL(url): ...

OpenID Discovery

Server Implementation

Complete OpenID server functionality for identity providers. Handles association requests, authentication requests, and verification with support for multiple session types and response encoding formats.

class Server:
    def __init__(self, store, op_endpoint=None, signatoryClass=Signatory, encoderClass=SigningEncoder, decoderClass=Decoder): ...
    def decodeRequest(self, query): ...
    def encodeResponse(self, response): ...
    def handleRequest(self, request): ...

class CheckIDRequest:
    def answer(self, allow, server_url=None, identity=None, claimed_id=None): ...
    def trustRootValid(self): ...
    def returnToVerified(self): ...

Server Implementation

Storage Backends

Pluggable storage system for associations and nonces with multiple backend implementations. Supports file-based, in-memory, and SQL database storage with automatic cleanup of expired data.

class OpenIDStore:
    def storeAssociation(self, server_url, association): ...
    def getAssociation(self, server_url, handle=None): ...
    def removeAssociation(self, server_url, handle): ...
    def useNonce(self, server_url, timestamp, salt): ...

class FileOpenIDStore(OpenIDStore): ...
class MemoryStore(OpenIDStore): ...
class SQLStore(OpenIDStore): ...

Storage Backends

OpenID Extensions

Implementation of standard OpenID extensions including Simple Registration (SREG) for basic profile data and Attribute Exchange (AX) for flexible attribute sharing between consumers and servers.

class SRegRequest:
    def __init__(self, required=None, optional=None, policy_url=None, sreg_ns_uri=ns_uri): ...
    def requestField(self, field_name, required=False, strict=False): ...
    def requestFields(self, field_names, required=False, strict=False): ...

class SRegResponse:
    def get(self, field_name, default=None): ...
    def items(self): ...

class FetchRequest:
    def add(self, attribute): ...
    def getRequiredAttrs(self): ...

class FetchResponse:
    def getSingle(self, type_uri, default=None): ...
    def get(self, type_uri): ...

OpenID Extensions

Association Management

Handles shared secrets between consumers and servers including creation, serialization, message signing, and expiration management. Supports HMAC-SHA1 and HMAC-SHA256 association types with plain-text and Diffie-Hellman session types.

class Association:
    def __init__(self, handle, secret, issued, lifetime, assoc_type): ...
    def sign(self, pairs): ...
    def signMessage(self, message): ...
    def checkMessageSignature(self, message): ...
    
class SessionNegotiator:
    def __init__(self, allowed_types): ...
    def isAllowed(self, assoc_type, session_type): ...
    def getAllowedType(self): ...

Association Management

Message Processing

OpenID protocol message handling with namespace management, encoding/decoding, and format conversion. Supports key-value form, URL encoding, and HTML form generation with proper namespace aliasing.

class Message:
    def __init__(self, openid_namespace=None): ...
    def fromPostArgs(cls, args): ...
    def fromKVForm(cls, kvform_string): ...
    def toURL(self, base_url): ...
    def toKVForm(self): ...
    def getArg(self, namespace, key, default=None): ...
    def setArg(self, namespace, key, value): ...

Message Processing

Core Utilities

Essential utility functions for OpenID implementations including URI normalization, cryptographic operations, key-value form processing, logging, and Diffie-Hellman key exchange.

def urinorm(uri): ...
def autoSubmitHTML(form, title='OpenID transaction in progress'): ...
def toBase64(data): ...
def fromBase64(data): ...

class DiffieHellman:
    def __init__(self, modulus, generator, private=None): ...
    def getSharedSecret(self, other_public): ...

Core Utilities

Types

# Response Status Constants
SUCCESS = 'success'
FAILURE = 'failure' 
CANCEL = 'cancel'
SETUP_NEEDED = 'setup_needed'

# Association Types
all_association_types = ['HMAC-SHA1', 'HMAC-SHA256']
default_association_order = [
    ('HMAC-SHA256', 'no-encryption'),
    ('HMAC-SHA1', 'no-encryption'),
    ('HMAC-SHA256', 'DH-SHA256'),
    ('HMAC-SHA1', 'DH-SHA1'),
]

# OpenID Namespace URIs
OPENID1_NS = 'http://openid.net/signon/1.0'
OPENID2_NS = 'http://specs.openid.net/auth/2.0'
IDENTIFIER_SELECT = 'http://specs.openid.net/auth/2.0/identifier_select'

# Discovery Service Types
OPENID_1_0_NS = 'http://openid.net/signon/1.0'
OPENID_IDP_2_0_TYPE = 'http://specs.openid.net/auth/2.0/server'
OPENID_2_0_TYPE = 'http://specs.openid.net/auth/2.0/signon'
OPENID_1_1_TYPE = 'http://openid.net/signon/1.1'
OPENID_1_0_TYPE = 'http://openid.net/signon/1.0'

# Session Types
session_types = ['DH-SHA1', 'DH-SHA256', 'no-encryption']

# SREG Extension
SREG_DATA_FIELDS = {
    'nickname': 'Any UTF-8 string that the End User wants to use as a nickname.',
    'email': 'The email address of the End User as specified in section 3.4.1 of [RFC2822]',
    'fullname': 'UTF-8 string free text representation of the End User\'s full name.',
    'dob': 'The End User\'s date of birth as YYYY-MM-DD.',
    'gender': 'The End User\'s gender, "M" for male, "F" for female.',
    'postcode': 'UTF-8 string free text that SHOULD conform to the End User\'s country\'s postal system.',
    'country': 'The End User\'s country of residence as specified by ISO3166.',
    'language': 'End User\'s preferred language as specified by ISO639.',
    'timezone': 'ASCII string from TimeZone database'
}

# Exception Types

# Consumer Exceptions
class ProtocolError(Exception): ...
class DiscoveryFailure(Exception): ...
class SetupNeededError(Exception): ...
class TypeURIMismatch(Exception): ...

# Server Exceptions  
class ServerError(Exception): ...
class VersionError(Exception): ...
class NoReturnToError(Exception): ...
class EncodingError(Exception): ...
class AlreadySigned(EncodingError): ...
class UntrustedReturnURL(ProtocolError): ...
class MalformedReturnURL(Exception): ...
class MalformedTrustRoot(Exception): ...

# Message Processing Exceptions
class UndefinedOpenIDNamespace(Exception): ...
class InvalidOpenIDNamespace(Exception): ...
class NamespaceAliasRegistrationError(Exception): ...

# Extension Exceptions
class SRegNamespaceError(Exception): ...
class AXError(Exception): ...
class NotAXMessage(Exception): ...

# Discovery Exceptions
class XRDSError(Exception): ...
class XRDSFetchingError(XRDSError): ...

# Trust Root Exceptions
class RealmVerificationRedirected(Exception): ...