次の方法で共有


認証、ロール、およびプロファイル

ユーザーの資格情報の検証、特定の操作に対するアクセスの制限、またはクライアント プロジェクトからの各ユーザーのプロパティの保持を実行する場合は、WCF RIA サービス ソリューションに認証ドメイン サービスを追加します。従来の ASP.NET Web アプリケーションでは、ASP.NET メンバーシップ フレームワークを使用してこれらの機能を実行できます。RIA サービス は、認証ドメイン サービスを介してメンバーシップ フレームワークをリッチ インターネット クライアントに公開することで、ASP.NET メンバーシップ フレームワークに基づいて作成されます。認証ドメイン サービスを追加すると、次の機能を有効にできます。

  • 認証 - ユーザーの資格情報を検証し、ユーザーをログイン済みまたはログアウト済みとしてマークします。

  • ロール - ユーザーを役割別にグループ化し、グループの認証済みメンバーにリソースへのアクセス許可を付与します。

  • プロファイル - 認証済みユーザーのプロパティを保持し、アプリケーションでそのプロパティを取得します。

ここでは、RIA Services ソリューションで認証、ロール、およびプロファイルを使用する方法について説明します。

認証 DomainService

RIA サービス には、プレゼンテーション層の認証、ロール、およびプロファイルへのアクセスを容易にする認証 DomainService テンプレートが用意されています。認証ドメイン サービスを作成するには、サーバー プロジェクトに新しい項目を作成し、項目の作成時に認証 DomainService テンプレートを選択します。

RIA_ServicesAddAuth

認証ドメイン サービスを追加すると、RIA Services フレームワークによって 2 つのクラスが自動的にサーバー プロジェクトに追加されます。認証サービスを表すクラスは、AuthenticationBase クラスから派生します。ユーザーを表すクラスは、UserBase クラスから派生します。ユーザー クラスには、認証済みユーザーのプロファイル プロパティが含まれます。

ソリューションをビルドすると、RIA Services によって WebContext クラスが自動的にクライアント プロジェクト内に生成されます。WebContext クラスを使用すると、クライアント プロジェクトで認証ドメイン サービスおよびユーザーにアクセスできます。Current プロパティを使用して、WebContext の現在のインスタンスを取得します。WebContext クラスは WebContextBase から派生します。

RIA Services ソリューションに認証ドメイン サービスを追加する方法の例については、「チュートリアル: Silverlight ナビゲーション アプリケーションでの認証サービスの使用」を参照してください。

Silverlight ビジネス アプリケーションと認証

Silverlight ビジネス アプリケーション テンプレートを選択してソリューションを作成すると、認証ドメイン サービス、およびユーザーのログインと登録を管理するためのコントロールが自動的にソリューションに追加されます。ソリューションでは、既定で、フォーム認証が使用されますが、Windows 認証用にソリューションを簡単に構成することができます。ロールが有効になり、1 つのプロファイル プロパティが定義されます。Silverlight ビジネス アプリケーションに既定で含まれる認証機能の例と、フォーム認証から Windows 認証に構成を変更する方法の詳細については、「チュートリアル: Silverlight ビジネス アプリケーション テンプレートの使用」を参照してください。Silverlight ビジネス アプリケーションの既定の機能に基づいた例については、「チュートリアル: Silverlight ビジネス アプリケーションでの認証サービスの使用」を参照してください。

次の図は登録ウィンドウを示しています。これは、Silverlight ビジネス アプリケーションに含まれる既定の機能の 1 つです。

[登録] ダイアログ ボックス

認証

RIA Services には、ソリューションにフォーム認証または Windows 認証を簡単に実装できるクラスが用意されています。RIA Services ソリューションで認証を使用するには、サーバー プロジェクトおよびクライアント プロジェクトを認証用に構成する必要があります。詳細については、「方法: RIA Services で認証を有効にする」を参照してください。

