Share via


驗證、角色和設定檔

當您想要驗證使用者的認證、限制特定作業的存取或從用戶端專案保留每個使用者的屬性,就可以在 WCF RIA Services 方案中加入驗證 DomainService。在傳統 ASP.NET Web 應用程式中可以使用 ASP.NET 成員資格架構執行這些功能。RIA Services 是透過驗證 DomainService 向豐富網際網路用戶端公開成員資格架構,做為 ASP.NET 成員資格架構的建置基礎。加入驗證 DomainService 之後,可以啟用下列功能:

  • 驗證 - 驗證使用者的認證,並將使用者的認證標示為已登入或已登出。

  • 角色 - 依責任分組使用者,並授與資源權限給群組的已驗證的成員。

  • 設定檔 - 保留已驗證的使用者的屬性,並在應用程式中擷取那些屬性。

本主題將介紹如何在 RIA Services 方案中使用驗證、角色和設定檔。

驗證 DomainService

RIA Services 提供驗證 DomainService 範本,有助於在展示層存取驗證、角色和設定檔。若要建立驗證 DomainService,只需在伺服器專案中建立新項目,並在建立項目時選取驗證 DomainService 範本。

RIA_ServicesAddAuth

加入驗證 DomainService 時,RIA Services 架構會自動加入兩個類別至伺服器專案。一個類別表示驗證 DomainService 衍生自 AuthenticationBase 類別。另一個類別表示使用者衍生自 UserBase 類別。使用者類別包含已驗證的使用者的設定檔屬性。

建置方案時,RIA Services 會在用戶端專案中自動產生 WebContext 類別。WebContext 類別可讓您在用戶端專案中存取驗證 DomainService 和使用者。您可以使用 Current 屬性擷取 WebContext 的目前執行個體。WebContext 類別衍生自 WebContextBase

如需加入驗證 DomainService 至 RIA Services 方案的範例,請參閱逐步解說:搭配 Silverlight 瀏覽應用程式使用驗證服務

Silverlight 商務應用程式和驗證

當您選取 Silverlight 商務應用程式範本來建立方案時,該方案會自動包含驗證 DomainService 和控制項以管理使用者的登入與註冊。根據預設,方案會使用表單驗證,但您可以很容易將它設為使用 Windows 驗證。方案也會啟用角色並定義一個設定檔屬性。如需 Silverlight 商務應用程式預設包含的驗證功能,以及如何將組態從表單驗證變更為 Windows 驗證的範例,請參閱逐步解說:使用 Silverlight 商務應用程式範本。如需以 Silverlight 商務應用程式的預設功能做為建置基礎的範例,請參閱逐步解說:搭配 Silverlight 商務應用程式使用驗證服務

下圖顯示的註冊視窗是 Silverlight 商務應用程式中包含的其中一個預設功能。

登錄對話方塊

驗證

RIA Services 提供的類別可讓您很容易在方案中實作表單驗證或 Windows 驗證。若要在 RIA Services 方案中使用驗證,您必須將伺服器專案和用戶端專案設定為使用驗證。如需詳細資訊,請參閱 HOW TO:啟用 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 屬性套用至網域作業,即可限制存取該網域作業。如需詳細資訊,請參閱 HOW TO:啟用 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;
    }
}

設定檔

設定檔屬性可讓您儲存使用者的相關資訊。您可以使用這些屬性,為每個使用者自訂應用程式。若要在方案中使用設定檔,您必須將方案設定為使用設定檔。如需詳細資訊,請參閱 HOW TO:啟用 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 - 指定只有屬於指定之角色的已驗證的使用者才能存取作業。

您也可以自行建立自訂授權屬性。如需詳細資訊,請參閱 HOW TO:建立自訂授權屬性

下列範例示範有三個網域作業的網域服務。RequiresAuthenticationAttributeRequiresRoleAttribute 屬性用於限制存取。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 的安全性