### Run Flask OIDC-op Example Source: https://github.com/identitypython/idpy-oidc/blob/main/example/flask_op/README.md Execute these commands to navigate to the example directory, install dependencies, and start the server. ```bash cd flask_op/ ``` ```bash pip install -r requirements.txt # install the dependencies ``` ```bash ./server.py config.yaml ``` -------------------------------- ### Clone Repository and Run Example Source: https://github.com/identitypython/idpy-oidc/blob/main/doc/client/server/contents/setup.md Clone the idpy-oidc repository, navigate to the Flask OP example directory, and run the provided script. ```bash git clone https://github.com/identitypython/idpy-oidc.git cd idpy-oidc/example/flask_op/ bash run.sh ``` -------------------------------- ### Example Flask OP Server Output Source: https://github.com/identitypython/idpy-oidc/blob/main/doc/client/server/contents/setup.md This is the expected output when running the Flask OpenID Provider example script. ```text flask_op % bash run.sh 2022-03-25 08:49:22,801 root DEBUG Configured logging using dictionary * Serving Flask app "oidc_op" (lazy loading) * Environment: production WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead. * Debug mode: on 2022-03-25 08:49:22,841 werkzeug INFO * Running on https://127.0.0.1:5000/ (Press CTRL+C to quit) 2022-03-25 08:49:22,842 werkzeug INFO * Restarting with stat 2022-03-25 08:49:23,202 root DEBUG Configured logging using dictionary 2022-03-25 08:49:23,240 werkzeug WARNING * Debugger is active! 2022-03-25 08:49:23,245 werkzeug INFO * Debugger PIN: 162-062-616 ``` -------------------------------- ### Full Client-Server OAuth2/OIDC Flow Setup Source: https://context7.com/identitypython/idpy-oidc/llms.txt Sets up an OpenID Connect server and client, including key definitions and endpoint configurations. ```python from idpyoidc.client.oidc import RP from idpyoidc.server import Server from idpyoidc.server.configure import OPConfiguration # Key definitions KEY_DEFS = [ {"type": "RSA", "use": ["sig"]}, {"type": "EC", "crv": "P-256", "use": ["sig"]} ] # Server setup server_conf = { "issuer": "https://op.example.com", "key_conf": {"uri_path": "jwks.json", "key_defs": KEY_DEFS}, "endpoint": { "provider_config": { "path": ".well-known/openid-configuration", "class": "idpyoidc.server.oidc.provider_config.ProviderConfiguration", }, "authorization": { "path": "authorization", "class": "idpyoidc.server.oidc.authorization.Authorization", }, "token": { "path": "token", "class": "idpyoidc.server.oidc.token.Token", }, "userinfo": { "path": "userinfo", "class": "idpyoidc.server.oidc.userinfo.UserInfo", } }, "token_handler_args": { "key_conf": {"key_defs": KEY_DEFS}, "code": {"lifetime": 600}, "token": {"lifetime": 3600}, }, "userinfo": {"class": "idpyoidc.server.user_info.UserInfo", "kwargs": {"db_file": "users.json"}} } server = Server(OPConfiguration(conf=server_conf)) # Client setup client_conf = { "issuer": "https://op.example.com", "client_id": "client_123", "client_secret": "secret_456", "redirect_uris": ["https://rp.example.com/callback"], "key_conf": {"key_defs": KEY_DEFS}, "allowed_scopes": ["openid", "profile", "email"], "services": { "provider_info": {"class": "idpyoidc.client.oidc.provider_info_discovery.ProviderInfoDiscovery"}, "authorization": {"class": "idpyoidc.client.oidc.authorization.Authorization"}, "accesstoken": {"class": "idpyoidc.client.oidc.access_token.AccessToken"}, "userinfo": {"class": "idpyoidc.client.oidc.userinfo.UserInfo"}, } } client = RP(config=client_conf) ``` -------------------------------- ### Basic User Info Configuration Source: https://github.com/identitypython/idpy-oidc/blob/main/doc/client/server/contents/conf.md Configure the user info endpoint with a database file. This is a fundamental setup. ```json "userinfo": { "class": "idpyoidc.server.user_info.UserInfo", "kwargs": { "db_file": "users.json" } } ``` -------------------------------- ### Authorization Response Example Source: https://github.com/identitypython/idpy-oidc/blob/main/doc/client/client/rp_handler.md This is an example of a typical query string received after a user is redirected back to the RP. ```text state=Oh3w3gKlvoM2ehFqlxI3HIK5&scope=openid&code=Z0FBQUFBQmFkdFFjUVpFWE81SHU5N1N4N01&iss=https%3A%2F%2Fexample.org%2Fop&client_id=zls2qhN1jO6A ``` -------------------------------- ### Install idpy-oidc Package Source: https://github.com/identitypython/idpy-oidc/blob/main/doc/client/server/contents/setup.md Install the idpy-oidc library using pip. ```bash pip install idpyoidc ``` -------------------------------- ### Create Session Example Source: https://github.com/identitypython/idpy-oidc/blob/main/doc/client/server/contents/session/session_management.md Demonstrates creating a new session using the SessionManager. Requires an AuthnEvent instance, authentication request details, user ID, client ID, and optional subject type and sector identifier. ```python authn_event = create_authn_event(self.user_id) session_manager.create_session(authn_event=authn_event, auth_req=auth_req, user_id=self.user_id, client_id=client_id, sub_type=sub_type, sector_identifier=sector_identifier) ``` -------------------------------- ### Configure DPoP Add-on in Client Configuration Source: https://github.com/identitypython/idpy-oidc/blob/main/doc/client/client/add_on/dpop.md Add this section to your client configuration to enable DPoP support. Specify the desired signing algorithms for DPoP. Ensure the 'function' path is correct for your setup. ```python 'add_ons': { "dpop": { "function": "idpyoidc.client.oauth2.add_on.dpop.add_support", "kwargs": { "signing_algorithms": ["ES256", "ES512"] } } } ``` -------------------------------- ### Configure JWK Set paths and key definitions Source: https://github.com/identitypython/idpy-oidc/blob/main/doc/client/server/contents/conf.md This configuration example shows how to define paths for private and public JWK Set files, specify key definitions (type, curve, usage), and control whether keys are read-only. ```yaml "keys": { "private_path": "private/jwks.json", "key_defs": [ { "type": "RSA", "use": [ "sig" ] }, { "type": "EC", "crv": "P-256", "use": [ "sig" ] } ], "public_path": "static/jwks.json", "read_only": false, "uri_path": "static/jwks.json" } ``` -------------------------------- ### Initialize OIDC RP Client Source: https://context7.com/identitypython/idpy-oidc/llms.txt Configure and initialize an OIDC Relying Party (RP) client. This includes setting up issuer details, client credentials, redirect URIs, and desired scopes. Use this for basic RP setup. ```python oidc_config = { "issuer": "https://op.example.com", "client_id": "oidc_client", "client_secret": "oidc_secret", "redirect_uris": ["https://rp.example.com/callback"], "response_types": ["code"], "scope": ["openid", "profile", "email", "address"], "key_conf": { "key_defs": [ {"type": "RSA", "use": ["sig"]}, {"type": "EC", "crv": "P-256", "use": ["sig"]} ] }, "services": { "provider_info": {"class": "idpyoidc.client.oidc.provider_info_discovery.ProviderInfoDiscovery"}, "authorization": {"class": "idpyoidc.client.oidc.authorization.Authorization"}, "accesstoken": {"class": "idpyoidc.client.oidc.access_token.AccessToken"}, "userinfo": {"class": "idpyoidc.client.oidc.userinfo.UserInfo"}, "registration": {"class": "idpyoidc.client.oidc.registration.Registration"}, } } # Initialize OIDC RP rp = RP(config=oidc_config) # Discover provider configuration provider_info = rp.do_request("provider_info") print(f"Issuer: {provider_info['issuer']}") print(f"Supported scopes: {provider_info.get('scopes_supported')}") # Get userinfo with access token userinfo = rp.do_request( "userinfo", request_args={"access_token": "SlAV32hkKG"}, state="session_state" ) print(f"User subject: {userinfo['sub']}") print(f"Email: {userinfo.get('email')}") # Fetch distributed claims if present if "_claim_sources" in userinfo: userinfo = rp.fetch_distributed_claims(userinfo) ``` -------------------------------- ### Per-Client Resource Indicators Configuration Source: https://github.com/identitypython/idpy-oidc/blob/main/doc/client/server/contents/conf.md Configure resource indicators for a specific client within its metadata. This example shows configuration for the authorization code endpoint. ```json "resource_indicators":{ "authorization_code": { "policy": { "callable": validate_authorization_resource_indicators_policy, "kwargs": { "resource_servers_per_client": ["RESOURCE_1"], }, }, }, }, } ``` -------------------------------- ### Initialize RP Handler for Multi-Provider Client Management Source: https://context7.com/identitypython/idpy-oidc/llms.txt Configure and initialize an RPHandler to manage multiple OpenID Provider (OP) connections. This setup is useful when your application needs to interact with several different OPs. ```python from idpyoidc.client.rp_handler import RPHandler # Configuration for multiple providers rph_config = { "base_url": "https://rp.example.com", "client_configs": { "https://google.com": { "client_id": "google_client_id", "client_secret": "google_secret", "redirect_uris": ["https://rp.example.com/callback/google"], "issuer": "https://accounts.google.com", }, "https://github.com": { "client_id": "github_client_id", "client_secret": "github_secret", "redirect_uris": ["https://rp.example.com/callback/github"], "issuer": "https://github.com", }, "": { # Default config for dynamic registration "redirect_uris": ["https://rp.example.com/callback"], "response_types": ["code"], } }, "services": { "provider_info": {"class": "idpyoidc.client.oidc.provider_info_discovery.ProviderInfoDiscovery"}, "authorization": {"class": "idpyoidc.client.oidc.authorization.Authorization"}, "accesstoken": {"class": "idpyoidc.client.oidc.access_token.AccessToken"}, "userinfo": {"class": "idpyoidc.client.oidc.userinfo.UserInfo"}, } } # Initialize RP Handler rph = RPHandler(config=rph_config) # Begin authentication flow with a specific issuer auth_info = rph.begin( issuer_id="https://google.com", req_args={"scope": ["openid", "email", "profile"]} ) # Returns: {"url": "https://accounts.google.com/authorize?", "state": "..."} # Or discover issuer via WebFinger auth_info = rph.begin(user_id="user@example.com") # Handle callback and finalize authentication callback_response = {"code": "auth_code", "state": "session_state"} result = rph.finalize(issuer="https://google.com", response=callback_response) # Returns: {"userinfo": {...}, "state": "...", "token": "...", "id_token": {...}} # Get tokens for a session tokens = rph.get_tokens(state="session_state") # Refresh access token new_tokens = rph.refresh_access_token(state="session_state") # Get userinfo userinfo = rph.get_user_info(state="session_state") # Logout logout_info = rph.logout(state="session_state", post_logout_redirect_uri="https://rp.example.com") ``` -------------------------------- ### Refresh Token Example Source: https://github.com/identitypython/idpy-oidc/blob/main/doc/client/server/contents/examples.md Use this snippet to refresh an access token using a refresh token. Ensure the initial scope included 'offline_access' to obtain a usable refresh token. ```python import requests CLIENT_ID = "DBP60x3KUQfCYWZlqFaS_Q" CLIENT_SECRET="8526270403788522b2444e87ea90c53bcafb984119cec92eeccc12f1" REFRESH_TOKEN = "Z0FBQUFBQ ... lN2JNODYtZThjMnFsZUNDcg==" data = { "grant_type" : "refresh_token", "client_id" : f"{CLIENT_ID}", "client_secret" : f"{CLIENT_SECRET}", "refresh_token" : f"{REFRESH_TOKEN}" } headers = {'Content-Type': "application/x-www-form-urlencoded" } response = requests.post( 'https://127.0.0.1:8000/oidcop/token', verify=False, data=data, headers=headers ) ``` ```json { 'access_token': 'eyJhbGc ... CIOH_09tT_YVa_gyTqg', 'token_type': 'Bearer', 'scope': 'openid profile email address phone offline_access', 'refresh_token': 'Z0FBQ ... 1TE16cm1Tdg==' } ``` -------------------------------- ### Handle OAuth2 Access Token Request and Response Source: https://context7.com/identitypython/idpy-oidc/llms.txt Provides examples for constructing AccessTokenRequest for code exchange, refreshing tokens, and client credentials grants. Also shows how to parse an AccessTokenResponse and includes a verification step for client credentials requests. ```python from idpyoidc.message.oauth2 import ( AccessTokenRequest, AccessTokenResponse, RefreshAccessTokenRequest, CCAccessTokenRequest ) # Authorization code exchange token_request = AccessTokenRequest( grant_type="authorization_code", code="SplxlOBeZQQYbYS6WxSbIA", redirect_uri="https://client.example.org/callback", client_id="s6BhdRkqt3", ) # Parse token response token_response = AccessTokenResponse( access_token="SlAV32hkKG", token_type="Bearer", expires_in=3600, refresh_token="8xLOxBtZp8", scope=["openid", "profile"] ) # Refresh token request refresh_request = RefreshAccessTokenRequest( grant_type="refresh_token", refresh_token="8xLOxBtZp8", scope=["openid"] ) # Client credentials grant cc_request = CCAccessTokenRequest( grant_type="client_credentials", scope=["api:read", "api:write"], client_id="service_client", client_secret="secret123" ) cc_request.verify() # Validates grant_type is "client_credentials" print(f"Access token: {token_response['access_token']}") print(f"Expires in: {token_response['expires_in']} seconds") ``` -------------------------------- ### Define a class with various data types using ImpExp Source: https://github.com/identitypython/idpy-oidc/blob/main/doc/client/server/contents/persistent_storage.md Create a class that inherits from ImpExp and defines parameters with different data types, including strings, lists, dictionaries, and message objects. This setup is the first step before assigning values and dumping the object. ```default from cryptojwt import KeyBundle from idpyoidc.impexp import ImpExp from idpyoidc.message.oauth2 import AuthorizationResponse from idpyoidc.message.oidc import AuthorizationRequest KEYSPEC = [ {"type": "RSA", "use": ["sig"]}, {"type": "EC", "crv": "P-256", "use": ["sig"]}, ] class ImpExpTest(ImpExp): parameter = { "string": "", "list": [], "dict": {}, "message": AuthorizationRequest, "response_class": object, "key_bundle": KeyBundle, "bundles": [KeyBundle], } ``` -------------------------------- ### Exchange Access Token Source: https://github.com/identitypython/idpy-oidc/blob/main/doc/client/server/contents/examples.md Use this Python code to exchange an existing access token for a new one. Ensure you have the 'requests' library installed. The `verify=False` argument is used for simplicity in this example and should be handled securely in production. ```python import requests CLIENT_ID="" CLIENT_SECRET="" SUBJECT_TOKEN="" REQUESTED_TOKEN_TYPE="urn:ietf:params:oauth:token-type:access_token" data = { "grant_type" : "urn:ietf:params:oauth:grant-type:token-exchange", "requested_token_type" : f"{REQUESTED_TOKEN_TYPE}", "client_id" : f"{CLIENT_ID}", "client_secret" : f"{CLIENT_SECRET}", "subject_token" : f"{SUBJECT_TOKEN}" } headers = {'Content-Type': "application/x-www-form-urlencoded" } response = requests.post( 'https://example.com/OIDC/token', verify=False, data=data, headers=headers ) ``` -------------------------------- ### Client Registration and Server Initialization Source: https://context7.com/identitypython/idpy-oidc/llms.txt Registers a client with the server and initializes the server's provider information. ```python # Register client with server server.context.cdb["client_123"] = { "client_id": "client_123", "client_secret": "secret_456", "redirect_uris": ["https://rp.example.com/callback"], "allowed_scopes": ["openid", "profile", "email"], } server.context.keyjar.import_jwks(client.keyjar.export_jwks(), "client_123") server.context.set_provider_info() ``` -------------------------------- ### Initialize Message with keyword arguments Source: https://github.com/identitypython/idpy-oidc/blob/main/doc/client/message/howto/message.md Shows how to initialize a Message instance directly with key-value pairs using keyword arguments. The printed output reflects the initialized state. ```default >>> from idpyoidc.message import Message >>> msg = Message(key='value', other=6) >>> print(msg) {'other': 6, 'key': 'value'} ``` -------------------------------- ### Introspection Endpoint Example Source: https://github.com/identitypython/idpy-oidc/blob/main/doc/client/server/contents/examples.md This example demonstrates how to use the idpyoidc OP introspection endpoint with HTTP Basic Authentication for the client. The token type hint can be 'access_token' or 'refresh_token'. ```python import base64 import requests TOKEN = "eyJhbGciOiJFUzI1NiIsImtpZCI6IlQwZGZTM1ZVYUcxS1ZubG9VVTQwUXpJMlMyMHpjSHBRYlMxdGIzZ3hZVWhCYzNGaFZWTlpTbWhMTUEifQ.eyJzY29wZSI6IFsib3BlbmlkIiwgInByb2ZpbGUiLCAiZW1haWwiLCAiYWRkcmVzcyIsICJwaG9uZSJdLCAiYXVkIjogWyJvTHlSajdzSkozWHZBWWplRENlOHJRIl0sICJqdGkiOiAiOWQzMjkzYjZiYmNjMTFlYmEzMmU5ODU0MWIwNzE1ZWQiLCAiY2xpZW50X2lkIjogIm9MeVJqN3NKSjNYdkFZamVEQ2U4clEiLCAic3ViIjogIm9MeVJqN3NKSjNYdkFZamVEQ2U4clEiLCAic2lkIjogIlowRkJRVUZCUW1keGJIVlpkRVJKYkZaUFkxQldaa0pQVUVGc1pHOUtWWFZ3VFdkZmVEY3diMVprYmpSamRrNXRMVzB4YTNnelExOHlRbHBHYTNRNVRHZEdUUzF1UW1sMlkzVnhjRE5sUm01dFRFSmxabGRXYVhJeFpFdHVSV2xtUzBKcExWTmFaRzV3VjJodU0yNXlSbTU0U1ZWVWRrWTRRM2x2UWs1TlpVUk9SazlGVlVsRWRteGhjWGx2UWxWRFdubG9WbTFvZGpORlVUSnBkaTFaUTFCcFptZFRabWRDVWt0YVNuaGtOalZCWVhkcGJFNXpaV2xOTTFCMk0yaE1jMDV0ZGxsUlRFc3dObWxsYUcxa1lrTkhkemhuU25OaWFWZE1kVUZzZDBwWFdWbzFiRWhEZFhGTFFXWTBPVzl5VjJOUk4zaGtPRDA9IiwgInR0eXBlIjogIlQiLCAiaXNzIjogImh0dHBzOi8vMTI3LjAuMC4xOjgwMDAiLCAiaWF0IjogMTYyMTc3NzMwNSwgImV4cCI6IDE2MjE3ODA5MDV9.pVqxUNznsoZu9ND18IEMJIHDOT6_HxzoFiTLsniNdbAdXTuOoiaKeRTqtDyjT9WuUPszdHkVjt5xxeFX8gQMuA" data = { 'token': TOKEN, 'token_type_hint': 'access_token' } _basic_secret = base64.b64encode( f'{"oLyRj7sJJ3XvAYjeDCe8rQ"}:{"53fb49f2a6501ec775355c89750dc416744a3253138d5a04e409b313"}'.encode() ) headers = { 'Authorization': f"Basic {_basic_secret.decode()}" } requests.post('https://127.0.0.1:8000/introspection', verify=False, data=data, headers=headers) ``` ```json { "active": true, "scope": "openid profile email address phone", "client_id": "oLyRj7sJJ3XvAYjeDCe8rQ", "token_type": "access_token", "exp": 0, "iat": 1621777305, "sub": "a7b0dea2958aec275a789d7d7dc8e7d09c6316dd4fc6ae92742ed3297e14dded", "iss": "https://127.0.0.1:8000", "aud": [ "oLyRj7sJJ3XvAYjeDCe8rQ" ] } ``` -------------------------------- ### Configure Client with DPoP Support Source: https://context7.com/identitypython/idpy-oidc/llms.txt Client configuration to enable DPoP (Demonstration of Proof-of-Possession) support. This add-on automatically generates DPoP proofs for requests. ```python # Client with DPoP support client_config = { "issuer": "https://server.example.com", "client_id": "dpop_client", "redirect_uris": ["https://app.example.com/callback"], "add_ons": { "dpop": { "function": "idpyoidc.client.oauth2.add_on.dpop.add_support", "kwargs": { "dpop_signing_alg_values_supported": ["ES256", "RS256"] } } }, "services": { "accesstoken": {"class": "idpyoidc.client.oauth2.access_token.AccessToken"}, } } ``` -------------------------------- ### Configure Server-Side PKCE Add-on Source: https://github.com/identitypython/idpy-oidc/blob/main/demo/README.md Enable PKCE support on the server by specifying the add-on function and its arguments. ```python "add_ons": { "pkce": { "function": "idpyoidc.server.oauth2.add_on.pkce.add_support", "kwargs": {}, }, } ``` -------------------------------- ### Get Grant Argument Function Signature Source: https://github.com/identitypython/idpy-oidc/blob/main/doc/client/server/contents/session/grant_management.md Retrieves a specific argument for a grant. Requires the branch ID and the argument name. ```python get_grant_argument(self, branch_id: str, arg: str) ``` -------------------------------- ### Get User Info Source: https://github.com/identitypython/idpy-oidc/blob/main/doc/client/client/rp_handler.md Requests user information from the userinfo endpoint if the client is permitted. This can refresh existing user data. ```python resp = self.rph.get_user_info(state_key) ``` -------------------------------- ### Get Access Token Source: https://github.com/identitypython/idpy-oidc/blob/main/doc/client/client/rp_handler.md Retrieves an access token using an authorization code received from the OP/AS. Access codes are single-use. ```python res = self.rph.get_access_token(state_key) ``` -------------------------------- ### Django-OIDC-OP User Info Configuration Source: https://github.com/identitypython/idpy-oidc/blob/main/doc/server/contents/conf.md Example configuration for user info in a Django-OIDC-OP implementation. It includes a policy function and a claims map for attribute mapping. ```default "userinfo": { "class": "oidc_provider.users.UserInfo", "kwargs": { "policy": { "function": "/path/to/callable", "kwargs": {} }, "claims_map": { "phone_number": "telephone", "family_name": "last_name", "given_name": "first_name", "email": "email", "verified_email": "email", "gender": "gender", "birthdate": "get_oidc_birthdate", "updated_at": "get_oidc_lastlogin" } } } ``` -------------------------------- ### Configure Server with PKCE Support Source: https://context7.com/identitypython/idpy-oidc/llms.txt Server configuration to enable PKCE support. The 'pkce' add-on automatically validates the code challenge and code verifier sent by the client. ```python # Server with PKCE support server_config = { "issuer": "https://server.example.com", "endpoint": { "authorization": { "path": "authorize", "class": "idpyoidc.server.oauth2.authorization.Authorization", }, "token": { "path": "token", "class": "idpyoidc.server.oauth2.token.Token", } }, "add_ons": { "pkce": { "function": "idpyoidc.server.oauth2.add_on.pkce.add_support", "kwargs": { "essential": False, # True to require PKCE for all clients "code_challenge_methods": ["S256", "plain"] } } } } server = Server(ASConfiguration(conf=server_config)) # Server will validate code_challenge/code_verifier automatically ``` -------------------------------- ### Django-OIDC-OP User Info Configuration Source: https://github.com/identitypython/idpy-oidc/blob/main/doc/client/server/contents/conf.md Example configuration for user info in a Django-OIDC-OP implementation. It includes a claims map for attribute mapping and an optional policy. ```json "userinfo": { "class": "oidc_provider.users.UserInfo", "kwargs": { "policy": { "function": "/path/to/callable", "kwargs": {} }, "claims_map": { "phone_number": "telephone", "family_name": "last_name", "given_name": "first_name", "email": "email", "verified_email": "email", "gender": "gender", "birthdate": "get_oidc_birthdate", "updated_at": "get_oidc_lastlogin" } } } ``` -------------------------------- ### Configure Client with PKCE Support Source: https://context7.com/identitypython/idpy-oidc/llms.txt Client configuration to enable PKCE support. The 'pkce' add-on automatically handles code challenge generation for authorization requests and code verifier inclusion for token requests. ```python from idpyoidc.client.oauth2 import Client from idpyoidc.server import Server from idpyoidc.server.configure import ASConfiguration # Client with PKCE support client_config = { "issuer": "https://server.example.com", "client_id": "public_client", "redirect_uris": ["https://app.example.com/callback"], "response_types": ["code"], "token_endpoint_auth_method": "none", # Public client "add_ons": { "pkce": { "function": "idpyoidc.client.oauth2.add_on.pkce.add_support", "kwargs": { "code_challenge_length": 64, "code_challenge_method": "S256" # S256 recommended, plain also supported } } }, "services": { "authorization": {"class": "idpyoidc.client.oauth2.authorization.Authorization"}, "accesstoken": {"class": "idpyoidc.client.oauth2.access_token.AccessToken"}, } } client = Client(config=client_config) # Authorization request will automatically include code_challenge auth_service = client.get_service("authorization") auth_params = auth_service.get_request_parameters( request_args={"response_type": "code", "scope": ["openid"]} ) # URL will include: code_challenge=...&code_challenge_method=S256 # Token request will automatically include code_verifier # (stored from authorization request) ``` -------------------------------- ### Get Node Info Function Signature Source: https://github.com/identitypython/idpy-oidc/blob/main/doc/client/server/contents/session/grant_management.md Retrieves information about a node. Requires a branch ID and optionally accepts a level parameter for depth control. ```python get_node_info(self, branch_id: str, level: Optional[int] = None) ``` -------------------------------- ### Configure Client-Side PKCE Add-on Source: https://github.com/identitypython/idpy-oidc/blob/main/demo/README.md Enable PKCE support on the client by specifying the add-on function and its arguments, including code challenge length and method. ```python "add_ons": { "pkce": { "function": "idpyoidc.client.oauth2.add_on.pkce.add_support", "kwargs": { "code_challenge_length": 64, "code_challenge_method": "S256" }, }, } ``` -------------------------------- ### Step 1: Provider Info Discovery Source: https://context7.com/identitypython/idpy-oidc/llms.txt Initiates the provider information discovery process on the client side. ```python # Step 1: Provider info discovery provider_service = client.get_service("provider_info") # In production, this would make HTTP request to /.well-known/openid-configuration ``` -------------------------------- ### Get Endpoint Context - Server Source: https://github.com/identitypython/idpy-oidc/blob/main/doc/client/server/contents/server.md Use this method to retrieve a link to the endpoint context. This is essential for instances needing access to endpoint-specific information or functionality. ```python server_get("endpoint_context") ``` -------------------------------- ### Configure Authentication Method Per Endpoint Source: https://github.com/identitypython/idpy-oidc/blob/main/doc/client/server/contents/clients.md Specify the authentication method to be used for different endpoints on a per-client basis. This example shows setting the method for AccessTokenRequest. ```python { "AccessTokenRequest": "client_secret_basic", ... } ``` -------------------------------- ### Configure Server with DPoP Support Source: https://context7.com/identitypython/idpy-oidc/llms.txt Server configuration to enable DPoP support. The server will automatically validate DPoP proofs sent by the client. ```python # Server with DPoP support server_config = { "issuer": "https://server.example.com", "add_ons": { "dpop": { "function": "idpyoidc.server.oauth2.add_on.dpop.add_support", "kwargs": { "dpop_signing_alg_values_supported": ["ES256", "RS256"], "dpop_endpoints": ["token", "userinfo"] } } } } # DPoP proof will be automatically generated for requests and validated on server ``` -------------------------------- ### Revoke Sub Tree Function Signature Source: https://github.com/identitypython/idpy-oidc/blob/main/doc/client/server/contents/session/grant_management.md Revokes a subtree of grants starting from a specified branch ID. Optionally accepts a level parameter to control the depth of revocation. ```python revoke_sub_tree(self, branch_id: str, level: Optional[int] = None) ``` -------------------------------- ### Create and Activate Virtual Environment Source: https://github.com/identitypython/idpy-oidc/blob/main/doc/client/server/contents/setup.md Use this command to create a Python virtual environment named 'env' and activate it. ```bash virtualenv -ppython3 env source env/bin/activate ``` -------------------------------- ### Initiate RP/Client Instance with RPHandler Source: https://github.com/identitypython/idpy-oidc/blob/main/doc/client/client/rp_handler.md Use RPHandler to initiate a client instance and construct the authorization request. This method runs initial services as configured. ```python from idpyoidc.client import RPHandler rph = RPHandler() issuer_id = "https://example.org/" info = rph.begin(issuer_id) print(info['url']) ``` -------------------------------- ### Get Subordinates Function Signature Source: https://github.com/identitypython/idpy-oidc/blob/main/doc/client/server/contents/session/grant_management.md Retrieves subordinate nodes or grants based on a given path. The path is a list of strings, and the return type is a list of NodeInfo or Grant objects. ```python get_subordinates(self, path: List[str]) -> List[Union[NodeInfo, Grant]] ``` -------------------------------- ### Resource Indicators Policy Callable Example Source: https://github.com/identitypython/idpy-oidc/blob/main/doc/client/server/contents/conf.md A Python callable function that validates resource indicators. It accepts request, context, and keyword arguments, returning an altered token request or a TokenErrorResponse. ```python def validate_resource_indicators_policy(request, context, **kwargs): if some_condition in request: return TokenErrorResponse( error="invalid_request", error_description="Some error occured" ) return request ``` -------------------------------- ### PKCE Add-on Configuration Source: https://github.com/identitypython/idpy-oidc/blob/main/doc/client/server/contents/conf.md Configure the Proof Key for Code Exchange (PKCE) add-on. Set `essential` to true to enforce PKCE for all authentication requests. `code_challenge_method` specifies the allowed challenge methods. ```default "add_on": { "pkce": { "function": "idpyoidc.server.oidc.add_on.pkce.add_pkce_support", "kwargs": { "essential": false, "code_challenge_method": "S256 S384 S512" } } } ``` -------------------------------- ### Get Specific Endpoint - Server Source: https://github.com/identitypython/idpy-oidc/blob/main/doc/client/server/contents/server.md Use this method to retrieve a link to a specific endpoint, such as the authorization endpoint. This allows dynamic access to various service points within the OIDC flow. ```python server_get("endpoint", "authorization") ``` -------------------------------- ### Configure Token Handler Arguments Source: https://github.com/identitypython/idpy-oidc/blob/main/demo/README.md Set up arguments for token handlers, including key configuration, authorization code lifetime, and JWT token settings. ```python "token_handler_args": { "key_conf": {"key_defs": KEYDEFS}, "code": { "lifetime": 600, "kwargs": { "crypt_conf": CRYPT_CONFIG } }, "token": { "class": "idpyoidc.server.token.jwt_token.JWTToken", "kwargs": { "lifetime": 3600, "aud": ["https://example.org/appl"], }, } }, ``` -------------------------------- ### Token Exchange Response Structure Source: https://github.com/identitypython/idpy-oidc/blob/main/doc/client/server/contents/examples.md This is an example of a JSON response received after a successful token exchange request. It includes the new access token, scope, issued token type, and expiration time. ```json { "access_token": "eyJhbGciOiJFUzI1NiIsI...Bo6aQcOKEN-1U88jjKxLb-9Q", "scope": "openid email", "issued_token_type": "urn:ietf:params:oauth:token-type:access_token", "expires_in": 86400 } ``` -------------------------------- ### Configure User Authentication (NoAuthn) Source: https://github.com/identitypython/idpy-oidc/blob/main/demo/README.md Set up anonymous authentication using NoAuthn, assuming a user like 'diana' is already authenticated. ```python "authentication": { "anon": { "acr": INTERNETPROTOCOLPASSWORD, "class": "idpyoidc.server.user_authn.user.NoAuthn", "kwargs": {"user": "diana"}, } }, ```