共用方式為


HOW TO:建立自訂授權屬性

本主題將示範如何加入自訂授權屬性。WCF RIA Services 架構提供 RequiresAuthenticationAttributeRequiresRoleAttribute 屬性。這些屬性讓您可以很容易指定哪些網域作業只提供給已驗證的使用者或特定角色中的使用者。除了這兩個屬性外,您還可以建立代表自訂授權邏輯的屬性,然後該屬性套用至網域作業。

公開網域服務時,網域服務便可供網路上的每個人使用。您不能假設您的用戶端應用程式是唯一可存取網域服務的應用程式。但是您可以使用自訂驗證屬性來限制對網域作業的存取,即使網域作業是從用戶端應用程式外部存時。

在本主題中,您將建立衍生自 AuthorizationAttribute 的類別,並覆寫 IsAuthorized 方法以提供自訂邏輯,藉此建立自訂授權屬性。您可以使用 IPrincipal 參數和 AuthorizationContext 參數來存取自訂驗證程式碼中可能需要的資訊。AuthorizationContext 物件在查詢作業上為 null

建立自訂授權屬性

  1. 在伺服器專案中,建立衍生自 AuthorizationAttribute 的類別。

  2. 覆寫 IsAuthorized 方法並加入用於判斷授權的邏輯。

    下列範例示範名為 RestrictAccessToAssignedManagers 的自訂屬性,這個屬性會檢查已驗證的使用者是否為正被修改 EmployeePayHistory 記錄之員工的經理。

    Public Class RestrictAccessToAssignedManagers
        Inherits AuthorizationAttribute
    
        Protected Overrides Function IsAuthorized(ByVal principal As System.Security.Principal.IPrincipal, ByVal authorizationContext As System.ComponentModel.DataAnnotations.AuthorizationContext) As System.ComponentModel.DataAnnotations.AuthorizationResult
            Dim eph As EmployeePayHistory
            Dim selectedEmployee As Employee
            Dim authenticatedUser As Employee
    
            eph = CType(authorizationContext.Instance, EmployeePayHistory)
    
            Using context As New AdventureWorksEntities()
                selectedEmployee = context.Employees.SingleOrDefault(Function(e) e.EmployeeID = eph.EmployeeID)
                authenticatedUser = context.Employees.SingleOrDefault(Function(e) e.LoginID = principal.Identity.Name)
            End Using
    
            If (selectedEmployee.ManagerID = authenticatedUser.EmployeeID) Then
                Return AuthorizationResult.Allowed
            Else
                Return New AuthorizationResult("Only the authenticated manager for the employee can add a new record.")
            End If
        End Function
    End Class
    
    public class RestrictAccessToAssignedManagers : AuthorizationAttribute
    {
        protected override AuthorizationResult IsAuthorized(System.Security.Principal.IPrincipal principal, AuthorizationContext authorizationContext)
        {
            EmployeePayHistory eph = (EmployeePayHistory)authorizationContext.Instance;
            Employee selectedEmployee;
            Employee authenticatedUser;
    
            using (AdventureWorksEntities context = new AdventureWorksEntities())
            {
                selectedEmployee = context.Employees.SingleOrDefault(e => e.EmployeeID == eph.EmployeeID);
                authenticatedUser = context.Employees.SingleOrDefault(e => e.LoginID == principal.Identity.Name);
            }
    
            if (selectedEmployee.ManagerID == authenticatedUser.EmployeeID)
            {
                return AuthorizationResult.Allowed;
            }
            else
            {
                return new AuthorizationResult("Only the authenticated manager for the employee can add a new record.");
            }
        }
    }
    
  3. 若要執行自訂授權邏輯,請將自訂授權屬性套用至網域作業。

    下列範例示範套用至網域作業的 RestrictAccessToAssignedManagers 屬性。

    <RestrictAccessToAssignedManagers()> _
    Public Sub InsertEmployeePayHistory(ByVal employeePayHistory As EmployeePayHistory)
        If ((employeePayHistory.EntityState = EntityState.Detached) _
                    = False) Then
            Me.ObjectContext.ObjectStateManager.ChangeObjectState(employeePayHistory, EntityState.Added)
        Else
            Me.ObjectContext.EmployeePayHistories.AddObject(employeePayHistory)
        End If
    End Sub
    
    [RestrictAccessToAssignedManagers]
    public void InsertEmployeePayHistory(EmployeePayHistory employeePayHistory)
    {
        if ((employeePayHistory.EntityState != EntityState.Detached))
        {
            this.ObjectContext.ObjectStateManager.ChangeObjectState(employeePayHistory, EntityState.Added);
        }
        else
        {
            this.ObjectContext.EmployeePayHistories.AddObject(employeePayHistory);
        }
    }