方法: カスタム承認属性を作成する
ここでは、承認のためのカスタム属性を追加する方法について説明します。WCF RIA サービス フレームワークには、RequiresAuthenticationAttribute 属性と RequiresRoleAttribute 属性が用意されています。これらの属性を使用すると、認証されているユーザーまたは特定の役割が割り当てられているユーザーのみが使用できるドメイン操作を容易に指定できます。この 2 つの属性に加えて、カスタマイズされた承認ロジックを表す属性を作成し、ドメイン操作に適用することができます。
ドメイン サービスを公開すると、ネットワーク上のすべてのユーザーがそのドメイン サービスを利用できます。クライアント アプリケーションがドメイン サービスにアクセスする唯一のアプリケーションとは限りません。クライアント アプリケーションの外部からドメイン操作にアクセスされる場合でも、カスタマイズされた認証属性を使用して、ドメイン操作へのアクセスを制限できます。
ここでは、カスタマイズされたロジックを提供するために、AuthorizationAttribute から派生するクラスを作成し、IsAuthorized メソッドをオーバーライドして、カスタム承認属性を作成します。IPrincipal パラメーターと AuthorizationContext パラメーターを使用して、カスタマイズされた認証コード内で必要になる可能性がある情報にアクセスできます。AuthorizationContext オブジェクトは、クエリ操作では null になります。
カスタマイズされた承認属性を作成するには
サーバー プロジェクトで、AuthorizationAttribute から派生するクラスを作成します。
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."); } } }
カスタマイズされた承認ロジックを実行するには、ドメイン操作にカスタム承認属性を適用します。
次の例は、ドメイン操作に適用された
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); } }