2017-04-05 13 views
0

내 Silex App에서 jasig/phpCas 인증을 구현했습니다. 거의 완료되었습니다.하지만 authfailure Response correclty를 처리 할 수 ​​없습니다.CAS SSO with Silex guard authfailure handler

$app['app.token_authenticator'] = function ($app) { 
return new MyApp\Domain\MyTokenAuthenticator($app['security.encoder_factory'],$app['cas'],$app['dao.usersso']); 
}; 

$app['security.firewalls'] = array(
    'default' => array(
      'pattern' => '^/.*$', 
      'anonymous' => true, 

      'guard' => array(
        'authenticators' => array(
          'app.token_authenticator' 
        ), 
      ), 
      'logout' => array ('logout_path' => '/logout', 'target_url' => '/goodbye'), 
      'form' => array('login_path' =>'/login', 'check_path' =>'/admin/login_check', 'authenticator' => 'time_authenticator'), 
      'users' => function() use ($app) { 
       return new MyApp\DAO\UserDAO($app['db']); 
      }, 
    ), 
); 

MyTokenAuthenticator 클래스 : SSO에서 유효한 사용자가 응용 프로그램에 거부 될 때

class MyTokenAuthenticator extends AbstractGuardAuthenticator 
{ 
    private $encoderFactory; 
    private $cas_settings; 
    private $sso_dao; 

    public function __construct(EncoderFactoryInterface $encoderFactory, $cas_settings, MyApp\DAO\UserSsoDAO $userdao) 
{ 
    $this->encoderFactory = $encoderFactory; 
    $this->cas_settings = $cas_settings; 
    $this->sso_dao = $userdao; 
} 

public function getCredentials(Request $request) 
{ 
    $bSSO = false; 

    //Test request for sso 
    if (strpos($request->get("ticket"),"cas-intra") !==false) 
     $bSSO = true; 
    if($request->get("sso") == "1") 
     $bSSO=true; 

    if ($bSSO) 
    { 
     if ($this->cas_settings['debug']) 
     { 
      \CAS_phpCAS::setDebug(); 
      \CAS_phpCAS::setVerbose(true); 
     } 

     \CAS_phpCAS::client(CAS_VERSION_2_0, 
       $this->cas_settings['server'], 
       $this->cas_settings['port'], 
       $this->cas_settings['context'], 
       false); 

     \CAS_phpCAS::setCasServerCACert('../app/config/cas.pem'); 
     // force CAS authentication 
     \CAS_phpCAS::forceAuthentication(); 
     $username = \CAS_phpCAS::getUser(); 
     return array ( 
       'username' => $username, 
       'secret' => 'SSO' 
     ); 
    } 

    //Nothing to do, skip custom auth 
    return; 
} 

/** 
* Get User from the SSO database. 
* Add it into the MyApp users database (Update if already exists) 
* {@inheritDoc} 
* @see \Symfony\Component\Security\Guard\GuardAuthenticatorInterface::getUser() 
*/ 
public function getUser($credentials, UserProviderInterface $userProvider) 
{ 
    //Get user stuf 
    .... 
    //return $userProvider->loadUserByUsername($credentials['username']); 
    return $user; 
} 

/** 
* 
* {@inheritDoc} 
* @see \Symfony\Component\Security\Guard\GuardAuthenticatorInterface::checkCredentials() 
*/ 
public function checkCredentials($credentials, UserInterface $user) 
{ 
    // check credentials - e.g. make sure the password is valid 
    // return true to cause authentication success 

    if ($this->sso_dao->isBAllowed($user->getLogin())) 
     return true; 
    else 
     throw new CustomUserMessageAuthenticationException("Sorry, you're not alllowed tu use this app."); 
} 

public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey) 
{ 
    // on success, let the request continue 
    return; 
} 

public function onAuthenticationFailure(Request $request, AuthenticationException $exception) 
{ 
    $data = array(
      'message' => strtr($exception->getMessageKey(), $exception->getMessageData()), 

      // or to translate this message 
      // $this->translator->trans($exception->getMessageKey(), $exception->getMessageData()) 
    ); 

    return new JsonResponse($data,403); 

} 

문제입니다. 렌더링없이 json 메시지가있는 페이지 을 표시합니다. 제 해결 방법은 sso 로그 아웃 링크가있는 최소 html 페이지를 응답으로 사용하고 session_destroy()을 사용하는 것입니다.

좋은 오류 메시지가 표시된 나뭇 가지를 통해 줄을 바꾸고 싶습니다. 연장 할 다른 수업이 있을까요? Silex의 문서는 도움이되지 않았습니다. 고맙습니다 !

+0

HTML 렌더링 오류가 발생하면 왜'''JsonResponse'''를 반환합니까? 내가 여기서 뭔가를 놓치고 있니? HTML 응답 만 원한다면, 클래스에 나뭇 가지를 주입 한 다음,''새로운 응답을 반환 할 수 있습니다 ($ this-> twig-> render ('error-template.twig', [ "data"=> $ data ]), Response :: HTTP_FORBIDDEN);''' – mTorres

+0

[documentation example] (http://silex.sensiolabs.org/doc/2.0/cookbook/guard_authentication.html)의 벙어리 복사/붙여 넣기였습니다. 'onAuthenticationFailure'는 좋은 이유 (사전 구성된 양식?)에 대한 응답이 필요합니다. 응답 객체로 렌더링하면 좋은 방법입니다. 저는 Silex를 처음 접했고 모든 가능성을 모릅니다. 나는 시험해 볼게. – raphr

답변

0

위로 돌아 가기이 질문에 대한 답변을 드리겠습니다. @mTorres 솔루션이 작동 중입니다. 나뭇 가지가 서비스 레지스트리에서이 시점에 설정되지 않았으므로 생성자를 통해 전체 앱 객체를 저장해야했습니다.

class MyTokenAuthenticator extends AbstractGuardAuthenticator 
{ 
    private $app; 

    public function __construct($app) 
    { 
     $this->app=$app; 
    } 

다음 사용자 정의 이벤트

public function onAuthenticationFailure(Request $request, AuthenticationException $exception) 
{ 
    return new \Symfony\Component\HttpFoundation\Response(
      $this->app['twig']->render('logout.html.twig',array(
       'error'   => $data, 
      )); 
} 

많은 감사를!