# |
May 17th 2021, 13:02 |
neon1024 |
Perhaps that’s what the docblock means when it says path |
# |
May 17th 2021, 13:01 |
neon1024 |
Strange that `getOriginalData` doesn’t take a dot hash |
# |
May 17th 2021, 13:01 |
ndm |
`$this->Authentication->getIdentity()->organisation_id` `$this->Authentication->getIdentity()->get('organisation_id')` `$this->Authentication->getIdentityData('organisation_id')` |
# |
May 17th 2021, 12:57 |
neon1024 |
Both seem very long |
# |
May 17th 2021, 12:57 |
neon1024 |
`$this->getRequest()->getSession()->read('Auth.organisation_id');` |
# |
May 17th 2021, 12:57 |
neon1024 |
`$this->Authentication->getIdentity()->getOriginalData()['organisation_id']` |
# |
May 17th 2021, 12:57 |
neon1024 |
Is there a more elegant way to get Authentication data from the session? |
# |
May 17th 2021, 12:36 |
richard |
@ndm thanks for your input, it does feel more appropriate to handle it with apache |
# |
May 17th 2021, 12:35 |
ndm |
@richard I'd always use server level solutions for that, doing it on PHP level is just a waste of performance... so with Apache using rewrite rules would most likely the most fitting approach. |
# |
May 17th 2021, 12:33 |
slackebot |
`$identity = new \Authentication\Identity($modifiedData);`. |
# |
May 17th 2021, 12:33 |
ndm |
@kushan You'd have to be a bit more specific about what exactly it is that you don't understand about using it. It's just a callback, and it expects that you return an object that implements `\Authentication\IdentityInterface`, so basically you modify the data that it receives (in case required), and wrap it an object that satisfies the required contract. The most basic option would be to use the built in identity class, eg |
# |
May 17th 2021, 12:13 |
richard |
is using apache my best bet or is cake application code a better way to tackle this |
# |
May 17th 2021, 12:13 |
richard |
What is the best solution when redirecting urls from an old site to urls on a new site, the harder part is query string params from the old site have to be translated to query string params on the new site |
# |
May 17th 2021, 12:03 |
kushan |
thanks @ndm but I believe, if I can set a custom decorator for LDAP auth, I can sort this issue without creating a new entity. I believe this is the answer, but I don't know how to use it https://book.cakephp.org/authentication/2/en/identity-object.html#using-a-custom-identity-decorator |
# |
May 17th 2021, 12:00 |
slackebot |
that is concerned, you'd either need to supply the role ID (you could query the role entity by name maybe) to avoid the unique validation error, or disable validation, or set the entity properties on the object instead of passing them to `newEntity()`. |
# |
May 17th 2021, 12:00 |
ndm |
Well, that doesn't really answer my question, as LDAP usernames might not be identical to your DB usernames, ie you could still have a matching profile for an LDAP user. I'm pressing on the DB querying because that would be the cleaner approach IMHO. However, if you do not have profiles for LDAP users, and do not intend to create any for them, so you really need to create "dummy entities" for them so to speak... then as far as |
# |
May 17th 2021, 11:57 |
kushan |
as you could see when a user enters usernam/password, it first check in the app's db for a matching user. If it cannot find a matching user, then look for LDAP |
# |
May 17th 2021, 11:57 |
kushan |
2. ldap |
# |
May 17th 2021, 11:56 |
kushan |
1. password |
# |
May 17th 2021, 11:56 |
kushan |
there are 2 ways |
# |
May 17th 2021, 11:56 |
slackebot |
LDAP_OPT_NETWORK_TIMEOUT => 5, ], ]); return $service; }``` @ndm The above might explain how i'm authenticating users |
# |
May 17th 2021, 11:56 |
slackebot |
$service->loadIdentifier('CustomLdap', [ 'fields' => ['username' => 'username', 'password' => 'password'], 'host' => Configure::readOrFail('LdapHost'), 'bindDN' => function ($username) use ($baseDN) { return "cn=$username,$baseDN"; }, 'baseDN' => $baseDN, 'ldap' => 'CustomExtensionAdapter', 'options' => [ LDAP_OPT_PROTOCOL_VERSION => 3, |
# |
May 17th 2021, 11:56 |
slackebot |
'fields' => $formAuthFields, 'loginUrl' => '/', ]); // Load identifiers $service->loadIdentifier('Authentication.Password', [ 'fields' => $formAuthFields, 'resolver' => [ 'className' => 'CustomOrm', 'customerId' => Router::getRequest()->getAttribute('customer')->id ], ]); // add LDAP identifier $baseDN = Configure::readOrFail('LdapBaseDN'); |
# |
May 17th 2021, 11:56 |
slackebot |
$service->setConfig([ 'unauthenticatedRedirect' => '/', 'queryParam' => 'redirect', ]); $formAuthFields = [ IdentifierInterface::CREDENTIAL_USERNAME => 'email', IdentifierInterface::CREDENTIAL_PASSWORD => 'password', ]; // Load the authenticators. Session should be first. $service->loadAuthenticator('Authentication.Session'); $service->loadAuthenticator('Authentication.Form', [ |
# |
May 17th 2021, 11:56 |
kushan |
```/** * Returns a service provider instance. * * @param \Psr\Http\Message\ServerRequestInterface $request Request * @return \Authentication\AuthenticationServiceInterface */ public function getAuthenticationService(ServerRequestInterface $request): AuthenticationServiceInterface { $service = new AuthenticationService(); // Define where users should be redirected to when they are not authenticated |
# |
May 17th 2021, 11:54 |
ndm |
I'm not quite sure I understand, do you _not_ have any matching users in your DB, or are you just not able to query them (for example because you have no unique value by which you could identify them)? |
# |
May 17th 2021, 11:51 |
kushan |
when I authenticate via LDAP, I don't check for any matching username in the DB. The reason I wanted to create a new entity is that I cannot find a way to authorize Ldap users without mapping data returned via LDAP auth to a User entity. |
# |
May 17th 2021, 11:49 |
ndm |
ps, you better pass the customer as an option to the identifier config, then you can remove the hard router depdendency. |
# |
May 17th 2021, 11:48 |
ndm |
I see. And do you have matching users in your database that you could identify by the username, or by information returned from the LDAP search? |
# |
May 17th 2021, 11:48 |
kushan |
the namespace of the above class is App\Identifier |
# |
May 17th 2021, 11:46 |
slackebot |
in_array($result[0]['employeetype'][0], EMPLOYEE_TYPE) ? USER_ROLE_ADMIN : false ]), 'customer_id' => Router::getRequest()->getAttribute('customer')->id ]); } } catch (ErrorException $e) { $this->_handleLdapError($e->getMessage()); } $this->_ldap->unbind(); return null; }``` |
# |
May 17th 2021, 11:46 |
slackebot |
= $this->_ldap->bind($config['bindDN']($username), $password); if ($ldapBind === true) { $filter = "(cn={$username})"; $result = $this->_ldap->search($config['baseDN'], $filter); $this->_ldap->unbind(); return new ArrayObject([ $config['fields'][self::CREDENTIAL_USERNAME] => $username, 'user_role' => new ArrayObject([ 'role' => |
# |
May 17th 2021, 11:46 |
kushan |
@ndm yes, but I extended Authentication\Identifier\LdapIdentifier class. In my CustomLdapIdentifier::_bindUser() ```/** * Try to bind the given user to the LDAP server * * @param string $username The username * @param string $password The password * * @return ArrayAccess|null */ protected function _bindUser(string $username, string $password): ?ArrayAccess { $config = $this->getConfig(); try { $ldapBind |
# |
May 17th 2021, 11:43 |
ndm |
@kushan Where does the LDAP identifier get all that information from? `customer_id`, `user_role` (a nested array)? Usually it returns an array object with just one field, the username. |
# |
May 17th 2021, 11:00 |
slackebot |
$user->get('user_role')['role']] //$user->get('user_role')['role'] is 'admin' in this case, and the 'admin is existed already'` `],` `}` `return $user->setAuthorization($auth);` `}` `]));` `}` |
# |
May 17th 2021, 11:00 |
slackebot |
\Authentication\Identity) {` `$Users = TableRegistry::_getTableLocator_()->get('Users');` `$user = $Users->newEntity(` `[` `'name' => 'test',` `'email' => 'test@test.com',` `'customer_id' => $user->get('customer_id'),` `'user_role_id' => 3,` `'user_role' => ['role' => |
# |
May 17th 2021, 11:00 |
slackebot |
My code... `public function middleware(MiddlewareQueue $middlewareQueue): MiddlewareQueue` `{` `$middlewareQueue` `// few other middleware before auth` `->add(new AuthenticationMiddleware($this))` `->add(new AuthorizationMiddleware($this, [` `// 'requireAuthorizationCheck' => false,` `'identityDecorator' => function ($auth, $user) {` `// for users authenticated via LDAP` `if ($user instanceof |
# |
May 17th 2021, 11:00 |
slackebot |
working as I cannot create and new user entity due to one of the DB rules set. I have Users and UserRoles models. In the UserRoles the 'role' filed is unique. If I tried to create a new entity to match the Users model using the data returned via LDAP auth, it throws an error as the role field is unique. I'm using the Authorization middleware similar to what's explained here https://book.cakephp.org/authorization/2/en/middleware.html |
# |
May 17th 2021, 11:00 |
kushan |
Hi, could someone help me with CakePHP authorisation issue please... I've been adding the new Authentication and Authorization plugins to an existing CakePHP 4.x application. I'm using Password and Ldap authentication at the moment, and the authentication with both methods is working. Also, the authorisation, when authenticated via the password, is working. However, the authorisation when authenticated via LDAP is not |
# |
May 17th 2021, 10:59 |
paolo.bragagni |
some 'bake for dummies' somewhere? |
# |
May 17th 2021, 10:58 |
paolo.bragagni |
cant understand how to bake my own actions and views in cake4 :( |