文章出處

本示例使用XPO.

新建一個XAF項目.填加兩個類進來:

 
[DefaultClassOptions]
public class Employee : Person {
    public Employee(Session session)
        : base(session) { }
    [Association("Employee-Task")]
    public XPCollection<EmployeeTask> OwnTasks {
        get { return GetCollection<EmployeeTask>("OwnTasks"); }
    }
}
[DefaultClassOptions, ImageName("BO_Task")]
public class EmployeeTask : Task {
    public EmployeeTask(Session session)
        : base(session) { }
    private Employee owner;
    [Association("Employee-Task")]
    public Employee Owner {
        get { return owner; }
        set { SetPropertyValue("Owner", ref owner, value); }
    }
}

 


Expanded 實現接口: ISecurityUser

 

填加引用: DevExpress.ExpressApp.Security.v16.2.dll 程序集 

using DevExpress.ExpressApp.Security;
using DevExpress.Persistent.Validation;
// ... 
public class Employee : Person, ISecurityUser {
    // ... 
    #region ISecurityUser Members
    private bool isActive = true;
    public bool IsActive {
        get { return isActive; }
        set { SetPropertyValue("IsActive", ref isActive, value); }
    }
    private string userName = String.Empty;
    [RuleRequiredField("EmployeeUserNameRequired", DefaultContexts.Save)]
    [RuleUniqueValue("EmployeeUserNameIsUnique", DefaultContexts.Save, 
        "The login with the entered user name was already registered within the system.")]
    public string UserName {
        get { return userName; }
        set { SetPropertyValue("UserName", ref userName, value); }
    }
    #endregion
}

 

Expanded 實現 IAuthenticationStandardUser 接口

using System.ComponentModel;
using DevExpress.Persistent.Base.Security;
// ... 
public class Employee : Person, ISecurityUser, IAuthenticationStandardUser {
    // ... 
    #region IAuthenticationStandardUser Members
    private bool changePasswordOnFirstLogon;
    public bool ChangePasswordOnFirstLogon {
        get { return changePasswordOnFirstLogon; }
        set { 
            SetPropertyValue("ChangePasswordOnFirstLogon", ref changePasswordOnFirstLogon, value);
        }
    }
    private string storedPassword;
    [Browsable(false), Size(SizeAttribute.Unlimited), Persistent, SecurityBrowsable]
    protected string StoredPassword {
        get { return storedPassword; }
        set { storedPassword = value; }
    }
    public bool ComparePassword(string password) {
        return PasswordCryptographer.VerifyHashedPasswordDelegate(this.storedPassword, password);
    }
    public void SetPassword(string password) {
        this.storedPassword = PasswordCryptographer.HashPasswordDelegate(password);
        OnChanged("StoredPassword");
    }
    #endregion
}

如果不想支持AuthenticationStandard驗證方式,則不需要實現這個接口.

 

Expanded 支持IAuthenticationActiveDirectoryUser 接口,為活動目錄驗證方式提供支持

 
using DevExpress.Persistent.Base.Security;
// ... 
public class Employee : Person, ISecurityUser, 
    IAuthenticationStandardUser, IAuthenticationActiveDirectoryUser {
    // ... 
}

如果不想支持 AuthenticationActiveDirectory 驗證方式則不需要實現此步驟.

 

Expanded 支持 ISecurityUserWithRoles 接口.即,讓用戶支持角色

[DefaultClassOptions]
public class Employee : Person, ISecurityUser,
    IAuthenticationStandardUser, IAuthenticationActiveDirectoryUser,
    ISecurityUserWithRoles {
    // ... 
    #region ISecurityUserWithRoles Members
    IList<ISecurityRole> ISecurityUserWithRoles.Roles {
        get {
            IList<ISecurityRole> result = new List<ISecurityRole>();
            foreach (EmployeeRole role in EmployeeRoles) {
                result.Add(role);
            }
            return result;
        }
    }
    #endregion
    [Association("Employees-EmployeeRoles")]
    [RuleRequiredField("EmployeeRoleIsRequired", DefaultContexts.Save,
        TargetCriteria = "IsActive",
        CustomMessageTemplate = "An active employee must have at least one role assigned")]
    public XPCollection<EmployeeRole> EmployeeRoles {
        get {
            return GetCollection<EmployeeRole>("EmployeeRoles");
        }
    }
}

定義了一個角色,是繼承自系統內置的:

