Skip to content

Commit 250a6e7

Browse files
bajnokkc00kiemon5ter
authored andcommitted
OIDC frontend: support Redis and session expiration
Support all storage backends from recent pyop. Add automatic expiration TTL for the different collections so that the session databases does not grow without bounds. The default TTL values were copied from pyop's current defaults. TODO: add pyop version requirement once there is an official release. Signed-off-by: Ivan Kanakarakis <[email protected]>
1 parent c969900 commit 250a6e7

File tree

2 files changed

+38
-11
lines changed

2 files changed

+38
-11
lines changed

doc/README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -459,22 +459,22 @@ Connect Relying Parties (RPs). The default configuration file can be found
459459
[here](../example/plugins/frontends/openid_connect_frontend.yaml.example).
460460
461461
As opposed to the other plugins, this plugin is NOT stateless (due to the nature of OpenID Connect using any other
462-
flow than "Implicit Flow"). However, the frontend supports using a MongoDB instance as its backend storage, so as long
462+
flow than "Implicit Flow"). However, the frontend supports using a MongoDB or Redis instance as its backend storage, so as long
463463
that's reachable from all machines it should not be a problem.
464464
465465
The configuration parameters available:
466466
* `signing_key_path`: path to a RSA Private Key file (PKCS#1). MUST be configured.
467-
* `db_uri`: connection URI to MongoDB instance where the data will be persisted, if it's not specified all data will only
467+
* `db_uri`: connection URI to MongoDB or Redis instance where the data will be persisted, if it's not specified all data will only
468468
be stored in-memory (not suitable for production use).
469-
* `client_db_uri`: connection URI to MongoDB instance where the client data will be persistent, if it's not specified the clients list will be received from the `client_db_path`.
469+
* `client_db_uri`: connection URI to MongoDB or Redis instance where the client data will be persistent, if it's not specified the clients list will be received from the `client_db_path`.
470470
* `client_db_path`: path to a file containing the client database in json format. It will only be used if `client_db_uri` is not set. If `client_db_uri` and `client_db_path` are not set, clients will only be stored in-memory (not suitable for production use).
471471
* `sub_hash_salt`: salt which is hashed into the `sub` claim. If it's not specified, SATOSA will generate a random salt on each startup, which means that users will get new `sub` value after every restart.
472472
* `provider`: provider configuration information. MUST be configured, the following configuration are supported:
473473
* `response_types_supported` (default: `[id_token]`): list of all supported response types, see [Section 3 of OIDC Core](http://openid.net/specs/openid-connect-core-1_0.html#Authentication).
474474
* `subject_types_supported` (default: `[pairwise]`): list of all supported subject identifier types, see [Section 8 of OIDC Core](http://openid.net/specs/openid-connect-core-1_0.html#SubjectIDTypes)
475475
* `scopes_supported` (default: `[openid]`): list of all supported scopes, see [Section 5.4 of OIDC Core](http://openid.net/specs/openid-connect-core-1_0.html#ScopeClaims)
476476
* `client_registration_supported` (default: `No`): boolean whether [dynamic client registration is supported](https://openid.net/specs/openid-connect-registration-1_0.html).
477-
If dynamic client registration is not supported all clients must exist in the MongoDB instance configured by the `db_uri` in the `"clients"` collection of the `"satosa"` database.
477+
If dynamic client registration is not supported all clients must exist in the MongoDB or Redis instance configured by the `db_uri` in the `"clients"` collection of the `"satosa"` database.
478478
The registration info must be stored using the client id as a key, and use the parameter names of a [OIDC Registration Response](https://openid.net/specs/openid-connect-registration-1_0.html#RegistrationResponse).
479479
* `authorization_code_lifetime`: how long authorization codes should be valid, see [default](https://github.com/IdentityPython/pyop#token-lifetimes)
480480
* `access_token_lifetime`: how long access tokens should be valid, see [default](https://github.com/IdentityPython/pyop#token-lifetimes)

src/satosa/frontends/openid_connect.py

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
from pyop.exceptions import (InvalidAuthenticationRequest, InvalidClientRegistrationRequest,
1717
InvalidClientAuthentication, OAuthError, BearerTokenError, InvalidAccessToken)
1818
from pyop.provider import Provider
19-
from pyop.storage import MongoWrapper
19+
from pyop.storage import StorageBase
2020
from pyop.subject_identifier import HashBasedSubjectIdentifierFactory
2121
from pyop.userinfo import Userinfo
2222
from pyop.util import should_fragment_encode
@@ -81,13 +81,22 @@ def _create_provider(self, endpoint_baseurl):
8181
client_db_uri = self.config.get("client_db_uri")
8282
cdb_file = self.config.get("client_db_path")
8383
if client_db_uri:
84-
cdb = MongoWrapper(client_db_uri, "satosa", "clients")
84+
cdb = StorageBase.from_uri(
85+
client_db_uri, db_name="satosa", collection="clients"
86+
)
8587
elif cdb_file:
8688
with open(cdb_file) as f:
8789
cdb = json.loads(f.read())
8890
else:
8991
cdb = {}
90-
self.user_db = MongoWrapper(db_uri, "satosa", "authz_codes") if db_uri else {}
92+
93+
#XXX What is the correct ttl for user_db? Is it the same as authz_code_db?
94+
self.user_db = (
95+
StorageBase.from_uri(db_uri, db_name="satosa", collection="authz_codes")
96+
if db_uri
97+
else {}
98+
)
99+
91100
self.provider = Provider(
92101
self.signing_key,
93102
capabilities,
@@ -102,10 +111,28 @@ def _init_authorization_state(self):
102111
sub_hash_salt = self.config.get("sub_hash_salt", rndstr(16))
103112
db_uri = self.config.get("db_uri")
104113
if db_uri:
105-
authz_code_db = MongoWrapper(db_uri, "satosa", "authz_codes")
106-
access_token_db = MongoWrapper(db_uri, "satosa", "access_tokens")
107-
refresh_token_db = MongoWrapper(db_uri, "satosa", "refresh_tokens")
108-
sub_db = MongoWrapper(db_uri, "satosa", "subject_identifiers")
114+
authz_code_db = StorageBase.from_uri(
115+
db_uri,
116+
db_name="satosa",
117+
collection="authz_codes",
118+
ttl=self.config["provider"].get("authorization_code_lifetime", 600),
119+
)
120+
access_token_db = StorageBase.from_uri(
121+
db_uri,
122+
db_name="satosa",
123+
collection="access_tokens",
124+
ttl=self.config["provider"].get("access_token_lifetime", 3600),
125+
)
126+
refresh_token_db = StorageBase.from_uri(
127+
db_uri,
128+
db_name="satosa",
129+
collection="refresh_tokens",
130+
ttl=self.config["provider"].get("refresh_token_lifetime", None),
131+
)
132+
#XXX what is the correct TTL for sub_db?
133+
sub_db = StorageBase.from_uri(
134+
db_uri, db_name="satosa", collection="subject_identifiers"
135+
)
109136
else:
110137
authz_code_db = None
111138
access_token_db = None

0 commit comments

Comments
 (0)