我在 CakePHP 4.0 中实现了新的身份验证、Authorization 和 RequestAuthorization 中间件。我想将 unauthorized 请求(来自经过身份验证的用户)重定向到各个页面,具体取决于他们的角色、状态等几个条件。目前,所有 unauthorized 请求都重定向到我的 unauthorized 重定向 url - Pages/权限页面。有没有办法从 RequestPolicy/canAccess 函数中动态更改 unauthorized 重定向 url?
我的 RequestPolicy/canAccess 函数如下所示(已编辑):
public function canAccess($identity, ServerRequest $request)
{
$unauthenticatedActions = $request->getAttribute('authentication')->getConfig('unauthenticatedActions');
if (in_array($request->getParam('action'), $unauthenticatedActions, true)) {
return true;
}
else if(!empty($identity)){
//check based on actions and user roles
$userRole = $identity->role;
$userStatus = $identity->status;
$accountType = $identity->accountsubType;
$action = $request->getParam('action');
$controller = $request->getParam('controller');
switch ($controller) {
case 'Pages':
return true;
break;
case 'Users':
if($userRole === 'ADMIN' && $userStatus === 'ACTIVE'){
return true;
}elseif($action === 'aaa'){
if($userRole === 'xxx' && $userStatus === 'ACTIVE'){
return true;
}
elseif($userRole === 'xxx' && $userStatus === 'EXPIRED'){
//redirect to custom 'suspended access' page
return false;
}
elseif($userRole === 'yyy' && $accountType === 'c'){
//redirect to custom 'restricted access' page
return false;
}
else{
return false;
}
}
...
return false;
case: "Sales":
...
default:
//none of the Controller names matches
return false; //redirects to the default unauthorized redirect url (pages/permission)
//here if I return true, I get the MissingControllerException, MissingActionException etc as expected
}else{
//force them back to the login page
$request = $request
->withParam('controller', 'users')
->withParam('action', 'login');
return true;
}
}
src/应用程序/中间件()
$middlewareQueue
....
->add(new AuthenticationMiddleware($this))
->add(new AuthorizationMiddleware($this, [
'requireAuthorizationCheck' => true,
'unauthorizedHandler' => [
'className' => 'CustomRedirect',
'url' => '/pages/permission',
'exceptions' => [
'MissingIdentityException' => 'Authorization\Exception\MissingIdentityException',
'ForbiddenException' => 'Authorization\Exception\ForbiddenException'
],
],
]))
->add(new RequestAuthorizationMiddleware());
回答1
不,策略不能这样做,这不是它所关心的,它应该做的就是回答是否允许给定身份访问给定资源的问题。
如果您想要自定义重定向,那么您应该考虑实现自定义“unauthorized 处理程序”,您可以在其中检查身份并计算重定向 URL。例如扩展内置的重定向处理程序,并覆盖其 URL 生成方法,类似于以下内容:
// in src/Middleware/UnauthorizedHandler/IdentityRedirectHandler.php
namespace App\Middleware\UnauthorizedHandler;
use Authorization\Middleware\UnauthorizedHandler\RedirectHandler;
use Psr\Http\Message\ServerRequestInterface;
class IdentityRedirectHandler extends RedirectHandler
{
protected function getUrl(ServerRequestInterface $request, array $options): string
{
$identity = $request->getAttribute('identity');
$role = $identity->get('role');
$status = $identity->get('status');
if ($role === 'xxx' && $status === 'b') {
$url = '/suspended';
} elseif ($role === 'yyy' && $status === 'c') {
$url = '/restricted';
} else {
// default URL from middleware config
$url = $options['url'];
}
$options['url'] = $url;
return parent::getUrl($request, $options);
}
}
// in src/Applicatiom.php
new AuthorizationMiddleware($this, [
'unauthorizedHandler' => [
'className' => 'IdentityRedirect',
'url' => '/default-redirect-url',
// ...
],
])
也可以看看