2024-04-18 01:23:58 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								< ? php  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								namespace  BookStack\Access\Oidc ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								use  Psr\Http\Message\ResponseInterface ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								class  OidcUserinfoResponse  implements  ProvidesClaims  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    protected  array  $claims  =  []; 
							 
						 
					
						
							
								
									
										
										
										
											2024-04-19 21:12:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    protected  ? OidcJwtWithClaims  $jwt  =  null ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-04-18 01:23:58 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-04-19 21:12:27 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    public  function  __construct ( ResponseInterface  $response ,  string  $issuer ,  array  $keys ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-04-18 01:23:58 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
									
										
										
										
											2024-04-19 21:12:27 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        $contentType  =  $response -> getHeader ( 'Content-Type' )[ 0 ]; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( $contentType  ===  'application/json' )  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-04-18 01:23:58 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								            $this -> claims  =  json_decode ( $response -> getBody () -> getContents (),  true ); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-04-19 21:12:27 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        if  ( $contentType  ===  'application/jwt' )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            $this -> jwt  =  new  OidcJwtWithClaims ( $response -> getBody () -> getContents (),  $issuer ,  $keys ); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            $this -> claims  =  $this -> jwt -> getAllClaims (); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2024-04-18 01:23:58 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    /** 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *  @ throws  OidcInvalidTokenException 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     */ 
							 
						 
					
						
							
								
									
										
										
										
											2024-04-19 23:43:51 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    public  function  validate ( string  $idTokenSub ,  string  $clientId ) :  bool 
							 
						 
					
						
							
								
									
										
										
										
											2024-04-18 01:23:58 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
									
										
										
										
											2024-04-19 21:12:27 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        if  ( ! is_null ( $this -> jwt ))  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-04-19 23:43:51 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								            $this -> jwt -> validateCommonTokenDetails ( $clientId ); 
							 
						 
					
						
							
								
									
										
										
										
											2024-04-19 21:12:27 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-04-18 01:23:58 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        $sub  =  $this -> getClaim ( 'sub' ); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // Spec: v1.0 5.3.2: The sub (subject) Claim MUST always be returned in the UserInfo Response.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( ! is_string ( $sub )  ||  empty ( $sub ))  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            throw  new  OidcInvalidTokenException ( " No valid subject value found in userinfo data " ); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // Spec: v1.0 5.3.2: The sub Claim in the UserInfo Response MUST be verified to exactly match the sub Claim in the ID Token;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // if they do not match, the UserInfo Response values MUST NOT be used.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( $idTokenSub  !==  $sub )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            throw  new  OidcInvalidTokenException ( " Subject value provided in the userinfo endpoint does not match the provided ID token value " ); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-04-19 22:05:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // Spec v1.0 5.3.4 Defines the following:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // Verify that the OP that responded was the intended OP through a TLS server certificate check, per RFC 6125 [RFC6125].
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          // This is effectively done as part of the HTTP request we're making through CURLOPT_SSL_VERIFYHOST on the request.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // If the Client has provided a userinfo_encrypted_response_alg parameter during Registration, decrypt the UserInfo Response using the keys specified during Registration.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          // We don't currently support JWT encryption for OIDC
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // If the response was signed, the Client SHOULD validate the signature according to JWS [JWS].
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          // This is done as part of the validateCommonClaims above.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-04-18 01:23:58 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    public  function  getClaim ( string  $claim ) :  mixed 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  $this -> claims [ $claim ]  ? ?  null ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    public  function  getAllClaims () :  array 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  $this -> claims ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}