Skip to content

Commit da79dbe

Browse files
committed
Add 'kid' (jwt key id) to JWTAuth header
1 parent 63b60a2 commit da79dbe

File tree

3 files changed

+31
-9
lines changed

3 files changed

+31
-9
lines changed

boxsdk/auth/jwt_auth.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ def __init__(
2222
client_id,
2323
client_secret,
2424
enterprise_id,
25+
jwt_key_id,
2526
rsa_private_key_file_sys_path,
2627
rsa_private_key_passphrase=None,
2728
store_tokens=None,
@@ -44,6 +45,10 @@ def __init__(
4445
The ID of the Box Developer Edition enterprise.
4546
:type enterprise_id:
4647
`unicode`
48+
:param jwt_key_id:
49+
Key ID for the JWT assertion.
50+
:type jwt_key_id:
51+
`unicode`
4752
:param rsa_private_key_file_sys_path:
4853
Path to an RSA private key file, used for signing the JWT assertion.
4954
:type rsa_private_key_file_sys_path:
@@ -95,6 +100,7 @@ def __init__(
95100
)
96101
self._enterprise_token = enterprise_id
97102
self._jwt_algorithm = jwt_algorithm
103+
self._jwt_key_id = jwt_key_id
98104
self._user_id = None
99105

100106
def _auth_with_jwt(self, sub, sub_type):
@@ -132,6 +138,9 @@ def _auth_with_jwt(self, sub, sub_type):
132138
},
133139
self._rsa_private_key,
134140
algorithm=self._jwt_algorithm,
141+
headers={
142+
'kid': self._jwt_key_id,
143+
},
135144
)
136145
data = {
137146
'grant_type': self._GRANT_TYPE,

requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@ cryptography>=0.9.2
22
pyjwt>=1.3.0
33
requests>=2.4.3
44
six >= 1.4.0
5-
.
5+
-e .

test/unit/auth/test_jwt_auth.py

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,11 @@ def jwt_algorithm(request):
2525
return request.param
2626

2727

28+
@pytest.fixture(scope='module')
29+
def jwt_key_id():
30+
return 'jwt_key_id_1'
31+
32+
2833
@pytest.fixture(params=(None, b'strong_password'))
2934
def rsa_passphrase(request):
3035
return request.param
@@ -47,6 +52,7 @@ def jwt_auth_init_mocks(
4752
mock_network_layer,
4853
successful_token_response,
4954
jwt_algorithm,
55+
jwt_key_id,
5056
rsa_passphrase,
5157
enterprise_token=None,
5258
):
@@ -76,6 +82,7 @@ def jwt_auth_init_mocks(
7682
network_layer=mock_network_layer,
7783
box_device_name='my_awesome_device',
7884
jwt_algorithm=jwt_algorithm,
85+
jwt_key_id=jwt_key_id,
7986
)
8087

8188
jwt_auth_open.assert_called_once_with(sentinel.rsa_path)
@@ -99,7 +106,7 @@ def jwt_auth_init_mocks(
99106

100107

101108
@contextmanager
102-
def jwt_auth_auth_mocks(jti_length, jwt_algorithm, sub, sub_type, oauth, assertion, client_id, secret):
109+
def jwt_auth_auth_mocks(jti_length, jwt_algorithm, jwt_key_id, sub, sub_type, oauth, assertion, client_id, secret):
103110
# pylint:disable=redefined-outer-name
104111
with patch('jwt.encode') as jwt_encode:
105112
with patch('boxsdk.auth.jwt_auth.datetime') as mock_datetime:
@@ -128,20 +135,21 @@ def jwt_auth_auth_mocks(jti_length, jwt_algorithm, sub, sub_type, oauth, asserti
128135
'aud': 'https://api.box.com/oauth2/token',
129136
'jti': jti,
130137
'exp': exp,
131-
}, secret, algorithm=jwt_algorithm)
138+
}, secret, algorithm=jwt_algorithm, headers={'kid': jwt_key_id})
132139

133140

