Authlib 1.6.3__py2.py3-none-any.whl → 1.6.5__py2.py3-none-any.whl
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.
- authlib/consts.py +1 -1
- authlib/integrations/django_oauth2/authorization_server.py +6 -2
- authlib/integrations/flask_oauth2/authorization_server.py +5 -3
- authlib/integrations/starlette_client/apps.py +16 -9
- authlib/jose/errors.py +8 -0
- authlib/jose/rfc7515/jws.py +43 -1
- authlib/jose/rfc7515/models.py +2 -2
- authlib/jose/rfc7516/models.py +4 -4
- authlib/jose/rfc7518/jwe_zips.py +15 -4
- authlib/jose/util.py +6 -0
- authlib/oauth2/rfc6749/authorization_server.py +2 -1
- authlib/oauth2/rfc6749/parameters.py +8 -3
- authlib/oauth2/rfc7591/endpoint.py +25 -6
- authlib-1.6.5.dist-info/METADATA +178 -0
- {authlib-1.6.3.dist-info → authlib-1.6.5.dist-info}/RECORD +18 -18
- authlib-1.6.3.dist-info/METADATA +0 -36
- {authlib-1.6.3.dist-info → authlib-1.6.5.dist-info}/WHEEL +0 -0
- {authlib-1.6.3.dist-info → authlib-1.6.5.dist-info}/licenses/LICENSE +0 -0
- {authlib-1.6.3.dist-info → authlib-1.6.5.dist-info}/top_level.txt +0 -0
authlib/consts.py
CHANGED
|
@@ -24,11 +24,15 @@ class AuthorizationServer(_AuthorizationServer):
|
|
|
24
24
|
"""
|
|
25
25
|
|
|
26
26
|
def __init__(self, client_model, token_model):
|
|
27
|
-
|
|
27
|
+
super().__init__()
|
|
28
28
|
self.client_model = client_model
|
|
29
29
|
self.token_model = token_model
|
|
30
|
+
self.load_config(getattr(settings, "AUTHLIB_OAUTH2_PROVIDER", {}))
|
|
31
|
+
|
|
32
|
+
def load_config(self, config):
|
|
33
|
+
self.config = config
|
|
30
34
|
scopes_supported = self.config.get("scopes_supported")
|
|
31
|
-
|
|
35
|
+
self.scopes_supported = scopes_supported
|
|
32
36
|
# add default token generator
|
|
33
37
|
self.register_token_generator("default", self.create_bearer_token_generator())
|
|
34
38
|
|
|
@@ -53,12 +53,14 @@ class AuthorizationServer(_AuthorizationServer):
|
|
|
53
53
|
self._query_client = query_client
|
|
54
54
|
if save_token is not None:
|
|
55
55
|
self._save_token = save_token
|
|
56
|
+
self.load_config(app.config)
|
|
56
57
|
|
|
58
|
+
def load_config(self, config):
|
|
57
59
|
self.register_token_generator(
|
|
58
|
-
"default", self.create_bearer_token_generator(
|
|
60
|
+
"default", self.create_bearer_token_generator(config)
|
|
59
61
|
)
|
|
60
|
-
self.scopes_supported =
|
|
61
|
-
self._error_uris =
|
|
62
|
+
self.scopes_supported = config.get("OAUTH2_SCOPES_SUPPORTED")
|
|
63
|
+
self._error_uris = config.get("OAUTH2_ERROR_URIS")
|
|
62
64
|
|
|
63
65
|
def query_client(self, client_id):
|
|
64
66
|
return self._query_client(client_id)
|
|
@@ -63,15 +63,22 @@ class StarletteOAuth2App(
|
|
|
63
63
|
client_cls = AsyncOAuth2Client
|
|
64
64
|
|
|
65
65
|
async def authorize_access_token(self, request, **kwargs):
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
66
|
+
if request.scope.get("method", "GET") == "GET":
|
|
67
|
+
error = request.query_params.get("error")
|
|
68
|
+
if error:
|
|
69
|
+
description = request.query_params.get("error_description")
|
|
70
|
+
raise OAuthError(error=error, description=description)
|
|
71
|
+
|
|
72
|
+
params = {
|
|
73
|
+
"code": request.query_params.get("code"),
|
|
74
|
+
"state": request.query_params.get("state"),
|
|
75
|
+
}
|
|
76
|
+
else:
|
|
77
|
+
async with request.form() as form:
|
|
78
|
+
params = {
|
|
79
|
+
"code": form.get("code"),
|
|
80
|
+
"state": form.get("state"),
|
|
81
|
+
}
|
|
75
82
|
|
|
76
83
|
if self.framework.cache:
|
|
77
84
|
session = None
|
authlib/jose/errors.py
CHANGED
|
@@ -33,6 +33,14 @@ class InvalidHeaderParameterNameError(JoseError):
|
|
|
33
33
|
super().__init__(description=description)
|
|
34
34
|
|
|
35
35
|
|
|
36
|
+
class InvalidCritHeaderParameterNameError(JoseError):
|
|
37
|
+
error = "invalid_crit_header_parameter_name"
|
|
38
|
+
|
|
39
|
+
def __init__(self, name):
|
|
40
|
+
description = f"Invalid Header Parameter Name: {name}"
|
|
41
|
+
super().__init__(description=description)
|
|
42
|
+
|
|
43
|
+
|
|
36
44
|
class InvalidEncryptionAlgorithmForECDH1PUWithKeyWrappingError(JoseError):
|
|
37
45
|
error = "invalid_encryption_algorithm_for_ECDH_1PU_with_key_wrapping"
|
|
38
46
|
|
authlib/jose/rfc7515/jws.py
CHANGED
|
@@ -4,6 +4,7 @@ from authlib.common.encoding import to_unicode
|
|
|
4
4
|
from authlib.common.encoding import urlsafe_b64encode
|
|
5
5
|
from authlib.jose.errors import BadSignatureError
|
|
6
6
|
from authlib.jose.errors import DecodeError
|
|
7
|
+
from authlib.jose.errors import InvalidCritHeaderParameterNameError
|
|
7
8
|
from authlib.jose.errors import InvalidHeaderParameterNameError
|
|
8
9
|
from authlib.jose.errors import MissingAlgorithmError
|
|
9
10
|
from authlib.jose.errors import UnsupportedAlgorithmError
|
|
@@ -33,6 +34,8 @@ class JsonWebSignature:
|
|
|
33
34
|
]
|
|
34
35
|
)
|
|
35
36
|
|
|
37
|
+
MAX_CONTENT_LENGTH: int = 256000
|
|
38
|
+
|
|
36
39
|
#: Defined available JWS algorithms in the registry
|
|
37
40
|
ALGORITHMS_REGISTRY = {}
|
|
38
41
|
|
|
@@ -64,6 +67,7 @@ class JsonWebSignature:
|
|
|
64
67
|
"""
|
|
65
68
|
jws_header = JWSHeader(protected, None)
|
|
66
69
|
self._validate_private_headers(protected)
|
|
70
|
+
self._validate_crit_headers(protected)
|
|
67
71
|
algorithm, key = self._prepare_algorithm_key(protected, payload, key)
|
|
68
72
|
|
|
69
73
|
protected_segment = json_b64encode(jws_header.protected)
|
|
@@ -87,6 +91,9 @@ class JsonWebSignature:
|
|
|
87
91
|
|
|
88
92
|
.. _`Section 7.1`: https://tools.ietf.org/html/rfc7515#section-7.1
|
|
89
93
|
"""
|
|
94
|
+
if len(s) > self.MAX_CONTENT_LENGTH:
|
|
95
|
+
raise ValueError("Serialization is too long.")
|
|
96
|
+
|
|
90
97
|
try:
|
|
91
98
|
s = to_bytes(s)
|
|
92
99
|
signing_input, signature_segment = s.rsplit(b".", 1)
|
|
@@ -95,6 +102,7 @@ class JsonWebSignature:
|
|
|
95
102
|
raise DecodeError("Not enough segments") from exc
|
|
96
103
|
|
|
97
104
|
protected = _extract_header(protected_segment)
|
|
105
|
+
self._validate_crit_headers(protected)
|
|
98
106
|
jws_header = JWSHeader(protected, None)
|
|
99
107
|
|
|
100
108
|
payload = _extract_payload(payload_segment)
|
|
@@ -132,6 +140,11 @@ class JsonWebSignature:
|
|
|
132
140
|
|
|
133
141
|
def _sign(jws_header):
|
|
134
142
|
self._validate_private_headers(jws_header)
|
|
143
|
+
# RFC 7515 §4.1.11: 'crit' MUST be integrity-protected.
|
|
144
|
+
# Reject if present in unprotected header, and validate only
|
|
145
|
+
# against the protected header parameters.
|
|
146
|
+
self._reject_unprotected_crit(jws_header.header)
|
|
147
|
+
self._validate_crit_headers(jws_header.protected)
|
|
135
148
|
_alg, _key = self._prepare_algorithm_key(jws_header, payload, key)
|
|
136
149
|
|
|
137
150
|
protected_segment = json_b64encode(jws_header.protected)
|
|
@@ -272,6 +285,28 @@ class JsonWebSignature:
|
|
|
272
285
|
if k not in names:
|
|
273
286
|
raise InvalidHeaderParameterNameError(k)
|
|
274
287
|
|
|
288
|
+
def _reject_unprotected_crit(self, unprotected_header):
|
|
289
|
+
"""Reject 'crit' when found in the unprotected header (RFC 7515 §4.1.11)."""
|
|
290
|
+
if unprotected_header and "crit" in unprotected_header:
|
|
291
|
+
raise InvalidHeaderParameterNameError("crit")
|
|
292
|
+
|
|
293
|
+
def _validate_crit_headers(self, header):
|
|
294
|
+
if "crit" in header:
|
|
295
|
+
crit_headers = header["crit"]
|
|
296
|
+
# Type enforcement for robustness and predictable errors
|
|
297
|
+
if not isinstance(crit_headers, list) or not all(
|
|
298
|
+
isinstance(x, str) for x in crit_headers
|
|
299
|
+
):
|
|
300
|
+
raise InvalidHeaderParameterNameError("crit")
|
|
301
|
+
names = self.REGISTERED_HEADER_PARAMETER_NAMES.copy()
|
|
302
|
+
if self._private_headers:
|
|
303
|
+
names = names.union(self._private_headers)
|
|
304
|
+
for k in crit_headers:
|
|
305
|
+
if k not in names:
|
|
306
|
+
raise InvalidCritHeaderParameterNameError(k)
|
|
307
|
+
elif k not in header:
|
|
308
|
+
raise InvalidCritHeaderParameterNameError(k)
|
|
309
|
+
|
|
275
310
|
def _validate_json_jws(self, payload_segment, payload, header_obj, key):
|
|
276
311
|
protected_segment = header_obj.get("protected")
|
|
277
312
|
if not protected_segment:
|
|
@@ -286,7 +321,14 @@ class JsonWebSignature:
|
|
|
286
321
|
header = header_obj.get("header")
|
|
287
322
|
if header and not isinstance(header, dict):
|
|
288
323
|
raise DecodeError('Invalid "header" value')
|
|
289
|
-
|
|
324
|
+
# RFC 7515 §4.1.11: 'crit' MUST be integrity-protected. If present in
|
|
325
|
+
# the unprotected header object, reject the JWS.
|
|
326
|
+
self._reject_unprotected_crit(header)
|
|
327
|
+
|
|
328
|
+
# Enforce must-understand semantics for names listed in protected
|
|
329
|
+
# 'crit'. This will also ensure each listed name is present in the
|
|
330
|
+
# protected header.
|
|
331
|
+
self._validate_crit_headers(protected)
|
|
290
332
|
jws_header = JWSHeader(protected, header)
|
|
291
333
|
algorithm, key = self._prepare_algorithm_key(jws_header, payload, key)
|
|
292
334
|
signing_input = b".".join([protected_segment, payload_segment])
|
authlib/jose/rfc7515/models.py
CHANGED
|
@@ -50,10 +50,10 @@ class JWSHeader(dict):
|
|
|
50
50
|
|
|
51
51
|
def __init__(self, protected, header):
|
|
52
52
|
obj = {}
|
|
53
|
-
if protected:
|
|
54
|
-
obj.update(protected)
|
|
55
53
|
if header:
|
|
56
54
|
obj.update(header)
|
|
55
|
+
if protected:
|
|
56
|
+
obj.update(protected)
|
|
57
57
|
super().__init__(obj)
|
|
58
58
|
self.protected = protected
|
|
59
59
|
self.header = header
|
authlib/jose/rfc7516/models.py
CHANGED
|
@@ -117,10 +117,10 @@ class JWESharedHeader(dict):
|
|
|
117
117
|
|
|
118
118
|
def __init__(self, protected, unprotected):
|
|
119
119
|
obj = {}
|
|
120
|
-
if protected:
|
|
121
|
-
obj.update(protected)
|
|
122
120
|
if unprotected:
|
|
123
121
|
obj.update(unprotected)
|
|
122
|
+
if protected:
|
|
123
|
+
obj.update(protected)
|
|
124
124
|
super().__init__(obj)
|
|
125
125
|
self.protected = protected if protected else {}
|
|
126
126
|
self.unprotected = unprotected if unprotected else {}
|
|
@@ -145,12 +145,12 @@ class JWEHeader(dict):
|
|
|
145
145
|
|
|
146
146
|
def __init__(self, protected, unprotected, header):
|
|
147
147
|
obj = {}
|
|
148
|
-
if protected:
|
|
149
|
-
obj.update(protected)
|
|
150
148
|
if unprotected:
|
|
151
149
|
obj.update(unprotected)
|
|
152
150
|
if header:
|
|
153
151
|
obj.update(header)
|
|
152
|
+
if protected:
|
|
153
|
+
obj.update(protected)
|
|
154
154
|
super().__init__(obj)
|
|
155
155
|
self.protected = protected if protected else {}
|
|
156
156
|
self.unprotected = unprotected if unprotected else {}
|
authlib/jose/rfc7518/jwe_zips.py
CHANGED
|
@@ -3,20 +3,31 @@ import zlib
|
|
|
3
3
|
from ..rfc7516 import JsonWebEncryption
|
|
4
4
|
from ..rfc7516 import JWEZipAlgorithm
|
|
5
5
|
|
|
6
|
+
GZIP_HEAD = bytes([120, 156])
|
|
7
|
+
MAX_SIZE = 250 * 1024
|
|
8
|
+
|
|
6
9
|
|
|
7
10
|
class DeflateZipAlgorithm(JWEZipAlgorithm):
|
|
8
11
|
name = "DEF"
|
|
9
12
|
description = "DEFLATE"
|
|
10
13
|
|
|
11
|
-
def compress(self, s):
|
|
14
|
+
def compress(self, s: bytes) -> bytes:
|
|
12
15
|
"""Compress bytes data with DEFLATE algorithm."""
|
|
13
16
|
data = zlib.compress(s)
|
|
14
|
-
#
|
|
17
|
+
# https://datatracker.ietf.org/doc/html/rfc1951
|
|
18
|
+
# since DEF is always gzip, we can drop gzip headers and tail
|
|
15
19
|
return data[2:-4]
|
|
16
20
|
|
|
17
|
-
def decompress(self, s):
|
|
21
|
+
def decompress(self, s: bytes) -> bytes:
|
|
18
22
|
"""Decompress DEFLATE bytes data."""
|
|
19
|
-
|
|
23
|
+
if s.startswith(GZIP_HEAD):
|
|
24
|
+
decompressor = zlib.decompressobj()
|
|
25
|
+
else:
|
|
26
|
+
decompressor = zlib.decompressobj(-zlib.MAX_WBITS)
|
|
27
|
+
value = decompressor.decompress(s, MAX_SIZE)
|
|
28
|
+
if decompressor.unconsumed_tail:
|
|
29
|
+
raise ValueError(f"Decompressed string exceeds {MAX_SIZE} bytes")
|
|
30
|
+
return value
|
|
20
31
|
|
|
21
32
|
|
|
22
33
|
def register_jwe_rfc7518():
|
authlib/jose/util.py
CHANGED
|
@@ -7,6 +7,9 @@ from authlib.jose.errors import DecodeError
|
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
def extract_header(header_segment, error_cls):
|
|
10
|
+
if len(header_segment) > 256000:
|
|
11
|
+
raise ValueError("Value of header is too long")
|
|
12
|
+
|
|
10
13
|
header_data = extract_segment(header_segment, error_cls, "header")
|
|
11
14
|
|
|
12
15
|
try:
|
|
@@ -20,6 +23,9 @@ def extract_header(header_segment, error_cls):
|
|
|
20
23
|
|
|
21
24
|
|
|
22
25
|
def extract_segment(segment, error_cls, name="payload"):
|
|
26
|
+
if len(segment) > 256000:
|
|
27
|
+
raise ValueError(f"Value of {name} is too long")
|
|
28
|
+
|
|
23
29
|
try:
|
|
24
30
|
return urlsafe_b64decode(segment)
|
|
25
31
|
except (TypeError, binascii.Error) as exc:
|
|
@@ -251,8 +251,9 @@ class AuthorizationServer(Hookable):
|
|
|
251
251
|
"""Validate current HTTP request for authorization page. This page
|
|
252
252
|
is designed for resource owner to grant or deny the authorization.
|
|
253
253
|
"""
|
|
254
|
+
request = self.create_oauth2_request(request)
|
|
255
|
+
|
|
254
256
|
try:
|
|
255
|
-
request = self.create_oauth2_request(request)
|
|
256
257
|
request.user = end_user
|
|
257
258
|
|
|
258
259
|
grant = self.get_authorization_grant(request)
|
|
@@ -54,9 +54,14 @@ def prepare_grant_uri(
|
|
|
54
54
|
if state:
|
|
55
55
|
params.append(("state", state))
|
|
56
56
|
|
|
57
|
-
for k in kwargs:
|
|
58
|
-
if
|
|
59
|
-
|
|
57
|
+
for k, value in kwargs.items():
|
|
58
|
+
if value is not None:
|
|
59
|
+
if isinstance(value, (list, tuple)):
|
|
60
|
+
for v in value:
|
|
61
|
+
if v is not None:
|
|
62
|
+
params.append((to_unicode(k), v))
|
|
63
|
+
else:
|
|
64
|
+
params.append((to_unicode(k), value))
|
|
60
65
|
|
|
61
66
|
return add_params_to_uri(uri, params)
|
|
62
67
|
|
|
@@ -4,6 +4,7 @@ import time
|
|
|
4
4
|
|
|
5
5
|
from authlib.common.security import generate_token
|
|
6
6
|
from authlib.consts import default_json_headers
|
|
7
|
+
from authlib.deprecate import deprecate
|
|
7
8
|
from authlib.jose import JoseError
|
|
8
9
|
from authlib.jose import JsonWebToken
|
|
9
10
|
|
|
@@ -41,7 +42,7 @@ class ClientRegistrationEndpoint:
|
|
|
41
42
|
request.credential = token
|
|
42
43
|
|
|
43
44
|
client_metadata = self.extract_client_metadata(request)
|
|
44
|
-
client_info = self.generate_client_info()
|
|
45
|
+
client_info = self.generate_client_info(request)
|
|
45
46
|
body = {}
|
|
46
47
|
body.update(client_metadata)
|
|
47
48
|
body.update(client_info)
|
|
@@ -91,10 +92,28 @@ class ClientRegistrationEndpoint:
|
|
|
91
92
|
except JoseError as exc:
|
|
92
93
|
raise InvalidSoftwareStatementError() from exc
|
|
93
94
|
|
|
94
|
-
def generate_client_info(self):
|
|
95
|
+
def generate_client_info(self, request):
|
|
95
96
|
# https://tools.ietf.org/html/rfc7591#section-3.2.1
|
|
96
|
-
|
|
97
|
-
|
|
97
|
+
try:
|
|
98
|
+
client_id = self.generate_client_id(request)
|
|
99
|
+
except TypeError: # pragma: no cover
|
|
100
|
+
client_id = self.generate_client_id()
|
|
101
|
+
deprecate(
|
|
102
|
+
"generate_client_id takes a 'request' parameter. "
|
|
103
|
+
"It will become mandatory in coming releases",
|
|
104
|
+
version="1.8",
|
|
105
|
+
)
|
|
106
|
+
|
|
107
|
+
try:
|
|
108
|
+
client_secret = self.generate_client_secret(request)
|
|
109
|
+
except TypeError: # pragma: no cover
|
|
110
|
+
client_secret = self.generate_client_secret()
|
|
111
|
+
deprecate(
|
|
112
|
+
"generate_client_secret takes a 'request' parameter. "
|
|
113
|
+
"It will become mandatory in coming releases",
|
|
114
|
+
version="1.8",
|
|
115
|
+
)
|
|
116
|
+
|
|
98
117
|
client_id_issued_at = int(time.time())
|
|
99
118
|
client_secret_expires_at = 0
|
|
100
119
|
return dict(
|
|
@@ -114,13 +133,13 @@ class ClientRegistrationEndpoint:
|
|
|
114
133
|
def create_endpoint_request(self, request):
|
|
115
134
|
return self.server.create_json_request(request)
|
|
116
135
|
|
|
117
|
-
def generate_client_id(self):
|
|
136
|
+
def generate_client_id(self, request):
|
|
118
137
|
"""Generate ``client_id`` value. Developers MAY rewrite this method
|
|
119
138
|
to use their own way to generate ``client_id``.
|
|
120
139
|
"""
|
|
121
140
|
return generate_token(42)
|
|
122
141
|
|
|
123
|
-
def generate_client_secret(self):
|
|
142
|
+
def generate_client_secret(self, request):
|
|
124
143
|
"""Generate ``client_secret`` value. Developers MAY rewrite this method
|
|
125
144
|
to use their own way to generate ``client_secret``.
|
|
126
145
|
"""
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: Authlib
|
|
3
|
+
Version: 1.6.5
|
|
4
|
+
Summary: The ultimate Python library in building OAuth and OpenID Connect servers and clients.
|
|
5
|
+
Author-email: Hsiaoming Yang <me@lepture.com>
|
|
6
|
+
License: BSD-3-Clause
|
|
7
|
+
Project-URL: Documentation, https://docs.authlib.org/
|
|
8
|
+
Project-URL: Purchase, https://authlib.org/plans
|
|
9
|
+
Project-URL: Issues, https://github.com/authlib/authlib/issues
|
|
10
|
+
Project-URL: Source, https://github.com/authlib/authlib
|
|
11
|
+
Project-URL: Donate, https://github.com/sponsors/lepture
|
|
12
|
+
Project-URL: Blog, https://blog.authlib.org/
|
|
13
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
14
|
+
Classifier: Environment :: Console
|
|
15
|
+
Classifier: Environment :: Web Environment
|
|
16
|
+
Classifier: Intended Audience :: Developers
|
|
17
|
+
Classifier: License :: OSI Approved :: BSD License
|
|
18
|
+
Classifier: Operating System :: OS Independent
|
|
19
|
+
Classifier: Programming Language :: Python
|
|
20
|
+
Classifier: Programming Language :: Python :: 3
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
24
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
25
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
26
|
+
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
27
|
+
Classifier: Programming Language :: Python :: Implementation :: PyPy
|
|
28
|
+
Classifier: Topic :: Security
|
|
29
|
+
Classifier: Topic :: Security :: Cryptography
|
|
30
|
+
Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
|
|
31
|
+
Classifier: Topic :: Internet :: WWW/HTTP :: WSGI :: Application
|
|
32
|
+
Requires-Python: >=3.9
|
|
33
|
+
Description-Content-Type: text/markdown
|
|
34
|
+
License-File: LICENSE
|
|
35
|
+
Requires-Dist: cryptography
|
|
36
|
+
Dynamic: license-file
|
|
37
|
+
|
|
38
|
+
<div align="center">
|
|
39
|
+
|
|
40
|
+
<picture>
|
|
41
|
+
<source media="(prefers-color-scheme: dark)" srcset="docs/_static/dark-logo.svg" />
|
|
42
|
+
<img alt="Authlib" src="docs/_static/light-logo.svg" height="68" />
|
|
43
|
+
</picture>
|
|
44
|
+
|
|
45
|
+
[](https://github.com/authlib/authlib/actions)
|
|
46
|
+
[](https://pypi.org/project/authlib)
|
|
47
|
+
[](https://anaconda.org/conda-forge/authlib)
|
|
48
|
+
[](https://pepy.tech/projects/authlib)
|
|
49
|
+
[](https://codecov.io/gh/authlib/authlib)
|
|
50
|
+
[](https://sonarcloud.io/summary/new_code?id=authlib_authlib)
|
|
51
|
+
|
|
52
|
+
</div>
|
|
53
|
+
|
|
54
|
+
The ultimate Python library in building OAuth and OpenID Connect servers.
|
|
55
|
+
JWS, JWK, JWA, JWT are included.
|
|
56
|
+
|
|
57
|
+
Authlib is compatible with Python3.9+.
|
|
58
|
+
|
|
59
|
+
## Migrations
|
|
60
|
+
|
|
61
|
+
Authlib will deprecate `authlib.jose` module, please read:
|
|
62
|
+
|
|
63
|
+
- [Migrating from `authlib.jose` to `joserfc`](https://jose.authlib.org/en/dev/migrations/authlib/)
|
|
64
|
+
|
|
65
|
+
## Sponsors
|
|
66
|
+
|
|
67
|
+
<table>
|
|
68
|
+
<tr>
|
|
69
|
+
<td><img align="middle" width="48" src="https://cdn.auth0.com/website/website/favicons/auth0-favicon.svg"></td>
|
|
70
|
+
<td>If you want to quickly add secure token-based authentication to Python projects, feel free to check Auth0's Python SDK and free plan at <a href="https://auth0.com/overview?utm_source=GHsponsor&utm_medium=GHsponsor&utm_campaign=authlib&utm_content=auth">auth0.com/overview</a>.</td>
|
|
71
|
+
</tr>
|
|
72
|
+
<tr>
|
|
73
|
+
<td><img align="middle" width="48" src="https://typlog.com/assets/icon-white.svg"></td>
|
|
74
|
+
<td>A blogging and podcast hosting platform with minimal design but powerful features. Host your blog and Podcast with <a href="https://typlog.com/">Typlog.com</a>.
|
|
75
|
+
</td>
|
|
76
|
+
</tr>
|
|
77
|
+
</table>
|
|
78
|
+
|
|
79
|
+
[**Fund Authlib to access additional features**](https://docs.authlib.org/en/latest/community/funding.html)
|
|
80
|
+
|
|
81
|
+
## Features
|
|
82
|
+
|
|
83
|
+
Generic, spec-compliant implementation to build clients and providers:
|
|
84
|
+
|
|
85
|
+
- [The OAuth 1.0 Protocol](https://docs.authlib.org/en/latest/basic/oauth1.html)
|
|
86
|
+
- [RFC5849: The OAuth 1.0 Protocol](https://docs.authlib.org/en/latest/specs/rfc5849.html)
|
|
87
|
+
- [The OAuth 2.0 Authorization Framework](https://docs.authlib.org/en/latest/basic/oauth2.html)
|
|
88
|
+
- [RFC6749: The OAuth 2.0 Authorization Framework](https://docs.authlib.org/en/latest/specs/rfc6749.html)
|
|
89
|
+
- [RFC6750: The OAuth 2.0 Authorization Framework: Bearer Token Usage](https://docs.authlib.org/en/latest/specs/rfc6750.html)
|
|
90
|
+
- [RFC7009: OAuth 2.0 Token Revocation](https://docs.authlib.org/en/latest/specs/rfc7009.html)
|
|
91
|
+
- [RFC7523: JWT Profile for OAuth 2.0 Client Authentication and Authorization Grants](https://docs.authlib.org/en/latest/specs/rfc7523.html)
|
|
92
|
+
- [RFC7591: OAuth 2.0 Dynamic Client Registration Protocol](https://docs.authlib.org/en/latest/specs/rfc7591.html)
|
|
93
|
+
- [RFC7592: OAuth 2.0 Dynamic Client Registration Management Protocol](https://docs.authlib.org/en/latest/specs/rfc7592.html)
|
|
94
|
+
- [RFC7636: Proof Key for Code Exchange by OAuth Public Clients](https://docs.authlib.org/en/latest/specs/rfc7636.html)
|
|
95
|
+
- [RFC7662: OAuth 2.0 Token Introspection](https://docs.authlib.org/en/latest/specs/rfc7662.html)
|
|
96
|
+
- [RFC8414: OAuth 2.0 Authorization Server Metadata](https://docs.authlib.org/en/latest/specs/rfc8414.html)
|
|
97
|
+
- [RFC8628: OAuth 2.0 Device Authorization Grant](https://docs.authlib.org/en/latest/specs/rfc8628.html)
|
|
98
|
+
- [RFC9068: JSON Web Token (JWT) Profile for OAuth 2.0 Access Tokens](https://docs.authlib.org/en/latest/specs/rfc9068.html)
|
|
99
|
+
- [RFC9101: The OAuth 2.0 Authorization Framework: JWT-Secured Authorization Request (JAR)](https://docs.authlib.org/en/latest/specs/rfc9101.html)
|
|
100
|
+
- [RFC9207: OAuth 2.0 Authorization Server Issuer Identification](https://docs.authlib.org/en/latest/specs/rfc9207.html)
|
|
101
|
+
- [Javascript Object Signing and Encryption](https://docs.authlib.org/en/latest/jose/index.html)
|
|
102
|
+
- [RFC7515: JSON Web Signature](https://docs.authlib.org/en/latest/jose/jws.html)
|
|
103
|
+
- [RFC7516: JSON Web Encryption](https://docs.authlib.org/en/latest/jose/jwe.html)
|
|
104
|
+
- [RFC7517: JSON Web Key](https://docs.authlib.org/en/latest/jose/jwk.html)
|
|
105
|
+
- [RFC7518: JSON Web Algorithms](https://docs.authlib.org/en/latest/specs/rfc7518.html)
|
|
106
|
+
- [RFC7519: JSON Web Token](https://docs.authlib.org/en/latest/jose/jwt.html)
|
|
107
|
+
- [RFC7638: JSON Web Key (JWK) Thumbprint](https://docs.authlib.org/en/latest/specs/rfc7638.html)
|
|
108
|
+
- [ ] RFC7797: JSON Web Signature (JWS) Unencoded Payload Option
|
|
109
|
+
- [RFC8037: ECDH in JWS and JWE](https://docs.authlib.org/en/latest/specs/rfc8037.html)
|
|
110
|
+
- [ ] draft-madden-jose-ecdh-1pu-04: Public Key Authenticated Encryption for JOSE: ECDH-1PU
|
|
111
|
+
- [OpenID Connect 1.0](https://docs.authlib.org/en/latest/specs/oidc.html)
|
|
112
|
+
- [x] OpenID Connect Core 1.0
|
|
113
|
+
- [x] OpenID Connect Discovery 1.0
|
|
114
|
+
- [x] OpenID Connect Dynamic Client Registration 1.0
|
|
115
|
+
|
|
116
|
+
Connect third party OAuth providers with Authlib built-in client integrations:
|
|
117
|
+
|
|
118
|
+
- Requests
|
|
119
|
+
- [OAuth1Session](https://docs.authlib.org/en/latest/client/requests.html#requests-oauth-1-0)
|
|
120
|
+
- [OAuth2Session](https://docs.authlib.org/en/latest/client/requests.html#requests-oauth-2-0)
|
|
121
|
+
- [OpenID Connect](https://docs.authlib.org/en/latest/client/requests.html#requests-openid-connect)
|
|
122
|
+
- [AssertionSession](https://docs.authlib.org/en/latest/client/requests.html#requests-service-account)
|
|
123
|
+
- HTTPX
|
|
124
|
+
- [AsyncOAuth1Client](https://docs.authlib.org/en/latest/client/httpx.html#httpx-oauth-1-0)
|
|
125
|
+
- [AsyncOAuth2Client](https://docs.authlib.org/en/latest/client/httpx.html#httpx-oauth-2-0)
|
|
126
|
+
- [OpenID Connect](https://docs.authlib.org/en/latest/client/httpx.html#httpx-oauth-2-0)
|
|
127
|
+
- [AsyncAssertionClient](https://docs.authlib.org/en/latest/client/httpx.html#async-service-account)
|
|
128
|
+
- [Flask OAuth Client](https://docs.authlib.org/en/latest/client/flask.html)
|
|
129
|
+
- [Django OAuth Client](https://docs.authlib.org/en/latest/client/django.html)
|
|
130
|
+
- [Starlette OAuth Client](https://docs.authlib.org/en/latest/client/starlette.html)
|
|
131
|
+
- [FastAPI OAuth Client](https://docs.authlib.org/en/latest/client/fastapi.html)
|
|
132
|
+
|
|
133
|
+
Build your own OAuth 1.0, OAuth 2.0, and OpenID Connect providers:
|
|
134
|
+
|
|
135
|
+
- Flask
|
|
136
|
+
- [Flask OAuth 1.0 Provider](https://docs.authlib.org/en/latest/flask/1/)
|
|
137
|
+
- [Flask OAuth 2.0 Provider](https://docs.authlib.org/en/latest/flask/2/)
|
|
138
|
+
- [Flask OpenID Connect 1.0 Provider](https://docs.authlib.org/en/latest/flask/2/openid-connect.html)
|
|
139
|
+
- Django
|
|
140
|
+
- [Django OAuth 1.0 Provider](https://docs.authlib.org/en/latest/django/1/)
|
|
141
|
+
- [Django OAuth 2.0 Provider](https://docs.authlib.org/en/latest/django/2/)
|
|
142
|
+
- [Django OpenID Connect 1.0 Provider](https://docs.authlib.org/en/latest/django/2/openid-connect.html)
|
|
143
|
+
|
|
144
|
+
## Useful Links
|
|
145
|
+
|
|
146
|
+
1. Homepage: <https://authlib.org/>.
|
|
147
|
+
2. Documentation: <https://docs.authlib.org/>.
|
|
148
|
+
3. Purchase Commercial License: <https://authlib.org/plans>.
|
|
149
|
+
4. Blog: <https://blog.authlib.org/>.
|
|
150
|
+
5. Twitter: <https://twitter.com/authlib>.
|
|
151
|
+
6. StackOverflow: <https://stackoverflow.com/questions/tagged/authlib>.
|
|
152
|
+
7. Other Repositories: <https://github.com/authlib>.
|
|
153
|
+
8. Subscribe Tidelift: [https://tidelift.com/subscription/pkg/pypi-authlib](https://tidelift.com/subscription/pkg/pypi-authlib?utm_source=pypi-authlib&utm_medium=referral&utm_campaign=links).
|
|
154
|
+
|
|
155
|
+
## Security Reporting
|
|
156
|
+
|
|
157
|
+
If you found security bugs, please do not send a public issue or patch.
|
|
158
|
+
You can send me email at <me@lepture.com>. Attachment with patch is welcome.
|
|
159
|
+
My PGP Key fingerprint is:
|
|
160
|
+
|
|
161
|
+
```
|
|
162
|
+
72F8 E895 A70C EBDF 4F2A DFE0 7E55 E3E0 118B 2B4C
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
Or, you can use the [Tidelift security contact](https://tidelift.com/security).
|
|
166
|
+
Tidelift will coordinate the fix and disclosure.
|
|
167
|
+
|
|
168
|
+
## License
|
|
169
|
+
|
|
170
|
+
Authlib offers two licenses:
|
|
171
|
+
|
|
172
|
+
1. BSD LICENSE
|
|
173
|
+
2. COMMERCIAL-LICENSE
|
|
174
|
+
|
|
175
|
+
Any project, open or closed source, can use the BSD license.
|
|
176
|
+
If your company needs commercial support, you can purchase a commercial license at
|
|
177
|
+
[Authlib Plans](https://authlib.org/plans). You can find more information at
|
|
178
|
+
<https://authlib.org/support>.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
authlib/__init__.py,sha256=9F2r7k-nrTBFVDVWk0oghhIpLioCwQtt-35ppwRNfGU,487
|
|
2
|
-
authlib/consts.py,sha256=
|
|
2
|
+
authlib/consts.py,sha256=9cqeotlkDe69rVuzp_CwFO01qxVvyzzzbB2UpHWEvDg,299
|
|
3
3
|
authlib/deprecate.py,sha256=BaH7IdSK0WEmanyJAl7-Rpmvm6NJcez-Z03k0OYPXl0,506
|
|
4
4
|
authlib/common/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
5
5
|
authlib/common/encoding.py,sha256=S80EkhVVJABStdEuZvQV1c47gQnu359fgLAFDmqLaP0,1544
|
|
@@ -23,7 +23,7 @@ authlib/integrations/django_oauth1/authorization_server.py,sha256=xtI50oMRKfA5tk
|
|
|
23
23
|
authlib/integrations/django_oauth1/nonce.py,sha256=jwhnA3SFCoGtEN7LBLv3pyKc1rWepFM9_iTSpt6BvR4,396
|
|
24
24
|
authlib/integrations/django_oauth1/resource_protector.py,sha256=xSpHsX7X88IXwE4Qb0pHMPPiEag_ZalGBjFZqt9nG4o,2332
|
|
25
25
|
authlib/integrations/django_oauth2/__init__.py,sha256=gmWoCspRgvmtO3VuA34-FluF5pmgbo-oQyeD1KW2rVQ,333
|
|
26
|
-
authlib/integrations/django_oauth2/authorization_server.py,sha256=
|
|
26
|
+
authlib/integrations/django_oauth2/authorization_server.py,sha256=6P0pYQpS83igXm-XyUmdIfTLq0_O3kpKApEVDynHaZA,4463
|
|
27
27
|
authlib/integrations/django_oauth2/endpoints.py,sha256=dlGwktdT_miFCZDKYTFaiKxBPxBlL0cGlJCsE19wBv4,1838
|
|
28
28
|
authlib/integrations/django_oauth2/requests.py,sha256=Qkk-G-VLlQwfh_QA2Wq9NBQr5EYnYGUSvX_ba9WZc5g,1850
|
|
29
29
|
authlib/integrations/django_oauth2/resource_protector.py,sha256=QTrO0nZWJVki2lggx80Ud9y9bM9wBTBRn4SXvchhMf0,2597
|
|
@@ -36,7 +36,7 @@ authlib/integrations/flask_oauth1/authorization_server.py,sha256=mogA8tai-cU2-0c
|
|
|
36
36
|
authlib/integrations/flask_oauth1/cache.py,sha256=iF_mvWvkv6S7n0bm5Q9kUqBIlXcmwgxx01chPZM27xo,3012
|
|
37
37
|
authlib/integrations/flask_oauth1/resource_protector.py,sha256=h3nDaEc1W7eRht4jLROURCDsZfFX9Ak9JyPGWJv63Eg,3842
|
|
38
38
|
authlib/integrations/flask_oauth2/__init__.py,sha256=cQ7vhDQuXp2R5IMPTpb6rR0ChKAt_tmY95mlrOjYXOc,284
|
|
39
|
-
authlib/integrations/flask_oauth2/authorization_server.py,sha256=
|
|
39
|
+
authlib/integrations/flask_oauth2/authorization_server.py,sha256=rWrRJh3pr6tito6OKYGTbdY4Y2OYMKyMmD20CtmVb1s,5911
|
|
40
40
|
authlib/integrations/flask_oauth2/errors.py,sha256=ku67ILaSYS9i028Ipx26TYslXTK9UWiumqf07tjbICo,1085
|
|
41
41
|
authlib/integrations/flask_oauth2/requests.py,sha256=DcLTETbx0OjNa8mpjRr4UKifuni1oXGQOHBlXF1WWSk,1480
|
|
42
42
|
authlib/integrations/flask_oauth2/resource_protector.py,sha256=s0LbjE0nTKbEIqngEe0chphOlULh9LmzVIiEdszd7ts,3875
|
|
@@ -56,22 +56,22 @@ authlib/integrations/sqla_oauth2/client_mixin.py,sha256=4hTqHeS34JUFJLLvOJqpfzBG
|
|
|
56
56
|
authlib/integrations/sqla_oauth2/functions.py,sha256=Lc_mK1LV_FonUUHXmswxlze7NPyAhs-pxW1pOGgWxXw,3156
|
|
57
57
|
authlib/integrations/sqla_oauth2/tokens_mixins.py,sha256=B62cFI-jZhtIU79of6l6Lxzia6tnutZHMeZrpSLIEd8,2261
|
|
58
58
|
authlib/integrations/starlette_client/__init__.py,sha256=qIPzeCFSCJ1AnCJ_I9tvmL2qDOJtaPUwgG7Mb4wz3VI,713
|
|
59
|
-
authlib/integrations/starlette_client/apps.py,sha256=
|
|
59
|
+
authlib/integrations/starlette_client/apps.py,sha256=3rIzMYCzdu4ajfyaHlBeFIJb6gI8lBjNl_Ry7VTT_go,4140
|
|
60
60
|
authlib/integrations/starlette_client/integration.py,sha256=Dlu7w36dPrBz_-ybcwmOasGrZprQiCQ9IQqd47VeDQk,2253
|
|
61
61
|
authlib/jose/__init__.py,sha256=wtdmtHrQV3a3-us9K6nVVGHrC82zSJ27FX106uUxeLI,1703
|
|
62
|
-
authlib/jose/errors.py,sha256=
|
|
62
|
+
authlib/jose/errors.py,sha256=NK3sAewwLTZ6eaNS4QVcpndf3oL2CySrwsF9xiTWDqs,3199
|
|
63
63
|
authlib/jose/jwk.py,sha256=LqCE7K1WozgSR_UHwXEajwVJjjBwXkIKebT1Z_AzFE0,491
|
|
64
|
-
authlib/jose/util.py,sha256=
|
|
64
|
+
authlib/jose/util.py,sha256=24oOQ3Vnm9gUa0rDyEau9-l-F7ovzsDV6VbzxTscCiU,1357
|
|
65
65
|
authlib/jose/drafts/__init__.py,sha256=AXAw9r6-6XsVbugtoJ6zFn0u85iYDssVLLbDGm-HIWU,520
|
|
66
66
|
authlib/jose/drafts/_jwe_algorithms.py,sha256=qkYzPAteYSs1jRZGc3lxBVPbYy8jFgf_O2GE-LW0xUM,7199
|
|
67
67
|
authlib/jose/drafts/_jwe_enc_cryptodome.py,sha256=-Qq-JWsBrui5-UJW1QqDltsJCygvWAicSkbQqcH0jdo,1848
|
|
68
68
|
authlib/jose/drafts/_jwe_enc_cryptography.py,sha256=yd63oNubl-vSMC8H_g8xFGCMa3AUEhOzrXQnGS2TBSU,1731
|
|
69
69
|
authlib/jose/rfc7515/__init__.py,sha256=ub5iDwyqk1z_W1QSFqtFn6tEJvLqEgMg6ftHmGVsSvQ,367
|
|
70
|
-
authlib/jose/rfc7515/jws.py,sha256=
|
|
71
|
-
authlib/jose/rfc7515/models.py,sha256=
|
|
70
|
+
authlib/jose/rfc7515/jws.py,sha256=QmpynjXy9YgMDP9V1ESSqivA3fFkoAFmoWy4DjBfr6s,13720
|
|
71
|
+
authlib/jose/rfc7515/models.py,sha256=81IbGsdq9I4Qe0NIusgRia4G3CFsh70gWf2v9lT9kJA,2448
|
|
72
72
|
authlib/jose/rfc7516/__init__.py,sha256=85pDv76XJrL_ZVl89Thr6ilzM9yelMWGBad20klWjDM,514
|
|
73
73
|
authlib/jose/rfc7516/jwe.py,sha256=MTOtywMG6Ji2-PM0paW4jx4r5q1zVC0GNL3pZveGHu4,30539
|
|
74
|
-
authlib/jose/rfc7516/models.py,sha256=
|
|
74
|
+
authlib/jose/rfc7516/models.py,sha256=vzYq1du-F59IqFlcGnTATVCDLEy0Tsisz5yF57tcppw,4381
|
|
75
75
|
authlib/jose/rfc7517/__init__.py,sha256=RmMT_4O1d4YaqVl_5V5bM0blqXqjdKZsdYNQObtTkPc,404
|
|
76
76
|
authlib/jose/rfc7517/_cryptography_key.py,sha256=bp-2kiKpzKdOWSuzMTCMhsyZdvdEUrv9nYVyNBlqqys,1361
|
|
77
77
|
authlib/jose/rfc7517/asymmetric_key.py,sha256=NoCPBm8rjoW1Lonyt-LP44_TZnwceRv6DKHoRb4DDRw,6464
|
|
@@ -82,7 +82,7 @@ authlib/jose/rfc7518/__init__.py,sha256=qvxQ-N7dlZu2d4qg30rH0JkNp-_eeaY0VK20vAv4
|
|
|
82
82
|
authlib/jose/rfc7518/ec_key.py,sha256=IIpDO9hKzDGhOd8CxwxH08iO_6j7sR86cJBm6wN0SFw,3921
|
|
83
83
|
authlib/jose/rfc7518/jwe_algs.py,sha256=tBw_lUUrs9RCYjyVi4OOu1_Fgh15Qtp-h4qHjCAc0e8,11422
|
|
84
84
|
authlib/jose/rfc7518/jwe_encs.py,sha256=A0wKhj9u9hF_B51U7nHxZFQ5TskRfJ5Uube1DlvB8Aw,5093
|
|
85
|
-
authlib/jose/rfc7518/jwe_zips.py,sha256=
|
|
85
|
+
authlib/jose/rfc7518/jwe_zips.py,sha256=dFCRYN5J7_iHmiaB8t_FjUqRz966t2TYXrJ2lmvUJfg,1060
|
|
86
86
|
authlib/jose/rfc7518/jws_algs.py,sha256=tCnBPwtlQ0gSY5LgW1F5FaKNT36kWkPHLXGxHBLLQCs,6573
|
|
87
87
|
authlib/jose/rfc7518/oct_key.py,sha256=0XRdpxpFExYtlXse9ZAM6Bj-26fgZOHHBQdJoTdl1ec,2744
|
|
88
88
|
authlib/jose/rfc7518/rsa_key.py,sha256=PmX2WWd3rLmwihqGhJYPW6C50aEmYghfbsZKPO_4bRU,4581
|
|
@@ -114,11 +114,11 @@ authlib/oauth2/base.py,sha256=8ZG02kdskhdh5vfK4P2nSsnE1WcwSUxsx5banmYJyVk,2025
|
|
|
114
114
|
authlib/oauth2/client.py,sha256=Txg4tghGHItiTE2TTzDi8r-3V6aCEf78oOgaQtUSRx8,18938
|
|
115
115
|
authlib/oauth2/rfc6749/__init__.py,sha256=35h_BcWs2rFC62A0U2AlVpMZCVnD74ddZELK35VTqF8,2845
|
|
116
116
|
authlib/oauth2/rfc6749/authenticate_client.py,sha256=nFBxSrw62zLYl1JRON3rjCv_BUZzTivZ7HYuqnkdQmg,3985
|
|
117
|
-
authlib/oauth2/rfc6749/authorization_server.py,sha256=
|
|
117
|
+
authlib/oauth2/rfc6749/authorization_server.py,sha256=GhuWgVVxuJ7fxwLUA-kHtLuo0DPmd0hM_sfYEV0gziA,13367
|
|
118
118
|
authlib/oauth2/rfc6749/errors.py,sha256=FfT5OJJEk0RJaUjJKT1v_npN5AvCUuASqP8LtX2e4xo,7242
|
|
119
119
|
authlib/oauth2/rfc6749/hooks.py,sha256=v8emOHmENAen3WbOXgmhLwHur6_i5QUgRE5NNXI_ukI,1004
|
|
120
120
|
authlib/oauth2/rfc6749/models.py,sha256=PZO-owOyb1RzbmD-xdYwO_Q6Si57pqFGPqhDXiDhNVs,7773
|
|
121
|
-
authlib/oauth2/rfc6749/parameters.py,sha256
|
|
121
|
+
authlib/oauth2/rfc6749/parameters.py,sha256=-hauWerU6UlMuyVA-oxQaWc_r_y5BfDVnz7nh-oZd7E,8564
|
|
122
122
|
authlib/oauth2/rfc6749/requests.py,sha256=8m2bVR9KrUGzqFRBI8aXp7h-Y3a8H6wLY5hLajYiIRM,5095
|
|
123
123
|
authlib/oauth2/rfc6749/resource_protector.py,sha256=OKXtwUVn0kgK55mIzc9mGNbfUpwoOWTxb105Td5iVPE,5404
|
|
124
124
|
authlib/oauth2/rfc6749/token_endpoint.py,sha256=kxjK39EHBgeD7uvJLyoLF5DAr1ef4l31jpCt6C4gYJ0,1103
|
|
@@ -150,7 +150,7 @@ authlib/oauth2/rfc7523/token.py,sha256=olIDs43sKuVtrOis5l7tRjJS-p_ns1c1VWkf9NUgM
|
|
|
150
150
|
authlib/oauth2/rfc7523/validator.py,sha256=4d0FHSi8UR9pLlyYRpG8M2lW8MvYZyoOuhS-RpZoNAA,1668
|
|
151
151
|
authlib/oauth2/rfc7591/__init__.py,sha256=BC7HMHZmLvgHIcpU3uRP48IHnVyeS77LADhhRw5h9aY,694
|
|
152
152
|
authlib/oauth2/rfc7591/claims.py,sha256=wAsPmqOD-qYPrZpCJxphLOrIPEthUJPml6O8I7J26n4,12169
|
|
153
|
-
authlib/oauth2/rfc7591/endpoint.py,sha256=
|
|
153
|
+
authlib/oauth2/rfc7591/endpoint.py,sha256=1SeM471z3G31RPTAlQcH0AG7eEx9fcMwnm67iNwpGeA,7183
|
|
154
154
|
authlib/oauth2/rfc7591/errors.py,sha256=oflYk0Qj9FBIU6eBvqgIpUMHK2dA73A8Y5UWOXZMmq4,1106
|
|
155
155
|
authlib/oauth2/rfc7592/__init__.py,sha256=8oCqEJwbLOyFLq9qmEFy2WFu6-bj9rCUpJMj0ICTZSA,295
|
|
156
156
|
authlib/oauth2/rfc7592/endpoint.py,sha256=CkY9RP3w4f3KXAHl4Mzqq9OtJlL7pgY8V1RyBkjHyBw,8788
|
|
@@ -199,8 +199,8 @@ authlib/oidc/discovery/models.py,sha256=yzdWYQn-VfC48gywoxswge4tgnKb8uQ-UkjhVTCl
|
|
|
199
199
|
authlib/oidc/discovery/well_known.py,sha256=ry1VHxCmwvjmlMxOFEbSC6FsE_ttijyRcn2xUpv2CaU,574
|
|
200
200
|
authlib/oidc/registration/__init__.py,sha256=lV_Og-DMFKzWWYsdK04oF83xKUGTE2gQhikPPsOdW84,77
|
|
201
201
|
authlib/oidc/registration/claims.py,sha256=K7Ft8GDXkVrjJrc53Ihkhn2SVN4pvEf3qiHOkzVOJ7g,17264
|
|
202
|
-
authlib-1.6.
|
|
203
|
-
authlib-1.6.
|
|
204
|
-
authlib-1.6.
|
|
205
|
-
authlib-1.6.
|
|
206
|
-
authlib-1.6.
|
|
202
|
+
authlib-1.6.5.dist-info/licenses/LICENSE,sha256=jhtIUY3pxs0Ay0jH_luAI_2Q1VUsoS6-c2Kg3zDdvkU,1514
|
|
203
|
+
authlib-1.6.5.dist-info/METADATA,sha256=JSpi4anvkVQ9zL3GuZR4mvuto9yjFI39uhUnGfKGwdY,9845
|
|
204
|
+
authlib-1.6.5.dist-info/WHEEL,sha256=JNWh1Fm1UdwIQV075glCn4MVuCRs0sotJIq-J6rbxCU,109
|
|
205
|
+
authlib-1.6.5.dist-info/top_level.txt,sha256=Rj3mJn0jhRuCs6x7ysI6hYE2PePbuxey6y6jswadAEY,8
|
|
206
|
+
authlib-1.6.5.dist-info/RECORD,,
|
authlib-1.6.3.dist-info/METADATA
DELETED
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: Authlib
|
|
3
|
-
Version: 1.6.3
|
|
4
|
-
Summary: The ultimate Python library in building OAuth and OpenID Connect servers and clients.
|
|
5
|
-
Author-email: Hsiaoming Yang <me@lepture.com>
|
|
6
|
-
License: BSD-3-Clause
|
|
7
|
-
Project-URL: Documentation, https://docs.authlib.org/
|
|
8
|
-
Project-URL: Purchase, https://authlib.org/plans
|
|
9
|
-
Project-URL: Issues, https://github.com/authlib/authlib/issues
|
|
10
|
-
Project-URL: Source, https://github.com/authlib/authlib
|
|
11
|
-
Project-URL: Donate, https://github.com/sponsors/lepture
|
|
12
|
-
Project-URL: Blog, https://blog.authlib.org/
|
|
13
|
-
Classifier: Development Status :: 5 - Production/Stable
|
|
14
|
-
Classifier: Environment :: Console
|
|
15
|
-
Classifier: Environment :: Web Environment
|
|
16
|
-
Classifier: Intended Audience :: Developers
|
|
17
|
-
Classifier: License :: OSI Approved :: BSD License
|
|
18
|
-
Classifier: Operating System :: OS Independent
|
|
19
|
-
Classifier: Programming Language :: Python
|
|
20
|
-
Classifier: Programming Language :: Python :: 3
|
|
21
|
-
Classifier: Programming Language :: Python :: 3.9
|
|
22
|
-
Classifier: Programming Language :: Python :: 3.10
|
|
23
|
-
Classifier: Programming Language :: Python :: 3.11
|
|
24
|
-
Classifier: Programming Language :: Python :: 3.12
|
|
25
|
-
Classifier: Programming Language :: Python :: 3.13
|
|
26
|
-
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
27
|
-
Classifier: Programming Language :: Python :: Implementation :: PyPy
|
|
28
|
-
Classifier: Topic :: Security
|
|
29
|
-
Classifier: Topic :: Security :: Cryptography
|
|
30
|
-
Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
|
|
31
|
-
Classifier: Topic :: Internet :: WWW/HTTP :: WSGI :: Application
|
|
32
|
-
Requires-Python: >=3.9
|
|
33
|
-
Description-Content-Type: text/x-rst
|
|
34
|
-
License-File: LICENSE
|
|
35
|
-
Requires-Dist: cryptography
|
|
36
|
-
Dynamic: license-file
|
|
File without changes
|
|
File without changes
|
|
File without changes
|