2016-04-05 12 views
0

私はカスタム属性を持っているが、アクセスを制御するためのリポジトリ方法をCRUDに適用される:CodeAccessSecurityAttribute派生クラス(タイプのロード中に障害が発生している)

Public Class SecureDbContextGenericRepository(Of TEntity As Class, TContext As DbContext) 
    Inherits DbContextGenericRepository(Of TEntity, TContext) 
    Public Sub New(connectionService As IConnectionService) 
    MyBase.New(connectionService) 
    End Sub 
    <EmployeeRoleRequirement(SecurityAction.Demand, EmployeeRoles:=EmployeeRoles.DataWriter)> 
    Public Overrides Sub Delete(ParamArray entities() As TEntity) 
    MyBase.Delete(entities) 
    End Sub 
    <EmployeeRoleRequirement(SecurityAction.Demand, EmployeeRoles:=EmployeeRoles.DataWriter)> 
    Public Overrides Sub Insert(ParamArray entities() As TEntity) 
    MyBase.Insert(entities) 
    End Sub 
    <EmployeeRoleRequirement(SecurityAction.Demand, EmployeeRoles:=EmployeeRoles.DataReader)> 
    Public Overrides Function [Select](Optional predicate As Func(Of TEntity, Boolean) = Nothing) As IList(Of TEntity) 
    Return MyBase.Select(predicate) 
    End Function 
    <EmployeeRoleRequirement(SecurityAction.Demand, EmployeeRoles:=EmployeeRoles.DataWriter)> 
    Public Overrides Sub Update(ParamArray entities() As TEntity) 
    MyBase.Update(entities) 
    End Sub 
End Class 

これは属性の実装です:

Public Class EmployeeRoleRequirementAttribute 
    Inherits CodeAccessSecurityAttribute 
    Public Sub New(action As SecurityAction) 
     MyBase.New(action) 
    End Sub 

    Public Overrides Function CreatePermission() As IPermission 
     Return New EmployeeRolePermission(_EmployeeRoles) 
    End Function 

    Public Property EmployeeRoles As EmployeeRoles 
    End Class 

<Flags> 
    Public Enum EmployeeRoles As Integer 
    DataReader = 0 
    DataWriter = 1 
    End Enum 

そして許可:

Public Class EmployeeRolePermission 
    Implements IPermission 
    Public Sub New(employeeRoles As EmployeeRoles) 
     _EmployeeRoles = employeeRoles 
    End Sub 

    Public Function Copy() As IPermission Implements IPermission.Copy 
     Return New EmployeeRolePermission(_EmployeeRoles) 
    End Function 
    Public Sub Demand() Implements IPermission.Demand 
     Dim principal = DirectCast(Thread.CurrentPrincipal, ProductionAssistantPrincipal) 
     If Not principal.IsInRole(_EmployeeRoles) Then 
     Throw New SecurityException(String.Format(My.Resources.EmployeeRoleNotFound, 
                principal.Identity.Name, 
                _EmployeeRoles.ToString())) 
     End If 
    End Sub 
    Public Sub FromXml(e As SecurityElement) Implements ISecurityEncodable.FromXml 
     Throw New NotImplementedException() 
    End Sub 
    Public Function Intersect(target As IPermission) As IPermission Implements IPermission.Intersect 
     Return New EmployeeRolePermission(_EmployeeRoles And DirectCast(target, EmployeeRolePermission).EmployeeRoles) 
    End Function 
    Public Function IsSubsetOf(target As IPermission) As Boolean Implements IPermission.IsSubsetOf 
     Return _EmployeeRoles.HasFlag(DirectCast(target, EmployeeRolePermission).EmployeeRoles) 
    End Function 
    Public Function ToXml() As SecurityElement Implements ISecurityEncodable.ToXml 
     Throw New NotImplementedException() 
    End Function 
    Public Function Union(target As IPermission) As IPermission Implements IPermission.Union 
     Return New EmployeeRolePermission(_EmployeeRoles Or DirectCast(target, EmployeeRolePermission).EmployeeRoles) 
    End Function 

    Public ReadOnly Property EmployeeRoles As EmployeeRoles 
    End Class 

たびの1 CRUDメソッドに達すると、TypeLoadExceptionがスローされます。私は本当にこれの原因を知っていませんが、私はCRUDメソッドから属性を削除すると、すべて正常に動作します。

答えて

1

これは属性の列挙型プロパティによるものです(詳細はhttps://connect.microsoft.com/VisualStudio/feedback/details/596251/custom-cas-attributes-with-an-enum-property-set-cause-a-typeloadexceptionを参照)。この問題を回避するには、属性で文字列値のプロパティを使用し、プロパティ設定ツールで列挙型にキャストするか、またはアクセス許可を作成する直前に実行します。 (個人的には早期の検証を可能にするために前者を選ぶかもしれませんが...)

+0

Visual Studioの開発チームは、実際遅らせるの束です。 6歳の問題はまだ解決されていません。 –

0

もう一つの回避策は、型の属性プロパティを作成することです。これはEnumで使用されます。この場合Integerです。

Public Class EmployeeRoleRequirementAttribute 
    Inherits CodeAccessSecurityAttribute 
    Public Sub New(action As SecurityAction) 
    MyBase.New(action) 
    End Sub 
    Public Overrides Function CreatePermission() As IPermission 
    Return New EmployeeRolePermission(CType(_RequiredEmployeeRoles, EmployeeRoles)) 
    End Function 

    Public Property RequiredEmployeeRoles As Integer 
End Class 

<Flags> 
Public Enum EmployeeRoles As Integer 
    DataReader = 0 
    DataWriter = 1 
End Enum 

その後、あなたは属性が使用されている場合、フラグの組み合わせは容易許可していない文字列を、使用する必要がいけない:

<EmployeeRoleRequirement(SecurityAction.Demand, RequiredEmployeeRoles:=EmployeeRoles.DataReader Or EmployeeRoles.DataWriter)> 
Sub SecuredMethod() 
End Sub 
関連する問題