サーバー プロジェクトとクライアント プロジェクトを構成した後、WebContext オブジェクトで Login メソッドを呼び出すことで、Silverlight アプリケーションからユーザーを非同期でログインします。Windows 認証を使用する場合または永続化された資格情報を持つユーザーを取得する場合は、Login メソッドを呼び出す必要はありません。代わりに、LoadUser メソッドを呼び出し、Windows 認証で認証されるユーザーを取得したり、永続化された資格情報を持つユーザーを読み込んだりします。

通常、次のメソッドとプロパティは、認証を実装したときにクライアント プロジェクトで使用されます。

メンバー 使用するコード 作業

Authentication

WebContext.Current.Authentication

認証サービスにアクセスします。

User

WebContext.Current.User

ユーザーの状態を含むオブジェクトにアクセスします。

Login

または

Login

または

Login

WebContext.Current.Authentication.Login(string, string)

または

WebContext.Current.Authentication.Login(LoginParameters)

または

WebContext.Current.Authentication.Login(LoginParameters, LoginOperation, object)

ユーザーの資格情報を非同期で検証します。

Logout

または

Logout

WebContext.Current.Authentication.Logout(boolean)

または

WebContext.Current.Authentication.Logout(LogoutOperation, object)

認証済みユーザーのログアウトを非同期で行います。

LoadUser

または

LoadUser

WebContext.Current.Authentication.LoadUser()

または

WebContext.Current.Authentication.LoadUser(LoadUserOperation, object)

認証済みユーザーの読み込み、ユーザー状態の更新、永続化されたユーザー認証の読み込み、または Windows 認証で使用するときにプリンシパル ユーザー プロジェクトを取得します。

次の例は、ログイン ボタンのイベント ハンドラーから Login メソッドを呼び出す方法を示しています。ログイン操作の結果に応答するコールバック メソッドが含まれています。

Private Sub LoginButton_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
    Dim lp As LoginParameters = New LoginParameters(UserName.Text, Password.Password)
    WebContext.Current.Authentication.Login(lp, AddressOf Me.LoginOperation_Completed, Nothing)
    LoginButton.IsEnabled = False
    LoginResult.Text = ""
End Sub

Private Sub LoginOperation_Completed(ByVal lo As LoginOperation)
    If (lo.HasError) Then
        LoginResult.Text = lo.Error.Message
        LoginResult.Visibility = System.Windows.Visibility.Visible
        lo.MarkErrorAsHandled()
    ElseIf (lo.LoginSuccess = False) Then
        LoginResult.Text = "Login failed. Please check user name and password."
        LoginResult.Visibility = System.Windows.Visibility.Visible
    ElseIf (lo.LoginSuccess = True) Then
        SetControlVisibility(True)
    End If
    LoginButton.IsEnabled = True
End Sub
private void LoginButton_Click(object sender, RoutedEventArgs e)
{
    LoginParameters lp = new LoginParameters(UserName.Text, Password.Password);
    WebContext.Current.Authentication.Login(lp, this.LoginOperation_Completed, null);
    LoginButton.IsEnabled = false;
    LoginResult.Text = "";
}

private void LoginOperation_Completed(LoginOperation lo)
{
    if (lo.HasError)
    {
        LoginResult.Text = lo.Error.Message;
        LoginResult.Visibility = System.Windows.Visibility.Visible;
        lo.MarkErrorAsHandled();
    }
    else if (lo.LoginSuccess == false)
    {
        LoginResult.Text = "Login failed. Please check user name and password.";
        LoginResult.Visibility = System.Windows.Visibility.Visible;
    }
    else if (lo.LoginSuccess == true)
    {
        SetControlVisibility(true);
    }
    LoginButton.IsEnabled = true;
}

ロール

認証を実装した後は、ロールを使用するようにソリューションを構成できます。ロールを使用して、ユーザーをグループに割り当てることができます。その後、そのロールのメンバーのみが特定のドメイン操作を利用できるように指定することができます。ドメイン操作へのアクセスを制限するには、RequiresRoleAttribute をそのドメイン操作に適用します。詳細については、「方法: RIA Services でロールを有効にする」を参照してください。

