2017-10-16 275 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