如何使用Autofac解析通用接口

时间:2014-06-19 02:32:24

标签: c# generics asp.net-mvc-5 inversion-of-control autofac

使用Autofac作为DI容器,我遇到了一个实现通用权限处理程序的问题,用于检查User / Principal是否可以访问特定实体。

权限服务使用以下通用接口:

public interface IClaimsPrincipalPermission<in TPrincipal, in TAction, in TResource> 
    where TPrincipal : AppUserPrincipal
    where TAction : BaseSecurity.Actions
    where TResource : BaseSecurity.Resources
{
    IdentityResult CheckAccess(SecurityAction secuirtyAction, TPrincipal principal, TAction action, TResource resource);
    IdentityResult CheckAccess(SecurityAction secuirtyAction, TPrincipal principal, TAction action, TResource resource, string id);
}

示例实现将是:

internal class FruitClaimsPrincipalPermission
    : IClaimsPrincipalPermission<AppUserPrincipal, UpdateAction, FruitResource>

{
    private readonly IFruitRepository _fruitRepository;

    public FruitClaimsPrincipalPermission(IFruitRepository fruitRepository)
    {
        if (fruitRepository == null)
            throw new ArgumentNullException("fruitRepository");
        _fruitRepository = fruitRepository;
    }

    #region Implementation of IClaimsPrincipalPermission<AppUserPrincipal, UpdateAction, FruitResource>
    public IdentityResult CheckAccess(System.Security.Permissions.SecurityAction secuirtyAction, AppUserPrincipal principal, CreateAction action, FruitResource resource) {
        if (principal == null || action == null || resource == null)
            throw new ArgumentNullException();

        if (!principal.Identity.IsAuthenticated)
            return IdentityResult.Failed(SecurityResouces.Requires_Authentication);

        if (!principal.IsSetupAdministrator)
            return IdentityResult.Failed(SecurityResouces.Requires_Setup_Admin_Role);

        return IdentityResult.Success;
    }

    public IdentityResult CheckAccess(System.Security.Permissions.SecurityAction secuirtyAction, AppUserPrincipal principal, CreateAction action, FruitResource resource, string id) {
        if (principal == null || action == null || resource == null)
            throw new ArgumentNullException();

        if (!principal.Identity.IsAuthenticated)
            return IdentityResult.Failed(SecurityResouces.Requires_Authentication);

        if (!principal.IsSetupAdministrator)
            return IdentityResult.Failed(SecurityResouces.Requires_Setup_Admin_Role);

        var fruit = _fruitRepository.GetById(id);

        if (fruit.AccountId != principal.AccountId)
            return IdentityResult.Failed(SecurityResouces.Owner_Account_User_Mismatch);

        return IdentityResult.Success;
    }
    #endregion
}

Web应用程序位于MVC 5和.Net 4.5中。我创建了一个自定义授权属性,用于装饰需要授权访问特定实体的任何控制器。 ResourceType ActionType 都是代表授权请求中的资源和操作的枚举。

public class ClaimsAuthorizeAttribute : AuthorizeAttribute
{
    private readonly ResourceType[] _resources;
    private readonly ActionType _action;

    public ClaimsAuthorizeAttribute(ActionType action, params ResourceType[] resources)
    {
        _resources = resources;
        _action = action;
    }

    protected override bool AuthorizeCore(System.Web.HttpContextBase httpContext)
    {
        var principal = new AppUserPrincipal(httpContext.User as ClaimsPrincipal);
        var action = ActionRepository.FindActions(_action);
        var resources = _resources.Select(ResourceRepository.FindResource).ToArray();
        return ClaimsAuthorization.CheckAccess(action, resources.First(), principal, "", out result);
    }

    public override void OnAuthorization(System.Web.Mvc.AuthorizationContext filterContext)
    {
        base.OnAuthorization(filterContext);
    }

}

ClaimsAuthorization 是ClaimsAuthorizationManager的子类,它实现了一个静态CheckAccess方法。

public class ClaimsAuthorization : ClaimsAuthorizationManager
{

    public static bool CheckAccess(Actions action, Resources resource, AppUserPrincipal principal, string entityId, out IdentityResult result)
    {
        result = DependencyResolver.Current.GetService<IPermissionExecutor>().CheckAccess(SecurityAction.Demand, principal, action, resource);
        return result.Succeeded;
    }
}

问题是我无法弄清楚如何从ClaimsAuthorization类中的静态CheckAccess方法调用 IClaimsPrincipalPermission 的正确实现。

我无法从控制器中找出如何将 IClaimsPrincipalPermission 的正确实例注入到ClaimsAuthorizeAttribute(研究让我相信它是不可能的),这似乎是我的唯一的选择是从ClaimsAthorization类中解析依赖项。因此,我尝试使用 DependencyResolver.Current.GetService 并创建实现 IPermissionExecutor PermissionExecutor 来解决依赖关系。为了不再延长这个问题,我不会在这里包括这些问题。解决这个问题的正确方法是什么?

0 个答案:

没有答案
相关问题