SignalR ハブの認証と承認Authentication and Authorization for SignalR Hubs

によってPatrick FletcherTom FitzMackenby Patrick Fletcher, Tom FitzMacken

Warning

このドキュメントは SignalR の最新バージョンはありません。This documentation isn't for the latest version of SignalR. 見てASP.NET Core SignalRします。Take a look at ASP.NET Core SignalR.

このトピックでは、どのユーザーまたはロールがハブ メソッドにアクセスできる制限する方法について説明します。This topic describes how to restrict which users or roles can access hub methods.

このトピックで使用されるソフトウェアのバージョンSoftware versions used in this topic

このトピックの以前のバージョンPrevious versions of this topic

SignalR の以前のバージョンについては、次を参照してください。以前のバージョンの SignalRします。For information about earlier versions of SignalR, see SignalR Older Versions.

意見やご質問Questions and comments

このチュートリアルの良い点に関するフィードバックや、ページ下部にあるコメントで改善できる点をお知らせください。Please leave feedback on how you liked this tutorial and what we could improve in the comments at the bottom of the page. チュートリアルに直接関係のない質問がある場合は、ASP.NET SignalR フォーラムまたはStackOverflow.comにて投稿してください。If you have questions that are not directly related to the tutorial, you can post them to the ASP.NET SignalR forum or StackOverflow.com.

概要Overview

このトピックは、次のセクションで構成されています。This topic contains the following sections:

属性を承認します。Authorize attribute

SignalR の提供、 Authorizeハブまたはメソッドへのアクセスを持つユーザーまたはロールを指定する属性。SignalR provides the Authorize attribute to specify which users or roles have access to a hub or method. この属性にある、Microsoft.AspNet.SignalR名前空間。This attribute is located in the Microsoft.AspNet.SignalR namespace. 適用する、Authorize属性をハブまたはハブ内の特定のメソッドのいずれか。You apply the Authorize attribute to either a hub or particular methods in a hub. 適用すると、 Authorize hub クラスでは、指定された承認要件を属性のすべてのハブ メソッドに適用されます。When you apply the Authorize attribute to a hub class, the specified authorization requirement is applied to all of the methods in the hub. このトピックでは、適用できる承認要件のさまざまな種類の例を示します。This topic provides examples of the different types of authorization requirements that you can apply. なし、Authorize属性は、接続されたクライアントがハブのすべてのパブリック メソッドにアクセスできます。Without the Authorize attribute, a connected client can access any public method on the hub.

Web アプリケーションで"Admin"をという名前のロールを定義している場合は、次のコードでのハブをそのロール内のユーザーのみがアクセスできることを指定できます。If you have defined a role named "Admin" in your web application, you could specify that only users in that role can access a hub with the following code.

[Authorize(Roles = "Admin")] 
public class AdminAuthHub : Hub 
{ 
}

または、すべてのユーザーに提供される 1 つのメソッドと 2 番目のメソッドのみが利用できる認証されたユーザーは、次に示すようにハブが含まれているを指定することができます。Or, you can specify that a hub contains one method that is available to all users, and a second method that is only available to authenticated users, as shown below.

public class SampleHub : Hub 
{ 
    public void UnrestrictedSend(string message){ . . . } 

    [Authorize] 
    public void AuthenticatedSend(string message){ . . . } 
}

