Skip to content

Commit e31a919

Browse files
author
Matej Spiller Muys
committed
Support for specifying client secret hasher
1 parent 90d7300 commit e31a919

File tree

9 files changed

+46
-1
lines changed

9 files changed

+46
-1
lines changed

AUTHORS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ Ludwig Hähne
8686
Łukasz Skarżyński
8787
Madison Swain-Bowden
8888
Marcus Sonestedt
89+
Matej Spiller Muys
8990
Matias Seniquiel
9091
Michael Howitz
9192
Owen Gong

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77
<!--
88
## [unreleased]
99
### Added
10+
* Support for specifying client secret hasher via CLIENT_SECRET_HASHER setting.
1011
### Changed
1112
### Deprecated
1213
### Removed

docs/settings.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,10 @@ CLIENT_SECRET_GENERATOR_LENGTH
104104
The length of the generated secrets, in characters. If this value is too low,
105105
secrets may become subject to bruteforce guessing.
106106

107+
CLIENT_SECRET_HASHER
108+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
109+
The hasher for storing generated secrets. By default library will use the first hasher in PASSWORD_HASHERS.
110+
107111
EXTRA_SERVER_KWARGS
108112
~~~~~~~~~~~~~~~~~~~
109113
A dictionary to be passed to oauthlib's Server class. Three options

oauth2_provider/models.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ def pre_save(self, model_instance, add):
4040
logger.debug(f"{model_instance}: {self.attname} is already hashed with {hasher}.")
4141
except ValueError:
4242
logger.debug(f"{model_instance}: {self.attname} is not hashed; hashing it now.")
43-
hashed_secret = make_password(secret)
43+
hashed_secret = make_password(secret, hasher=oauth2_settings.CLIENT_SECRET_HASHER)
4444
setattr(model_instance, self.attname, hashed_secret)
4545
return hashed_secret
4646
return super().pre_save(model_instance, add)

oauth2_provider/settings.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
"CLIENT_ID_GENERATOR_CLASS": "oauth2_provider.generators.ClientIdGenerator",
3838
"CLIENT_SECRET_GENERATOR_CLASS": "oauth2_provider.generators.ClientSecretGenerator",
3939
"CLIENT_SECRET_GENERATOR_LENGTH": 128,
40+
"CLIENT_SECRET_HASHER": "default",
4041
"ACCESS_TOKEN_GENERATOR": None,
4142
"REFRESH_TOKEN_GENERATOR": None,
4243
"EXTRA_SERVER_KWARGS": {},

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ omit = ["*/migrations/*"]
6262
show_missing = true
6363

6464
[tool.pytest.ini_options]
65+
DJANGO_SETTINGS_MODULE = "tests.settings"
6566
django_find_project = false
6667
addopts = [
6768
"--cov=oauth2_provider",

tests/custom_hasher.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
from django.contrib.auth.hashers import PBKDF2PasswordHasher
2+
3+
4+
class MyPBKDF2PasswordHasher(PBKDF2PasswordHasher):
5+
"""
6+
A subclass of PBKDF2PasswordHasher that uses less iterations.
7+
"""
8+
9+
algorithm = "fast_pbkdf2"
10+
iterations = 10000

tests/settings.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,15 @@
8989
"tests",
9090
)
9191

92+
PASSWORD_HASHERS = [
93+
"django.contrib.auth.hashers.PBKDF2PasswordHasher",
94+
"django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher",
95+
"django.contrib.auth.hashers.Argon2PasswordHasher",
96+
"django.contrib.auth.hashers.BCryptSHA256PasswordHasher",
97+
"django.contrib.auth.hashers.ScryptPasswordHasher",
98+
"tests.custom_hasher.MyPBKDF2PasswordHasher",
99+
]
100+
92101
LOGGING = {
93102
"version": 1,
94103
"disable_existing_loggers": False,

tests/test_models.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,24 @@ def test_hashed_secret(self):
7272
self.assertNotEqual(app.client_secret, CLEARTEXT_SECRET)
7373
self.assertTrue(check_password(CLEARTEXT_SECRET, app.client_secret))
7474

75+
76+
@override_settings(OAUTH2_PROVIDER={"CLIENT_SECRET_HASHER": "fast_pbkdf2"})
77+
def test_hashed_from_settings(self):
78+
app = Application.objects.create(
79+
name="test_app",
80+
redirect_uris="http://localhost http://example.com http://example.org",
81+
user=self.user,
82+
client_type=Application.CLIENT_CONFIDENTIAL,
83+
authorization_grant_type=Application.GRANT_AUTHORIZATION_CODE,
84+
client_secret=CLEARTEXT_SECRET,
85+
hash_client_secret=True,
86+
)
87+
88+
self.assertNotEqual(app.client_secret, CLEARTEXT_SECRET)
89+
self.assertIn("fast_pbkdf2", app.client_secret)
90+
self.assertTrue(check_password(CLEARTEXT_SECRET, app.client_secret))
91+
92+
7593
def test_unhashed_secret(self):
7694
app = Application.objects.create(
7795
name="test_app",

0 commit comments

Comments
 (0)