CAS SSO与Silex guard authfailure处理程序

时间:2017-04-05 11:32:22

标签: php symfony cas silex

我在My Silex App中实现了jasig / phpCas身份验证。 这几乎已经完成,但我无法处理authfailure响应相关。

pythonw.exe

MyTokenAuthenticator类:

$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']);
            },
    ),
);

问题是在应用中拒绝来自SSO的有效用户。它显示  带有json消息的页面,没有任何渲染。 我的解决方法是使用带有sso注销链接的最小html页面作为响应和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); } ,但它的快速和脏修复。

我希望通过twig重新登录并提供一个很好的错误消息。也许还有其他一些类可以延伸? Silex的文档没有帮助。谢谢!

1 个答案:

答案 0 :(得分:0)

回到这个问题,因为我在开发者的其他方面。 @mTorres解决方案正在运行。我不得不通过构造函数存储整个app对象,因为此时服务注册表中没有设置twig。

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,
            ));
}

非常感谢!