次の例は、さまざまな承認シナリオに対処します。The following examples address different authorization scenarios:

  • [Authorize] -認証されたユーザーのみ[Authorize] – only authenticated users
  • [Authorize(Roles = "Admin,Manager")] – 指定したロールのユーザーを認証されたのみ[Authorize(Roles = "Admin,Manager")] – only authenticated users in the specified roles
  • [Authorize(Users = "user1,user2")] – 指定されたユーザー名を持つユーザーを認証されたのみ[Authorize(Users = "user1,user2")] – only authenticated users with the specified user names
  • [Authorize(RequireOutgoing=false)] – だけで認証されたユーザーは、ハブで呼び出すことができますが、サーバーからクライアントに返送の呼び出しによる制限はありません、承認など、特定のユーザーだけがメッセージを送信できますが、他のすべてのユーザー メッセージが表示されることができます。[Authorize(RequireOutgoing=false)] – only authenticated users can invoke the hub, but calls from the server back to clients are not limited by authorization, such as, when only certain users can send a message but all others can receive the message. RequireOutgoing プロパティは、ハブ内の個人メソッドではなく、全体のハブにのみ適用できます。The RequireOutgoing property can only be applied to the entire hub, not on individuals methods within the hub. RequireOutgoing が false に設定されていない場合は、サーバーから承認要件を満たすユーザーのみが呼び出されます。When RequireOutgoing is not set to false, only users that meet the authorization requirement are called from the server.

すべてのハブの認証が必要です。Require authentication for all hubs

アプリケーションで呼び出すことによってすべてのハブおよびハブ メソッドの認証を要求できます、 RequireAuthenticationメソッド、アプリケーションの起動時にします。You can require authentication for all hubs and hub methods in your application by calling the RequireAuthentication method when the application starts. 複数のハブおよびすべての認証の要件を適用するした場合、このメソッドを使用する場合があります。You might use this method when you have multiple hubs and want to enforce an authentication requirement for all of them. この方法では、ロール、ユーザー、または送信の承認の要件を指定できません。With this method, you cannot specify requirements for role, user, or outgoing authorization. ハブ メソッドへのアクセスが認証されたユーザーに制限のみ指定することができます。You can only specify that access to the hub methods is restricted to authenticated users. ただし、ハブまたはその他の要件を指定するメソッドに、Authorize 属性を適用できます。However, you can still apply the Authorize attribute to hubs or methods to specify additional requirements. 属性で指定したすべての要件は、認証の基本的な要件に追加されます。Any requirement you specify in an attribute is added to the basic requirement of authentication.

次の例では、すべてのハブ メソッドを認証されたユーザーに制限するスタートアップ ファイルを示します。The following example shows a Startup file which restricts all hub methods to authenticated users.

public partial class Startup {
    public void Configuration(IAppBuilder app) {
        app.MapSignalR();
        GlobalHost.HubPipeline.RequireAuthentication();
    }
}

呼び出す場合、RequireAuthentication()メソッド SignalR 要求の処理が完了したら、SignalR がスローされます、InvalidOperationException例外。If you call the RequireAuthentication() method after a SignalR request has been processed, SignalR will throw a InvalidOperationException exception. SignalR は、パイプラインが呼び出された後、モジュールを HubPipeline に追加することはできませんので、この例外をスローします。SignalR throws this exception because you cannot add a module to the HubPipeline after the pipeline has been invoked. 前の例では、呼び出しを示しています、RequireAuthenticationメソッドで、Configurationメソッドの最初の要求を処理する前に 1 回実行されます。The previous example shows calling the RequireAuthentication method in the Configuration method which is executed one time prior to handling the first request.

カスタマイズされた承認Customized authorization

派生したクラスを作成するには承認を決定する方法をカスタマイズする必要がある場合AuthorizeAttributeをオーバーライドし、 UserAuthorizedメソッド。If you need to customize how authorization is determined, you can create a class that derives from AuthorizeAttribute and override the UserAuthorized method. 要求ごとには、SignalR は、ユーザーに承認要求を完了するかどうかを判断するには、このメソッドを呼び出します。For each request, SignalR invokes this method to determine whether the user is authorized to complete the request. オーバーライドされたメソッドで、承認のシナリオに必要なロジックを提供します。In the overridden method, you provide the necessary logic for your authorization scenario. 次の例では、クレーム ベース id 経由で認証を実行する方法を示します。The following example shows how to enforce authorization through claims-based identity.