通常、次のメソッドとプロパティは、ロールを実装したときに使用されます。

メンバー 使用するコード 作業

Roles

WebContext.Current.User.Roles

ユーザーが割り当てられているロールにアクセスします。

IsInRole

WebContext.Current.User.IsInRole(string)

認証済みユーザーが指定されたロールのメンバーであるかどうかを確認します。

次の例は、Managers という名前のロールのメンバーにアクセスが制限されているドメイン操作を示します。

<RequiresRole("Managers")> _
Public Function GetCustomers() As IQueryable(Of Customer)
    Return Me.ObjectContext.Customers
End Function
[RequiresRole("Managers")]
public IQueryable<Customer> GetCustomers()
{
    return this.ObjectContext.Customers;
}

ユーザーが必要な資格情報を持っていない場合にドメイン操作を呼び出すと、ドメイン操作は例外を返します。ドメイン操作を呼び出す前に資格情報を確認することで、この状況を回避できます。次の例は、データを読み込む前にユーザーが必要なロールのメンバーであるかどうかを確認する方法を示しています。

Private Sub LoadRestrictedReports()
    Dim loadSales = context.Load(context.GetSalesOrderHeadersQuery().Take(numberOfRows))
    SalesOrdersGrid.ItemsSource = loadSales.Entities
    SalesOrdersGrid.Visibility = System.Windows.Visibility.Visible

    If (WebContext.Current.User.IsInRole("Managers")) Then
        Dim loadCustomers = context.Load(context.GetCustomersQuery().Take(numberOfRows))
        CustomersGrid.ItemsSource = loadCustomers.Entities
        CustomersGrid.Visibility = System.Windows.Visibility.Visible
    Else
        CustomersGrid.Visibility = System.Windows.Visibility.Collapsed
    End If
End Sub
private void LoadRestrictedReports()
{
    LoadOperation<SalesOrderHeader> loadSales = context.Load(context.GetSalesOrderHeadersQuery().Take(numberOfRows));
    SalesOrdersGrid.ItemsSource = loadSales.Entities;
    SalesOrdersGrid.Visibility = System.Windows.Visibility.Visible;

    if (WebContext.Current.User.IsInRole("Managers"))
    {
        LoadOperation<Customer> loadCustomers = context.Load(context.GetCustomersQuery().Take(numberOfRows));
        CustomersGrid.ItemsSource = loadCustomers.Entities;
        CustomersGrid.Visibility = System.Windows.Visibility.Visible;
    }
    else
    {
        CustomersGrid.Visibility = System.Windows.Visibility.Collapsed;
    }
}

プロファイル

プロファイル プロパティを使用すると、ユーザーに関する情報を保存できます。このプロパティを使用すると、ユーザーごとにアプリケーションをカスタマイズできます。ソリューションでプロファイルを使用するには、プロファイルのソリューションを構成する必要があります。詳細については、「方法: RIA Services でプロファイルを有効にする」を参照してください。

通常、次のメソッドとプロパティは、プロファイルを実装したときに使用されます。

メンバー 使用するコード 作業

User

WebContext.Current.User

User クラスに追加したすべてのプロパティを含むオブジェクト (User.PhoneNumber など) にアクセスします。

LoadUser

または

LoadUser

WebContext.Current.Authentication.LoadUser()

または

WebContext.Current.Authentication.LoadUser(LoadUserOperation, object)

ユーザーの状態を更新します。

SaveUser

または

SaveUser

WebContext.Current.Authentication.SaveUser(boolean)

または

WebContext.Current.Authentication.SaveUser(SaveUserOperation, object)

プロファイル プロパティ値を設定した後などに、ユーザー状態の変更を保存します。

次の例は、ユーザーが選択した値に基づいてユーザー プロパティを設定する方法を示しています。

