2017-05-31 4 views
3

HttpModuleを使用してカスタム認証と認証を行うアプリケーションを開発しています。私の問題は、HttpModuleで設定されたユーザーIDがSignalRコンテキストオブジェクトでアクセスできないことです。私はHttpModuleをBeginRequestイベントハンドラに次の操作を行いHttpModuleを使用してSignalRを認証することは可能です

は、カスタム認証ロジックの後:

var userClaims = new List<Claim>(); 
userClaims.Add(new Claim(ClaimTypes.NameIdentifier, <some id>)); 
userClaims.Add(new Claim(ClaimTypes.Name, <some name>)); 
userClaims.Add(new Claim(ClaimTypes.Email, <da email>)); 
userClaims.Add(new Claim(ClaimTypes.Authentication, "true")); 

var id = new ClaimsIdentity(userClaims); 
var principal = new ClaimsPrincipal(new[] { id }); 
Thread.CurrentPrincipal = principal; 
HttpContext.Current.User = principal; 

私は、これは絶対に要求が認証されたかのようにすべてが以下に動作するだろう、しかし、これはそうではないと思いました。

私はこのようになります認証を処理するためにSignalR AuthorizeAttributeクラスを作成しました:

[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)] 
public class CustomAuthAttribute : AuthorizeAttribute 
{ 
    public override bool AuthorizeHubConnection(HubDescriptor hubDescriptor, IRequest request) 
    { 
     if (HttpContext.Current.Request.Path.StartsWith("/signalr/connect")) 
     { 
      var test = (ClaimsPrincipal)HttpContext.Current.User; 
      var test2 = (ClaimsPrincipal)Thread.Current.Principal; 
     } 

     return true; 
    } 

    public override bool AuthorizeHubMethodInvocation(IHubIncomingInvokerContext hubContext, bool appliesToMethod) 
    { 
     var test = (ClaimsPrincipal)hubContext.Hub.Context.User; 
     return true; 
    } 
} 

だから私の計画はいずれかを行うためにAuthorizeHubMethodInvocationメソッド内からhubContext.Hub.Context.UserのVARにアクセスすることでしたカスタム認可が必要でした。ただし、これにはデフォルトのWindowsPrincipalが含まれています。

AuthorizeHubConnection呼び出し(実際には通常のHTTP要求でwebsocket呼び出しではない)を調べると、HttpContext.Currentオブジェクトにはユーザーが設定したとおりに設定されていないことがわかります。

私はHttpContext.Current.Itemsコレクションにアクセスできることがわかります。私はこれを使って、モジュールからPrincetをSignalRコンテキストに投げることができたと思いますが、それが私がするべきことではないかと思います。

HttpModuleをOWINミドルウェアとして書き直すのが最も簡単ですか?とにかく/私たちがASP.NET 5に更新すると、私はものを変更しなければならないようです。あなたに雇用保障を与えるMS製品のようなものはありません。

答えて

2

私はこの質問を少し前に投稿しました。私は、MS記事Authentication and Authorization for SignalR Hubsに関するコメントで私の解答を説明しました。 auth用のOWINミドルウェアを実装しようとした後、すべての要求に対してすべてのモジュールを実行するためにいくつかのgoofy設定を行う必要があることがわかりましたが、これは非効率的です。私はすべての要求に対してAuth OWINミドルウェアコンポーネントを実行する方法を理解できなかったので、私はそのアプローチを断念し、私のHttpModuleに固執しました。上記のリンク先のページに掲載ここSignalRの認証のための私の解決策の概要は次のとおりです。)

1記事に示されているようAuthorizeAttributeクラスを作成します。

[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)] 
public class CustomAuthAttribute : AuthorizeAttribute 

2)認証クラスを使用してハブクラスを飾りますあなたは作成しました。命名規則は、(SomeName)Authクラス自体の属性とハブデコレーションの(SomeName)のように見えます。

[CustomAuth] 
public class ServerWebSocket : Hub 

3)の代わりにドキュメントのように「UserAuthorized」メソッドをオーバーライドする、(私はいくつかの他のSOポストからこれを得たが、私は今それを見つけることができません)、次のメソッドをオーバーライドします。

これは、実際にそう股関節に設定されている

if (req.Path.StartsWith("/signalr/connect") || req.Path.StartsWith("/signalr/reconnect")) 
{ 
    var user_info = doFullAuth(<some token>); 
    HttpContext.Current.Items.Add("userDat", user_info); 
} 

:実際に私のHttpModuleをして、私はSignalRの接続要求をキャッチし、ユーザーを承認し、そのようにいるHttpContext Itemsコレクション内の項目を設定するために

public override bool AuthorizeHubConnection(HubDescriptor hubDescriptor, IRequest request) 
public override bool AuthorizeHubMethodInvocation(IHubIncomingInvokerContext hubContext, bool appliesToMethod) 

ユーザーに許可がない場合、HttpModuleで接続要求が完全に拒否されます。だから私は実際には、SignalRのauthメソッド "AuthorizeHubConnection"を実装していません。しかし、 "AuthorizeHubMethodInvocation"メソッドでは、元の接続要求で設定されたHttpContext.Current.Itemsを呼び出してユーザーデータにアクセスし、ユーザーがメソッドにアクセスできるかどうかを判断するカスタムロジックを実行します。

これは、静的ファイルなどを保護するためのすべての要求を認証したい場合には、これを動作させるための最良の方法です。

関連する問題