php - Configuración de denyCallback personalizado incluso al devolver false de matchCallback con comportamientos Yii2
permissions user-permissions (2)
Puede definir denyCallback
como propiedad de AccessControl
lugar de definirlo en AccessRule
. Se llamará si allow
después de la verificación de la regla devuelve nulo . Tiene la misma firma que denyCallback
en AccessRule
:
public function behaviors() {
return [
''access'' => [
''class'' => AccessControl::className(),
''only'' => [''view''],
''rules'' => [
[
''allow'' => true,
''actions'' => [''view''],
''matchCallback'' => function ($rule, $action) {
return Yii::$app->authManager->can($rule, $action);
}
],
''denyCallback'' => function ($rule, $action){...}
// everything else is denied
],
],
];
}
Como otra opción, puede extender la clase AccessRule
y anular el método AccessRule
allows()
para que devuelva false en lugar de nulo cuando falla la comprobación de coincidencia, y se denyCallback
su regla denyCallback
:
class MyAccessRule extends AccessRule
{
public function allows($action, $user, $request)
{
$allows = parent::allows($action, $user, $request);
if ($allows === null) {
return false;
} else {
return $allows;
}
}
}
matchCallback
solo determina si debe aplicarse o no la regla, y si matchCallback
devuelve verdadero y otros parámetros coinciden (por ejemplo, roles , verbos , etc.), invocar a allow
allows()
devolverá el parámetro allow
de rule verdadero o falso al configurarlo en la configuración. Y si matchCallback
devuelve falso , allow
será nulo y no se invocará denyCallback de la regla, pero se denyCallback
AccessControl denyCallback
si está configurado.
Como mencionaste en los comentarios, la tercera opción es hacer que allows()
devuelva el resultado de la devolución de llamada.
class MyAccessRule extends AccessRule
{
public $allowCallback;
public function allows($action, $user, $request)
{
if(!empty($this->allowCallback) {
return call_user_func($this->allowCallback);
}
$allows = parent::allows($action, $user, $request);
if ($allows === null) {
return false;
} else {
return $allows;
}
}
}
Estoy usando Yii2
y estoy utilizando sus comportamientos dentro de mis controladores.
Estoy construyendo mi propio sistema de permisos y debido a que los permisos son bastante complejos, necesito hacer uso de una coincidencia de llamada .
Aquí hay un ejemplo:
public function behaviors() {
return [
''access'' => [
''class'' => AccessControl::className(),
''only'' => [''view''],
''rules'' => [
[
''allow'' => true,
''actions'' => [''view''],
''matchCallback'' => function ($rule, $action) {
return Yii::$app->authManager->can($rule, $action);
}
],
// everything else is denied
],
],
];
}
Ahora, desafortunadamente, la forma en que funciona matchCallback
es devolviendo true
o false
si debe continuar ejecutando la regla, en lugar de poder devolver verdadero o falso de si están permitidos o no.
Por lo tanto, si devuelvo false
que no debe continuar (y por lo tanto, no los puedo permitir), no puedo personalizar el denyCallback
cuando abandona la ejecución de la regla.
¿De todos modos puedo personalizar el denyCallback
incluso si devuelvo false
de matchCallback
, o debo manejar mi situación de una manera diferente?
Bueno ... usando Yii::$app->authManager->checkAccess($uerId,$permissionName,$dataToPassInArray)
es bastante simple entonces. Si quieres iniciar sesión en la identificación del usuario actual, deberías obtener la instancia actual del usuario por Yii::$app->user->identity
first. Las propiedades de la instancia del usuario conectado dependen del modelo de usuario que utilice (por ejemplo, yii/web/User
u otras personalizadas).