现在的位置: 首页 > 综合 > 正文

XAF 字段级权限扩展-根据对象选择属性

2012年08月17日 ⁄ 综合 ⁄ 共 13749字 ⁄ 字号 评论关闭

 

需要参考:http://www.cnblogs.com/Tonyyang/archive/2011/05/21/2052627.html

// Developer Express Code Central Example:
// How to implement the MemberLevel security manually (for example, to deny the 'Read' access for declared properties of some business class, and allow access for the inherited properties)
// 
// Hello,
// 
// This sample demonstrates how to implement the Member Level security
// manually.
// 
// This is a workaround solution until we implement this feature in an
// out-of-the-box manner (see "Security.MemberLevel: Add an ability to protect some
// object's properties rather than an entire object (Field-level security)" at
// http://www.devexpress.com/issue=S19569). This approach doesn't protect
// information within Reports and Analysis modules, and anywhere else, where
// special controls are used.
// 
// Currently, XAF Security is implemented at the UI
// level. For more details see:
// - "Allow injection of a new and independent
// functionality into the load business class process and into the 'get/set'
// methods of a certain property" at http://www.devexpress.com/issue=S30538
// 
// For
// more details about this example, see:
// - "How to implement the MemberLevel
// security manually" at http://www.devexpress.com/kbid=K18110
// 
// See also:
// -
// "Security: Roles that do not have a Read access level to an object should not
// see "protected content" items in Detail and List Views" at
// http://www.devexpress.com/issue=S30144
// - "Allow injection of a new and
// independent functionality into the load business class process and into the
// 'get/set' methods of a certain property" at
// http://www.devexpress.com/issue=S30538
// - "Security.MemberLevel: How to show a
// list of available properties (DropDown edit) for the "Member" editor (which is a
// TextEdit)?" at http://www.devexpress.com/issue=Q134009
// 
// Thanks,
// Dan.
// 
// You can find sample updates and versions for different programming languages here:
// http://www.devexpress.com/example=E485

using System;
using System.Collections.Generic;
using DevExpress.ExpressApp.Security;
using System.ComponentModel;
using DevExpress.Xpo;
using System.Security;
using DevExpress.Persistent.Base;
using DevExpress.Persistent.BaseImpl;
using DevExpress.Xpo.Metadata;
using System.Collections;
using DevExpress.Xpo.Metadata.Helpers;
using DevExpress.ExpressApp;

namespace MemberLevelSecurityDemo.Module {
    
public enum MemberOperation { NotAssigned, Read, Write }

    public class MemberAccessPermissionItem {
        
private string memberName;
        
private Type objectType;
        
private MemberOperation operation;
        
private ObjectAccessModifier modifier;
        
public MemberAccessPermissionItem() { }
        
public MemberAccessPermissionItem(MemberAccessPermissionItem source) {
            
this.memberName = source.memberName;
            
this.objectType = source.objectType;
            
this.operation = source.operation;
            
this.modifier = source.modifier;
        }
        
public Type ObjectType {
            
get { return objectType; }
            
set { objectType = value; }
        }
      
        
public string MemberName {
            
get { return memberName; }
            
set { memberName = value; }
        }
        
public MemberOperation Operation {
            
get { return operation; }
            
set { operation = value; }
        }
        
public ObjectAccessModifier Modifier {
            
get { return modifier; }
            
set { modifier = value; }
        }
    }

