@@ -75,7 +75,7 @@ def _mint_token(
7575 token_args = meth (_context , client_id , token_args )
7676
7777 if token_args :
78- _args = { " token_args" : token_args }
78+ _args = token_args
7979 else :
8080 _args = {}
8181
@@ -258,7 +258,6 @@ def process_request(self, req: Union[Message, dict], **kwargs):
258258 if (
259259 issue_refresh
260260 and "refresh_token" in _supports_minting
261- and "refresh_token" in grant_types_supported
262261 ):
263262 try :
264263 refresh_token = self ._mint_token (
@@ -370,7 +369,7 @@ def process_request(self, req: Union[Message, dict], **kwargs):
370369 token_type = "DPoP"
371370
372371 token = _grant .get_token (token_value )
373- scope = _grant .find_scope (token . based_on )
372+ scope = _grant .find_scope (token )
374373 if "scope" in req :
375374 scope = req ["scope" ]
376375 access_token = self ._mint_token (
@@ -543,6 +542,27 @@ def post_parse_request(self, request, client_id="", **kwargs):
543542 )
544543
545544 resp = self ._enforce_policy (request , token , config )
545+ if isinstance (resp , TokenErrorResponse ):
546+ return resp
547+
548+ scopes = resp .get ("scope" , [])
549+ scopes = _context .scopes_handler .filter_scopes (scopes , client_id = resp ["client_id" ])
550+
551+ if not scopes :
552+ logger .error ("All requested scopes have been filtered out." )
553+ return self .error_cls (
554+ error = "invalid_scope" , error_description = "Invalid requested scopes"
555+ )
556+
557+ _requested_token_type = resp .get (
558+ "requested_token_type" , "urn:ietf:params:oauth:token-type:access_token"
559+ )
560+ _token_class = self .token_types_mapping [_requested_token_type ]
561+ if _token_class == "refresh_token" and "offline_access" not in scopes :
562+ return TokenErrorResponse (
563+ error = "invalid_request" ,
564+ error_description = "Exchanging this subject token to refresh token forbidden" ,
565+ )
546566
547567 return resp
548568
@@ -572,7 +592,7 @@ def _enforce_policy(self, request, token, config):
572592 error_description = "Unsupported requested token type" ,
573593 )
574594
575- request_info = dict (scope = request .get ("scope" , [] ))
595+ request_info = dict (scope = request .get ("scope" , token . scope ))
576596 try :
577597 check_unknown_scopes_policy (request_info , request ["client_id" ], _context )
578598 except UnAuthorizedClientScope :
@@ -602,11 +622,11 @@ def _enforce_policy(self, request, token, config):
602622 logger .error (f"Error while executing the { fn } policy callable: { e } " )
603623 return self .error_cls (error = "server_error" , error_description = "Internal server error" )
604624
605- def token_exchange_response (self , token ):
625+ def token_exchange_response (self , token , issued_token_type ):
606626 response_args = {}
607627 response_args ["access_token" ] = token .value
608628 response_args ["scope" ] = token .scope
609- response_args ["issued_token_type" ] = token . token_class
629+ response_args ["issued_token_type" ] = issued_token_type
610630
611631 if token .expires_at :
612632 response_args ["expires_in" ] = token .expires_at - utc_time_sans_frac ()
@@ -636,6 +656,7 @@ def process_request(self, request, **kwargs):
636656 error = "invalid_request" , error_description = "Subject token invalid"
637657 )
638658
659+ grant = _session_info ["grant" ]
639660 token = _mngr .find_token (_session_info ["branch_id" ], request ["subject_token" ])
640661 _requested_token_type = request .get (
641662 "requested_token_type" , "urn:ietf:params:oauth:token-type:access_token"
@@ -650,16 +671,19 @@ def process_request(self, request, **kwargs):
650671 if "dpop_signing_alg_values_supported" in _context .provider_info :
651672 if request .get ("dpop_jkt" ):
652673 _token_type = "DPoP"
674+ scopes = request .get ("scope" , [])
653675
654676 if request ["client_id" ] != _session_info ["client_id" ]:
655677 _token_usage_rules = _context .authz .usage_rules (request ["client_id" ])
656678
657679 sid = _mngr .create_exchange_session (
658680 exchange_request = request ,
681+ original_grant = grant ,
659682 original_session_id = sid ,
660683 user_id = _session_info ["user_id" ],
661684 client_id = request ["client_id" ],
662685 token_usage_rules = _token_usage_rules ,
686+ scopes = scopes ,
663687 )
664688
665689 try :
@@ -676,25 +700,30 @@ def process_request(self, request, **kwargs):
676700 else :
677701 resources = request .get ("audience" )
678702
703+ _token_args = None
704+ if resources :
705+ _token_args = {"resources" : resources }
706+
679707 try :
680708 new_token = self ._mint_token (
681709 token_class = _token_class ,
682710 grant = _session_info ["grant" ],
683711 session_id = sid ,
684712 client_id = request ["client_id" ],
685713 based_on = token ,
686- scope = request . get ( "scope" ) ,
687- token_args = { "resources" : resources } ,
714+ scope = scopes ,
715+ token_args = _token_args ,
688716 token_type = _token_type ,
689717 )
718+ new_token .expires_at = token .expires_at
690719 except MintingNotAllowed :
691720 logger .error (f"Minting not allowed for { _token_class } " )
692721 return self .error_cls (
693722 error = "invalid_grant" ,
694723 error_description = "Token Exchange not allowed with that token" ,
695724 )
696725
697- return self .token_exchange_response (token = new_token )
726+ return self .token_exchange_response (new_token , _requested_token_type )
698727
699728 def _validate_configuration (self , config ):
700729 if "requested_token_types_supported" not in config :
@@ -763,14 +792,13 @@ def validate_token_exchange_policy(request, context, subject_token, **kwargs):
763792 f"forbidden" ,
764793 )
765794
766- if "scope" in request :
767- scopes = list (set (request .get ("scope" )).intersection (kwargs .get ("scope" )))
768- if scopes :
769- request ["scope" ] = scopes
770- else :
771- return TokenErrorResponse (
772- error = "invalid_request" ,
773- error_description = "No supported scope requested" ,
774- )
795+ scopes = request .get ("scope" , subject_token .scope )
796+ scopes = list (set (scopes ).intersection (subject_token .scope ))
797+ if kwargs .get ("scope" ):
798+ scopes = list (set (scopes ).intersection (kwargs .get ("scope" )))
799+ if scopes :
800+ request ["scope" ] = scopes
801+ else :
802+ request .pop ("scope" )
775803
776804 return request
0 commit comments