inpython-package 1.1.9__tar.gz → 1.1.10__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. {inpython_package-1.1.9/inpython_package.egg-info → inpython_package-1.1.10}/PKG-INFO +2 -2
  2. inpython_package-1.1.10/inpython/injcd.py +15 -0
  3. {inpython_package-1.1.9 → inpython_package-1.1.10}/inpython/inrest/in_jwt.py +157 -142
  4. {inpython_package-1.1.9 → inpython_package-1.1.10/inpython_package.egg-info}/PKG-INFO +2 -2
  5. {inpython_package-1.1.9 → inpython_package-1.1.10}/setup.py +2 -2
  6. inpython_package-1.1.9/inpython/injcd.py +0 -15
  7. {inpython_package-1.1.9 → inpython_package-1.1.10}/LICENSE.txt +0 -0
  8. {inpython_package-1.1.9 → inpython_package-1.1.10}/README.md +0 -0
  9. {inpython_package-1.1.9 → inpython_package-1.1.10}/inpython/__init__.py +0 -0
  10. {inpython_package-1.1.9 → inpython_package-1.1.10}/inpython/__main__.py +0 -0
  11. {inpython_package-1.1.9 → inpython_package-1.1.10}/inpython/aotools/__init__.py +0 -0
  12. {inpython_package-1.1.9 → inpython_package-1.1.10}/inpython/aotools/aogeo.py +0 -0
  13. {inpython_package-1.1.9 → inpython_package-1.1.10}/inpython/ingraph/__init__.py +0 -0
  14. {inpython_package-1.1.9 → inpython_package-1.1.10}/inpython/ingraph/ingraph.py +0 -0
  15. {inpython_package-1.1.9 → inpython_package-1.1.10}/inpython/inqrcode/__init__.py +0 -0
  16. {inpython_package-1.1.9 → inpython_package-1.1.10}/inpython/inqrcode/inqrcode.py +0 -0
  17. {inpython_package-1.1.9 → inpython_package-1.1.10}/inpython/inqrcode/paymentqrcode.py +0 -0
  18. {inpython_package-1.1.9 → inpython_package-1.1.10}/inpython/inrest/__init__.py +0 -0
  19. {inpython_package-1.1.9 → inpython_package-1.1.10}/inpython/intools/Servalux-devis.py +0 -0
  20. {inpython_package-1.1.9 → inpython_package-1.1.10}/inpython/intools/__init__.py +0 -0
  21. {inpython_package-1.1.9 → inpython_package-1.1.10}/inpython/intools/in_cron.py +0 -0
  22. {inpython_package-1.1.9 → inpython_package-1.1.10}/inpython/intools/in_docx.py +0 -0
  23. {inpython_package-1.1.9 → inpython_package-1.1.10}/inpython/intools/in_docx_extract.py +0 -0
  24. {inpython_package-1.1.9 → inpython_package-1.1.10}/inpython/intools/in_docx_extract_canvas.py +0 -0
  25. {inpython_package-1.1.9 → inpython_package-1.1.10}/inpython/intools/in_docx_protect.py +0 -0
  26. {inpython_package-1.1.9 → inpython_package-1.1.10}/inpython/intools/in_geo_calc.py +0 -0
  27. {inpython_package-1.1.9 → inpython_package-1.1.10}/inpython/intools/in_log.py +0 -0
  28. {inpython_package-1.1.9 → inpython_package-1.1.10}/inpython/intools/in_projet.py +0 -0
  29. {inpython_package-1.1.9 → inpython_package-1.1.10}/inpython/intools/in_test.py +0 -0
  30. {inpython_package-1.1.9 → inpython_package-1.1.10}/inpython/intools/xls_to_csv.py +0 -0
  31. {inpython_package-1.1.9 → inpython_package-1.1.10}/inpython/servalux/__init__.py +0 -0
  32. {inpython_package-1.1.9 → inpython_package-1.1.10}/inpython/servalux/docx_ext_schema_svl.py +0 -0
  33. {inpython_package-1.1.9 → inpython_package-1.1.10}/inpython/servalux/servalux-devis.py +0 -0
  34. {inpython_package-1.1.9 → inpython_package-1.1.10}/inpython_package.egg-info/SOURCES.txt +0 -0
  35. {inpython_package-1.1.9 → inpython_package-1.1.10}/inpython_package.egg-info/dependency_links.txt +0 -0
  36. {inpython_package-1.1.9 → inpython_package-1.1.10}/inpython_package.egg-info/requires.txt +0 -0
  37. {inpython_package-1.1.9 → inpython_package-1.1.10}/inpython_package.egg-info/top_level.txt +0 -0
  38. {inpython_package-1.1.9 → inpython_package-1.1.10}/setup.cfg +0 -0