[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
public class AuthorizeClaimsAttribute : AuthorizeAttribute
{
    protected override bool UserAuthorized(System.Security.Principal.IPrincipal user)
    {
        if (user == null)
        {
            throw new ArgumentNullException("user");
        }

        var principal = user as ClaimsPrincipal;

        if (principal != null)
        {
            Claim authenticated = principal.FindFirst(ClaimTypes.Authentication);
            if (authenticated != null && authenticated.Value == "true")
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        else
        {
            return false;
        }
    }
}

クライアントに認証情報を渡すPass authentication information to clients

クライアントで実行されるコードで認証情報を使用する必要があります。You may need to use authentication information in the code that runs on the client. クライアントでメソッドの呼び出し時に、必要な情報を渡します。You pass the required information when calling the methods on the client. たとえば、チャット アプリケーションの方法でしたをパラメーターとして渡す、メッセージを投稿する人のユーザー名次に示すよう。For example, a chat application method could pass as a parameter the user name of the person posting a message, as shown below.

public Task SendChatMessage(string message)
{
    string name;
    var user = Context.User;

    if (user.Identity.IsAuthenticated)
    {
        name = user.Identity.Name;
    }
    else
    {
        name = "anonymous";
    }
    return Clients.All.addMessageToPage(name, message);
}

または、次に示すように認証情報を表し、そのオブジェクトをパラメーターとして渡すオブジェクトを作成することができます。Or, you can create an object to represent the authentication information and pass that object as a parameter, as shown below.

public class SampleHub : Hub
{
    public override Task OnConnected()
    {
        return Clients.All.joined(GetAuthInfo());
    }

    protected object GetAuthInfo()
    {
        var user = Context.User;
        return new
        {
            IsAuthenticated = user.Identity.IsAuthenticated,
            IsAdmin = user.IsInRole("Admin"),
            UserName = user.Identity.Name
        };
    }
}

悪意のあるユーザーがそのクライアントからの要求を模倣するために使用できますよう他のクライアントに 1 つのクライアント接続 id を渡してください。You should never pass one client's connection id to other clients, as a malicious user could use it to mimic a request from that client.

.NET クライアントの認証オプションAuthentication options for .NET clients

認証されたユーザーを制限するハブとの対話、により、コンソール アプリなどの .NET クライアントがある場合は、cookie、connection ヘッダー。 または、証明書で認証資格情報を渡すことができます。When you have a .NET client, such as a console app, which interacts with a hub that is limited to authenticated users, you can pass the authentication credentials in a cookie, the connection header, or a certificate. このセクションの例では、ユーザーを認証するため、これらのさまざまなメソッドを使用する方法を示します。The examples in this section show how to use those different methods for authenticating a user. 完全に機能する SignalR アプリケーションではありません。They are not fully-functional SignalR apps. SignalR を使って .NET クライアントの詳細については、次を参照してください。ハブ API ガイド - .NET クライアントします。For more information about .NET clients with SignalR, see Hubs API Guide - .NET Client.

ASP.NET フォーム認証を使用するハブを操作すると、.NET クライアント、接続の認証クッキーを手動で設定する必要があります。When your .NET client interacts with a hub that uses ASP.NET Forms Authentication, you will need to manually set the authentication cookie on the connection. Cookie を追加する、CookieContainerプロパティをHubConnectionオブジェクト。You add the cookie to the CookieContainer property on the HubConnection object. 次の例では、web ページから、認証 cookie を取得し、接続をそのクッキーを追加します。 コンソール アプリを示します。The following example shows a console app that retrieves an authentication cookie from a web page and adds that cookie to the connection.

class Program
{
    static void Main(string[] args)
    {
        var connection = new HubConnection("http://www.contoso.com/");
        Cookie returnedCookie;

        Console.Write("Enter user name: ");
        string username = Console.ReadLine();

        Console.Write("Enter password: ");
        string password = Console.ReadLine();

        var authResult = AuthenticateUser(username, password, out returnedCookie);

        if (authResult)
        {
            connection.CookieContainer = new CookieContainer();
            connection.CookieContainer.Add(returnedCookie);
            Console.WriteLine("Welcome " + username);
        }
        else
        {
            Console.WriteLine("Login failed");
        }    
    }

    private static bool AuthenticateUser(string user, string password, out Cookie authCookie)
    {
        var request = WebRequest.Create("https://www.contoso.com/RemoteLogin") as HttpWebRequest;
        request.Method = "POST";
        request.ContentType = "application/x-www-form-urlencoded";
        request.CookieContainer = new CookieContainer();

        var authCredentials = "UserName=" + user + "&Password=" + password;
        byte[] bytes = System.Text.Encoding.UTF8.GetBytes(authCredentials);
        request.ContentLength = bytes.Length;
        using (var requestStream = request.GetRequestStream())
        {
            requestStream.Write(bytes, 0, bytes.Length);
        }

        using (var response = request.GetResponse() as HttpWebResponse)
        {
            authCookie = response.Cookies[FormsAuthentication.FormsCookieName];
        }

        if (authCookie != null)
        {
            return true;
        }
        else
        {
            return false;
        }
    }
}

コンソール アプリに資格情報を投稿するwww.contoso.com/RemoteLogin次のコード ビハインド ファイルを含む空のページを参照する可能性があります。The console app posts the credentials to www.contoso.com/RemoteLogin which could refer to an empty page that contains the following code-behind file.

using System;
using System.Web.Security;

namespace SignalRWithConsoleChat
{
    public partial class RemoteLogin : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            string username = Request["UserName"];
            string password = Request["Password"];
            bool result = Membership.ValidateUser(username, password);
            if (result)
            {
                FormsAuthentication.SetAuthCookie(username, false);
            }
        }
    }
}