134141
def test_authenticate_app_user_sends_post_request_with_correct_params(
135142
mock_network_layer,
136143
successful_token_response,
137144
jti_length,
138145
jwt_algorithm,
146+
jwt_key_id,
139147
rsa_passphrase,
140148
):
141149
# pylint:disable=redefined-outer-name
142150
fake_user_id = 'fake_user_id'
143-
with jwt_auth_init_mocks(mock_network_layer, successful_token_response, jwt_algorithm, rsa_passphrase) as params:
144-
with jwt_auth_auth_mocks(jti_length, jwt_algorithm, fake_user_id, 'user', *params) as oauth:
151+
with jwt_auth_init_mocks(mock_network_layer, successful_token_response, jwt_algorithm, jwt_key_id, rsa_passphrase) as params:
152+
with jwt_auth_auth_mocks(jti_length, jwt_algorithm, jwt_key_id, fake_user_id, 'user', *params) as oauth:
145153
oauth.authenticate_app_user(User(None, fake_user_id))
146154

147155

@@ -150,6 +158,7 @@ def test_authenticate_instance_sends_post_request_with_correct_params(
150158
successful_token_response,
151159
jti_length,
152160
jwt_algorithm,
161+
jwt_key_id,
153162
rsa_passphrase,
154163
):
155164
# pylint:disable=redefined-outer-name
@@ -158,10 +167,11 @@ def test_authenticate_instance_sends_post_request_with_correct_params(
158167
mock_network_layer,
159168
successful_token_response,
160169
jwt_algorithm,
170+
jwt_key_id,
161171
rsa_passphrase,
162172
enterprise_token,
163173
) as params:
164-
with jwt_auth_auth_mocks(jti_length, jwt_algorithm, enterprise_token, 'enterprise', *params) as oauth:
174+
with jwt_auth_auth_mocks(jti_length, jwt_algorithm, jwt_key_id, enterprise_token, 'enterprise', *params) as oauth:
165175
oauth.authenticate_instance()
166176

167177

@@ -170,12 +180,13 @@ def test_refresh_app_user_sends_post_request_with_correct_params(
170180
successful_token_response,
171181
jti_length,
172182
jwt_algorithm,
183+
jwt_key_id,
173184
rsa_passphrase,
174185
):
175186
# pylint:disable=redefined-outer-name
176187
fake_user_id = 'fake_user_id'
177-
with jwt_auth_init_mocks(mock_network_layer, successful_token_response, jwt_algorithm, rsa_passphrase) as params:
178-
with jwt_auth_auth_mocks(jti_length, jwt_algorithm, fake_user_id, 'user', *params) as oauth:
188+
with jwt_auth_init_mocks(mock_network_layer, successful_token_response, jwt_algorithm, jwt_key_id, rsa_passphrase) as params:
189+
with jwt_auth_auth_mocks(jti_length, jwt_algorithm, jwt_key_id, fake_user_id, 'user', *params) as oauth:
179190
oauth._user_id = fake_user_id # pylint:disable=protected-access
180191
oauth.refresh(None)
181192

@@ -185,6 +196,7 @@ def test_refresh_instance_sends_post_request_with_correct_params(
185196
successful_token_response,
186197
jti_length,
187198
jwt_algorithm,
199+
jwt_key_id,
188200
rsa_passphrase,
189201
):
190202
# pylint:disable=redefined-outer-name
@@ -193,8 +205,9 @@ def test_refresh_instance_sends_post_request_with_correct_params(
193205
mock_network_layer,
194206
successful_token_response,
195207
jwt_algorithm,
208+
jwt_key_id,
196209
rsa_passphrase,
197210
enterprise_token,
198211
) as params:
199-
with jwt_auth_auth_mocks(jti_length, jwt_algorithm, enterprise_token, 'enterprise', *params) as oauth:
212+
with jwt_auth_auth_mocks(jti_length, jwt_algorithm, jwt_key_id, enterprise_token, 'enterprise', *params) as oauth:
200213
oauth.refresh(None)

0 commit comments

Comments
 (0)