@@ -1,12 +1,12 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: inpython-package
3
- Version: 1.1.9
3
+ Version: 1.1.10
4
4
  Summary: # Infodata's IN-Tools U2Python Package
5
5
  Home-page: https://bitbucket.org/infodata-dev/inpython
6
6
  Author: infodata
7
7
  Author-email: jcd@infodata.lu
8
8
  License: MIT
9
- Requires-Python: >=3.4
9
+ Requires-Python: >=3.11
10
10
  Description-Content-Type: text/markdown
11
11
  License-File: LICENSE.txt
12
12
  Requires-Dist: msal>=1.22
@@ -0,0 +1,15 @@
1
+ import sys
2
+ from inrest import in_jwt
3
+
4
+ def main(argv):
5
+ #
6
+ try:
7
+ token = "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJDYW14amZKUGw5aXhKWDdTQ3VKMXI0X2JWb2hFbVdkb3RHRmkwYmF5TFNzIn0.eyJleHAiOjE3ODc1NjU5MTcsImlhdCI6MTc4NzU2NTYxNywiYXV0aF90aW1lIjoxNzg3NTU0MzA4LCJqdGkiOiJvbnJ0YWM6MzVjODY2ZGYtNmIzZC02MjVlLTExMTgtNDI1ZmUyNjc3YjY3IiwiaXNzIjoiaHR0cHM6Ly9rZXljbG9hay5kZXYuaW50cmEucHJpbWVhbGUubmV0L2F1dGgvcmVhbG1zL3ByaW1lYWxlLWNvbm5lY3QiLCJhdWQiOiJhY2NvdW50Iiwic3ViIjoiZDFiMGM5M2MtMjhlMy00YzM4LTk3MTMtNjU1ZTFjM2FkN2Q4IiwidHlwIjoiQmVhcmVyIiwiYXpwIjoicmVmZXJlbnRpZWwtZnJvbnQiLCJzaWQiOiIxUGMteGRHZ21hSmtOelI2NmNOTDRTdGoiLCJhY3IiOiIwIiwiYWxsb3dlZC1vcmlnaW5zIjpbImh0dHA6Ly9sb2NhbGhvc3Q6NDIwMyIsImh0dHBzOi8vcmVmZXJlbnRpZWwuZGV2LmludHJhLnByaW1lYWxlLm5ldCJdLCJyZWFsbV9hY2Nlc3MiOnsicm9sZXMiOlsib2ZmbGluZV9hY2Nlc3MiLCJ1bWFfYXV0aG9yaXphdGlvbiIsImRlZmF1bHQtcm9sZXMtYWQgZmxvcsOpYWxlIl19LCJyZXNvdXJjZV9hY2Nlc3MiOnsiYWNjb3VudCI6eyJyb2xlcyI6WyJtYW5hZ2UtYWNjb3VudCIsIm1hbmFnZS1hY2NvdW50LWxpbmtzIiwidmlldy1wcm9maWxlIl19fSwic2NvcGUiOiJvcGVuaWQgZW1haWwgcHJvZmlsZSIsImVtYWlsX3ZlcmlmaWVkIjpmYWxzZSwibmFtZSI6Ik5pY29sYXMgU2FiaW4gKFByaW3DqWFsZSBGcmFuY2UpIFNhYmluIiwicHJlZmVycmVkX3VzZXJuYW1lIjoibmlzYWJpbiIsImdpdmVuX25hbWUiOiJOaWNvbGFzIFNhYmluIChQcmltw6lhbGUgRnJhbmNlKSIsImZhbWlseV9uYW1lIjoiU2FiaW4iLCJlbWFpbCI6Im5pc2FiaW5AcHJpbWVhbGUuY29tIn0.nb3ii1SoGiypmZm2tTDsoKEqYPhrjSrQCMs5I4XHca1CJS_c2jwE6sbfJBio98xKwZEwokt9_-7uLxD6LKVxhVZHBI08X-TEs_iNh1XRynJcORsdr2z9oiYc4rW8lq-H_22zo33vbWnrjnQflxLvTwD8-xvnwbTVBqqJKUY7mugZBy9KnR6uOJqMks0D7uon2-XiKJq9idznYOtaoGHbeb9vMZJxrJTHV7gj9SNzOeGOGJQoLxqG2QCbA-uYlBYvp4xV2iUIH9eeUr1hcETw4wHAdn87qxHj5dqsU7zN0oO7fAdcCXzWvXHnx__Wi7pKfVPLUSD0jNSy4ugmGcuoRg"
8
+ claims = in_jwt.validate_keycloak_jwt(token, "http://localhost:8080/realms/myrealm","myclient-web")
9
+ print(claims)
10
+ except ValueError as e:
11
+ print(f"Erreur: {e}")
12
+
13
+ if __name__ == "__main__":
14
+ main(sys.argv[1:])
15
+
@@ -1,142 +1,157 @@
1
- #--------------------------------------------------------
2
- # Manipulates a Json web token
3
- #
4
- #--------------------------------------------------------
5
- # 22/08/2024 (JCD) : Creation fonction generateJwtClientAssertion
6
- # 21/08/2026 (JCD) : ajout validate_keycloak_jwt et validate_microsoft_jwt
7
- #--------------------------------------------------------
8
- from cryptography.hazmat.primitives.serialization import pkcs12
9
- from cryptography.hazmat.primitives import serialization
10
- from cryptography.hazmat.backends import default_backend
11
- import jwt
12
- import datetime
13
- from jwt import PyJWKClient
14
- import json
15
-
16
- # Generates a jwt client assertion from a private key
17
- def generateJwtClientAssertion(mode,path_certificate,private_key,client_id,audience,expirationTime=10):
18
- """ Return jwt token assertion
19
-
20
- Parameters
21
- ------------
22
- mode:int
23
- = 1 : Private key
24
- = 2 : Private password
25
- path_certificate: string
26
- Path crt/cer file if mode = 1
27
- Path pfx file if mode = 2
28
- private_key: byte
29
- Path key file file if mode = 1
30
- Private password if mode = 2
31
- client_id: string
32
- audience: string
33
- expirationTime: string, Optional
34
- in minutes. Default to 10 minutes
35
- """
36
- try:
37
- if mode != "1" and mode != "2" :
38
- raise Exception("Unmanaged mode")
39
-
40
- if not expirationTime:
41
- expirationTime = 10
42
- else:
43
- expirationTime = int(expirationTime)
44
-
45
- # Load the public certificate
46
- with open(path_certificate, "rb") as cert_file:
47
- certificate_data = cert_file.read()
48
-
49
- # Load the private key
50
- if mode == "1":
51
- with open(private_key, "rb") as key_file:
52
- private_key = serialization.load_pem_private_key(
53
- key_file.read(),
54
- password=None,
55
- backend=default_backend()
56
- )
57
- else:
58
- private_key, certificate, additional_certs = pkcs12.load_key_and_certificates(
59
- certificate_data, private_key.encode(), backend=default_backend()
60
- )
61
-
62
- now = datetime.datetime.now(datetime.timezone.utc)
63
- # Define the JWT claims
64
- claims = {
65
- "iss": client_id, # The issuer, typically your client ID
66
- "sub": client_id, # The subject, typically your client ID
67
- "aud": audience, # The audience, typically the token endpoint URL
68
- "exp": now + datetime.timedelta(expirationTime), # Expiration time
69
- "jti": "unique-identifier", # JWT ID, a unique identifier for the JWT
70
- }
71
-
72
- # Create the JWT (client assertion)
73
- if mode == 1:
74
- client_assertion = jwt.encode(
75
- claims,
76
- private_key,
77
- algorithm="RS256",
78
- headers={"x5c": [certificate_data.decode("utf-8").replace("\n", "")]}
79
- )
80
- else:
81
- client_assertion = jwt.encode(
82
- claims, private_key, algorithm="RS256", headers={"alg": "RS256","typ": "JWT"}
83
- )
84
- return client_assertion
85
- except:
86
- raise # so that the caller receives the exception
87
-
88
- def validate_keycloak_jwt(token: str,keycloak_url: str,client_id: str):
89
- """
90
- Valide un JWT Keycloak.
91
- """
92
- try:
93
- jwks_url = (f"{keycloak_url}/protocol/openid-connect/certs")
94
- signing_key = PyJWKClient(jwks_url).get_signing_key_from_jwt(token)
95
- payload = jwt.decode(
96
- token,
97
- signing_key.key,
98
- algorithms=["RS256"],
99
- issuer=keycloak_url,
100
- audience=client_id
101
- )
102
- return json.dumps(payload)
103
- except jwt.ExpiredSignatureError:
104
- raise ValueError("JWT expiré")
105
- except jwt.InvalidIssuerError:
106
- raise ValueError("Issuer Keycloak incorrect")
107
- except jwt.InvalidAudienceError:
108
- raise ValueError("Audience Keycloak incorrect")
109
- except jwt.InvalidTokenError as e:
110
- raise ValueError(
111
- f"JWT Keycloak invalide: {str(e)}"
112
- )
113
- except Exception as e:
114
- raise ValueError(
115
- f"Erreur validation Keycloak: {str(e)}"
116
- )
117
-
118
- def validate_microsoft_jwt(token: str, issuer: str = None, audience: str = None):
119
- """
120
- Valide un JWT Microsoft en récupérant les clés JWKS depuis:
121
- https://login.microsoftonline.com/common/discovery/v2.0/keys
122
- """
123
- try:
124
- jwks_url = "https://login.microsoftonline.com/common/discovery/v2.0/keys"
125
- signing_key = PyJWKClient(jwks_url).get_signing_key_from_jwt(token)
126
-
127
- options = {"verify_aud": bool(audience), "verify_iss": bool(issuer)}
128
- claims = jwt.decode(
129
- token,
130
- signing_key.key,
131
- algorithms=["RS256"],
132
- audience=audience,
133
- issuer=issuer,
134
- options=options
135
- )
136
- return json.dumps(claims)
137
- except jwt.ExpiredSignatureError:
138
- raise ValueError("JWT Microsoft expiré")
139
- except jwt.InvalidTokenError as e:
140
- raise ValueError(f"JWT Microsoft invalide: {str(e)}")
141
- except Exception as e:
142
- raise ValueError(f"Erreur validation Microsoft: {str(e)}")
1
+ #--------------------------------------------------------
2
+ # Manipulates a Json web token
3
+ #
4
+ #--------------------------------------------------------
5
+ # 22/08/2024 (JCD) : Creation fonction generateJwtClientAssertion
6
+ # 21/08/2026 (JCD) : ajout validate_keycloak_jwt et validate_microsoft_jwt
7
+ #--------------------------------------------------------
8
+ from cryptography.hazmat.primitives.serialization import pkcs12
9
+ from cryptography.hazmat.primitives import serialization
10
+ from cryptography.hazmat.backends import default_backend
11
+ import jwt
12
+ import datetime
13
+ from jwt import PyJWKClient
14
+ import json
15
+
16
+ # Generates a jwt client assertion from a private key
17
+ def generateJwtClientAssertion(mode,path_certificate,private_key,client_id,audience,expirationTime=10):
18
+ """ Return jwt token assertion
19
+
20
+ Parameters
21
+ ------------
22
+ mode:int
23
+ = 1 : Private key
24
+ = 2 : Private password
25
+ path_certificate: string
26
+ Path crt/cer file if mode = 1
27
+ Path pfx file if mode = 2
28
+ private_key: byte
29
+ Path key file file if mode = 1
30
+ Private password if mode = 2
31
+ client_id: string
32
+ audience: string
33
+ expirationTime: string, Optional
34
+ in minutes. Default to 10 minutes
35
+ """
36
+ try:
37
+ if mode != "1" and mode != "2" :
38
+ raise Exception("Unmanaged mode")
39
+
40
+ if not expirationTime:
41
+ expirationTime = 10
42
+ else:
43
+ expirationTime = int(expirationTime)
44
+
45
+ # Load the public certificate
46
+ with open(path_certificate, "rb") as cert_file:
47
+ certificate_data = cert_file.read()
48
+
49
+ # Load the private key
50
+ if mode == "1":
51
+ with open(private_key, "rb") as key_file:
52
+ private_key = serialization.load_pem_private_key(
53
+ key_file.read(),
54
+ password=None,
55
+ backend=default_backend()
56
+ )
57
+ else:
58
+ private_key, certificate, additional_certs = pkcs12.load_key_and_certificates(
59
+ certificate_data, private_key.encode(), backend=default_backend()
60
+ )
61
+
62
+ now = datetime.datetime.now(datetime.timezone.utc)
63
+ # Define the JWT claims
64
+ claims = {
65
+ "iss": client_id, # The issuer, typically your client ID
66
+ "sub": client_id, # The subject, typically your client ID
67
+ "aud": audience, # The audience, typically the token endpoint URL
68
+ "exp": now + datetime.timedelta(expirationTime), # Expiration time
69
+ "jti": "unique-identifier", # JWT ID, a unique identifier for the JWT
70
+ }
71
+
72
+ # Create the JWT (client assertion)
73
+ if mode == 1:
74
+ client_assertion = jwt.encode(
75
+ claims,
76
+ private_key,
77
+ algorithm="RS256",
78
+ headers={"x5c": [certificate_data.decode("utf-8").replace("\n", "")]}
79
+ )
80
+ else:
81
+ client_assertion = jwt.encode(
82
+ claims, private_key, algorithm="RS256", headers={"alg": "RS256","typ": "JWT"}
83
+ )
84
+ return client_assertion
85
+ except:
86
+ raise # so that the caller receives the exception
87
+
88
+ def validate_keycloak_jwt(token: str,keycloak_url: str,client_id: str):
89
+ """
90
+ Valide un JWT Keycloak.
91
+ Accepte un client_id qui correspond soit a aud, soit a azp.
92
+ """
93
+ try:
94
+ jwks_url = (f"{keycloak_url}/protocol/openid-connect/certs")
95
+ signing_key = PyJWKClient(jwks_url).get_signing_key_from_jwt(token)
96
+ payload = jwt.decode(
97
+ token,
98
+ signing_key.key,
99
+ algorithms=["RS256"],
100
+ issuer=keycloak_url,
101
+ options={"verify_aud": False}
102
+ )
103
+
104
+ aud = payload.get("aud")
105
+ azp = payload.get("azp")
106
+
107
+ if isinstance(aud, list):
108
+ audience_matches = client_id in aud
109
+ else:
110
+ audience_matches = aud == client_id
111
+
112
+ if not audience_matches and azp != client_id:
113
+ raise ValueError(
114
+ "Audience Keycloak incorrect: "
115
+ f"client_id='{client_id}' ne correspond ni a aud='{aud}' "
116
+ f"ni a azp='{azp}'"
117
+ )
118
+
119
+ return json.dumps(payload)
120
+ except jwt.ExpiredSignatureError:
121
+ raise ValueError("Expired JWT")
122
+ except jwt.InvalidIssuerError:
123
+ raise ValueError("Issuer Keycloak incorrect")
124
+ except jwt.InvalidTokenError as e:
125
+ raise ValueError(
126
+ f"JWT Keycloak invalide: {str(e)}"
127
+ )
128
+ except Exception as e:
129
+ raise ValueError(
130
+ f"Erreur validation Keycloak: {str(e)}"
131
+ )
132
+
133
+ def validate_microsoft_jwt(token: str, issuer: str = None, audience: str = None):
134
+ """
135
+ Valide un JWT Microsoft en récupérant les clés JWKS depuis:
136
+ https://login.microsoftonline.com/common/discovery/v2.0/keys
137
+ """
138
+ try:
139
+ jwks_url = "https://login.microsoftonline.com/common/discovery/v2.0/keys"
140
+ signing_key = PyJWKClient(jwks_url).get_signing_key_from_jwt(token)
141
+
142
+ options = {"verify_aud": bool(audience), "verify_iss": bool(issuer)}
143
+ claims = jwt.decode(
144
+ token,
145
+ signing_key.key,
146
+ algorithms=["RS256"],
147
+ audience=audience,
148
+ issuer=issuer,
149
+ options=options
150
+ )
151
+ return json.dumps(claims)
152
+ except jwt.ExpiredSignatureError:
153
+ raise ValueError("JWT Microsoft expiré")
154
+ except jwt.InvalidTokenError as e:
155
+ raise ValueError(f"JWT Microsoft invalide: {str(e)}")
156
+ except Exception as e:
157
+ raise ValueError(f"Erreur validation Microsoft: {str(e)}")
@@ -1,12 +1,12 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: inpython-package
3
- Version: 1.1.9
3
+ Version: 1.1.10
4
4
  Summary: # Infodata's IN-Tools U2Python Package