Private Sub OKButton_Click(ByVal sender As Object, ByVal e As RoutedEventArgs) Handles OKButton.Click
    Dim newSelection = Integer.Parse(defaultRows.SelectionBoxItem.ToString())
    If (newSelection <> WebContext.Current.User.DefaultRows) Then
        WebContext.Current.User.DefaultRows = newSelection
        WebContext.Current.Authentication.SaveUser(True)
    End If
    Me.DialogResult = True
End Sub
private void OKButton_Click(object sender, RoutedEventArgs e)
{
    int newSelection = int.Parse(defaultRows.SelectionBoxItem.ToString());
    if (newSelection != WebContext.Current.User.DefaultRows)
    {
        WebContext.Current.User.DefaultRows = newSelection;
        WebContext.Current.Authentication.SaveUser(true);
    }
    this.DialogResult = true;
}

クライアントでの認証エラーの処理

コールバック メソッドを呼び出すときにそのメソッドをパラメーターとして指定することにより、ユーザーのログイン、ログアウト、読み込み、または保存を実行する際に発生するエラーを処理できます。コールバック メソッドで、エラーを処理するコードを追加し、MarkErrorAsHandled メソッドを呼び出して、フレームワークが例外をスローしないように指定します。AuthenticationService クラスを使用すると、次のメソッドを呼び出すときにコールバック メソッドを指定できます。

  • LoadUser

  • Login

  • Logout

  • SaveUser

前の「認証」セクションの例は、エラーを処理する Login 操作のコールバック メソッドを示しています。

詳細については、「クライアントでのエラー処理」を参照してください。

ドメイン サービスへのアクセスの制限

認証およびロールを実装した後、ドメイン サービスへのアクセスを特定のユーザーのみに制限できます。次の属性は、ドメイン サービス全体、またはサービスの個々の操作に適用します。サービス全体に適用した属性は、すべての操作に適用されます。

  • RequiresAuthenticationAttribute - 有効な認証資格情報を持つユーザーのみが操作にアクセスできるように指定します。

  • RequiresRoleAttribute - 指定されたロールに属する認証済みユーザーのみが操作にアクセスできるように指定します。

独自にカスタマイズした承認属性を作成することもできます。詳細については、「方法: カスタム承認属性を作成する」を参照してください。

3 つのドメイン操作を含むドメイン サービスを次の例に示します。RequiresAuthenticationAttribute 属性および RequiresRoleAttribute 属性は、アクセスを制限するために使用されます。GetProducts ドメイン操作は、すべてのユーザーが使用できます。GetSalesOrderHeaders は認証済みユーザー、GetCustomers は Managers ロールのユーザーのみが使用できます。

<EnableClientAccess()>  _
Public Class AdventureWorksDomainService
    Inherits LinqToEntitiesDomainService(Of AdventureWorksLT_DataEntities)

    <RequiresRole("Managers")> _
    Public Function GetCustomers() As IQueryable(Of Customer)
        Return Me.ObjectContext.Customers
    End Function
    
    Public Function GetProducts() As IQueryable(Of Product)
        Return Me.ObjectContext.Products
    End Function

    <RequiresAuthentication()> _
    Public Function GetSalesOrderHeaders() As IQueryable(Of SalesOrderHeader)
        Return Me.ObjectContext.SalesOrderHeaders
    End Function
End Class
[EnableClientAccess()]
public class AdventureWorksDomainService : LinqToEntitiesDomainService<AdventureWorksLT_DataEntities>
{
    [RequiresRole("Managers")]
    public IQueryable<Customer> GetCustomers()
    {
        return this.ObjectContext.Customers;
    }
 
    public IQueryable<Product> GetProducts()
    {
        return this.ObjectContext.Products;
    }

    [RequiresAuthentication()]
    public IQueryable<SalesOrderHeader> GetSalesOrderHeaders()
    {
        return this.ObjectContext.SalesOrderHeaders;
    }
}

参照

処理手順

チュートリアル: Silverlight ナビゲーション アプリケーションでの認証サービスの使用
チュートリアル: Silverlight ビジネス アプリケーションでの認証サービスの使用

概念

WCF RIA Services のセキュリティ