| 1 |  |  | <?php | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3 |  |  | namespace Krtv\Bundle\SingleSignOnServiceProviderBundle\EntryPoint; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 4 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 5 |  |  | use Krtv\Bundle\SingleSignOnServiceProviderBundle\Context\AuthenticationContext; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 6 |  |  | use Krtv\Bundle\SingleSignOnServiceProviderBundle\Context\AuthenticationContextFactory; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 7 |  |  | use Symfony\Component\HttpFoundation\ParameterBag; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 8 |  |  | use Symfony\Component\HttpFoundation\Request; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 9 |  |  | use Symfony\Component\HttpKernel\UriSigner; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 10 |  |  | use Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 11 |  |  | use Symfony\Component\Security\Core\Exception\AuthenticationException; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 12 |  |  | use Symfony\Component\Security\Http\HttpUtils; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 13 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 14 |  |  | /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 15 |  |  |  * Class SingleSignOnAuthenticationEntryPoint | 
            
                                                                                                            
                            
            
                                    
            
            
                | 16 |  |  |  * @package Krtv\Bundle\SingleSignOnServiceProviderBundle\EntryPoint | 
            
                                                                                                            
                                                                
            
                                    
            
            
                | 17 |  |  |  */ | 
            
                                                                        
                            
            
                                    
            
            
                | 18 |  |  | class SingleSignOnAuthenticationEntryPoint implements AuthenticationEntryPointInterface | 
            
                                                                        
                            
            
                                    
            
            
                | 19 |  |  | { | 
            
                                                                        
                            
            
                                    
            
            
                | 20 |  |  |     /** | 
            
                                                                        
                            
            
                                    
            
            
                | 21 |  |  |      * @var AuthenticationContextFactory | 
            
                                                                        
                            
            
                                    
            
            
                | 22 |  |  |      */ | 
            
                                                                        
                            
            
                                    
            
            
                | 23 |  |  |     private $contextFactory; | 
            
                                                                        
                            
            
                                    
            
            
                | 24 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 25 |  |  |     /** | 
            
                                                                        
                            
            
                                    
            
            
                | 26 |  |  |      * @var HttpUtils | 
            
                                                                        
                            
            
                                    
            
            
                | 27 |  |  |      */ | 
            
                                                                        
                            
            
                                    
            
            
                | 28 |  |  |     private $httpUtils; | 
            
                                                                        
                            
            
                                    
            
            
                | 29 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 30 |  |  |     /** | 
            
                                                                        
                            
            
                                    
            
            
                | 31 |  |  |      * @var UriSigner | 
            
                                                                        
                            
            
                                    
            
            
                | 32 |  |  |      */ | 
            
                                                                        
                            
            
                                    
            
            
                | 33 |  |  |     private $uriSigner; | 
            
                                                                        
                            
            
                                    
            
            
                | 34 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 35 |  |  |     /** | 
            
                                                                        
                            
            
                                    
            
            
                | 36 |  |  |      * @param AuthenticationContextFactory $contextFactory | 
            
                                                                        
                            
            
                                    
            
            
                | 37 |  |  |      * @param UriSigner $signer | 
            
                                                                        
                            
            
                                    
            
            
                | 38 |  |  |      * @param HttpUtils $httpUtils | 
            
                                                                        
                            
            
                                    
            
            
                | 39 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 40 |  |  |     public function __construct(AuthenticationContextFactory $contextFactory, UriSigner $signer, HttpUtils $httpUtils) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 41 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 42 |  |  |         $this->contextFactory = $contextFactory; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 43 |  |  |         $this->httpUtils      = $httpUtils; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 44 |  |  |         $this->uriSigner      = $signer; | 
            
                                                                                                            
                                                                
            
                                    
            
            
                | 45 |  |  |     } | 
            
                                                                        
                            
            
                                    
            
            
                | 46 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 47 |  |  |     public function start(Request $request, AuthenticationException $authException = null) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 48 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 49 |  |  |         $context = $request->attributes->get($this->contextFactory->getAttribute()); /* @var AuthenticationContext $context */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 50 |  |  |         $options = $context->getOptions(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 51 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 52 |  |  |         $targetPathParameter    = $options->get('target_path_parameter'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 53 |  |  |         $failurePathParameter   = $options->get('failure_path_parameter'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 54 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 55 |  |  |         $serviceParameter       = $options->get('sso_service_parameter'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 56 |  |  |         $serviceExtraParameter  = $options->get('sso_service_extra_parameter'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 57 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 58 |  |  |         $loginRequiredParameter = $options->get('sso_login_required_parameter'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 59 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 60 |  |  |         $scheme = $options->get('sso_scheme'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 61 |  |  |         $host   = $options->get('sso_host'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 62 |  |  |         $path   = $options->get('sso_path'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 63 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 64 |  |  |         // OTP validate callback should point to /otp/validate/ route on service provider | 
            
                                                                                                            
                            
            
                                    
            
            
                | 65 |  |  |         // For example: http://service.provider/otp/validate/ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 66 |  |  |         $otpValidateUrl = $context->getOtpValidationPath($request); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 67 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 68 |  |  |         // Target path is a URL or path to previous URL or it | 
            
                                                                                                            
                            
            
                                    
            
            
                | 69 |  |  |         // should be an any route which user should visit after OTP valid check. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 70 |  |  |         $targetUrl      = $context->getTargetPath($request); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 71 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 72 |  |  |         // Add extra parameters to Target URL which are marked as proxy parameters. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 73 |  |  |         if ($context->getServiceProxy()->count()) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 74 |  |  |             if (strpos($targetUrl, '?') === false) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 75 |  |  |                 $targetUrl .= '?'; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 76 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 77 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 78 |  |  |             $params = array(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 79 |  |  |             foreach ($context->getServiceProxy() as $name => $value) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 80 |  |  |                 $params[$name] = $context->getServiceExtra()->get($name); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 81 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 82 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 83 |  |  |             $targetUrl .= http_build_query($params); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 84 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 85 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 86 |  |  |         // Sign Target URL to be able verify signature later | 
            
                                                                                                            
                            
            
                                    
            
            
                | 87 |  |  |         $targetUrl = $this->uriSigner->sign($targetUrl); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 88 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 89 |  |  |         // User will be redirected to this route if he isn't authenticated on identity provider | 
            
                                                                                                            
                            
            
                                    
            
            
                | 90 |  |  |         // or if identity provider returned invalid response on OTP check. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 91 |  |  |         $failureUrl     = $context->getFailurePath($request); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 92 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 93 |  |  |         // Failure URL should contain Target URL to be able catch it if user came back from identity provider | 
            
                                                                                                            
                            
            
                                    
            
            
                | 94 |  |  |         if ($failureUrl) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 95 |  |  |             if (strpos($failureUrl, '?') === false) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 96 |  |  |                 $separator = '?'; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 97 |  |  |             } else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 98 |  |  |                 $separator = '&'; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 99 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 100 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 101 |  |  |             $failureUrl .= sprintf('%s%s=%s', $separator, $targetPathParameter, rawurlencode($targetUrl)); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 102 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 103 |  |  |             // If failure url is the same with current host we add a login_required=1 parameter | 
            
                                                                                                            
                            
            
                                    
            
            
                | 104 |  |  |             // To be able to suppress SSO Authentication attempt. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 105 |  |  |             // Make sure that your failure url is accessible as guest. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 106 |  |  |             if (strpos($failureUrl, $request->getSchemeAndHttpHost()) === 0) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 107 |  |  |                 $failureUrl .= sprintf('&%s=%s', $loginRequiredParameter, $options->get('sso_login_required')); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 108 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 109 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 110 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 111 |  |  |         $redirectUri = sprintf('%s/?%s=%s', rtrim($otpValidateUrl, '/'), $targetPathParameter, rawurlencode($targetUrl)); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 112 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 113 |  |  |         // Build SSO login URL. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 114 |  |  |         $redirectUri = sprintf('%s://%s%s/?%s=%s', $scheme, $host, rtrim($path, '/'), $targetPathParameter, rawurlencode($redirectUri)); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 115 |  |  |         $redirectUri = sprintf('%s&%s=%s', $redirectUri, $failurePathParameter, rawurlencode($failureUrl)); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 116 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 117 |  |  |         // Append service provider name to root sso login url to be able determine it on identity provider. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 118 |  |  |         if ($context->getService()) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 119 |  |  |             $redirectUri .= sprintf('&%s=%s', $serviceParameter, $context->getService()); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 120 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 121 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 122 |  |  |         // Append all extra parameters to root sso login url | 
            
                                                                                                            
                            
            
                                    
            
            
                | 123 |  |  |         if ($context->getService() && $context->getServiceExtra()->count()) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 124 |  |  |             $redirectUri .= sprintf('&%s', http_build_query(array( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 125 |  |  |                 $serviceExtraParameter => $context->getServiceExtra()->all() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 126 |  |  |             ))); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 127 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 128 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 129 |  |  |         // Sign data | 
            
                                                                                                            
                            
            
                                    
            
            
                | 130 |  |  |         $redirectUri = $this->uriSigner->sign($redirectUri); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 131 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 132 |  |  |         return $this->httpUtils->createRedirectResponse($request, $redirectUri); | 
            
                                                                                                            
                                                                
            
                                    
            
            
                | 133 |  |  |     } | 
            
                                                        
            
                                    
            
            
                | 134 |  |  | } | 
            
                                                        
            
                                    
            
            
                | 135 |  |  |  |