0

嗨,有人可以帮助我防止 bjyauthorize 捕获我引发的 api 事件错误吗?

bjyauthorize 将未登录用户重定向到添加到配置中的登录表单。但是由于我的 api 被允许用于所有角色,即使是来宾,我只希望它返回由 ApiProblemListener 捕获的 Json 错误消息

ApplicationRest\Module.php

class Module implements
    ConfigProviderInterface, 
    AutoloaderProviderInterface
{

    public function onBootstrap(MvcEvent $e)
    {
        $app = $e->getApplication();
        $sm = $app->getServiceManager();
        $events = $app->getEventManager();

        $listener = $sm->get('ApplicationRest\ApiAuthenticationListener');
        $events->getSharedManager()->attach('ApplicationRest\Controller', 'dispatch', $listener, 500);

        $events->attach('render', array($this, 'onRender'), 100);
        $events->attach($sm->get('ApplicationRest\ApiProblemListener'));
    }

    /**
     * Listener for the render event
     * Attaches a rendering/response strategy to the View.
     *
     * @param  \Zend\Mvc\MvcEvent $e
     */
    public function onRender($e)
    {
        $result = $e->getResult();
        if (!$result instanceof RestfulJsonModel) {
            return;
        }
        //var_dump(123);exit();


        $app = $e->getTarget();
        $services = $app->getServiceManager();
        $view = $services->get('View');
        $restfulJsonStrategy = $services->get('ApplicationRest\RestfulJsonStrategy');
        $events = $view->getEventManager();

        // register at high priority, to "beat" normal json strategy registered
        // via view manager
        $events->attach($restfulJsonStrategy, 500);
    }
}

有很多模块,我真的在考虑将我的 apiModule “ApplicationRest”移到另一个项目,但我真的不想在每次对主项目进行一些更新时更新模型和服务。

欢迎任何建议!谢谢你的时间!

编辑:提供更多 HeaderAuthentication 类

class HeaderAuthentication implements AdapterInterface
{

    const AUTHORIZATION_HEADER = 'Authorization';
    const CRYPTO = 'sha256';

    protected $request;
    protected $repository;

    public function __construct(RequestInterface $request, UserRepository $repository)
    {
        $this->request = $request;
        $this->repository = $repository;
    }

    /**
     * Authorization: Key={key} Timestamp={timestamp} Signature={signature}
     * @return Result
     */
    public function authenticate()
    {
        $request = $this->getRequest();
        if (!$request instanceof Request) {
            return;
        }
        $headers = $request->getHeaders();

        // Check Authorization header presence
        if (!$headers->has(static::AUTHORIZATION_HEADER)) {
            return new Result(Result::FAILURE, null, array(
                'Authorization header missing'
            ));
        }

        $authorization = $headers->get(static::AUTHORIZATION_HEADER)->getFieldValue();

        // Validate public key
        $publicKey = $this->extractPublicKey($authorization);
        $user = $this->getUserRepository()
                     ->findOneByApiSecret($publicKey);

        if (null === $user) {
            $code = Result::FAILURE_IDENTITY_NOT_FOUND;
            return new Result($code, null, array(
                'User not found based on public key'
            ));
        }

        // Validate signature
        $signature = $this->extractSignature($authorization);
        /*$hmac = $this->getHmac($request, $user);
        if ($signature !== $hmac) {
            $code = Result::FAILURE_CREDENTIAL_INVALID;
            return new Result($code, null, array(
                'Signature does not match'
            ));
        }*/

        return new Result(Result::SUCCESS, $user);
    }
}

ApiAuthenticationListener

class ApiAuthenticationListener
{

    protected $adapter;

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

    public function __invoke(MvcEvent $event)
    {
        $result = $this->adapter->authenticate();

        if (!$result->isValid()) {
            $response = $event->getResponse();

            // Set some response content
            $response->setStatusCode(401);
            return $response;
        }

        // All is OK
        $event->setParam('user', $result->getIdentity());
    }

}
4

1 回答 1

1

我猜你在你的路线上配置了警卫。你需要通过你的模块配置告诉 BJYAuthorize,这个控制器或路由不应该受到保护。

'bjyauthorize' => [

    'default_role'          => 'guest',

    ...     

    'guards' => [
        'BjyAuthorize\Guard\Controller' => [

            // system tools
            ['controller' => 'Application\Controller\Api', 'roles' => [] ],

            ['controller' => 'error', 'roles' => []],

        ],
    ],
],

我删除了特定于应用程序的细节,但这种类型的事情很快就解决了。我同样需要 CLI 路由不受 http auth 的保护。

于 2015-06-10T15:44:46.487 回答