Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 18f7fa9

Browse files
authored
Merge pull request auth0#456 from auth0/private_key_jwt
2 parents 6ebd7a2 + bd8798b commit 18f7fa9

32 files changed

+408
-571
lines changed

.circleci/config.yml

Lines changed: 3 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,9 @@ executors:
99
python_3_10:
1010
docker:
1111
- image: cimg/python:3.10
12-
python_2_7:
13-
docker:
14-
- image: cimg/python:2.7
1512

1613
jobs:
17-
python_3:
14+
build:
1815
executor: python_3_10
1916
steps:
2017
- checkout
@@ -25,21 +22,10 @@ jobs:
2522
- run: bash <(curl -s https://codecov.io/bash)
2623
- run: make -C docs html
2724

28-
python_2:
29-
executor: python_2_7
30-
steps:
31-
- checkout
32-
- python/install-packages:
33-
pkg-manager: pip-dist
34-
path-args: ".[test]"
35-
- run: coverage run -m unittest discover -s auth0/v3/test -t .
36-
- codecov/upload
37-
3825
workflows:
3926
main:
4027
jobs:
41-
- python_3
42-
- python_2
28+
- build
4329
- ship/python-publish:
4430
prefix-tag: false
4531
context:
@@ -50,5 +36,4 @@ workflows:
5036
only:
5137
- master
5238
requires:
53-
- python_3
54-
- python_2
39+
- build

EXAMPLES.md

Lines changed: 18 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
- [Authentication SDK](#authentication-sdk)
44
- [ID token validation](#id-token-validation)
5-
- [Organizations](#organizations)
5+
- [Authenticating with a application configured to use `private_key_jwt` token endpoint auth method](#authenticating-with-a-application-configured-to-use-private-key-jwt-token-endpoint-auth-method)
66
- [Management SDK](#management-sdk)
77
- [Connections](#connections)
88
- [Error handling](#error-handling)
@@ -50,102 +50,26 @@ tv.verify(id_token)
5050

5151
If the token verification fails, a `TokenValidationError` will be raised. In that scenario, the ID token should be deemed invalid and its contents should not be trusted.
5252

53-
54-
55-
### Organizations
56-
57-
[Organizations](https://auth0.com/docs/organizations) is a set of features that provide better support for developers who build and maintain SaaS and Business-to-Business (B2B) applications.
58-
59-
Note that Organizations is currently only available to customers on our Enterprise and Startup subscription plans.
60-
61-
62-
#### Log in to an organization
63-
64-
Log in to an organization by specifying the ``organization`` property when calling ``authorize()``:
65-
66-
```python
67-
from auth0.v3.authentication.authorize_client import AuthorizeClient
68-
69-
client = AuthorizeClient('my.domain.com')
70-
71-
client.authorize(client_id='client_id',
72-
redirect_uri='http://localhost',
73-
organization="org_abc")
74-
```
75-
76-
When logging into an organization, it is important to ensure the `org_id` claim of the ID Token matches the expected organization value. The `TokenVerifier` can be be used to ensure the ID Token contains the expected `org_id` claim value:
77-
78-
```python
79-
from auth0.v3.authentication.token_verifier import TokenVerifier, AsymmetricSignatureVerifier
80-
81-
domain = 'myaccount.auth0.com'
82-
client_id = 'exampleid'
83-
84-
# After authenticating
85-
id_token = auth_result['id_token']
86-
87-
jwks_url = 'https://{}/.well-known/jwks.json'.format(domain)
88-
issuer = 'https://{}/'.format(domain)
89-
90-
sv = AsymmetricSignatureVerifier(jwks_url) # Reusable instance
91-
tv = TokenVerifier(signature_verifier=sv, issuer=issuer, audience=client_id)
92-
93-
# pass the expected organization the user logged in to:
94-
tv.verify(id_token, organization='org_abc')
95-
96-
```
97-
98-
#### Accept user invitations
99-
100-
Accept a user invitation by specifying the `invitation` property when calling `authorize()`. Note that you must also specify the ``organization`` if providing an ``invitation``.
101-
The ID of the invitation and organization are available as query parameters on the invitation URL, e.g., ``https://your-domain.auth0.com/login?invitation=invitation_id&organization=org_id&organization_name=org_name``
102-
103-
```python
104-
from auth0.v3.authentication.authorize_client import AuthorizeClient
105-
106-
client = AuthorizeClient('my.domain.com')
107-
108-
client.authorize(client_id='client_id',
109-
redirect_uri='http://localhost',
110-
organization='org_abc',
111-
invitation="invitation_123")
112-
```
113-
114-
#### Authorizing users from an Organization
115-
116-
If an `org_id` claim is present in the Access Token, then the claim should be validated by the API to ensure that the value received is expected or known.
117-
118-
In particular:
119-
120-
- The issuer (`iss`) claim should be checked to ensure the token was issued by Auth0
121-
- The organization ID (`org_id`) claim should be checked to ensure it is a value that is already known to the application. This could be validated against a known list of organization IDs, or perhaps checked in conjunction with the current request URL. e.g. the sub-domain may hint at what organization should be used to validate the Access Token.
122-
123-
Normally, validating the issuer would be enough to ensure that the token was issued by Auth0. In the case of organizations, additional checks should be made so that the organization within an Auth0 tenant is expected.
124-
125-
If the claim cannot be validated, then the application should deem the token invalid.
126-
127-
The snippet below attempts to illustrate how this verification could look like using the external [PyJWT](https://pyjwt.readthedocs.io/en/latest/usage.html#encoding-decoding-tokens-with-rs256-rsa) library. This dependency will take care of pulling the RS256 Public Key that was used by the server to sign the Access Token. It will also validate its signature, expiration, and the audience value. After the basic verification, get the `org_id` claim and check it against the expected value. The code assumes your application is configured to sign tokens using the RS256 algorithm. Check the [Validate JSON Web Tokens](https://auth0.com/docs/tokens/json-web-tokens/validate-json-web-tokens) article to learn more about this verification.
53+
### Authenticating with a application configured to use `private_key_jwt` token endpoint auth method
12854

12955
```python
130-
import jwt # PyJWT
131-
from jwt import PyJWKClient
132-
133-
access_token = # access token from the request
134-
url = 'https://{YOUR AUTH0 DOMAIN}/.well-known/jwks.json'
135-
jwks_client = PyJWKClient(url)
136-
signing_key = jwks_client.get_signing_key_from_jwt(access_token)
137-
data = jwt.decode(
138-
access_token,
139-
signing_key.key,
140-
algorithms=['RS256'],
141-
audience='{YOUR API AUDIENCE}'
56+
from auth0.v3.authentication import GetToken
57+
58+
private_key = """-----BEGIN RSA PRIVATE KEY-----
59+
MIIJKQIBAAKCAgEAwfUb0nUC0aKB3WiytFhnCIg455BYC+dR3MUGadWpIg7S6lbi
60+
...
61+
2tjIvH4GN9ZkIGwzxIOP61wkUGwGaIzacOTIWOvqRI0OaYr9U18Ep1trvgGR
62+
-----END RSA PRIVATE KEY-----
63+
"""
64+
65+
get_token = GetToken(
66+
"my-domain.us.auth0.com",
67+
"my-client-id",
68+
client_assertion_signing_key=private_key,
69+
)
70+
token = get_token.client_credentials(
71+
"https://my-domain.us.auth0.com/api/v2/"
14272
)
143-
144-
organization = # expected organization ID
145-
if data['org_id'] != organization:
146-
raise Exception('Organization (org_id) claim mismatch')
147-
148-
# if this line is reached, validation is successful
14973
```
15074

15175
## Management SDK

README.md

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -38,29 +38,29 @@ For example:
3838
```python
3939
from auth0.v3.authentication import Social
4040

41-
social = Social('myaccount.auth0.com')
41+
social = Social('my-domain.us.auth0.com', 'my-client-id')
4242

43-
social.login(client_id='...', access_token='...', connection='facebook')
43+
social.login(access_token='...', connection='facebook')
4444
```
4545

4646
If you need to sign up a user using their email and password, you can use the Database object.
4747

4848
```python
4949
from auth0.v3.authentication import Database
5050

51-
database = Database('myaccount.auth0.com'')
51+
database = Database('my-domain.us.auth0.com', 'my-client-id')
5252

53-
database.signup(client_id='...', email='[email protected]', password='secr3t', connection='Username-Password-Authentication')
53+
database.signup(email='[email protected]', password='secr3t', connection='Username-Password-Authentication')
5454
```
5555

5656
If you need to authenticate a user using their email and password, you can use the `GetToken` object, which enables making requests to the `/oauth/token` endpoint.
5757

5858
```python
5959
from auth0.v3.authentication import GetToken
6060

61-
token = GetToken('myaccount.auth0.com')
61+
token = GetToken('my-domain.us.auth0.com', 'my-client-id', client_secret='my-client-secret')
6262

63-
token.login(client_id='...', client_secret='...', username='[email protected]', password='secr3t', realm='Username-Password-Authentication')
63+
token.login(username='[email protected]', password='secr3t', realm='Username-Password-Authentication')
6464
```
6565

6666
#### Management SDK
@@ -73,9 +73,8 @@ domain = 'myaccount.auth0.com'
7373
non_interactive_client_id = 'exampleid'
7474
non_interactive_client_secret = 'examplesecret'
7575

76-
get_token = GetToken(domain)
77-
token = get_token.client_credentials(non_interactive_client_id,
78-
non_interactive_client_secret, 'https://{}/api/v2/'.format(domain))
76+
get_token = GetToken(domain, non_interactive_client_id, client_secret=non_interactive_client_secret)
77+
token = get_token.client_credentials('https://{}/api/v2/'.format(domain))
7978
mgmt_api_token = token['access_token']
8079
```
8180

@@ -98,7 +97,6 @@ For more code samples on how to integrate the auth0-python SDK in your Python ap
9897

9998
### Authentication Endpoints
10099

101-
- API Authorization - Authorization Code Grant (`authentication.AuthorizeClient`)
102100
- Database ( `authentication.Database` )
103101
- Delegated ( `authentication.Delegated` )
104102
- Enterprise ( `authentication.Enterprise` )
@@ -140,6 +138,7 @@ For more code samples on how to integrate the auth0-python SDK in your Python ap
140138
- UserBlocks() (`Auth0().user_blocks` )
141139
- UsersByEmail() ( `Auth0().users_by_email` )
142140
- Users() ( `Auth0().users` )
141+
143142
## Feedback
144143

145144
### Contributing

V4_MIGRATION_GUIDE.md

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# V4 Migration Guide
2+
3+
Guide to migrating from `3.x` to `4.x`
4+
5+
- [Python <3.6 is no longer supported](#python-36-is-no-longer-supported)
6+
- [Client ID and client secret are now specified in the constructor for authentication clients](#client-id-and-client-secret-are-now-specified-in-the-constructor-for-authentication-clients)
7+
- [AuthorizeClient and Logout have been removed](#authorizeclient-and-logout-have-been-removed)
8+
9+
## Python <3.6 is no longer supported
10+
11+
Python 3.5 and Python 2 are EOL and are no longer supported.
12+
13+
## Client ID and client secret are now specified in the constructor for authentication clients
14+
15+
### Before
16+
17+
```py
18+
from auth0.v3.authentication import GetToken
19+
20+
get_token = GetToken('my-domain.us.auth0.com')
21+
22+
get_token.client_credentials('my-client-id', 'my-client-secret', 'my-api')
23+
```
24+
25+
### After
26+
27+
```py
28+
from auth0.v3.authentication import GetToken
29+
30+
# `client_secret` is optional (you can now use `client_assertion_signing_key` as an alternative)
31+
get_token = GetToken('my-domain.us.auth0.com', 'my-client-id', client_secret='my-client-secret')
32+
33+
get_token.client_credentials('my-api')
34+
```
35+
36+
## AuthorizeClient and Logout have been removed
37+
38+
The authorize and logout requests need to be done in a user agent, so it didn't make sense to include them in a REST client.

auth0/v3/authentication/__init__.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,17 @@
1-
from .authorize_client import AuthorizeClient
21
from .database import Database
32
from .delegated import Delegated
43
from .enterprise import Enterprise
54
from .get_token import GetToken
6-
from .logout import Logout
75
from .passwordless import Passwordless
86
from .revoke_token import RevokeToken
97
from .social import Social
108
from .users import Users
119

1210
__all__ = (
13-
"AuthorizeClient",
1411
"Database",
1512
"Delegated",
1613
"Enterprise",
1714
"GetToken",
18-
"Logout",
1915
"Passwordless",
2016
"RevokeToken",
2117
"Social",

auth0/v3/authentication/authorize_client.py

Lines changed: 0 additions & 40 deletions
This file was deleted.

0 commit comments

Comments
 (0)