    [NonPersistent, DefaultProperty("DisplayName")]
    
public class MemberAccessPermission : PermissionBase
    {
        
public string DisplayName { get { return this.ToString(); } }
        
private List<MemberAccessPermissionItem> items = new List<MemberAccessPermissionItem>();
        
private MemberAccessPermissionItem GetDesignModeItem() {
            
if(items.Count > 1) {
                
throw new InvalidOperationException();
            }
            
if(items.Count == 0) {
                items.Add(
new MemberAccessPermissionItem());
            }
            
return items[0];
        }
        
private List<MemberAccessPermissionItem> CloneItems() {
            List
<MemberAccessPermissionItem> clonedItems = new List<MemberAccessPermissionItem>();
            
foreach(MemberAccessPermissionItem item in items) {
                clonedItems.Add(
new MemberAccessPermissionItem(item));
            }
            
return clonedItems;
        }
        
public MemberAccessPermission() { }
        
public MemberAccessPermission(Type objectType, string memberName, MemberOperation operation) 
            : 
this(objectType, memberName, operation, ObjectAccessModifier.Allow) {
        }
        
public MemberAccessPermission(Type objectType, string memberName, MemberOperation operation, ObjectAccessModifier modifier) {
            
this.ObjectType = objectType;
            
this.MemberName = memberName;
            
this.Operation = operation;
            
this.Modifier = modifier;
        }
        
public override System.Security.IPermission Union(System.Security.IPermission target) {
            MemberAccessPermission result 
= (MemberAccessPermission)Copy();
            result.items.AddRange(((MemberAccessPermission)target).CloneItems());
            
return result;
        }
        
public override bool IsSubsetOf(System.Security.IPermission target) {
            
if(base.IsSubsetOf(target)) {
                
foreach(MemberAccessPermissionItem targetItem in ((MemberAccessPermission)target).items) {
                    
if(targetItem.ObjectType == ObjectType
                        
&& targetItem.MemberName == MemberName
                        
&& targetItem.Operation == Operation) {
                        
return targetItem.Modifier == Modifier;
                    }
                }
                
return true;
            }
            
return false;
        }

        [TypeConverter(typeof(PermissionTargetBusinessClassListConverter))]
        
public Type ObjectType {
            
get { return GetDesignModeItem().ObjectType; }
            
set { GetDesignModeItem().ObjectType = value; }
        }

