Asp.net web api 从ASP.NET WebAPI 2中的标头和/或查询字符串中检索承载令牌 背景:

Asp.net web api 从ASP.NET WebAPI 2中的标头和/或查询字符串中检索承载令牌 背景:,asp.net-web-api,signalr,asp.net-identity,signalr-hub,Asp.net Web Api,Signalr,Asp.net Identity,Signalr Hub,我有一个ASP.NET WebAPI项目。我正在使用承载令牌来验证我的用户。我的一些控制器操作被标记为[Authorized]过滤器。在客户端,客户端通过调用http://foo.bar/Token然后将该令牌作为授权头添加到其请求中 到目前为止没有问题,在我的Startup.Auth.cs类中,所有设置都正常工作: OAuthOptions=新的OAuthorizationServerOptions { TokenEndpointPath=新路径字符串(“/Token”), Provider=

我有一个ASP.NET WebAPI项目。我正在使用承载令牌来验证我的用户。我的一些控制器操作被标记为
[Authorized]
过滤器。在客户端,客户端通过调用
http://foo.bar/Token
然后将该令牌作为
授权
头添加到其请求中

到目前为止没有问题,在我的
Startup.Auth.cs
类中,所有设置都正常工作:

OAuthOptions=新的OAuthorizationServerOptions
{
TokenEndpointPath=新路径字符串(“/Token”),
Provider=新的ApplicationAuthProvider(PublicClientId),
AuthorizeEndpointPath=新路径字符串(“/api/Account/ExternalLogin”),
AccessTokenExpireTimeSpan=TimeSpan.FromDays(14),
//在生产模式下,设置AllowInsecureHttp=false
AllowInsecureHttp=true
};
//使应用程序能够使用承载令牌对用户进行身份验证
应用程序使用OAuthBealerTokens(OAuthOptions);
现在,我已经在我的项目中添加了一些SignalR集线器,我还想对集线器中的用户进行身份验证。还有一些其他问题涉及到如何将客户机的承载令牌添加到信号器连接中。总结:

  • 一种方法是,由于以下事实,这是不鼓励的。因此,您可以回退到使用“长轮询”。(不是我想要的)
  • 另一种方法是。这种方法也不被鼓励,因为。但我仍然希望使用这种方法,因为我不希望长时间轮询
我尝试的是: 所以我创建了这个类来从查询字符串中检索我的访问令牌

公共类QueryStringOAuthBearerProvider:OAuthBeareAuthenticationProvider
{
公共覆盖任务RequestToken(OAuthRequestTokenContext上下文)
{
var value=context.Request.Query.Get(“访问令牌”);
如果(!string.IsNullOrEmpty(值))
{
context.Token=值;
}
返回Task.FromResult(空);
}
}
然后在客户端,我这样做是为了传递我的访问令牌:

var connection=$.hubConnection();
var hub=connection.createhubbroxy('fooHub');
connection.qs={'access_token':myAccessToken};
//初始化连接
这是我的想法,但是当我想在
Startup.Auth.cs
类中注册我的
querystringOAuthBearProvider
时,问题就出现了

下面是我如何更改Startup.Auth.cs类的:

OAuthOptions=新的OAuthorizationServerOptions
{
TokenEndpointPath=新路径字符串(“/Token”),
Provider=新的ApplicationAuthProvider(PublicClientId),
AuthorizeEndpointPath=新路径字符串(“/api/Account/ExternalLogin”),
AccessTokenExpireTimeSpan=TimeSpan.FromDays(14),
//在生产模式下,设置AllowInsecureHttp=false
AllowInsecureHttp=true
};
//使应用程序能够使用承载令牌对用户进行身份验证
应用程序使用OAuthBealerTokens(OAuthOptions);
//使应用程序能够从查询字符串中检索令牌以对用户进行身份验证
app.useAuthBeareAuthentication(新的OAuthBeareAuthenticationOptions()
{
Provider=newQueryStringOAuthBearProvider()
});
所以我想现在我可以用:

  • WebAPI调用请求标头中的默认承载令牌
  • my Signal集线器查询字符串中的自定义访问令牌
  • 结果: 当我连接到集线器时,我可以从查询字符串中检索访问令牌,并对用户进行身份验证。但当我试图调用WebAPI控制器操作时,我得到了
    System.invalidoOperationException
    ,表示
    序列包含多个元素。我想这是因为我注册了两种方法来通过承载令牌验证我的用户,而OWIN不喜欢这样

    问题: 如何使用这两种方法获取不记名令牌

    • WebApi调用的默认行为(授权标头)
    • querystringOAuthBearProvider(查询字符串),用于信号集线器集线器

    请注意,我不想将访问令牌作为查询字符串传递给我的WebApi操作,而只想传递给信号集线器。

    在盲目搜索答案时,我遇到了一个类似于我的问题的,一位名叫马哈茂德的人在评论中说:

    我发现了问题。不要使用
    app.useAuthBearTokens(OAuthOptions)
    apply
    app.useAuthAuthorizationServer(OAuthOptions)

    它在我的情况下起了作用,现在我可以使用这两种方法来获得持票人代币。这是我修改的
    Startup.Auth.cs
    类:

    OAuthOptions=新的OAuthorizationServerOptions
    {
    TokenEndpointPath=新路径字符串(“/Token”),
    Provider=新的ApplicationAuthProvider(PublicClientId),
    AuthorizeEndpointPath=新路径字符串(“/api/Account/ExternalLogin”),
    AccessTokenExpireTimeSpan=TimeSpan.FromDays(14),
    //在生产模式下,设置AllowInsecureHttp=false
    AllowInsecureHttp=true
    };
    //使应用程序能够使用承载令牌对用户进行身份验证
    //应用程序使用OAuthBealerTokens(OAuthOptions);//评论这行。
    app.useAuthAuthorizationServer(OAuthOptions);//增加了这一行
    //使应用程序能够从查询字符串中检索令牌以对用户进行身份验证
    app.useAuthBeareAuthentication(新的OAuthBeareAuthenticationOptions()
    {
    Provider=newQueryStringOAuthBearProvider()
    });
    
    我使用了逻辑,但在QueryStringOAuthBearProvider类中进行了一些更新,然后得到了正确的结果

    public class QueryStringOAuthBearerProvider : OAuthBearerAuthenticationProvider
    {
        public override Task RequestToken(OAuthRequestTokenContext context)
        {
            var value = context.Request.Query.Get("access_token");
    
            if (!string.IsNullOrEmpty(value))
            {
                context.Token = value;
            }
    
             return Task.FromResult<object>(context);
        }
    }
    
    公共类QueryStringOAuthBearerProvider:OAuthBeareAuthenticationProvider
    {
    公共覆盖任务RequestToken(OAuthRequestTokenContext上下文)
    {
    var value=context.Request.Query.Get(“访问令牌”);
    如果(!string.IsNullOrEmpty(值))
    {
    context.Token=值;