代码之家  ›  专栏  ›  技术社区  ›  Steven B.

webapi2中依赖注入的服务授权

  •  2
  • Steven B.  · 技术社区  · 8 年前

    我有一个n层web api 2项目,其结构如下:

    1. Web层
    2. 服务/业务层
    3. 数据/存储库层

    web控制器使用Autofac注入了相应的服务,每个服务都注入了相应的存储库。这个很好用。

    public class OrderService : IOrderService
    {
        private readonly IOrderRepo _Repo;
        private readonly EnterpriseUser _EnterpriseUser;
    
        public OrderService(IOrderRepo repo, EnterpriseUser enterpriseUser)
        {
            this._Repo = repo;
            this._EnterpriseUser = enterpriseUser;
        }
        ....
    }
    

    我的问题出现在身份验证过程中。这个 EnterpriseUser 需要从当前 IIdentity .

    builder.Register(ctx =>
    {
        // Identity extension to retrieve claim from User
        var userLinkCode = ctx.Resolve<HttpContextBase>().User.Identity.GetUserLinkCode();
        // Retrieves a header from the request
        var partnerLinkCode = ctx.Resolve<ConnectionInfo>().PartnerLinkCode;
        return EnterpriseUser.Create(userLinkCode, partnerLinkCode);
    })
    .As<EnterpriseUser>()
    .InstancePerRequest();
    

    因此,当用户的令牌过期时,Autofac将抛出以下异常

    已注册以创建'LVV.Services.EnterpriseUser用户'返回null

    AuthorizeAttribute 永远无法拒绝 401 Unauthorized 因为控制器的构造函数在 授权属性 .

    可能是一种用 401 如果委托返回null?

    1 回复  |  直到 8 年前
        1
  •  2
  •   KozhevnikovDmitry    8 年前

    我建议实施 NullObject pattern AuthorizeAttribute 做好它的工作,不要把Autofac和constructor与原始空值混淆。我看不到你的全部代码,所以下面的例子只是这个想法的一个说明。假设我们扩展 EnterpriseUser

    public class EnterpriseUser
    {
        /// <summary>
        /// Always true for real user
        /// </summary>
        public virtual bool IsAuthentificated => true;
    
        public static EnterpriseUser Create(string userLinkCode, string partnerLinkCode)
        {
            if (string.IsNullOrEmpty(userLinkCode) ||
                string.IsNullOrEmpty(partnerLinkCode))
            {
                return new DummyEnterpriseUser();
            }
    
            // create true user here with usin link codes
            return new EnterpriseUser(userLinkCode, partnerLinkCode);
        }
    
        // Some usefull code here
    }
    
    
    /// <summary>
    /// NullObject implementation for <see cref="EnterpriseUser"/>
    /// </summary>
    public class DummyEnterpriseUser : EnterpriseUser
    {
        /// <summary>
        /// Always false for dummy user
        /// </summary>
        public override bool IsAuthentificated => false;
    
        public DummyEnterpriseUser()
        {
    
        }
    } 
    

    IsAuthentificated 为了以防万一,你可能不需要它。我还假设你的扩展方法 GetUserLinkCode 退货 null 如果是空的索赔。当然,最终的实现将取决于您的代码。

    推荐文章