Add HS256 support for JWS.
This commit is contained in:
parent
af3a0c0581
commit
dff76cd1ea
5 changed files with 44 additions and 13 deletions
|
@ -113,7 +113,7 @@ class AuthorizeEndpoint(object):
|
||||||
user=self.request.user,
|
user=self.request.user,
|
||||||
aud=self.client.client_id,
|
aud=self.client.client_id,
|
||||||
nonce=self.params.nonce)
|
nonce=self.params.nonce)
|
||||||
query_fragment['id_token'] = encode_id_token(id_token_dic)
|
query_fragment['id_token'] = encode_id_token(id_token_dic, self.client)
|
||||||
else:
|
else:
|
||||||
id_token_dic = {}
|
id_token_dic = {}
|
||||||
|
|
||||||
|
|
|
@ -140,7 +140,7 @@ class TokenEndpoint(object):
|
||||||
'refresh_token': token.refresh_token,
|
'refresh_token': token.refresh_token,
|
||||||
'token_type': 'bearer',
|
'token_type': 'bearer',
|
||||||
'expires_in': settings.get('OIDC_TOKEN_EXPIRE'),
|
'expires_in': settings.get('OIDC_TOKEN_EXPIRE'),
|
||||||
'id_token': encode_id_token(id_token_dic),
|
'id_token': encode_id_token(id_token_dic, token.client),
|
||||||
}
|
}
|
||||||
|
|
||||||
return dic
|
return dic
|
||||||
|
@ -173,7 +173,7 @@ class TokenEndpoint(object):
|
||||||
'refresh_token': token.refresh_token,
|
'refresh_token': token.refresh_token,
|
||||||
'token_type': 'bearer',
|
'token_type': 'bearer',
|
||||||
'expires_in': settings.get('OIDC_TOKEN_EXPIRE'),
|
'expires_in': settings.get('OIDC_TOKEN_EXPIRE'),
|
||||||
'id_token': encode_id_token(id_token_dic),
|
'id_token': encode_id_token(id_token_dic, self.token.client),
|
||||||
}
|
}
|
||||||
|
|
||||||
return dic
|
return dic
|
||||||
|
|
|
@ -6,6 +6,7 @@ from Crypto.PublicKey.RSA import importKey
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
from hashlib import md5
|
from hashlib import md5
|
||||||
from jwkest.jwk import RSAKey as jwk_RSAKey
|
from jwkest.jwk import RSAKey as jwk_RSAKey
|
||||||
|
from jwkest.jwk import SYMKey
|
||||||
from jwkest.jws import JWS
|
from jwkest.jws import JWS
|
||||||
|
|
||||||
from oidc_provider.lib.utils.common import get_issuer
|
from oidc_provider.lib.utils.common import get_issuer
|
||||||
|
@ -55,21 +56,26 @@ def create_id_token(user, aud, nonce):
|
||||||
return dic
|
return dic
|
||||||
|
|
||||||
|
|
||||||
def encode_id_token(payload):
|
def encode_id_token(payload, client):
|
||||||
"""
|
"""
|
||||||
Represent the ID Token as a JSON Web Token (JWT).
|
Represent the ID Token as a JSON Web Token (JWT).
|
||||||
|
|
||||||
Return a hash.
|
Return a hash.
|
||||||
"""
|
"""
|
||||||
keys = []
|
alg = client.jwt_alg
|
||||||
|
if alg == 'RS256':
|
||||||
|
keys = []
|
||||||
|
for rsakey in RSAKey.objects.all():
|
||||||
|
keys.append(jwk_RSAKey(key=importKey(rsakey.key), kid=rsakey.kid))
|
||||||
|
|
||||||
for rsakey in RSAKey.objects.all():
|
if not keys:
|
||||||
keys.append(jwk_RSAKey(key=importKey(rsakey.key), kid=rsakey.kid))
|
raise Exception('You must add at least one RSA Key.')
|
||||||
|
elif alg == 'HS256':
|
||||||
if not keys:
|
keys = [SYMKey(key=client.client_secret, alg=alg)]
|
||||||
raise Exception('You must add at least one RSA Key.')
|
else:
|
||||||
|
raise Exception('Unsupported key algorithm.')
|
||||||
|
|
||||||
_jws = JWS(payload, alg='RS256')
|
_jws = JWS(payload, alg=alg)
|
||||||
|
|
||||||
return _jws.sign_compact(keys)
|
return _jws.sign_compact(keys)
|
||||||
|
|
||||||
|
|
20
oidc_provider/migrations/0011_client_jwt_alg.py
Normal file
20
oidc_provider/migrations/0011_client_jwt_alg.py
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Generated by Django 1.9 on 2016-03-22 17:42
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('oidc_provider', '0010_code_is_authentication'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='client',
|
||||||
|
name='jwt_alg',
|
||||||
|
field=models.CharField(choices=[(b'HS256', b'HS256'), (b'RS256', b'RS256')], default=b'RS256', max_length=10, verbose_name='JWT Algorithm'),
|
||||||
|
),
|
||||||
|
]
|
|
@ -16,11 +16,16 @@ class Client(models.Model):
|
||||||
('id_token token', 'id_token token (Implicit Flow)'),
|
('id_token token', 'id_token token (Implicit Flow)'),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
JWT_ALGS = [
|
||||||
|
('HS256', 'HS256'),
|
||||||
|
('RS256', 'RS256'),
|
||||||
|
]
|
||||||
|
|
||||||
name = models.CharField(max_length=100, default='')
|
name = models.CharField(max_length=100, default='')
|
||||||
client_id = models.CharField(max_length=255, unique=True)
|
client_id = models.CharField(max_length=255, unique=True)
|
||||||
client_secret = models.CharField(max_length=255, unique=True)
|
client_secret = models.CharField(max_length=255, unique=True)
|
||||||
response_type = models.CharField(max_length=30,
|
response_type = models.CharField(max_length=30, choices=RESPONSE_TYPE_CHOICES)
|
||||||
choices=RESPONSE_TYPE_CHOICES)
|
jwt_alg = models.CharField(max_length=10, choices=JWT_ALGS, default='RS256', verbose_name=_(u'JWT Algorithm'))
|
||||||
date_created = models.DateField(auto_now_add=True)
|
date_created = models.DateField(auto_now_add=True)
|
||||||
|
|
||||||
_redirect_uris = models.TextField(default='', verbose_name=_(u'Redirect URI'), help_text=_(u'Enter each URI on a new line.'))
|
_redirect_uris = models.TextField(default='', verbose_name=_(u'Redirect URI'), help_text=_(u'Enter each URI on a new line.'))
|
||||||
|
|
Loading…
Reference in a new issue