我正在尝试使用新的cakephp/authentication插件在cakephp 3.8上配置ldap身份验证,并且不确定如何将经过身份验证的ldap用户与本地实体匹配。
我的配置紧跟documentation,并且可以使用完整的here。
在我的Application.php
类Application
中实现了AuthenticationServiceProviderInterface
和AuthorizationServiceProviderInterface
public function getAuthenticationService(ServerRequestInterface $request,
ResponseInterface $response)
{
$service = new AuthenticationService();
$service->loadIdentifier('Authentication.Password', [...]),
$service->loadIdentifier('Authentication.Ldap', [
'fields' => [
'username' => 'username',
'password' => 'password'
],
'host' => 'ldap.forumsys.com',
'port' => '389',
'bindDN' => function($username) {
return 'uid='.$username.',DC=example,DC=com';
},
'options' => [LDAP_OPT_PROTOCOL_VERSION => 3]
]);
$service->loadAuthenticator('Authentication.Session');
$service->loadAuthenticator('Authentication.Form', [
'fields' => [
'username' => 'email',
'password' => 'password'
],
'loginUrl' => '/users/login'
]);
return $service;
}
在我的中间件中,我正在尝试用授权内容装饰身份。使用常规本地系统进行身份验证时,$identity
是App\Model\Entity\User
,但是使用ldap用户登录时,它是Authentication\Identity
所以当我打电话给setAuthorization
'identityDecorator' => function (AuthorizationServiceInterface $authorization,
ArrayAccess $identity) {
$identity->setAuthorization($authorization);
}
由于Call to undefined method Authentication\Identity::setAuthorization()
中的所有内容都是
$identity
object(Authentication\Identity) {
'config' => [
'fieldMap' => [
'id' => 'id'
]
],
'data' => object(ArrayObject) {
username => 'einstein'
}
}
我如何将经过身份验证的ldap用户与他们的本地用户匹配,并从Authentication\Identity
转换为App\Model\Entity\User
?
最终目标是还可以从ldap数据(如果不存在)中选择生成本地用户。
中间件尝试
Application.php
public function middleware($middlewareQueue)
{
...
$middlewareQueue->add($authentication);
$middlewareQueue->add($ldap_matcher);
$middlewareQueue->add($authorization);
return $middlewareQueue;
}
LdapMatcherMiddleware.php
class LdapMatcherMiddleware
{
public function __invoke(ServerRequestInterface $request,
ResponseInterface $response, $next)
{
$identity = $request->getAttribute('identity');
if ($identity !== null) {
$identity = $this->buildIdentity($identity);
$request = $request->withAttribute('identity', $identity);
}
$response = $next($request, $response);
return $response;
}
public function buildIdentity($identity)
{
$Users = TableRegistry::getTableLocator()->get('Users');
$username = $identity->getOriginalData()['username'];
$user = $Users->find()->where(['username' => $username])->first();
if (is_null($identity)) {
$user = $this->createLocalUserFromLdap($identity);
}
return $user;
}
public function createLocalUserFromLdap($identity)
{
$Users = TableRegistry::getTableLocator()->get('Users');
$user = $Users->newEntity([
'username' => $identity->getOriginalData()['username']
]);
$Users->save($user);
return $user;
}
}
答案 0 :(得分:1)
我如何将经过身份验证的ldap用户与其本地对应者匹配,并从Authentication \ Identity转换为App \ Model \ Entity \ User?
我将在身份验证中间件之后添加另一个中间件,并在那里执行该步骤。
$users = TableRegistry::getTableLocator()->get('Users');
$entity = $users->newEntity($identity->getOriginalData());
然后执行此实体的授权所需要做的一切。
最终目标是还可以从ldap数据(如果不存在)中选择生成本地用户。
只需在某个地方实现您的逻辑并以与上述身份相同的方式获取实体即可。
$users = TableRegistry::getTableLocator()->get('Users');
$entity = $users->newEntity($identity->getOriginalData());
// Check if it exists inside this method and if not just create it
$users->createLocalUserFromLDAP($entity);