Windows 認証Windows authentication

Windows 認証を使用する場合を使用して現在のユーザーの資格情報を渡すことができます、される DefaultCredentialsプロパティ。When using Windows authentication, you can pass the current user's credentials by using the DefaultCredentials property. される DefaultCredentials の値には、接続の資格情報を設定します。You set the credentials for the connection to the value of the DefaultCredentials.

class Program
{
    static void Main(string[] args)
    {
        var connection = new HubConnection("http://www.contoso.com/");
        connection.Credentials = CredentialCache.DefaultCredentials;
        connection.Start().Wait();
    }
}

接続ヘッダーConnection header

アプリケーションが cookie を使用していない場合は、ユーザー情報を接続ヘッダーで渡すことができます。If your application is not using cookies, you can pass user information in the connection header. たとえば、接続ヘッダーでトークンを渡すことができます。For example, you can pass a token in the connection header.

class Program
{
    static void Main(string[] args)
    {
        var connection = new HubConnection("http://www.contoso.com/");
        connection.Headers.Add("myauthtoken", /* token data */);
        connection.Start().Wait();
    }
}

次に、ハブでは、ユーザーのトークンを確認します。Then, in the hub, you would verify the user's token.

証明書Certificate

ユーザーを確認するクライアント証明書を渡すことができます。You can pass a client certificate to verify the user. 接続を作成するときに、証明書を追加します。You add the certificate when creating the connection. 次の例では、接続にクライアント証明書を追加する方法のみを示しています。完全なコンソール アプリは表示されません。The following example shows only how to add a client certificate to the connection; it does not show the full console app. 使用して、 X509Certificateクラス、証明書を作成するいくつかの方法を提供します。It uses the X509Certificate class which provides several different ways to create the certificate.

class Program
{
    static void Main(string[] args)
    {
        var connection = new HubConnection("http://www.contoso.com/");
        connection.AddClientCertificate(X509Certificate.CreateFromCertFile("MyCert.cer"));
        connection.Start().Wait();
    }
}