使用Simple Injector创建实例时,为什么Thread.CurrentPrincipal.Identity.IsAuthenticated为false

时间:2014-09-22 21:40:27

标签: c# asp.net-web-api2 simple-injector claims iprincipal

基本上我正在尝试获取当前访问Web Api的经过身份验证的用户(通过持有者令牌)的当前声明集;通过将当前主体注入到辅助类中,然后将其注入到注入ApiController的类中。

但是,返回的主体永远不是我想要的主体,因为它未经过身份验证且不包含任何声明。如果我在创建ApiController之后逐步执行它的构造函数,则正确设置本地ApiController.User主值。

以下是我创建并链接到下面的示例解决方案的一些代码......

集装箱登记:

namespace PrincipalInjector
{
    using System.Security.Principal;
    using System.Threading;
    using System.Web;
    using System.Web.Http;

    using SimpleInjector;
    using SimpleInjector.Integration.WebApi;

    public static class ContainerConfig
    {
        public static void Register(HttpConfiguration config)
        {
            Container container = new Container();
            InitializeContainer(container);
            container.RegisterWebApiControllers(config);
            container.Verify();
            config.DependencyResolver = new SimpleInjectorWebApiDependencyResolver(container);
        }

        private static void InitializeContainer(Container container)
        {
            container.RegisterWebApiRequest<IPrincipal>(() => 
                HttpContext.Current.User != null ? HttpContext.Current.User : Thread.CurrentPrincipal);
        }
    }
}

样本控制器:

namespace PrincipalInjector.Controllers
{
    using System.Collections.Generic;
    using System.Linq;
    using System.Security.Claims;
    using System.Security.Principal;
    using System.Web.Http;

    public class DefaultController : ApiController
    {
        private readonly IPrincipal principal;

        public DefaultController(IPrincipal principal)
        {
            this.principal = principal;
        }

        // GET api/default
        public IEnumerable<string> Get()
        {
            IList<string> roles = new List<string>();
            ClaimsIdentity claimsIdentity = null;

            if (this.principal.Identity.IsAuthenticated)
            {
                claimsIdentity = (ClaimsIdentity)this.principal.Identity;
                roles.Add("From injected principal");
            }
            else
            {
                claimsIdentity = (ClaimsIdentity)this.User.Identity;
                roles.Add("From ApiController.User");
            }

            if (claimsIdentity.Claims.Where(c => c.Type == ClaimTypes.Role.ToString()).Count() > 0)
            {
                roles = roles.Union(claimsIdentity.Claims.Where(c => c.Type == ClaimTypes.Role.ToString()).Select(c => c.Value)).ToList();                
            }
            else
            {
                roles.Add("No roles found");
            }

            return roles;
        }
    }
}

示例控制器显示注入的主体未经过身份验证,但本地ApiController.User主体是并包含用户角色。在上面的示例中,角色始终从路径“From ApiController.User”返回。

有没有人知道为什么从简单的注入器获取Thread.CurrentPrincipal时索赔不可用?

干杯

编辑:在此处添加了一个设计的示例解决方案,显示IPrincipal没有注入角色详细信息,但本地ApiController用户主体执行:http://www.filedropper.com/principalinjector

进一步修改:更新内联示例代码

更多信息

如果我修改容器以使用延迟加载,我可以从进样器中获取主体...

容器更换:

 container.RegisterWebApiRequest<Lazy<IPrincipal>>(() => new Lazy<IPrincipal>(() => Thread.CurrentPrincipal));

控制器更改:

        private readonly Lazy<IPrincipal> principal;

        public DefaultController(Lazy<IPrincipal> principal)
        {
            this.principal = principal;
        }

        ...

        if (this.principal.Value.Identity.IsAuthenticated)
        {
            claimsIdentity = (ClaimsIdentity)this.principal.Value.Identity;
            roles.Add("From injected principal");
        }

        ...

0 个答案:

没有答案