Some examples, how to run flask_op and django_op but also some typical configuration in relation to common use cases.
JWTConnect-Python-OidcRP is Relaing Party for tests, see related page.
You can run a working instance of JWTConnect-Python-OidcRP.flask_rp with:
pip install git+https://github.com/openid/JWTConnect-Python-OidcRP.git
# get entire project to have examples files
git clone https://github.com/openid/JWTConnect-Python-OidcRP.git
cd JWTConnect-Python-OidcRP/example/flask_rp
# run it as it come
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.
Get to the RP landing page to choose your authentication endpoint. The first option aims to use Provider Discovery.
The AS/OP supports dynamic client registration, it accepts the authentication request and prompt to us the login form. Read passwd.json file to get credentials.
The identity representation with the information fetched from the user info endpoint.
We can even test the single logout
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
)
oidc-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=='
}
Here an example about how to consume oidc-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)
oidc-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"
]
}
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
)
oidc-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 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.