5
5
  Home-page: https://bitbucket.org/infodata-dev/inpython
6
6
  Author: infodata
7
7
  Author-email: jcd@infodata.lu
8
8
  License: MIT
9
- Requires-Python: >=3.4
9
+ Requires-Python: >=3.11
10
10
  Description-Content-Type: text/markdown
11
11
  License-File: LICENSE.txt
12
12
  Requires-Dist: msal>=1.22
@@ -9,7 +9,7 @@ with open("README.md", "r", encoding="utf-8") as fh:
9
9
 
10
10
  setup(
11
11
  name="inpython-package",
12
- version="1.1.9",
12
+ version="1.1.10",
13
13
  author="infodata",
14
14
  author_email="jcd@infodata.lu",
15
15
  packages=find_packages(),
@@ -18,7 +18,7 @@ setup(
18
18
  long_description_content_type="text/markdown",
19
19
  url="https://bitbucket.org/infodata-dev/inpython",
20
20
  license='MIT',
21
- python_requires='>=3.4',
21
+ python_requires='>=3.11',
22
22
  install_requires=[
23
23
  "msal>=1.22",
24
24
  "requests",
@@ -1,15 +0,0 @@
1
- import sys
2
- from inrest import in_jwt
3
-
4
- def main(argv):
5
- #
6
- try:
7
- token = "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJTd3JnRjIyV1FVaHZBZUxpQTBhQnhmV2hqNGgtX0hLSXFuVzRpd3JTWnFVIn0.eyJleHAiOjE3ODc0MjM5MzksImlhdCI6MTc4NzQyMzYzOSwiYXV0aF90aW1lIjoxNzg3NDE5OTc2LCJqdGkiOiJiZGUxNjZmZS0wMDc3LTIyNWMtNDRkMi0yOWJkNzlkZTBjZDEiLCJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjgwODAvcmVhbG1zL215cmVhbG0iLCJhdWQiOiJteWNsaWVudC13ZWIiLCJzdWIiOiI0MGM1MGI5MS1iYjlmLTQ5MjEtYjg2YS1hYzQ1YWZiYTE1NWYiLCJ0eXAiOiJJRCIsImF6cCI6Im15Y2xpZW50LXdlYiIsInNpZCI6InQwZi1qWm5nVjYxVklQT29RQTJWa3p1VCIsImF0X2hhc2giOiJNN1VoMG12SFZKczdDaDVfN1F1bDZRIiwiYWNyIjoiMCIsImVtYWlsX3ZlcmlmaWVkIjpmYWxzZSwibmFtZSI6IkpDIERldyIsInByZWZlcnJlZF91c2VybmFtZSI6Im15dXNlciIsImdpdmVuX25hbWUiOiJKQyIsImZhbWlseV9uYW1lIjoiRGV3IiwiZW1haWwiOiJqY2RAaW5mb2RhdGEubHUifQ.AuQWfzPHZjHzdtwMipDsR_VrxR2dl1Q3aHD1Ym5h9hZfHwiVtPH3prZ9ptDAmXkagz29uphx_X--yfOmqGlZiC4ygHsGXBkmohNRteIHRO_hu72iBM9kEaU8QakX_HTZXmhC99HHrSNGjYcdl9koNz9cZSvCd9EysGLGF1Bs2NWV0hwQzQVfYIpeDCgm2vyvLSLhJYH4UJariM4H0D9KhX7tgi5qRFxEn2lYlSam1pBuDTrNFrXoUvE_iN68e-wMQql0ib_WWQKVTmeXvxoLzHM2K_544MqqssWO2gZ5JnnV2ZlB1KgxqHATQxFLyGGZzsWMLLdHb91yIb_lfBIV7Q"
8
- claims = in_jwt.validate_keycloak_jwt(token, "http://localhost:8080/realms/myrealm","myclient-web")
9
- print(claims)
10
- except ValueError as e:
11
- print(f"Erreur: {e}")
12
-
13
- if __name__ == "__main__":
14
- main(sys.argv[1:])
15
-