@@ -327,6 +327,55 @@ async def test_client_registration(
327327 # assert await mock_oauth_provider.clients_store.get_client(
328328 # client_info["client_id"]
329329 # ) is not None
330+
331+ @pytest .mark .anyio
332+ async def test_authorize_form_post (
333+ self , test_client : httpx .AsyncClient , mock_oauth_provider : MockOAuthProvider
334+ ):
335+ """Test the authorization endpoint using POST with form-encoded data."""
336+ # Register a client
337+ client_metadata = {
338+ "redirect_uris" : ["https://client.example.com/callback" ],
339+ "client_name" : "Test Client" ,
340+ "grant_types" : ["authorization_code" , "refresh_token" ],
341+ }
342+
343+ response = await test_client .post (
344+ "/register" ,
345+ json = client_metadata ,
346+ )
347+ assert response .status_code == 201
348+ client_info = response .json ()
349+
350+ # Create a PKCE challenge
351+ code_verifier = "some_random_verifier_string"
352+ code_challenge = (
353+ base64 .urlsafe_b64encode (hashlib .sha256 (code_verifier .encode ()).digest ())
354+ .decode ()
355+ .rstrip ("=" )
356+ )
357+
358+ # Use POST with form-encoded data for authorization
359+ response = await test_client .post (
360+ "/authorize" ,
361+ data = {
362+ "response_type" : "code" ,
363+ "client_id" : client_info ["client_id" ],
364+ "redirect_uri" : "https://client.example.com/callback" ,
365+ "code_challenge" : code_challenge ,
366+ "code_challenge_method" : "S256" ,
367+ "state" : "test_form_state" ,
368+ },
369+ )
370+ assert response .status_code == 302
371+
372+ # Extract the authorization code from the redirect URL
373+ redirect_url = response .headers ["location" ]
374+ parsed_url = urlparse (redirect_url )
375+ query_params = parse_qs (parsed_url .query )
376+
377+ assert "code" in query_params
378+ assert query_params ["state" ][0 ] == "test_form_state"
330379
331380 @pytest .mark .anyio
332381 async def test_authorization_flow (
@@ -337,7 +386,7 @@ async def test_authorization_flow(
337386 client_metadata = {
338387 "redirect_uris" : ["https://client.example.com/callback" ],
339388 "client_name" : "Test Client" ,
340- "grant_types" : ["authorization_code" , "refresh_token" ]
389+ "grant_types" : ["authorization_code" , "refresh_token" ],
341390 }
342391
343392 response = await test_client .post (
@@ -355,7 +404,7 @@ async def test_authorization_flow(
355404 .rstrip ("=" )
356405 )
357406
358- # 3. Request authorization
407+ # 3. Request authorization using GET with query params
359408 response = await test_client .get (
360409 "/authorize" ,
361410 params = {
@@ -381,7 +430,7 @@ async def test_authorization_flow(
381430 # 5. Exchange the authorization code for tokens
382431 response = await test_client .post (
383432 "/token" ,
384- json = {
433+ data = {
385434 "grant_type" : "authorization_code" ,
386435 "client_id" : client_info ["client_id" ],
387436 "client_secret" : client_info ["client_secret" ],
@@ -411,7 +460,7 @@ async def test_authorization_flow(
411460 # 7. Refresh the token
412461 response = await test_client .post (
413462 "/token" ,
414- json = {
463+ data = {
415464 "grant_type" : "refresh_token" ,
416465 "client_id" : client_info ["client_id" ],
417466 "client_secret" : client_info ["client_secret" ],
@@ -429,7 +478,7 @@ async def test_authorization_flow(
429478 # 8. Revoke the token
430479 response = await test_client .post (
431480 "/revoke" ,
432- json = {
481+ data = {
433482 "client_id" : client_info ["client_id" ],
434483 "client_secret" : client_info ["client_secret" ],
435484 "token" : new_token_response ["access_token" ],
@@ -505,10 +554,10 @@ def test_tool(x: int) -> str:
505554 .rstrip ("=" )
506555 )
507556
508- # Request authorization
509- response = await test_client .get (
557+ # Request authorization using POST with form-encoded data
558+ response = await test_client .post (
510559 "/authorize" ,
511- params = {
560+ data = {
512561 "response_type" : "code" ,
513562 "client_id" : client_info ["client_id" ],
514563 "redirect_uri" : "https://client.example.com/callback" ,
@@ -530,7 +579,7 @@ def test_tool(x: int) -> str:
530579 # Exchange the authorization code for tokens
531580 response = await test_client .post (
532581 "/token" ,
533- json = {
582+ data = {
534583 "grant_type" : "authorization_code" ,
535584 "client_id" : client_info ["client_id" ],
536585 "client_secret" : client_info ["client_secret" ],
0 commit comments