現在ログインしているユーザーがコントローラーのアクションにアクセスできることを確認できるコンポーネントがあります。
public class ControllerAccessChecker : IControllerAccessChecker
{
ILifetimeScope _scope;
public ControllerAccessChecker(ILifetimeScope scope)
{
_scope = scope;
}
public bool IsAccessible<TController>(Expression<Action<TController>> action, RequestContext requestContext) where TController : Controller
{
var actionName = GetActionName(action);
var result = false;
using (var childScope = _scope.BeginLifetimeScope())
{
var controller = childScope.Resolve<TController>();
result = HasActionPermission(requestContext, actionName, controller);
}
return result;
}
private static string GetActionName(LambdaExpression actionExpression)
{
object operand;
if (actionExpression.Body as UnaryExpression != null)
{
operand = ((UnaryExpression)actionExpression.Body).Operand;
}
else
{
operand = actionExpression.Body;
}
MethodCallExpression methodCallExpression = (MethodCallExpression)operand;
return methodCallExpression.Method.Name;
}
private static bool HasActionPermission(RequestContext requestContext, string actionName, ControllerBase controller)
{
var controllerContext = new ControllerContext(requestContext, controller);
var controllerDescriptor = new ReflectedControllerDescriptor(controller.GetType());
var actionDescriptor = controllerDescriptor.FindAction(controllerContext, actionName);
return ActionIsAuthorized(controllerContext, actionDescriptor);
}
private static bool ActionIsAuthorized(ControllerContext controllerContext, ActionDescriptor actionDescriptor)
{
if (actionDescriptor == null)
return false;
AuthorizationContext authContext = new AuthorizationContext(controllerContext, actionDescriptor);
foreach (Filter authFilter in FilterProviders.Providers.GetFilters(controllerContext, actionDescriptor).Where(x => x.Instance is IAuthorizationFilter))
{
((IAuthorizationFilter)authFilter.Instance).OnAuthorization(authContext);
if (authContext.Result != null)
return false;
}
return true;
}
}
ご覧のとおりILifetimeScope
、コンストラクターに注入していますが、これが良い方法かどうかはわかりません。また、メソッド内で正しいことを行っているかどうかもわかりませんIsAccessible
。この Autofac のスコープ階層アプローチは、私にとって本当に混乱を招きます。
コントローラー用のある種の抽象ファクトリについて考えていましたが、Autofac で実装するのは簡単ではないようです。IIndex<,>
ここで、使用と登録に関する記事と回答をいくつか見つけまし.Keyed()
たが、このような場合に実際に使用する必要があるとは思いません。つまり、必要なタイプを知っているので、それを求めるだけで簡単になるはずです。