idp_oidc: add a client and global setting for the idtoken duration (fixes #21232)
The default expire duration is still 30 seconds and can be changed with the IDTOKEN_DURATION app setting. The duration can be customized for each client with the new 'idtoken_duration' field. License: MIT
This commit is contained in:
parent
c2e2293d4f
commit
d639f7755b
|
@ -26,6 +26,11 @@ class AppSettings(object):
|
|||
def SCOPES(self):
|
||||
return self._setting('SCOPES', [])
|
||||
|
||||
@property
|
||||
def IDTOKEN_DURATION(self):
|
||||
return self._setting('IDTOKEN_DURATION', 30)
|
||||
|
||||
|
||||
import sys
|
||||
|
||||
app_settings = AppSettings('A2_IDP_OIDC_')
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('authentic2_idp_oidc', '0007_oidcclient_has_api_access'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='oidcclient',
|
||||
name='idtoken_duration',
|
||||
field=models.DurationField(
|
||||
verbose_name='time during which the token is valid',
|
||||
blank=True,
|
||||
null=True,
|
||||
default=None),
|
||||
),
|
||||
]
|
|
@ -80,6 +80,11 @@ class OIDCClient(Service):
|
|||
max_length=255,
|
||||
verbose_name=_('client secret'),
|
||||
default=generate_uuid)
|
||||
idtoken_duration = models.DurationField(
|
||||
verbose_name=_('time during which the token is valid'),
|
||||
blank=True,
|
||||
null=True,
|
||||
default=None)
|
||||
authorization_mode = models.PositiveIntegerField(
|
||||
default=AUTHORIZATION_MODE_BY_SERVICE,
|
||||
choices=AUTHORIZATION_MODES,
|
||||
|
|
|
@ -68,6 +68,12 @@ def authorization_error(request, redirect_uri, error, error_description=None, er
|
|||
return redirect(request, redirect_uri, params=params, resolve=False)
|
||||
|
||||
|
||||
def idtoken_duration(client):
|
||||
if client.idtoken_duration:
|
||||
return client.idtoken_duration
|
||||
return datetime.timedelta(seconds=app_settings.IDTOKEN_DURATION)
|
||||
|
||||
|
||||
@setting_enabled('ENABLE', settings=app_settings)
|
||||
def authorize(request, *args, **kwargs):
|
||||
logger = logging.getLogger(__name__)
|
||||
|
@ -272,8 +278,7 @@ def authorize(request, *args, **kwargs):
|
|||
id_token.update({
|
||||
'iss': request.build_absolute_uri('/'),
|
||||
'aud': client.client_id,
|
||||
'exp': timestamp_from_datetime(
|
||||
start + datetime.timedelta(seconds=30)),
|
||||
'exp': timestamp_from_datetime(start + idtoken_duration(client)),
|
||||
'iat': timestamp_from_datetime(start),
|
||||
'auth_time': last_auth['when'],
|
||||
'acr': acr,
|
||||
|
@ -379,8 +384,7 @@ def token(request, *args, **kwargs):
|
|||
'iss': request.build_absolute_uri('/'),
|
||||
'sub': utils.make_sub(client, oidc_code.user),
|
||||
'aud': client.client_id,
|
||||
'exp': timestamp_from_datetime(
|
||||
start + datetime.timedelta(seconds=30)),
|
||||
'exp': timestamp_from_datetime(start + idtoken_duration(client)),
|
||||
'iat': timestamp_from_datetime(start),
|
||||
'auth_time': timestamp_from_datetime(oidc_code.auth_time),
|
||||
'acr': acr,
|
||||
|
|
|
@ -64,7 +64,14 @@ OIDC_CLIENT_PARAMS = [
|
|||
},
|
||||
{
|
||||
'authorization_mode': OIDCClient.AUTHORIZATION_MODE_NONE,
|
||||
}
|
||||
},
|
||||
{
|
||||
'idtoken_duration': datetime.timedelta(hours=1),
|
||||
},
|
||||
{
|
||||
'authorization_flow': OIDCClient.FLOW_IMPLICIT,
|
||||
'idtoken_duration': datetime.timedelta(hours=1),
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
|
@ -198,7 +205,13 @@ def test_authorization_code_sso(login_first, oidc_settings, oidc_client, simple_
|
|||
assert claims['aud'] == oidc_client.client_id
|
||||
assert parse_timestamp(claims['iat']) <= now()
|
||||
assert parse_timestamp(claims['auth_time']) <= now()
|
||||
assert parse_timestamp(claims['exp']) >= now()
|
||||
exp_delta = (parse_timestamp(claims['exp']) - now()).total_seconds()
|
||||
assert exp_delta > 0
|
||||
if oidc_client.idtoken_duration:
|
||||
assert abs(exp_delta - oidc_client.idtoken_duration.total_seconds()) < 2
|
||||
else:
|
||||
assert abs(exp_delta - 30) < 2
|
||||
|
||||
if login_first:
|
||||
assert claims['acr'] == '0'
|
||||
else:
|
||||
|
|
Loading…
Reference in New Issue