@@ -79,29 +79,16 @@ def test_should_throw_error_if_jwt_payload_missing_iss(self):
79
79
== MCPAuthTokenVerificationExceptionCode .INVALID_TOKEN
80
80
)
81
81
82
- def test_should_throw_error_if_jwt_payload_missing_client_id (self ):
83
- # Test different invalid JWT payloads
84
- jwt_missing_client_id = create_jwt (
85
- {"iss" : "https://logto.io/" , "sub" : "user12345" }
86
- )
87
- jwt_invalid_client_id_type = create_jwt (
82
+ def test_should_throw_error_if_client_id_is_not_string (self ):
83
+ token = create_jwt (
88
84
{"iss" : "https://logto.io/" , "client_id" : 12345 , "sub" : "user12345" }
89
85
)
90
- jwt_empty_client_id = create_jwt (
91
- {"iss" : "https://logto.io/" , "client_id" : "" , "sub" : "user12345" }
92
- )
93
86
94
- for token in [
95
- jwt_missing_client_id ,
96
- jwt_invalid_client_id_type ,
97
- jwt_empty_client_id ,
98
- ]:
99
- with pytest .raises (MCPAuthTokenVerificationException ) as exc_info :
100
- verify_jwt (token )
101
- assert (
102
- exc_info .value .code
103
- == MCPAuthTokenVerificationExceptionCode .INVALID_TOKEN
104
- )
87
+ with pytest .raises (MCPAuthTokenVerificationException ) as exc_info :
88
+ verify_jwt (token )
89
+ assert (
90
+ exc_info .value .code == MCPAuthTokenVerificationExceptionCode .INVALID_TOKEN
91
+ )
105
92
106
93
def test_should_throw_error_if_jwt_payload_missing_sub (self ):
107
94
# Test different invalid JWT payloads
@@ -226,3 +213,53 @@ def test_should_return_verified_jwt_payload_without_scopes(self):
226
213
assert result .subject == claims ["sub" ]
227
214
assert result .audience == claims ["aud" ]
228
215
assert result .scopes == []
216
+
217
+ def test_should_return_verified_jwt_payload_without_client_id (self ):
218
+ # Create JWT without client_id
219
+ claims = {
220
+ "iss" : "https://logto.io/" ,
221
+ "sub" : "user12345" ,
222
+ "aud" : "audience12345" ,
223
+ }
224
+ jwt_token = create_jwt (claims )
225
+
226
+ # Verify
227
+ result = verify_jwt (jwt_token )
228
+
229
+ # Assertions
230
+ assert result .issuer == claims ["iss" ]
231
+ assert result .client_id is None
232
+ assert result .subject == claims ["sub" ]
233
+ assert result .audience == claims ["aud" ]
234
+ assert result .scopes == []
235
+
236
+ # Empty client_id should not raise an error
237
+ claims ["client_id" ] = ""
238
+ claims ["azp" ] = "client12345" # Should be ignored if client_id is a string
239
+ jwt_token = create_jwt (claims )
240
+ result = verify_jwt (jwt_token )
241
+ assert result .issuer == claims ["iss" ]
242
+ assert result .client_id == ""
243
+ assert result .subject == claims ["sub" ]
244
+ assert result .audience == claims ["aud" ]
245
+ assert result .scopes == []
246
+
247
+ def test_should_fall_back_to_azp_if_client_id_is_missing (self ):
248
+ # Create JWT with azp instead of client_id
249
+ claims = {
250
+ "iss" : "https://logto.io/" ,
251
+ "azp" : "client12345" ,
252
+ "sub" : "user12345" ,
253
+ "aud" : "audience12345" ,
254
+ }
255
+ jwt_token = create_jwt (claims )
256
+
257
+ # Verify
258
+ result = verify_jwt (jwt_token )
259
+
260
+ # Assertions
261
+ assert result .issuer == claims ["iss" ]
262
+ assert result .client_id == claims ["azp" ]
263
+ assert result .subject == claims ["sub" ]
264
+ assert result .audience == claims ["aud" ]
265
+ assert result .scopes == []
0 commit comments