tea*_*ime 5 c# iprincipal claims simple-injector asp.net-web-api2
基本上我正在尝试获取当前访问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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
样品控制器:
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;
}
}
}
Run Code Online (Sandbox Code Playgroud)
示例控制器显示注入的主体未经过身份验证,但本地ApiController.User主体是并包含用户角色.在上面的示例中,角色始终从路径"From ApiController.User"返回.
有人知道为什么从简单的注入器获取Thread.CurrentPrincipal时索赔不可用吗?
干杯
编辑:在这里添加了人为的示例解决方案,显示IPrincipal没有注入角色详细信息,但本地ApiController用户主体执行:http://www.filedropper.com/principalinjector
进一步编辑:内联更新的示例代码
更多信息:
如果我修改容器以使用延迟加载,我可以从注入器获取主体...
集装箱变更:
container.RegisterWebApiRequest<Lazy<IPrincipal>>(() => new Lazy<IPrincipal>(() => Thread.CurrentPrincipal));
Run Code Online (Sandbox Code Playgroud)
控制器更改:
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");
}
...
Run Code Online (Sandbox Code Playgroud)