Skip to content

OAuth2 Client code refactoring and linting #71

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 148 commits into from
Jul 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
148 commits
Select commit Hold shift + click to select a range
9d0bd40
Improved the support for Token revocation.
rohe Mar 19, 2023
9e2d3d9
map_supported_to_preferred must be done before allow_refresh_token.
rohe Mar 21, 2023
c023f74
Renamed some test modules.
rohe Mar 22, 2023
0d08fd3
A general resource service interface.
rohe Mar 22, 2023
1e2fb9c
Made demo directory. Moved some modules there, renamed. Fixed warning…
rohe Mar 23, 2023
73d6dcc
Made demo directory. Moved some modules there, renamed. Fixed warning…
rohe Mar 23, 2023
45c9898
More demo modules.
rohe Mar 25, 2023
379da47
More demo modules.
rohe Mar 25, 2023
686dd9a
Working on dpop support
rohe Mar 26, 2023
fcb2690
More demos
rohe Mar 27, 2023
c3251cb
More demos
rohe Mar 28, 2023
f51f795
Improved the support for Token revocation.
rohe Mar 19, 2023
d2f832f
map_supported_to_preferred must be done before allow_refresh_token.
rohe Mar 21, 2023
2a04e0b
Renamed some test modules.
rohe Mar 22, 2023
87b00e2
A general resource service interface.
rohe Mar 22, 2023
668b60d
Made demo directory. Moved some modules there, renamed. Fixed warning…
rohe Mar 23, 2023
a30b918
Made demo directory. Moved some modules there, renamed. Fixed warning…
rohe Mar 23, 2023
8b5383a
More demo modules.
rohe Mar 25, 2023
7ffa6e7
More demo modules.
rohe Mar 25, 2023
d13e01a
Working on dpop support
rohe Mar 26, 2023
73aa6a9
More demos
rohe Mar 27, 2023
0e034ab
More demos
rohe Mar 28, 2023
fc02430
Working on dpop (version #14) support ... working.
rohe Mar 31, 2023
9ce2ac7
merge
rohe Apr 1, 2023
eb2a39a
Allow for callback function to find client information.
rohe Apr 3, 2023
a8b2343
Fixed faulty response_types handling.
rohe Apr 5, 2023
7871f79
Corrected token lifetime handling.
rohe Apr 9, 2023
f1d2946
Made all senarios use Flow.
rohe Apr 10, 2023
d97f3d6
Started a refactored and fixed some errors.
rohe Apr 11, 2023
a9eff2b
Refactored all oauth stories.
rohe Apr 11, 2023
0065ec8
Refactored a couple more.
rohe Apr 11, 2023
8af4e9e
Refactoring is completed
rohe Apr 12, 2023
5f05778
Updated README
rohe Apr 14, 2023
d1da7e8
Got the PAR example working.
rohe Apr 19, 2023
fd69ed3
Added client authentication to PAR.
rohe Apr 20, 2023
cc8e710
Improved the support for Token revocation.
rohe Mar 19, 2023
84b6aa8
map_supported_to_preferred must be done before allow_refresh_token.
rohe Mar 21, 2023
33edc10
Renamed some test modules.
rohe Mar 22, 2023
ab8c108
A general resource service interface.
rohe Mar 22, 2023
b15f1ed
Made demo directory. Moved some modules there, renamed. Fixed warning…
rohe Mar 23, 2023
3f91224
Made demo directory. Moved some modules there, renamed. Fixed warning…
rohe Mar 23, 2023
63d60b3
More demo modules.
rohe Mar 25, 2023
cd22a35
More demo modules.
rohe Mar 25, 2023
72d9f18
Working on dpop support
rohe Mar 26, 2023
a04696b
More demos
rohe Mar 27, 2023
77ff5d2
More demos
rohe Mar 28, 2023
1d68d4b
Improved the support for Token revocation.
rohe Mar 19, 2023
cb04871
map_supported_to_preferred must be done before allow_refresh_token.
rohe Mar 21, 2023
dda9feb
Renamed some test modules.
rohe Mar 22, 2023
36d155d
A general resource service interface.
rohe Mar 22, 2023
9a5b305
Made demo directory. Moved some modules there, renamed. Fixed warning…
rohe Mar 23, 2023
b6dcb0f
More demo modules.
rohe Mar 25, 2023
69c8868
More demo modules.
rohe Mar 25, 2023
cd298de
More demos
rohe Mar 28, 2023
829e1e2
Working on dpop (version #14) support ... working.
rohe Mar 31, 2023
abf0098
Allow for callback function to find client information.
rohe Apr 3, 2023
71bf3ef
Fixed faulty response_types handling.
rohe Apr 5, 2023
ba73b3a
Corrected token lifetime handling.
rohe Apr 9, 2023
5d4748f
Made all senarios use Flow.
rohe Apr 10, 2023
8171a21
Started a refactored and fixed some errors.
rohe Apr 11, 2023
fccffa7
Refactored all oauth stories.
rohe Apr 11, 2023
ac49a17
Refactored a couple more.
rohe Apr 11, 2023
51efba6
Refactoring is completed
rohe Apr 12, 2023
f37879d
Updated README
rohe Apr 14, 2023
e94d936
Got the PAR example working.
rohe Apr 19, 2023
c399a85
Added client authentication to PAR.
rohe Apr 20, 2023
6cca8aa
test is normally not accessible from demo.
rohe Apr 22, 2023
cface46
Merge branch 'tok_rev' of https://github.com/IdentityPython/idpy-oidc…
rohe Apr 22, 2023
ac3a8f9
More informative
rohe Apr 22, 2023
b472cab
Cleaned up
rohe Apr 23, 2023
f97cda7
JAR can also include encryption.
rohe May 4, 2023
24f53fb
pkce is a OAuth2 extension.
rohe May 6, 2023
cd9b7cf
Improved the support for Token revocation.
rohe Mar 19, 2023
5b8a505
map_supported_to_preferred must be done before allow_refresh_token.
rohe Mar 21, 2023
003930e
Renamed some test modules.
rohe Mar 22, 2023
96e3527
A general resource service interface.
rohe Mar 22, 2023
c6e8cc7
Made demo directory. Moved some modules there, renamed. Fixed warning…
rohe Mar 23, 2023
c832c6a
Made demo directory. Moved some modules there, renamed. Fixed warning…
rohe Mar 23, 2023
34ac36e
More demo modules.
rohe Mar 25, 2023
cfd343b
More demo modules.
rohe Mar 25, 2023
5e4265b
Working on dpop support
rohe Mar 26, 2023
a1be6f0
More demos
rohe Mar 27, 2023
953ec86
More demos
rohe Mar 28, 2023
cd5b4de
Improved the support for Token revocation.
rohe Mar 19, 2023
43135ea
map_supported_to_preferred must be done before allow_refresh_token.
rohe Mar 21, 2023
9726bae
Renamed some test modules.
rohe Mar 22, 2023
f15a2eb
A general resource service interface.
rohe Mar 22, 2023
627bc8a
Made demo directory. Moved some modules there, renamed. Fixed warning…
rohe Mar 23, 2023
ecfc40a
More demo modules.
rohe Mar 25, 2023
33484d0
More demo modules.
rohe Mar 25, 2023
2db8464
More demos
rohe Mar 28, 2023
75ce239
Working on dpop (version #14) support ... working.
rohe Mar 31, 2023
d3a96d9
Allow for callback function to find client information.
rohe Apr 3, 2023
8ca9eda
Fixed faulty response_types handling.
rohe Apr 5, 2023
5f89332
Corrected token lifetime handling.
rohe Apr 9, 2023
4386f56
Made all senarios use Flow.
rohe Apr 10, 2023
28b0340
Started a refactored and fixed some errors.
rohe Apr 11, 2023
87e0d92
Refactored all oauth stories.
rohe Apr 11, 2023
c61d6c8
Refactored a couple more.
rohe Apr 11, 2023
54eac77
Refactoring is completed
rohe Apr 12, 2023
576f701
Updated README
rohe Apr 14, 2023
958fc7c
Got the PAR example working.
rohe Apr 19, 2023
5ff54d5
Added client authentication to PAR.
rohe Apr 20, 2023
5a94d7f
test is normally not accessible from demo.
rohe Apr 22, 2023
00b6ceb
Improved the support for Token revocation.
rohe Mar 19, 2023
2d8cd5c
map_supported_to_preferred must be done before allow_refresh_token.
rohe Mar 21, 2023
1fcb167
Renamed some test modules.
rohe Mar 22, 2023
8ada28b
A general resource service interface.
rohe Mar 22, 2023
3f02014
Made demo directory. Moved some modules there, renamed. Fixed warning…
rohe Mar 23, 2023
56c74b3
More demo modules.
rohe Mar 25, 2023
6cc5003
More demo modules.
rohe Mar 25, 2023
22ed10d
Working on dpop support
rohe Mar 26, 2023
72a43f7
Improved the support for Token revocation.
rohe Mar 19, 2023
a52ed48
map_supported_to_preferred must be done before allow_refresh_token.
rohe Mar 21, 2023
faa26cb
Renamed some test modules.
rohe Mar 22, 2023
0279794
A general resource service interface.
rohe Mar 22, 2023
0d430f3
Made demo directory. Moved some modules there, renamed. Fixed warning…
rohe Mar 23, 2023
7920b88
More demo modules.
rohe Mar 25, 2023
fecbc99
More demo modules.
rohe Mar 25, 2023
ec4ae23
Working on dpop (version #14) support ... working.
rohe Mar 31, 2023
7c3abe6
Started a refactored and fixed some errors.
rohe Apr 11, 2023
aa176bc
Refactored a couple more.
rohe Apr 11, 2023
138abdb
Refactoring is completed
rohe Apr 12, 2023
3feae43
Cleaned up
rohe Apr 23, 2023
8d5d21e
JAR can also include encryption.
rohe May 4, 2023
79a82af
pkce is a OAuth2 extension.
rohe May 6, 2023
198d5b2
pkce is an oauth2 thing not OIDC.
rohe May 10, 2023
2b9c4c6
Fix conflicts
rohe May 10, 2023
67ffe60
Fix wrong import and list instead of List.
rohe May 10, 2023
56ff6b5
How this worked before is strange.
rohe May 10, 2023
5003d7d
Fixed bandit complain
rohe May 13, 2023
1a168cf
Merge pull request #64 from IdentityPython/tok_rev
rohe May 17, 2023
52a1b61
Add fixes on PKCE and client_authn
ctriant May 18, 2023
09a39a0
Add option for audience restriction enforcement
ctriant May 18, 2023
472efd8
StandAloneClient a simplified version of RPHandler that is made to on…
rohe Jun 8, 2023
25358a4
Now the StandAloneClient works both for oidc and oauth2.
rohe Jun 8, 2023
ca85bef
Getting client_secret was broken.
rohe Jun 9, 2023
7569430
Simplifications
rohe Jun 9, 2023
aca1857
Implement default configuration.
rohe Jun 14, 2023
0711a00
RPHandler uses StandAloneClient.
rohe Jun 15, 2023
d126975
Adding tests
rohe Jun 18, 2023
4ac1af6
Cleaned up.
rohe Jun 19, 2023
729507b
Adding tests
rohe Jun 20, 2023
bc9e3ad
Merge pull request #65 from ctriant/fixes
rohe Jun 20, 2023
63f6ed3
Merge pull request #66 from IdentityPython/enforce-aud-restriction
rohe Jun 27, 2023
63e1162
Refactored key jar making.
rohe Jun 27, 2023
2669489
Merge branch 'stand_alone_client' of https://github.com/IdentityPytho…
rohe Jun 27, 2023
55d16fc
Merge pull request #70 from IdentityPython/stand_alone_client
rohe Jul 11, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
315 changes: 315 additions & 0 deletions demo/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,315 @@
# Usage stories

This is a set of usage stories.
Here to display what you can do with IdpyOIDC using OAuth2 or OIDC.

Every story follows the same pattern it starts by initiating one client/RP and
one AS/OP.
After that a sequence of requests/responses are performed. Each one follows this
pattern:

- The client/RP constructs the request and possible client authentication information
- The request and client authentication information is printed
- The AS/OP does client authentication based on the authentication information received
- The AS/OP parses and verifies the client request
- The AS/OP constructs the server response
- The client/RP parses and verifies the server response
- The parsed and verified response is printed

This pattern is repeated for each request/response in the sequence.

To understand the descriptions below you have to remember that an AS/OP provides
**endpoints** while a client/RP accesses **services**. An endpoint can
support more than one service. A service can only reside at one endpoint.

## Basic OAuth2 Stories

These are based on the two basic OAuth2 RFCs;
* [The OAuth 2.0 Authorization Framework](https://www.rfc-editor.org/rfc/rfc6749)
* [The OAuth 2.0 Authorization Framework: Bearer Token Usage](https://www.rfc-editor.org/rfc/rfc6750)

### Client Credentials Grant (oauth2_cc.py)

Displays the usage of the
[client credentials grant](https://www.rfc-editor.org/rfc/rfc6749#section-4.4) .

The client can request an access token using only its client
credentials (or other supported means of authentication).

The request/response sequence only contains the client credential exchange.

The client is statically registered with the AS.

#### configuration

The server configuration expresses these points:

- The server needs only one endpoint, the token endpoint.
- The token released form the token endpoint is a signed JSON Web token (JWT)
- The server deals only with access tokens. The default lifetime of a token is 3600
seconds.
- The server can deal with 2 client authentication methods at the token endpoint:
client_secret_basic and client_secret_post
- In this example the audience for the token (the resource server) is statically set.


"endpoint": {
"token": {
"path": "token",
"class": Token,
"kwargs": {
"client_authn_method": ["client_secret_basic", "client_secret_post"],
},
},
},
"token_handler_args": {
"jwks_defs": {"key_defs": KEYDEFS},
"token": {
"class": "idpyoidc.server.token.jwt_token.JWTToken",
"kwargs": {
"lifetime": 3600,
"aud": ["https://example.org/appl"],
}
}
}

The client configuration

- lists only one service - client credentials
- specifies client ID and client secret since the client is statically
registered with the server.


"client_id": "client_1",
"client_secret": "another password",
"base_url": "https://example.com",
"services": {
"client_credentials": {
"class": "idpyoidc.client.oauth2.client_credentials.CCAccessTokenRequest"
}
}

**services** is a dictionary. The keys in that dictionary is for your usage only.
Internally the software uses identifiers that are statically assigned to every Service class.
This means that you can not have two instances of the same class in a _services_
definition.

### Resource Owners Password Credentials (oauth2_ropc.py)

**NOTE** Resource Owners Password Credentials is not part of OAuth2.1

Displays the usage of the
[resource owners username and password](https://www.rfc-editor.org/rfc/rfc6749#section-4.3)
for doing authorization.

The resource owner password credentials grant type is suitable in
cases where the resource owner has a trust relationship with the
client, such as the device operating system or a highly privileged application.

#### Configuration

The big difference between Client Credentials and Resource Owners Passsword credentials
is that the server also most support user authentication. Therefor this
part is added to the server configuration:

"authentication": {
"user": {
"acr": "urn:oasis:names:tc:SAML:2.0:ac:classes:InternetProtocolPassword",
"class": "idpyoidc.server.user_authn.user.UserPass",
"kwargs": {
"db_conf": {
"class": "idpyoidc.server.util.JSONDictDB",
"kwargs": {"filename": full_path("passwd.json")}
}
}
}
}

This allows for a very simple username/password check against a static file.

On the client side the change is that the service configuration now looks
like this:

services = {
"ropc": {
"class": "idpyoidc.client.oauth2.resource_owner_password_credentials.ROPCAccessTokenRequest"
}
}


### Authorization Code Grant (oauth2_code.py)

The
[authorization code grant](https://www.rfc-editor.org/rfc/rfc6749#section-4.1)
is used to obtain both access tokens and possibly refresh tokens and is optimized
for confidential clients.

Since this is a redirection-based flow, the client must be capable of
interacting with the resource owner's user-agent (typically a web
browser) and capable of receiving incoming requests (via redirection)
from the authorization server.

In the demo implementation the response is transmitted directly from the server
to the client no user agent is involved.

In this story the flow contains three request/responses

- Fetching server metadata
- Authorization
- Access token

#### Configuration

Let's take it part by part.
First the endpoints, straight forward support for the sequence of exchanges we
want to exercise.

"endpoint": {
"metadata": {
"path": ".well-known/oauth-authorization-server",
"class": "idpyoidc.server.oauth2.server_metadata.ServerMetadata",
"kwargs": {},
},
"authorization": {
"path": "authorization",
"class": "idpyoidc.server.oauth2.authorization.Authorization",
"kwargs": {},
},
"token": {
"path": "token",
"class": "idpyoidc.server.oauth2.token.Token",
"kwargs": {},
}
},

Next comes the type of tokens the grant manager can issue.
In this case authorization codes and access tokens.

"token_handler_args": {
"key_conf": {"key_defs": KEYDEFS},
"code": {
"lifetime": 600,
"kwargs": {
"crypt_conf": CRYPT_CONFIG
}
},
"token": {
"class": "idpyoidc.server.token.jwt_token.JWTToken",
"kwargs": {
"lifetime": 3600,
"aud": ["https://example.org/appl"],
},
}
},

The software can produce 3 types of tokens.

- An encrypted value, unreadable by anyone but the server
- A signed JSON Web Token following the pattern described in
[JSON Web Token (JWT) Profile for OAuth 2.0 Access Tokens](https://datatracker.ietf.org/doc/rfc9068/)
- An IDToken which only is used to represent ID Tokens.

In this example only the two first types are used since no ID Tokens are produced.

The next part is about the grant manager.

"authz": {
"class": AuthzHandling,
"kwargs": {
"grant_config": {
"usage_rules": {
"authorization_code": {
"supports_minting": ["access_token"],
"max_usage": 1,
},
"access_token": {
"expires_in": 600,
}
}
}
},
},

What this says is that an authorization code can only be used once and
only to mint an access token. The lifetime for an authorization code is
the default which is 300 seconds (5 minutes).
The access token can not be used to mint anything. Note that in the
token handler arguments the lifetime is set to 3600 seconds for a token
while in the authz part and access tokens lifetime is defined to be
600 seconds. It's the later that is used since it is more specific.

"authentication": {
"anon": {
"acr": INTERNETPROTOCOLPASSWORD,
"class": "idpyoidc.server.user_authn.user.NoAuthn",
"kwargs": {"user": "diana"},
}
},

It's convenient to use this no-authentication method in this context since we
can't deal with user interaction.
What happens is that authentication is assumed to have happened and that
it resulted in that **diana** was authenticated.

## OAuth2 Extension Stories

The stories display support for a set of OAuth2 extension RFCs

### PKCE (oauth2_add_on_pkce.py)

[Proof Key for Code Exchange by OAuth Public Clients](https://datatracker.ietf.org/doc/rfc7636/).
A technique to mitigate against the authorization code interception attack through
the use of Proof Key for Code Exchange (PKCE).

#### Configuration

On the server side only one thing is added:

"add_ons": {
"pkce": {
"function": "idpyoidc.server.oauth2.add_on.pkce.add_support",
"kwargs": {},
},
}

Similar on the client side:

"add_ons": {
"pkce": {
"function": "idpyoidc.client.oauth2.add_on.pkce.add_support",
"kwargs": {
"code_challenge_length": 64,
"code_challenge_method": "S256"
},
},
}

### JAR (oauth2_add_on_jar.py)

[JWT-Secured Authorization Request (JAR)](https://datatracker.ietf.org/doc/rfc9101/)
This document introduces the ability to send request parameters in a
JSON Web Token (JWT) instead, which allows the request to be signed
with JSON Web Signature (JWS) and encrypted with JSON Web Encryption
(JWE) so that the integrity, source authentication, and
confidentiality properties of the authorization request are attained.
The request can be sent by value or by reference.

#### Configuration

On the server side nothing has to be done. The support for the
request and request_uri parameters are built in to begin with.
The reason for this is that OIDC had this from the beginning.

On the client side this had to be added:

"add_ons": {
"jar": {
"function": "idpyoidc.client.oauth2.add_on.jar.add_support",
"kwargs": {
'request_type': 'request_parameter',
'request_object_signing_alg': "ES256",
'expires_in': 600
},
},
}

27 changes: 27 additions & 0 deletions demo/common.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import os

BASEDIR = os.path.abspath(os.path.dirname(__file__))


def full_path(local_file):
return os.path.join(BASEDIR, local_file)


CRYPT_CONFIG = {
"kwargs": {
"keys": {
"key_defs": [
{"type": "OCT", "use": ["enc"], "kid": "password"},
{"type": "OCT", "use": ["enc"], "kid": "salt"},
]
},
"iterations": 1,
}
}

SESSION_PARAMS = {"encrypter": CRYPT_CONFIG}

KEYDEFS = [
{"type": "RSA", "key": "", "use": ["sig"]},
{"type": "EC", "crv": "P-256", "use": ["sig"]},
]
Loading