        [DataSourceProperty("Types")]
        [Custom(
"PropertyEditorType""MemberLevelSecurityDemo.Module.WinStringArrayComboPropertyEditor")]
        
public string MemberName {
            
get { return GetDesignModeItem().MemberName; }
            
set { GetDesignModeItem().MemberName = value; }
        }
        
public MemberOperation Operation {
            
get { return GetDesignModeItem().Operation; }
            
set { GetDesignModeItem().Operation = value; }
        }
        
public ObjectAccessModifier Modifier {
            
get { return GetDesignModeItem().Modifier; }
            
set { GetDesignModeItem().Modifier = value; }
        }
        
public override System.Security.SecurityElement ToXml() {
            SecurityElement result 
= base.ToXml();
            SecurityElement itemElement 
= new SecurityElement("MemberAccessPermissionItem");
            itemElement.AddAttribute(
"Operation", Operation.ToString());
            itemElement.AddAttribute(
"ObjectType", (ObjectType != null? ObjectType.ToString() : "");
            itemElement.AddAttribute(
"Modifier", Modifier.ToString());
            itemElement.AddAttribute(
"MemberName", MemberName.ToString());
            result.AddChild(itemElement);
            
return result;
        }
        
public override void FromXml(System.Security.SecurityElement element) {
            items.Clear();
            
if(element.Children != null) {
                
if(element.Children.Count != 1) {
                    
throw new InvalidOperationException();
                }
                SecurityElement childElement 
= (SecurityElement)element.Children[0];
                ObjectType 
= ReflectionHelper.FindType(childElement.Attributes["ObjectType"].ToString());
                Operation 
= (MemberOperation)Enum.Parse(typeof(MemberOperation), childElement.Attributes["Operation"].ToString());
                Modifier 
= (ObjectAccessModifier)Enum.Parse(typeof(ObjectAccessModifier), childElement.Attributes["Modifier"].ToString());
                MemberName 
= childElement.Attributes["MemberName"].ToString();
            }
        }
        
public override string ToString() {
            
return ((ObjectType != null? ObjectType.Name : "N/A"+ "." + MemberName + " - " + Modifier + " " + Operation;
            
//return base.ToString();
        }
        
public override System.Security.IPermission Copy() {
            MemberAccessPermission result 
= new MemberAccessPermission();
            result.items.AddRange(CloneItems());
            
return result;
        }

        [Browsable(false)]
        
public object Types
        {
            
get { return GetTypes(); }
        }

        public string[] GetTypes()
        {
            
return GetObjectProperties(ObjectType);
        }

        public string[] GetObjectProperties(Type objectType)
        {
            
if (objectType == nullreturn null;

            XPClassInfo classInfo = CurrentUser.Session.Dictionary.GetClassInfo(objectType);
            
if (classInfo != null)
                
return GetObjectProperties(classInfo, new ArrayList());
            
return new string[] { };
        }

        public string[] GetObjectProperties(XPClassInfo xpoInfo, ArrayList processed)
        {
            
if (processed.Contains(xpoInfo)) return new string[] { };
            processed.Add(xpoInfo);
            ArrayList result 
= new ArrayList();
            
foreach (XPMemberInfo m in xpoInfo.PersistentProperties)
                
if (!(m is ServiceField) && m.IsPersistent)
                {
                    result.Add(m.Name);
                    
if (m.ReferenceType != null)
                    {
                        
string[] childProps = GetObjectProperties(m.ReferenceType, processed);
                        
foreach (string child in childProps)
                            result.Add(
string.Format("{0}.{1}", m.Name, child));
                    }
                }

            foreach (XPMemberInfo m in xpoInfo.CollectionProperties)
            {
                
string[] childProps = GetObjectProperties(m.CollectionElementType, processed);
                
foreach (string child in childProps)
                    result.Add(
string.Format("{0}.{1}", m.Name, child));
            }
            
return result.ToArray(typeof(string)) as string[];
        }

        private readonly User CurrentUser = SecuritySystem.CurrentUser as User;

    }
}

// Developer Express Code Central Example:
// How to implement the MemberLevel security manually (for example, to deny the 'Read' access for declared properties of some business class, and allow access for the inherited properties)
// 
// Hello,
// 
// This sample demonstrates how to implement the Member Level security
// manually.
// 
// This is a workaround solution until we implement this feature in an
// out-of-the-box manner (see "Security.MemberLevel: Add an ability to protect some
// object's properties rather than an entire object (Field-level security)" at
// http://www.devexpress.com/issue=S19569). This approach doesn't protect
// information within Reports and Analysis modules, and anywhere else, where
// special controls are used.
// 
// Currently, XAF Security is implemented at the UI
// level. For more details see:
// - "Allow injection of a new and independent
// functionality into the load business class process and into the 'get/set'
// methods of a certain property" at http://www.devexpress.com/issue=S30538
// 
// For
// more details about this example, see:
// - "How to implement the MemberLevel
// security manually" at http://www.devexpress.com/kbid=K18110
// 
// See also:
// -
// "Security: Roles that do not have a Read access level to an object should not
// see "protected content" items in Detail and List Views" at
// http://www.devexpress.com/issue=S30144
// - "Allow injection of a new and
// independent functionality into the load business class process and into the
// 'get/set' methods of a certain property" at
// http://www.devexpress.com/issue=S30538
// - "Security.MemberLevel: How to show a
// list of available properties (DropDown edit) for the "Member" editor (which is a
// TextEdit)?" at http://www.devexpress.com/issue=Q134009
// 
// Thanks,
// Dan.
// 
// You can find sample updates and versions for different programming languages here:
// http://www.devexpress.com/example=E485

using System;
using System.Collections.Generic;
using System.Text;
using DevExpress.ExpressApp.Security;
using DevExpress.Persistent.Base;
using DevExpress.ExpressApp;
using DevExpress.ExpressApp.DC;

namespace MemberLevelSecurityDemo.Module
{
    
public class MemberLevelObjectAccessComparer : ObjectAccessComparer
    {
        
public override bool IsMemberReadGranted(Type requestedType, string propertyName, SecurityContextList securityContexts)
        {
            ITypeInfo typeInfo 
= XafTypesInfo.Instance.FindTypeInfo(requestedType);
            IMemberInfo memberInfo 
= typeInfo.FindMember(propertyName);
            
foreach (IMemberInfo currentMemberInfo in memberInfo.GetPath())
            {
                
if (!SecuritySystem.IsGranted(new MemberAccessPermission(currentMemberInfo.Owner.Type, currentMemberInfo.Name, MemberOperation.Read)))
                {
                    
return false;
                }
            }
            
return base.IsMemberReadGranted(requestedType, propertyName, securityContexts);
        }
        
public override bool IsMemberModificationDenied(object targetObject, IMemberInfo memberInfo)
        {
            
foreach (IMemberInfo currentMemberInfo in memberInfo.GetPath())
            {
                
if (!SecuritySystem.IsGranted(new MemberAccessPermission(currentMemberInfo.Owner.Type, currentMemberInfo.Name, MemberOperation.Write)))
                {
                    
return true;
                }
            }
            
return base.IsMemberModificationDenied(targetObject, memberInfo);
        }
    }
}

 

抱歉!评论已关闭.