Examples ******** Some examples, how to run [flask_op](https://github.com/IdentityPython/tree/master/example/flask_op) and [django_op](https://github.com/peppelinux/django-oidc-op) but also some typical configuration in relation to common use cases. Configure flask-rp ------------------ The client part of _idpyoidc_ is Relaying Party for tests. You can run a working instance of `idpy-oidc.flask_rp` with: pip install git+https://github.com/IdentityPython/idpy-oidc.git get entire project to have examples files git clone https://github.com/IdentityPython/idpy-oidc.git cd idpy-oidc/example/flask_rp run it as it comes bash run.sh Now you can connect to `https://127.0.0.1:8090/` to see the RP landing page and select your authentication endpoint. Authentication examples +++++++++++++++++++++++ ![RP](../_images/1.png) Get to the RP landing page to choose your authentication endpoint. The first option aims to use Provider Discovery. ![OP Auth](../_images/2.png) The AS/OP supports dynamic client registration, it accepts the authentication request and prompt to us the login form. Read [passwd.json](https://github.com/IdentityPython/oidc-op/blob/master/example/flask_op/passwd.json) file to get credentials. ![Access](../_images/3.png) The identity representation with the information fetched from the user info endpoint. ![Logout](../_images/4.png) We can even test the single logout Refresh token ------------- Here an example about how to refresh a token. It is important to consider that only scope=offline_access will get a usable refresh token:: 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 ) The idpyoidc OP will return a json response like this:: { 'access_token': 'eyJhbGc ... CIOH_09tT_YVa_gyTqg', 'token_type': 'Bearer', 'scope': 'openid profile email address phone offline_access', 'refresh_token': 'Z0FBQ ... 1TE16cm1Tdg==' } Introspection endpoint ---------------------- Here an example about how to use a idpyoidc OP introspection endpoint. This example uses a client with an HTTP Basic Authentication:: 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) The idpyoidc OP will return a json response like this:: { "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" ] } Token exchange -------------- Here an example about how to exchange an access token for a new access token.:: 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 ) The idpyoidc OP will return a json response like this:: { "access_token": "eyJhbGciOiJFUzI1NiIsI...Bo6aQcOKEN-1U88jjKxLb-9Q", "scope": "openid email", "issued_token_type": "urn:ietf:params:oauth:token-type:access_token", "expires_in": 86400 } In order to request a refresh token the value of `requested_token_type` should be set to `urn:ietf:params:oauth:token-type:refresh_token`. The [RFC-8693](https://datatracker.ietf.org/doc/html/rfc8693) describes the `audience` parameter that defines the authorized targets of a token exchange request. If `subject_token = urn:ietf:params:oauth:token-type:refresh_token` then `audience` should not be included in the token exchange request.