Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save user-1024/00f76dfe47a63659de070d449c9946f9 to your computer and use it in GitHub Desktop.

Select an option

Save user-1024/00f76dfe47a63659de070d449c9946f9 to your computer and use it in GitHub Desktop.
Copy of reverseengineeredsolidauthenticationbytimschupp.ipynb
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"id": "view-in-github",
"colab_type": "text"
},
"source": [
"<a href=\"https://colab.research.google.com/gist/user-1024/00f76dfe47a63659de070d449c9946f9/copy-of-reverseengineeredsolidauthenticationbytimschupp.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "kwWF7d-QPyuU"
},
"source": [
"# Tim's Notebook for the 'Solid Auth' Presentation\n",
"\n",
"> Author: Tim Schupp (tim@timschupp.de)\n",
"> Published at `blog.t1m.me/blog/solid-auth`\n",
"\n",
"Made for 'Data eco systems lab'"
]
},
{
"cell_type": "code",
"source": [
"!pip3 install jwcrypto"
],
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "Huy2CS0NQBP2",
"outputId": "e95df297-116d-4d49-edd4-ae2dbff844df"
},
"execution_count": 68,
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"Requirement already satisfied: jwcrypto in /usr/local/lib/python3.10/dist-packages (1.5.0)\n",
"Requirement already satisfied: cryptography>=3.4 in /usr/local/lib/python3.10/dist-packages (from jwcrypto) (41.0.7)\n",
"Requirement already satisfied: deprecated in /usr/local/lib/python3.10/dist-packages (from jwcrypto) (1.2.14)\n",
"Requirement already satisfied: cffi>=1.12 in /usr/local/lib/python3.10/dist-packages (from cryptography>=3.4->jwcrypto) (1.16.0)\n",
"Requirement already satisfied: wrapt<2,>=1.10 in /usr/local/lib/python3.10/dist-packages (from deprecated->jwcrypto) (1.14.1)\n",
"Requirement already satisfied: pycparser in /usr/local/lib/python3.10/dist-packages (from cffi>=1.12->cryptography>=3.4->jwcrypto) (2.21)\n"
]
}
]
},
{
"cell_type": "code",
"execution_count": 107,
"metadata": {
"id": "bPJbOKHIPyuV"
},
"outputs": [],
"source": [
"import requests\n",
"import json\n",
"import hashlib\n",
"import urllib\n",
"from IPython.display import JSON\n",
"import base64\n",
"import os\n",
"import secrets\n",
"import jwt\n",
"import uuid\n",
"import time\n",
"from jwcrypto import jwk\n",
"from urllib.parse import urlparse, parse_qs\n",
"\n",
"\n",
"def format_response(response):\n",
" headers = dict(response.headers)\n",
" body = response.json()\n",
" print(\"HEADERS:\")\n",
" print(json.dumps(headers, indent=4))\n",
" print(\"BODY:\")\n",
" print(json.dumps(body, indent=4))\n",
" print(\"COOKIES: \")\n",
" print(response.cookies)\n",
" return headers, body\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "kt-oQuePPyuW"
},
"source": [
"# 0 - setup the environment\n",
"\n",
"- check the profile card of a user e.g.: `https://solid5.signal-api.dev/demo-pod/profile/card#me`\n",
"- identify the `solid:oidcIssuer`\n",
"- also visit https://solid5.signal-api.dev/ to create a test user\n",
"- `test@nomail.com`, `Test123!`, pod name: `tmp-pod-test`\n"
]
},
{
"cell_type": "code",
"execution_count": 108,
"metadata": {
"id": "OvbA-svwPyuW"
},
"outputs": [],
"source": [
"OICD_SERVER = \"https://solid5.signal-api.dev\" # Some OpenId connect issuer\n",
"CLIENT_NAME = \"App\"\n",
"CLIENT_URL = \"https://localhost\""
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "YH-AcxapPyuW"
},
"source": [
"# 1 - extract the open ID confirguration\n",
"\n",
"- should always be hosted at `/.well-known/openid-configuration`"
]
},
{
"cell_type": "code",
"execution_count": 109,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "lKPA-6g-PyuX",
"outputId": "4334b9bc-2d40-4ed1-db89-25fb9ab69074"
},
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"HEADERS:\n",
"{\n",
" \"Date\": \"Sun, 03 Dec 2023 22:20:11 GMT\",\n",
" \"Content-Type\": \"application/json; charset=utf-8\",\n",
" \"Content-Length\": \"2027\",\n",
" \"Connection\": \"keep-alive\",\n",
" \"Vary\": \"Accept,Authorization,Origin\",\n",
" \"X-Powered-By\": \"Community Solid Server\",\n",
" \"Updates-Via\": \"wss://solid5.signal-api.dev/\",\n",
" \"Access-Control-Allow-Origin\": \"*\",\n",
" \"Access-Control-Allow-Credentials\": \"true\",\n",
" \"Access-Control-Expose-Headers\": \"Accept-Patch,ETag,Last-Modified,Link,Location,MS-Author-Via,Updates-Via,WAC-Allow\",\n",
" \"Strict-Transport-Security\": \"max-age=15724800; includeSubDomains\"\n",
"}\n",
"BODY:\n",
"{\n",
" \"authorization_endpoint\": \"https://solid5.signal-api.dev/.oidc/auth\",\n",
" \"claims_parameter_supported\": true,\n",
" \"claims_supported\": [\n",
" \"azp\",\n",
" \"sub\",\n",
" \"webid\",\n",
" \"sid\",\n",
" \"auth_time\",\n",
" \"iss\"\n",
" ],\n",
" \"code_challenge_methods_supported\": [\n",
" \"S256\"\n",
" ],\n",
" \"end_session_endpoint\": \"https://solid5.signal-api.dev/.oidc/session/end\",\n",
" \"grant_types_supported\": [\n",
" \"implicit\",\n",
" \"authorization_code\",\n",
" \"refresh_token\"\n",
" ],\n",
" \"id_token_signing_alg_values_supported\": [\n",
" \"ES256\"\n",
" ],\n",
" \"issuer\": \"https://solid5.signal-api.dev/\",\n",
" \"jwks_uri\": \"https://solid5.signal-api.dev/.oidc/jwks\",\n",
" \"registration_endpoint\": \"https://solid5.signal-api.dev/.oidc/reg\",\n",
" \"response_modes_supported\": [\n",
" \"form_post\",\n",
" \"fragment\",\n",
" \"query\"\n",
" ],\n",
" \"response_types_supported\": [\n",
" \"code id_token\",\n",
" \"code\",\n",
" \"id_token\",\n",
" \"none\"\n",
" ],\n",
" \"scopes_supported\": [\n",
" \"openid\",\n",
" \"profile\",\n",
" \"offline_access\",\n",
" \"webid\"\n",
" ],\n",
" \"subject_types_supported\": [\n",
" \"public\"\n",
" ],\n",
" \"token_endpoint_auth_methods_supported\": [\n",
" \"client_secret_basic\",\n",
" \"client_secret_jwt\",\n",
" \"client_secret_post\",\n",
" \"private_key_jwt\",\n",
" \"none\"\n",
" ],\n",
" \"token_endpoint_auth_signing_alg_values_supported\": [\n",
" \"HS256\",\n",
" \"RS256\",\n",
" \"PS256\",\n",
" \"ES256\",\n",
" \"EdDSA\"\n",
" ],\n",
" \"token_endpoint\": \"https://solid5.signal-api.dev/.oidc/token\",\n",
" \"request_object_signing_alg_values_supported\": [\n",
" \"HS256\",\n",
" \"RS256\",\n",
" \"PS256\",\n",
" \"ES256\",\n",
" \"EdDSA\"\n",
" ],\n",
" \"request_parameter_supported\": false,\n",
" \"request_uri_parameter_supported\": true,\n",
" \"require_request_uri_registration\": true,\n",
" \"introspection_endpoint\": \"https://solid5.signal-api.dev/.oidc/token/introspection\",\n",
" \"introspection_endpoint_auth_methods_supported\": [\n",
" \"client_secret_basic\",\n",
" \"client_secret_jwt\",\n",
" \"client_secret_post\",\n",
" \"private_key_jwt\",\n",
" \"none\"\n",
" ],\n",
" \"introspection_endpoint_auth_signing_alg_values_supported\": [\n",
" \"HS256\",\n",
" \"RS256\",\n",
" \"PS256\",\n",
" \"ES256\",\n",
" \"EdDSA\"\n",
" ],\n",
" \"dpop_signing_alg_values_supported\": [\n",
" \"RS256\",\n",
" \"PS256\",\n",
" \"ES256\",\n",
" \"EdDSA\"\n",
" ],\n",
" \"revocation_endpoint\": \"https://solid5.signal-api.dev/.oidc/token/revocation\",\n",
" \"revocation_endpoint_auth_methods_supported\": [\n",
" \"client_secret_basic\",\n",
" \"client_secret_jwt\",\n",
" \"client_secret_post\",\n",
" \"private_key_jwt\",\n",
" \"none\"\n",
" ],\n",
" \"revocation_endpoint_auth_signing_alg_values_supported\": [\n",
" \"HS256\",\n",
" \"RS256\",\n",
" \"PS256\",\n",
" \"ES256\",\n",
" \"EdDSA\"\n",
" ],\n",
" \"claim_types_supported\": [\n",
" \"normal\"\n",
" ]\n",
"}\n",
"COOKIES: \n",
"<RequestsCookieJar[]>\n"
]
}
],
"source": [
"session = requests.Session()\n",
"\n",
"res = session.get(f\"{OICD_SERVER}/.well-known/openid-configuration\")\n",
"\n",
"headers, body = format_response(res)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "oG62uCdvPyuX"
},
"source": [
"# 2 - find the client registration endpoint\n",
"\n",
"- the open-id configuration should be complete in a sense that it provides informations and options to paths and parameters for available endpoints"
]
},
{
"cell_type": "code",
"execution_count": 110,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "XZbBQL6QPyuX",
"outputId": "241a5ecc-a496-4769-f9b1-144a66019ff2"
},
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"REGISTRATION_ENDPOINT https://solid5.signal-api.dev/.oidc/reg\n",
"JWKS_URI https://solid5.signal-api.dev/.oidc/jwks\n",
"TOKEN_ENDPOINT https://solid5.signal-api.dev/.oidc/token\n"
]
}
],
"source": [
"REGISTRATION_ENDPOINT = body['registration_endpoint']\n",
"JWKS_URI = body['jwks_uri']\n",
"TOKEN_ENDPOINT = body['token_endpoint']\n",
"\n",
"print(\"REGISTRATION_ENDPOINT \",REGISTRATION_ENDPOINT)\n",
"print(\"JWKS_URI \",JWKS_URI)\n",
"print(\"TOKEN_ENDPOINT \",TOKEN_ENDPOINT)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "7smqC_n4PyuX"
},
"source": [
"# 3 - register a client app"
]
},
{
"cell_type": "code",
"execution_count": 111,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "jAeLad_wPyuY",
"outputId": "5fd5e3d5-faeb-4d5e-90c2-29de589ef090"
},
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"HEADERS:\n",
"{\n",
" \"Date\": \"Sun, 03 Dec 2023 22:20:14 GMT\",\n",
" \"Content-Type\": \"application/json; charset=utf-8\",\n",
" \"Content-Length\": \"872\",\n",
" \"Connection\": \"keep-alive\",\n",
" \"Vary\": \"Accept,Authorization,Origin\",\n",
" \"X-Powered-By\": \"Community Solid Server\",\n",
" \"Updates-Via\": \"wss://solid5.signal-api.dev/\",\n",
" \"Access-Control-Allow-Origin\": \"*\",\n",
" \"Access-Control-Allow-Credentials\": \"true\",\n",
" \"Access-Control-Expose-Headers\": \"Accept-Patch,ETag,Last-Modified,Link,Location,MS-Author-Via,Updates-Via,WAC-Allow\",\n",
" \"Pragma\": \"no-cache\",\n",
" \"Cache-Control\": \"no-cache, no-store\",\n",
" \"Strict-Transport-Security\": \"max-age=15724800; includeSubDomains\"\n",
"}\n",
"BODY:\n",
"{\n",
" \"application_type\": \"web\",\n",
" \"grant_types\": [\n",
" \"authorization_code\",\n",
" \"refresh_token\"\n",
" ],\n",
" \"id_token_signed_response_alg\": \"ES256\",\n",
" \"post_logout_redirect_uris\": [],\n",
" \"require_auth_time\": false,\n",
" \"response_types\": [\n",
" \"code\"\n",
" ],\n",
" \"subject_type\": \"public\",\n",
" \"token_endpoint_auth_method\": \"client_secret_basic\",\n",
" \"introspection_endpoint_auth_method\": \"client_secret_basic\",\n",
" \"revocation_endpoint_auth_method\": \"client_secret_basic\",\n",
" \"require_signed_request_object\": false,\n",
" \"request_uris\": [],\n",
" \"client_id_issued_at\": 1701642014,\n",
" \"client_id\": \"53c01SRwOhLafyLD2bV95\",\n",
" \"client_name\": \"App\",\n",
" \"client_secret_expires_at\": 0,\n",
" \"client_secret\": \"ZIVRVf6Eit7BbOMearEbIoxV5QAwyS5GeT1ZsGZUZrcN4t-zGrqomjd5upKWj5FXSOG1Dpww3LmydLTCfdMP5w\",\n",
" \"redirect_uris\": [\n",
" \"https://localhost\"\n",
" ],\n",
" \"registration_client_uri\": \"https://solid5.signal-api.dev/.oidc/reg/53c01SRwOhLafyLD2bV95\",\n",
" \"registration_access_token\": \"Ve5gGO62vT7-oDr5s_ecxKl-eZWNQj9FaxYuo02Q3-a\"\n",
"}\n",
"COOKIES: \n",
"<RequestsCookieJar[]>\n"
]
}
],
"source": [
"res = session.post(REGISTRATION_ENDPOINT, json={\n",
" \"client_name\":CLIENT_NAME,\n",
" \"application_type\":\"web\",\n",
" \"redirect_uris\":[CLIENT_URL],\n",
" \"subject_type\":\"public\",\n",
" \"token_endpoint_auth_method\":\"client_secret_basic\",\n",
" \"id_token_signed_response_alg\":\"ES256\",\n",
" \"grant_types\":[\"authorization_code\",\"refresh_token\"]\n",
"})\n",
"\n",
"headers, body = format_response(res)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "VGFX1IlHPyuY"
},
"source": [
"# 4 - extract client id and generate a client code challenge\n",
"\n",
"- generate a random string as `state` to verify later and protect against request forgery\n",
"- create a `code_challenge` based on a hashed random number to verify the client without exposing it's identity"
]
},
{
"cell_type": "code",
"execution_count": 112,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "2P7jST9kPyuY",
"outputId": "c5962481-6f63-46f9-bc3f-3b8c5ee6ea57"
},
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"CLIENT_ID 53c01SRwOhLafyLD2bV95\n",
"CLIENT_SECRET ZIVRVf6Eit7BbOMearEbIoxV5QAwyS5GeT1ZsGZUZrcN4t-zGrqomjd5upKWj5FXSOG1Dpww3LmydLTCfdMP5w\n",
"REGISTRATION_URI https://solid5.signal-api.dev/.oidc/reg/53c01SRwOhLafyLD2bV95\n",
"CODE_CHALLENGE dBCfEOb3jDgSrSanBrGD57Yfy4CSmp0zzefbPl-Oh-Q\n",
"CODE_VERIFIER cEyRWF8X60PdhV_EkHmpuuiMXcLuIfcaq5sbcfM6ujw\n",
"RANDOM_STATE 3675cf48ff4fceeb\n"
]
}
],
"source": [
"CLIENT_ID = body['client_id']\n",
"CLIENT_SECRET = body['client_secret']\n",
"REGISTRATION_URI = body['registration_client_uri']\n",
"\n",
"RANDOM_STATE = secrets.token_hex(8)\n",
"CODE_VERIFIER = base64.urlsafe_b64encode(os.urandom(32)).decode('utf-8').replace('=', '')\n",
"CODE_CHALLENGE = base64.urlsafe_b64encode(hashlib.sha256(CODE_VERIFIER.encode('utf-8')).digest()).decode('utf-8').replace('=', '')\n",
"\n",
"print('CLIENT_ID ', CLIENT_ID)\n",
"print('CLIENT_SECRET', CLIENT_SECRET)\n",
"print('REGISTRATION_URI', REGISTRATION_URI)\n",
"print('CODE_CHALLENGE ', CODE_CHALLENGE)\n",
"print('CODE_VERIFIER ', CODE_VERIFIER)\n",
"print('RANDOM_STATE', RANDOM_STATE)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "Nde719v0PyuY"
},
"source": [
"# 5 - build the login redirect url"
]
},
{
"cell_type": "code",
"execution_count": 113,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "iL7m65wbPyuY",
"outputId": "3a5b65b3-234f-4348-f59b-d92565f3c675"
},
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"https://solid5.signal-api.dev/.oidc/auth?client_id=53c01SRwOhLafyLD2bV95&redirect_uri=https%3A%2F%2Flocalhost&response_type=code&scope=openid+offline_access+webid&state=3675cf48ff4fceeb&code_challenge=dBCfEOb3jDgSrSanBrGD57Yfy4CSmp0zzefbPl-Oh-Q&code_challenge_method=S256&prompt=consent&response_mode=query\n"
]
}
],
"source": [
"LOGIN_URL = OICD_SERVER + \"/.oidc/auth?\" + urllib.parse.urlencode({\n",
" 'client_id': CLIENT_ID,\n",
" 'redirect_uri': CLIENT_URL,\n",
" 'response_type': 'code',\n",
" 'scope': 'openid offline_access webid',\n",
" 'state': RANDOM_STATE,\n",
" 'code_challenge': CODE_CHALLENGE,\n",
" 'code_challenge_method': 'S256',\n",
" 'prompt': 'consent',\n",
" 'response_mode': 'query'\n",
"})\n",
"\n",
"print(LOGIN_URL)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "rZPYwUCoPyuZ"
},
"source": [
"# 6 - Visit the login link\n",
"\n",
"- should redirect `/idp/login`\n",
"- enter login credentials\n",
"- should redirect to `/idp/confirm`\n",
"- confirm client app access\n",
"- redirect back to client app ( here faked ) e.g.: `?code=opJg1Gn-UUpEaUhLgNsKdne_FL8-0ODgGZjsmE2hj9b&state=65ba479f032e465ba6185b23b3483528`"
]
},
{
"cell_type": "code",
"execution_count": 114,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "DEdlWHqmPyuZ",
"outputId": "2ea1ad6f-ec48-4b1c-cbac-5f3b0415a3f9"
},
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"https://localhost/?code=XMgIeA1Q4Hd48yLL-eMOX0i23CwT3N4fAf7BqQjudRR&state=3675cf48ff4fceeb\n",
"REDIRECTED_URL https://localhost/?code=XMgIeA1Q4Hd48yLL-eMOX0i23CwT3N4fAf7BqQjudRR&state=3675cf48ff4fceeb\n"
]
}
],
"source": [
"REDIRECTED_URL = input()\n",
"print('REDIRECTED_URL', REDIRECTED_URL)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "0CIc1X5UPyuZ"
},
"source": [
"# 7 - Extract State and Code, Prepare Token Request\n",
"\n",
"- check the `state` to ensure no request forgery is going on\n",
"- build a `DPoP` claim about the token request we are about to perform\n",
" - prevents replay attacks\n",
" - reduces security rists accociated with token leakage"
]
},
{
"cell_type": "code",
"execution_count": 115,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "lB2wIhIZPyuZ",
"outputId": "51fce793-cc89-4dda-d749-dce405a06eae"
},
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"CLIENT_URL https://localhost\n",
"CLIENT_ID 53c01SRwOhLafyLD2bV95\n",
"CODE_VERIFIER cEyRWF8X60PdhV_EkHmpuuiMXcLuIfcaq5sbcfM6ujw\n",
"TOKEN_ENDPOINT https://solid5.signal-api.dev/.oidc/token\n",
"dpop_token eyJ0eXAiOiJkcG9wK2p3dCIsImFsZyI6IkVTMjU2IiwiandrIjp7Imt0eSI6IkVDIiwiY3J2IjoiUC0yNTYiLCJ4Ijoic2o5bTNMUG5VUmJLdVhhM3hFVUtPX3dWRlNDc2pPWk5UdDdXejR0a0MyayIsInkiOiI0SWt3TWFFaTd1SWdxd3VfZXFleTkxV05tcVFBXzhRSkpWMWhQOWZEYmdBIn19.eyJqdGkiOiJhNTk0MmQ1MS1jMTM4LTRlNTQtYmIwNS05ZjUxMDMzZDczNGYiLCJodG0iOiJQT1NUIiwiaHR1IjoiaHR0cHM6Ly9zb2xpZDUuc2lnbmFsLWFwaS5kZXYvLm9pZGMvdG9rZW4iLCJpYXQiOjE3MDE2NDIwMzF9.EdSBo-a1zzitv7DxZcMBvCtSHFFOxhvuvLArfQ1PEGpKZur-E4kPZu2TU7wc1eq4OaTUVGRi3ckUdxEa8lAsUg\n"
]
}
],
"source": [
"parsed_url = urlparse(REDIRECTED_URL)\n",
"query_params = parse_qs(parsed_url.query)\n",
"AUTH_CODE = query_params.get('code', [None])[0]\n",
"state_value = query_params.get('state', [None])[0]\n",
"if state_value != RANDOM_STATE:\n",
" raise Exception('State value does not match the expected value')\n",
"\n",
"\n",
"def create_dpop_header(http_method, http_url, key):\n",
" # build the clain about the current request\n",
" dpop_claims = {\n",
" \"jti\": str(uuid.uuid4()), # unique request id\n",
" \"htm\": http_method, # request method\n",
" \"htu\": http_url, # what url requested\n",
" \"iat\": int(time.time()) # when ?\n",
" }\n",
"\n",
" # get pub & priv keys\n",
" private_key_pem = key.export_to_pem(private_key=True, password=None)\n",
" public_jwk = key.export_public(as_dict=True)\n",
"\n",
" # create DPoP jwt token\n",
" dpop_token = jwt.encode(\n",
" dpop_claims,\n",
" private_key_pem,\n",
" algorithm='ES256',\n",
" headers={\n",
" 'typ': 'dpop+jwt',\n",
" 'alg': 'ES256',\n",
" 'jwk': public_jwk\n",
" }\n",
" )\n",
" return dpop_token\n",
"\n",
"# generate public & private keys\n",
"key = jwk.JWK.generate(kty='EC', crv='P-256')\n",
"\n",
"dpop_token = create_dpop_header('POST', TOKEN_ENDPOINT, key)\n",
"\n",
"print('CLIENT_URL', CLIENT_URL)\n",
"print('CLIENT_ID', CLIENT_ID)\n",
"print('CODE_VERIFIER', CODE_VERIFIER)\n",
"print('TOKEN_ENDPOINT', TOKEN_ENDPOINT)\n",
"print('dpop_token', dpop_token)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "FLbYx7OOPyuZ"
},
"source": [
"# 8 - Request Access Token\n",
"- post request with `code`, `client_id` & `code_verifier` to `/.oidc/token`\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": 116,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "6Tcanqe7PyuZ",
"outputId": "6423803a-ca62-4b00-ca43-f5eec580f26f"
},
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"HEADERS:\n",
"{\n",
" \"Date\": \"Sun, 03 Dec 2023 22:20:35 GMT\",\n",
" \"Content-Type\": \"application/json; charset=utf-8\",\n",
" \"Content-Length\": \"1425\",\n",
" \"Connection\": \"keep-alive\",\n",
" \"Vary\": \"Accept,Authorization,Origin\",\n",
" \"X-Powered-By\": \"Community Solid Server\",\n",
" \"Updates-Via\": \"wss://solid5.signal-api.dev/\",\n",
" \"Access-Control-Allow-Origin\": \"*\",\n",
" \"Access-Control-Allow-Credentials\": \"true\",\n",
" \"Access-Control-Expose-Headers\": \"Accept-Patch,ETag,Last-Modified,Link,Location,MS-Author-Via,Updates-Via,WAC-Allow\",\n",
" \"Pragma\": \"no-cache\",\n",
" \"Cache-Control\": \"no-cache, no-store\",\n",
" \"Strict-Transport-Security\": \"max-age=15724800; includeSubDomains\"\n",
"}\n",
"BODY:\n",
"{\n",
" \"access_token\": \"eyJhbGciOiJFUzI1NiIsInR5cCI6ImF0K2p3dCIsImtpZCI6IkhmLWNoU1R6TGwzX0doZTJUTWdwUUl1N2xIekVjT0V0OFJHbWVWbjNRUW8ifQ.eyJ3ZWJpZCI6Imh0dHBzOi8vc29saWQ1LnNpZ25hbC1hcGkuZGV2L3RtcC1wb2QtdGVzdC9wcm9maWxlL2NhcmQjbWUiLCJqdGkiOiJSQ2dzcjQycnZYam9yZU5DRVJGSnkiLCJzdWIiOiJodHRwczovL3NvbGlkNS5zaWduYWwtYXBpLmRldi90bXAtcG9kLXRlc3QvcHJvZmlsZS9jYXJkI21lIiwiaWF0IjoxNzAxNjQyMDM1LCJleHAiOjE3MDE2NDU2MzUsInNjb3BlIjoiIiwiY2xpZW50X2lkIjoiNTNjMDFTUndPaExhZnlMRDJiVjk1IiwiaXNzIjoiaHR0cHM6Ly9zb2xpZDUuc2lnbmFsLWFwaS5kZXYvIiwiYXVkIjoic29saWQiLCJjbmYiOnsiamt0IjoiOWtzcVdIcGd5TTZyNnBGWVVJNElOUWhKX3JQM1VmaF9hZjQydV9tU0tQYyJ9fQ.uZN2khF_w2M_WhNb7HMkRqE3a8JnH0HgVEYEUBmiVs4PXuFSPhi8bwAjg4etNuCy9CTMKce7wSsD8DFWD5CEcQ\",\n",
" \"expires_in\": 3600,\n",
" \"id_token\": \"eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IkhmLWNoU1R6TGwzX0doZTJUTWdwUUl1N2xIekVjT0V0OFJHbWVWbjNRUW8ifQ.eyJhenAiOiI1M2MwMVNSd09oTGFmeUxEMmJWOTUiLCJzdWIiOiJodHRwczovL3NvbGlkNS5zaWduYWwtYXBpLmRldi90bXAtcG9kLXRlc3QvcHJvZmlsZS9jYXJkI21lIiwid2ViaWQiOiJodHRwczovL3NvbGlkNS5zaWduYWwtYXBpLmRldi90bXAtcG9kLXRlc3QvcHJvZmlsZS9jYXJkI21lIiwiYXRfaGFzaCI6IlhaZXVpUlMyNk5rV1IxRFFQXzZNa3ciLCJhdWQiOiI1M2MwMVNSd09oTGFmeUxEMmJWOTUiLCJleHAiOjE3MDE2NDU2MzUsImlhdCI6MTcwMTY0MjAzNSwiaXNzIjoiaHR0cHM6Ly9zb2xpZDUuc2lnbmFsLWFwaS5kZXYvIn0.WgOTrpUuWOF6MSTHjJ3cii1jf5Qt359vhAS-T-e0ds4Rjjx2GMn6S54qD4LNAxglqCLUKUAUUM-A5BTwW5nyMQ\",\n",
" \"refresh_token\": \"f4I6t_laB1-7H47h00JLnS_5EYjsF2byMw40KbW09yB\",\n",
" \"scope\": \"\",\n",
" \"token_type\": \"DPoP\"\n",
"}\n",
"COOKIES: \n",
"<RequestsCookieJar[]>\n"
]
}
],
"source": [
"# prepare request body\n",
"token_data = {\n",
" 'grant_type': 'authorization_code',\n",
" 'code': AUTH_CODE,\n",
" 'redirect_uri': CLIENT_URL,\n",
" 'client_id': CLIENT_ID,\n",
" 'code_verifier': CODE_VERIFIER\n",
"}\n",
"\n",
"res = session.post(\n",
" TOKEN_ENDPOINT,\n",
" data=token_data,\n",
" auth=(CLIENT_ID, CLIENT_SECRET),\n",
" headers={'DPoP': dpop_token}\n",
")\n",
"\n",
"headers, body = format_response(res)"
]
},
{
"cell_type": "markdown",
"source": [
"# 9 - Retrieve access token"
],
"metadata": {
"id": "RYZsms5flHsm"
}
},
{
"cell_type": "code",
"source": [
"ACCESS_TOKEN = body['access_token']\n",
"ID_TOKEN = body['id_token']\n",
"REFRESH_TOKEN = body['refresh_token']\n",
"\n",
"print('ACCESS_TOKEN ', ACCESS_TOKEN)\n",
"print('ID_TOKEN ', ID_TOKEN)\n",
"print('REFRESH_TOKEN ', REFRESH_TOKEN)"
],
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "k2hEPoIrl90t",
"outputId": "d2c4da05-4ae0-44ff-c480-ee2b2861306a"
},
"execution_count": 117,
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"ACCESS_TOKEN eyJhbGciOiJFUzI1NiIsInR5cCI6ImF0K2p3dCIsImtpZCI6IkhmLWNoU1R6TGwzX0doZTJUTWdwUUl1N2xIekVjT0V0OFJHbWVWbjNRUW8ifQ.eyJ3ZWJpZCI6Imh0dHBzOi8vc29saWQ1LnNpZ25hbC1hcGkuZGV2L3RtcC1wb2QtdGVzdC9wcm9maWxlL2NhcmQjbWUiLCJqdGkiOiJSQ2dzcjQycnZYam9yZU5DRVJGSnkiLCJzdWIiOiJodHRwczovL3NvbGlkNS5zaWduYWwtYXBpLmRldi90bXAtcG9kLXRlc3QvcHJvZmlsZS9jYXJkI21lIiwiaWF0IjoxNzAxNjQyMDM1LCJleHAiOjE3MDE2NDU2MzUsInNjb3BlIjoiIiwiY2xpZW50X2lkIjoiNTNjMDFTUndPaExhZnlMRDJiVjk1IiwiaXNzIjoiaHR0cHM6Ly9zb2xpZDUuc2lnbmFsLWFwaS5kZXYvIiwiYXVkIjoic29saWQiLCJjbmYiOnsiamt0IjoiOWtzcVdIcGd5TTZyNnBGWVVJNElOUWhKX3JQM1VmaF9hZjQydV9tU0tQYyJ9fQ.uZN2khF_w2M_WhNb7HMkRqE3a8JnH0HgVEYEUBmiVs4PXuFSPhi8bwAjg4etNuCy9CTMKce7wSsD8DFWD5CEcQ\n",
"ID_TOKEN eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IkhmLWNoU1R6TGwzX0doZTJUTWdwUUl1N2xIekVjT0V0OFJHbWVWbjNRUW8ifQ.eyJhenAiOiI1M2MwMVNSd09oTGFmeUxEMmJWOTUiLCJzdWIiOiJodHRwczovL3NvbGlkNS5zaWduYWwtYXBpLmRldi90bXAtcG9kLXRlc3QvcHJvZmlsZS9jYXJkI21lIiwid2ViaWQiOiJodHRwczovL3NvbGlkNS5zaWduYWwtYXBpLmRldi90bXAtcG9kLXRlc3QvcHJvZmlsZS9jYXJkI21lIiwiYXRfaGFzaCI6IlhaZXVpUlMyNk5rV1IxRFFQXzZNa3ciLCJhdWQiOiI1M2MwMVNSd09oTGFmeUxEMmJWOTUiLCJleHAiOjE3MDE2NDU2MzUsImlhdCI6MTcwMTY0MjAzNSwiaXNzIjoiaHR0cHM6Ly9zb2xpZDUuc2lnbmFsLWFwaS5kZXYvIn0.WgOTrpUuWOF6MSTHjJ3cii1jf5Qt359vhAS-T-e0ds4Rjjx2GMn6S54qD4LNAxglqCLUKUAUUM-A5BTwW5nyMQ\n",
"REFRESH_TOKEN f4I6t_laB1-7H47h00JLnS_5EYjsF2byMw40KbW09yB\n"
]
}
]
},
{
"cell_type": "code",
"source": [
"UPLOAD_PATH = \"/tmp-pod-test/raw_data/test.txt\"\n",
"LOCAL_PATH = \"/tmp/demo/test.txt\"\n",
"\n",
"with open(LOCAL_PATH, 'rb') as file_content:\n",
" file_data = file_content.read()\n",
"\n",
"upload_url = f\"{OICD_SERVER}{UPLOAD_PATH}\"\n",
"print('upload_url ', upload_url)\n",
"\n",
"dpop_header = create_dpop_header('PUT', upload_url, key)\n",
"\n",
"headers = {\n",
" 'Authorization': f'DPoP {ACCESS_TOKEN}',\n",
" 'Dpop': dpop_header,\n",
" 'Content-Type': 'text/plain' # Adjust Content-Type to your file's MIME type\n",
"}\n",
"\n",
"response = session.put(upload_url, headers=headers, data=file_data) # Use data instead of files\n",
"\n",
"if response.ok:\n",
" print('File uploaded successfully.')\n",
"else:\n",
" print('File upload failed.')\n",
" print(response.text)"
],
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "LMnijN04mJF7",
"outputId": "e4d004cd-de46-4f1b-9ff8-c2991c6fdc3e"
},
"execution_count": 118,
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"upload_url https://solid5.signal-api.dev/tmp-pod-test/raw_data/test.txt\n",
"File uploaded successfully.\n"
]
}
]
},
{
"cell_type": "code",
"source": [],
"metadata": {
"id": "oHGDjs5Bpy-O"
},
"execution_count": null,
"outputs": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.8.10"
},
"colab": {
"provenance": [],
"include_colab_link": true
}
},
"nbformat": 4,
"nbformat_minor": 0
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment