eXpress App Framework Team

This Blog

News

You are welcome to test the new XAF features prior to the 17.2 release: one, two, three, four, five, five

May 2013 - Posts

  • Security in On-line shop? That’s easy!

    There are many reasons why Security is a necessity when developing even the simplest online shop backend. Instead of listing them all I will concentrate on how to empower the application prototype we created for our DXSK8 e-shop with a flexible Security System.

    You may recall that in the previous post we applied a XAF layer(rich application) over an EF model located in an external lib (DSK8.Service). Now we will extend the same EF model to support XAF’s Security System.

    1) Designing an Entity Framework Model for Security System objects.

    XAF’s Security system uses Users, Roles and Permissions to configure both data access and UI generation for both platforms! This is done with the help of several system interfaces such as :
    User: ISecurityUser, IAuthenticationStandardUser, IOperationPermissionProvider
    Role:, IOperationPermissionProvider.

    Our EF model from the DXSK8.Service project already contains an Employee entity, which is just perfect for taking on the role of XAF’s system user. We begin by adding all public properties of the user depended interfaces to our Employee entity. XAF interfaces are well designed and there are only three as you see below. The UserName in the black frame already existed in our Login entity, it’s not in the Employee entity with the rest of the new fields. XAF has no problems understand it as is!

    image

    The next step is to design the Roles and Permissions objects. While XAF supports member level and criteria based systems as well, I will utilize the Type Permission system in this case. I only need the Roles and TypePermissionObject entities listed below.

    image

    Be sure to follow the database migration steps detailed by EF. For the purposes of this blog I followed a standard technic described in Code First Migrations. 

    Note that we must use partial classes to implement the consumed interfaces this implementation simple and can be reusable, for example let’s see how easy it is to implement the Employee interfaces. For Role, TypePermissionObject implementation please check sample at the end of the post (See also How to: Implement Custom Security Objects (Users, Roles, Operation Permissions))).

    [ImageName("BO_User"), DefaultProperty("UserName")]

    public partial class Employee : ISecurityUserIAuthenticationStandardUser,

                                    IOperationPermissionProvider {

     

        #region IOperationPermissionProvider

        IEnumerable<IOperationPermissionProvider> IOperationPermissionProvider.GetChildren() {

            if (!Roles.IsLoaded) {

                Roles.Load();

            }

            return new EnumerableConverter<IOperationPermissionProvider, Role>(Roles);

        }

     

        IEnumerable<IOperationPermission> IOperationPermissionProvider.GetPermissions() {

            return new IOperationPermission[0];

        }

        #endregion

        #region ISecurityUser

        Boolean ISecurityUser.IsActive {

            get { return IsActive.HasValue && IsActive.Value; }

        }

     

        String ISecurityUser.UserName {

            get { return UserName; }

        }

        #endregion

     

        #region IAuthenticationStandardUser

        Boolean IAuthenticationStandardUser.ComparePassword(String password) {

            var passwordCryptographer = new PasswordCryptographer();

            return passwordCryptographer.AreEqual(StoredPassword, password);

        }

     

        public void SetPassword(String password) {

            var passwordCryptographer = new PasswordCryptographer();

            StoredPassword = passwordCryptographer.GenerateSaltedPassword(password);

        }

     

        Boolean IAuthenticationStandardUser.ChangePasswordOnFirstLogon {

            get { return ChangePasswordOnFirstLogon.HasValue && ChangePasswordOnFirstLogon.Value; }

            set { ChangePasswordOnFirstLogon = value; }

        }

     

        String IAuthenticationStandardUser.UserName {

            get { return UserName; }

        }

        #endregion

     

    }

    2)  Installing a XAF Security System

    Although XAF has strong design time support I will go through this step using one line of code in both Program.cs and Global.asax.cs just before application.Setup() call.

    application.Security = new SecurityStrategyComplex(typeof(DXSK8.Service.Employee), typeof(DXSK8.Service.Role), new AuthenticationStandard());

    application.Setup();

    The snippet above will assist you with applying a security strategy using the Entity Framework entities located in the external DXSk8.Service lib . For this type of security strategy XAF spares our time as usual and will automatically display a customizable credentials window for both win and web platforms as shown,

     

    image

    image

     

    In addition XAF detects the custom Security EF Entities we designed in step 1 and automatically populates the navigation menu.

     

    Win
    image
    Web
    image
       

     

    3) Supplying initial data

    It is absolutely imperative that someone working on your project is assigned the security password. In addition, a user with admin privileges must also be assigned. Use the XafApplication’s CustomCheckCompatibility event inside our platform agnostic module to assign these admin priviledges.

     

    public override void Setup(XafApplication application) {

        base.Setup(application);

        application.CustomCheckCompatibility+=ApplicationOnCustomCheckCompatibility;

        application.CreateCustomObjectSpaceProvider += ApplicationOnCreateCustomObjectSpaceProvider;

    }

     

    void ApplicationOnCustomCheckCompatibility(object sender, CustomCheckCompatibilityEventArgs e) {

        var objectSpace = e.ObjectSpaceProvider.CreateUpdatingObjectSpace(true);

        var updater = new Updater(objectSpace, Version.Parse("1.0.0.0"));

        updater.UpdateDatabaseAfterUpdateSchema();

    }

    and the UpdateDatabaseAfterUpdateSchema where we created:
    a) A Content Manager role with CRUD on Product but ReadOnly on Orders/Employees

    b) A Sales Manager role wirh CRUD on Order but ReadOnly on Product/Employees

    public override void UpdateDatabaseAfterUpdateSchema() {

        base.UpdateDatabaseAfterUpdateSchema();

        if (ObjectSpace.FindObject<Employee>(CriteriaOperator.Parse("UserName=?","Admin")) == null) {

            var roleAndUser = CreateRoleAndUser("Admin");

            roleAndUser.IsAdministrative = true;

            CreateRole("Content Manager", new[]{

                CRUDPermission(typeof(Product)),

                ReadOnlyPermission(typeof(Order)),

                ReadOnlyPermission(typeof(Employee))

            });

     

            CreateRole("Sales Manager", new[]{

                CRUDPermission(typeof(Order)),

                ReadOnlyPermission(typeof(Product)),

                ReadOnlyPermission(typeof(Employee))

            });

     

            var employees = ObjectSpace.GetObjects<Employee>();

            foreach (var employee in employees) {

                employee.IsActive = true;

                employee.ChangePasswordOnFirstLogon = true;

            }

     

            ObjectSpace.CommitChanges();

        }

    }

    Use this post’s sample to explore the implementation of the remaining methods, which happens to be rather simple.

     

    The remainder of the project needs a business user to simply associate Employees with Roles using XAF’s well thought-out UI. For example, the next two screenshots illustrate how to assign a Content Manager Role to a list of users.

     

    image

    image

    Conclusion

    There are many difficulties and complexities when it comes to addressing business problems with technology. And that’s exactly why tools like XAF, which bridge business and technology are such a life saver. You just witness just how simple it was to integrate a complex and sensitive feature like security while working with EF as datalayer. Thanks to the flexible and well-designed XAF, your product can now be marketed more easily since it features a complete security system.

    I close this time with a phrase I often hear from our customers :

    XAF really works!

    Download a sample from here and attach the mdf file found in the DXSK8.Service/App_Data folder to your SQL instance. Be sure to visit How to: Get Started with the Entity Framework Model First in XAF for coverage of the basics.

    .

  • Merge Changes when Two Users Edit the Same Record Simultaneously

    In multi-user data-aware applications, there are times when one user edits a record while another user is editing the same record. As long as the changes being made do not affect the same field (e.g., one user modifies the task description while another user attaches a file), XAF can resolve the situation, and merge simultaneous changes made by different users. The following video demonstrates this scenario.

    To try out this functionality (which will be available in version 13.1 of XAF), add the following code to your Program.cs file.

    static void Main() {
    DevExpress.Xpo.XpoDefault.TrackPropertiesModifications = true;
    // ...
    }
     
    Note that ASP.NET applications are not supported, because user interaction dialogs are currently only implemented for WinForms. The core helper classes are located in the DevExpress.ExpressApp.Xpo assembly so that support for ASP.NET can be added in the future.
     

    Important note:

    To support this functionality, persistent properties should be implemented in a specific manner. If you implement your business model in code, then follow XPO best practices and use either the SetPropertyValue or OnChanged method in persistent property setters. These methods have several overloads. Use the overloads that take both the old and new property values:

    SetPropertyValue("PropertyName", ref propertyValueHolder, value);
     
    OnChanged("PropertyName", propertyValueHolder, value)


    If you use the Data Model Designer or Business Object Designer to create the data model, then you do not need to worry about implementing persistent properties. Designers automatically declare persistent properties in the proper manner.
     
    If you have any questions about this functionality, feel free to leave a comment below.
  • UI Annotation using Business Rules

    XAF contains several kinds of modules, one of which is a Validation Module. Validation can be applied to the content of XAF objects when specific rules are applied to the Validation Module. In this post you can find a sample XAF application which extends the Validation to provide support for Warning/Information messages.

    Today’s implementation can be used by any Validation Business Rule that exists in the XAF’s Application Model. Displayed below is the default list of these rules, applicable to custom business rules as well.

    image

    The sample code extends the Application Model of the IModelRuleBase. By using one more property like the RuleType, the Application Model marks the rule as a warning or as information shown below:

    image

    This will not raise exceptions for Warning and Information Rules when Validation occurs, but will change their notification icon accordingly.

    Windows

    image

    Web

    image

    HOW TO APPLY THIS GREAT FUNCTIONALITY TO YOUR PROJECT?

    1. Download  RuleType.zip and open it in VS.
    2. Copy its only one Controller located in the RuleTypeController.cs and spanned across three modules to your own platform agnostic and platform depended modules (Win/Web).

      image
    3. Hit F5 and profit!

    Note: I “borrowed” the code for RuleType support from our community project expandframework I hope that this blog demonstrated once again just how flexible and powerful XAF is when it comes to providing reusable solutions!

    Subscribe to XAF feed
    Subscribe to community feed

LIVE CHAT

Chat is one of the many ways you can contact members of the DevExpress Team.
We are available Monday-Friday between 7:30am and 4:30pm Pacific Time.

If you need additional product information, write to us at info@devexpress.com or call us at +1 (818) 844-3383

FOLLOW US

DevExpress engineers feature-complete Presentation Controls, IDE Productivity Tools, Business Application Frameworks, and Reporting Systems for Visual Studio, along with high-performance HTML JS Mobile Frameworks for developers targeting iOS, Android and Windows Phone. Whether using WPF, ASP.NET, WinForms, HTML5 or Windows 10, DevExpress tools help you build and deliver your best in the shortest time possible.

Copyright © 1998-2017 Developer Express Inc.
All trademarks or registered trademarks are property of their respective owners