using DevExpress.Persistent.BaseImpl.PermissionPolicy;
// ... 
[ImageName("BO_Role")]
public class EmployeeRole : PermissionPolicyRoleBase, IPermissionPolicyRoleWithUsers {
    public EmployeeRole(Session session)
        : base(session) {
    }
    [Association("Employees-EmployeeRoles")]
    public XPCollection<Employee> Employees {
        get {
            return GetCollection<Employee>("Employees");
        }
    }
    IEnumerable<IPermissionPolicyUser> IPermissionPolicyRoleWithUsers.Users {
        get { return Employees.OfType<IPermissionPolicyUser>(); }
    } 
}

 

Expanded 支持 IPermissionPolicyUser 接口,為實現每個用戶提供權限數據

 
using DevExpress.ExpressApp.Utils;
// ... 
[DefaultClassOptions]
public class Employee : Person, ISecurityUser,
    IAuthenticationStandardUser, IAuthenticationActiveDirectoryUser,
    IPermissionPolicyUser {
    // ... 
    #region IPermissionPolicyUser Members
    IEnumerable<IPermissionPolicyRole> IPermissionPolicyUser.Roles {
        get { return EmployeeRoles.OfType<IPermissionPolicyRole>(); }
    }
    #endregion
}

其實這個接口還是挺有用的,上面的代碼是從角色中讀取權限的數據.

 

Expanded 支持 ICanInitialize 接口 

 

ICanInitialize.Initialize 在 AuthenticationActiveDirectory 驗證方式并且設置了 AuthenticationActiveDirectory.CreateUserAutomatically為true時.如果你不需要支持這個自動創建,可以跳過這里.

 

using DevExpress.ExpressApp;
using DevExpress.Data.Filtering;
// ... 
[DefaultClassOptions]
public class Employee : Person, ISecurityUser,
    IAuthenticationStandardUser, IAuthenticationActiveDirectoryUser,
    IPermissionPolicyUser, ICanInitialize {
    // ... 
    #region ICanInitialize Members
    void ICanInitialize.Initialize(IObjectSpace objectSpace, SecurityStrategyComplex security) {
        EmployeeRole newUserRole = (EmployeeRole)objectSpace.FindObject<EmployeeRole>(
            new BinaryOperator("Name", security.NewUserRoleName));
        if (newUserRole == null) {
            newUserRole = objectSpace.CreateObject<EmployeeRole>();
            newUserRole.Name = security.NewUserRoleName;
            newUserRole.IsAdministrative = true;
            newUserRole.Employees.Add(this);
        }
    }
    #endregion
}

Expanded 應用創建的自定義類

 

 如圖所示,在屬性欄中設置自定義的類.

Expanded 創建管理員賬號

 如果你決定使用活動目錄驗證方式,需要跳過這里.
在module項目的databaseUpdate文件夾中,找到Updater.cs. 重寫 ModuleUpdater.UpdateDatabaseAfterUpdateSchema 方法.
 
using DevExpress.ExpressApp.Security.Strategy;
// ... 
public override void UpdateDatabaseAfterUpdateSchema() {
    base.UpdateDatabaseAfterUpdateSchema();
    EmployeeRole adminEmployeeRole = ObjectSpace.FindObject<EmployeeRole>(
        new BinaryOperator("Name", SecurityStrategy.AdministratorRoleName));
    if (adminEmployeeRole == null) {
        adminEmployeeRole = ObjectSpace.CreateObject<EmployeeRole>();
        adminEmployeeRole.Name = SecurityStrategy.AdministratorRoleName;
        adminEmployeeRole.IsAdministrative = true;
        adminEmployeeRole.Save();
    }
    Employee adminEmployee = ObjectSpace.FindObject<Employee>(
        new BinaryOperator("UserName", "Administrator"));
    if (adminEmployee == null) {
        adminEmployee = ObjectSpace.CreateObject<Employee>();
        adminEmployee.UserName = "Administrator";
        adminEmployee.SetPassword("");
        adminEmployee.EmployeeRoles.Add(adminEmployeeRole);
    }
    ObjectSpace.CommitChanges();
}

就是說,在數據庫結構創建(或更新)完成后,執行上面的代碼.

 

Expanded 運行

 win:

 

 

Expanded 只顯示當前用戶的的"任務"

應用 ListViewFilterAttribute 特性到EmployeeTask 類,定義一個列表過濾.
CurrentUserId會取得當前用戶的id
[ListViewFilter("All Tasks", "")]
[ListViewFilter("My Tasks", "[Owner.Oid] = CurrentUserId()")]
public class EmployeeTask : Task {
    // ... 
}

結果如下.

 
如果你只是想為用戶加幾個屬性,則不需要上面這么麻煩
直接繼承自PermissionPolicyUser即可,然后加屬性.當然,不要忘記
這一步的應用類就好了.
 

文章列表


不含病毒。www.avast.com
arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()