2017-10-16 274 views
0

我在使用OpenIddict的ASP.NET Core 2.0应用程序中使用JWT身份验证。如何授权使用JWT的SignalR Core Hub方法

我在this thread的想法如下,在SignalR握手后调用AuthorizeWithJWT方法。但是现在,我不知道我应该在AuthorizeWithJWT方法中设置什么,因此我可以使用[Authorize(Roles="Admin")]作为示例。

我试图设置情境的用户,但它是只读:

public class BaseHub : Hub 
{  
    public async Task AuthorizeWithJWT(string AccessToken) 
    { 
     //get user claims from AccesToken 
     this.Context.User = user; //error User is read only 
    } 
} 

而且使用授权属性:

public class VarDesignImportHub : BaseHub 
{ 
    [Authorize(Roles = "Admin")] 
    public async Task Import(string ConnectionString) 
    { 
    } 
} 

回答

2

我强烈建议你继续在握手级别执行身份验证,而不是去使用您在SignalR级别实现的定制和非标准解决方案。

假设你正在使用的验证处理程序,你可以迫使它从查询字符串检索访问令牌:

public void ConfigureServices(IServiceCollection services) 
{ 
    services.AddAuthentication() 
     .AddOAuthValidation(options => 
     { 
      options.Events.OnRetrieveToken = context => 
      { 
       context.Token = context.Request.Query["access_token"]; 

       return Task.CompletedTask; 
      }; 
     }); 
} 

或者OnMessageReceived如果你想使用JWTBearer

services.AddAuthentication() 
    .AddJwtBearer(o => 
    { 
     o.Events = new JwtBearerEvents() 
     { 
      OnMessageReceived = context => 
      { 
       if (context.Request.Path.ToString().StartsWith("/HUB/")) 
        context.Token = context.Request.Query["access_token"]; 
       return Task.CompletedTask; 
      }, 
     }; 
    }); 

不应该要求其他更改。

+0

是的,这将是一个有效的情况,但作为github线程([link1](https://github.com/aspnet/SignalR/issues/888#issuecomment-330727192),[link2](https:/ /github.com/aspnet/SignalR/issues/888#issuecomment-330721385))这种方法存在一些安全风险。因为查询中的access_token是公共的(你可以记录它...)。如果没有其他方法是可能的,将会这样做。 – Makla

+0

但一次访问令牌可以做到这一点? @Pinpoint你怎么看? – Makla

+0

唯一的“风险”是访问令牌将包含在日志中(这在OAuth2承载规范中有明确说明)。为了避免这种情况,可以使用过滤API禁用包括查询字符串的日志记录跟踪。 – Pinpoint