I have created a project with zf3 mvc and apigility. I have admin modules which is located within ‘administrator/module’ folder (the same folder as default ‘module’ folder which I have too). I want to organize all my ajax calls with help of rest/rpc of apigility. I have done that successfully. The next step is protect all my requests to that rest/rpc apigility collection, entities and actions. There is a way to do that with Oauth2 as this is API stuff.
I am trying to follow this article https://apigility.org/documentation/auth/user-differentiation to get my goal. I set ‘deny_by_default’ to ‘true’:
'zf-mvc-auth' => [
'authorization' => [
'deny_by_default' => true,
Also, I have this config:
'zf-mvc-auth' => [
'authentication' => [
'map' => [
'\\Admin\\Module\\User\\V1\\Rest' => 'oauth2_pdo',
'ZF\\OAuth2' => 'session',
],
'adapters' => [
'oauth2_pdo' => [
'adapter' => \ZF\MvcAuth\Authentication\OAuth2Adapter::class,
'storage' => [
'adapter' => \PDO::class,
'dsn' => 'mysql:host=localhost;dbname=my_db_name',
'route' => '/administrator/oauth',
'username' => 'root',
'password' => 'mypass',
],
],
'session' => [
'adapter' => \Module\Application\Authentication\Adapter\SessionAdapter::class,
'storage' => [
Zend\Authentication\Storage\Session::class,
],
],
],
Also, I have created SessionAdapter as was shown at article where ‘webauth’ I have replaced with ‘Admin\Zend_Auth’ session namespace and ‘user’ role have replaced with ‘admin’ role. Also I have created UserIdentity. If you have noticed, within article within SessionAdapter’s authenticate method there is line:
$userIdentity = new Identity\UserIdentity($session->auth);
where $session->auth is a string, right? But within UserIdentity __construct method is required array, right? Different types. I have modified code that UserIdentity __construct accept string identity of user (username). After that I get user object from db with help of doctrine and return user id within UserIdentity::getId() method. Also within onBootstrap method I have added authentication stuff, but instead line:
$defaultAuthenticationListener->attach(new Authentication\AuthenticationAdapter());
I have created authentication listener and added this:
$defaultAuthenticationListener->attach($serviceManager->get(Adapter\SessionAdapter::class));
Here AuthenticationAdapter was replaced with SessionAdapter because there is no AuthenticationAdapter mention within article earlier, right?
Also, I have added authorization listener where I have added rules for my ‘admin’ role:
$authorization->allow('admin', 'ZF\\OAuth2\\Controller\\Auth' . '::authorize');
$authorization->allow('admin', 'ZF\\OAuth2\\Controller\\Auth' . '::token');
$authorization->allow('admin', 'ZF\\OAuth2\\Controller\\Auth' . '::resource');
$authorization->allow('admin', 'ZF\\OAuth2\\Controller\\Auth' . '::receive-code');
$authorization->allow('admin', 'ZF\\OAuth2\\Controller\\Auth' . '::revoke');
I have added all actions of Auth controller because I experimented.
And now, I am opening my login page, fill login form with username and password and submit. Within view template I show my identity with identity plugin:
Idenity: <?= $this->identity();?>
and it shows that I am login as testusername. It’s great! Now I am opening in browser url /administrator/api/rest/v1/user/item but I see this:
{
"type":"http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html",
"title":"Forbidden",
"status":403,
"detail":"Forbidden"
}
But why??? I have done everything as was showing within article but with some fixes. I start to debug code with xDebug and set breakpoints within all actions of /vendor/zfcampus/zf-oauth2/src/Controller/AuthController.php but it never calls. We have this config:
'ZF\\OAuth2' => 'session',
But OAuth2 controller is never called and SessionAdapter->authenticate() method is never called to. But if I open this url /administrator/oauth in browser I wiil be redirected with SessionAdapter->authenticate() method as expected to the login page. If I send post request to the /administrator/oauth I get this:
{
"type": "http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html",
"title": "invalid_request",
"status": 400,
"detail": "The grant type was not specified in the request"
}
Which is fine at current moment because I just need to know that ZF\OAuth2\Controller\AuthController is called.
So, it looks like that this config:
'ZF\\OAuth2' => 'session',
do nothing if I open my rest urls within browser. Also, it looks like zf-mvc-auth call bshaffer’s OAuth2 authenticate method directly without calling ZF\OAuth2\Controller\AuthController. What have I missed?