Authentication OAuth:ASP.NET Web API用户。标识不';t加载身份验证令牌提供程序设置的声明

Authentication OAuth:ASP.NET Web API用户。标识不';t加载身份验证令牌提供程序设置的声明,authentication,asp.net-web-api,oauth,castle-windsor,claims-based-identity,Authentication,Asp.net Web Api,Oauth,Castle Windsor,Claims Based Identity,我使用的是OAuth承载身份验证,在Startup.cs中配置如下: OAuthBearerAuthenticationOptions oAuthBearerOptions = new OAuthBearerAuthenticationOptions { AccessTokenProvider = new AccessTokenProvider(), Authenti

我使用的是OAuth承载身份验证,在Startup.cs中配置如下:

        OAuthBearerAuthenticationOptions oAuthBearerOptions = 
            new OAuthBearerAuthenticationOptions
            {
                AccessTokenProvider = new AccessTokenProvider(),
                AuthenticationMode = AuthenticationMode.Active
            };
        app.UseOAuthBearerAuthentication(oAuthBearerOptions);
。。。其中AccessTokenProvider实现为:

public class AccessTokenProvider : AuthenticationTokenProvider
{
    public override async Task ReceiveAsync(AuthenticationTokenReceiveContext context)
    {
        // Internal logic to get data needed for building identity...

        // Create claims identity
        ClaimsIdentity identity = new ClaimsIdentity(identityName);
        identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, nameIdentifier));
        // Add other claims

        // Set claims identity
        context.SetTicket(new AuthenticationTicket(identity, new AuthenticationProperties()));
    }
}
如果我在
ReceiveAsync
的末尾设置了一个断点,我可以验证标识是否正确构建(有声明),以及是否达到了
SetTicket

但当我尝试从Web API控制器访问标识时:

public abstract class BaseStorageController : ApiController
{
    protected IStorageService StorageService;

    protected BaseStorageController(IStorageServiceFactory storageServiceFactory)
    {
        StorageService = storageServiceFactory.CreateStorageService(User.Identity as ClaimsIdentity);
    }
}

。。。身份声明列表为空

这是什么原因造成的

旁注:我不知道这是否相关,但我使用Castle Windsor作为IOC容器将依赖项注入到我的控制器中(在上面的例子中,是IStorageServiceFactory)。在我添加之前,上面的内容似乎有效(声明不是空的)。但是,我没有使用CW来管理任何与身份验证相关的内容。以下是我的api控制器CW安装程序:

public class ApiControllerInstaller : IWindsorInstaller
{
    public void Install(IWindsorContainer container, IConfigurationStore store)
    {
        container.Register(Classes.FromThisAssembly().BasedOn<ApiController>().LifestylePerWebRequest());
    }
}
public类ApiControllerInstaller:IWindsorInstaller
{
public void安装(IWindsorContainer、IConfigurationStore)
{
Register(Classes.fromthissembly().BasedOn().LifestylePerWebRequest());
}
}

我找到了答案。这与依赖注入/控制反转无关。在添加之前,我不确定它是如何工作的

问题与此处描述的类似(但在我的情况下,解决方案不同):

基本上,
IPrincipal
无法从api控制器的构造函数访问,这就是为什么没有声明(用户尚未通过身份验证)<代码>用户。标识只能从控制器的操作中访问,而不能从构造函数中访问。为了解决这个问题,我将基本控制器实现更改为以下内容:

public abstract class BaseStorageController : ApiController
{
    private readonly IStorageServiceFactory _storageServiceFactory;
    private IStorageService _storageService;

    protected BaseStorageController(IStorageServiceFactory storageServiceFactory)
    {
        _storageServiceFactory = storageServiceFactory;
    }

    protected IStorageService StorageService
    {
        get
        {
            if (_storageService == null)
            {
                _storageService = _storageServiceFactory.CreateStorageService(User.Identity as ClaimsIdentity);
            }
            return _storageService;
        }
    }
}
由于
StorageService
只能通过控制器操作进行访问,
User.Identity
经过身份验证,并在调用
StorageService
getter时填充声明

希望这对别人有帮助

 protected IStorageService StorageService
{
    get
    {
        if (_storageService == null)
        {
            _storageService = _storageServiceFactory.CreateStorageService(User.Identity as ClaimsIdentity);
        }
        return _storageService;
    }
}
这不是实现DI的最佳方法

最好使用构造函数注入。 检查 如果您不熟悉Unity,请点击此链接,非常有用:


问候

谢谢!!!我整天都在讨论构造函数问题,并尝试了多种不同的authprovider实现。这就解决了这个问题。IPrincipal在web api控制器的构造函数中不可用,这意味着构造函数注入在这种情况下不起作用。