5

基本認証を実装するServiceStackサービスをAsp.Net上に作成しました。サービスルートではすべてが正常に機能しています。ログインでき、後続の呼び出しで検証されるセッションCookieを取得します。これらのリクエストにはHttpClientを使用しています。

同じAsp.Netサービスで実行されるSignalRハブもありますが、プリンシパルがハブメソッドで認証されていません。

基本的に必要なのは、ServiceStackがハブへの呼び出しをインターセプトし、セッションCookieを検証し、Context.User.Identityにデータを入力して、認証済みとしてマークすることです。その設定ができれば、ハブの単純な[Authorize]属性が残りの作業を行います。

これが私のコードのサンプルです:

// set up a HttpClient with a cookie container to hold the session cookie
var cookieJar = new CookieContainer();
var handler = new HttpClientHandler { CookieContainer = cookieJar, UseCookies = true,  UseDefaultCredentials = false };

var client = new HttpClient(handler) { BaseAddress = _baseUri };

client.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Basic",
    Convert.ToBase64String(Encoding.ASCII.GetBytes(string.Format("{0}:{1}", userName, password))));

// do client login and get response with session cookie...
var response = client.PostAsync(...);

// add the cookies to the SignalR hub connection
var responseCookies = cookieJar.GetCookies(_baseUri);
var cookieContainer = new CookieContainer();
foreach (Cookie cookie in responseCookies)
{
   cookieContainer.Add(cookie);
}
_hubConnection = new HubConnection(_baseUri.ToString()) { CookieContainer = cookieContainer };

この設定後、セッションCookieは呼び出しごとにハブに送信されます。どういうわけか、ServiceStackがそれらの要求をインターセプトし、認証されたユーザーを設定する必要があります。

4

2 に答える 2

6

ServiceStackに認証を実行させ、ユーザーセッションを永続化します。次に、認証が必要なSignalRハブエンドポイントに次のコードを入力します。

var cache = AppHostBase.Resolve<ICacheClient>();
var sess = cache.SessionAs<AuthUserSession>();
if (!sess.IsAuthenticated)
    throw new AuthenticationException();
于 2013-02-08T08:01:01.553 に答える
2

Johanの答えは機能しますが、このコードをすべてのメソッドに配置するのはあまり便利ではありません。ハブコンストラクターに配置すると、「シングルトン経由でアクセス可能なASP.NET要求のみがサポートされます」という例外で、ページの更新時にWebで失敗します。

代わりに、ハブとメソッドの呼び出し認証をより細かく制御できるカスタム属性を作成することを選択しました。

最も単純な属性は次のようになります。

[AttributeUsage(AttributeTargets.Class, Inherited = false)]
public class AuthorizeServiceStack : AuthorizeAttribute
{
    public override bool AuthorizeHubConnection(HubDescriptor hubDescriptor, IRequest request)
    {
        return CheckAuthorization();
    }

    public override bool AuthorizeHubMethodInvocation(IHubIncomingInvokerContext hubIncomingInvokerContext, bool appliesToMethod)
    {
        return CheckAuthorization();
    }

    private static bool CheckAuthorization()
    {
        var cache = AppHostBase.Resolve<ICacheClient>();
        var sess = cache.SessionAs<AuthUserSession>();
        return sess.IsAuthenticated;
    }

}

ご覧のとおり、コードはJohanの回答と同じですが、Webでも機能し、cache.SessionAsを呼び出すときにHttpContext.Currentがnullにならないようにします。

于 2015-04-23T08:38:40.617 に答える