Security in On-line shop? Easily!

Έχουν δημοσιευτεί 24 Μαΐου 13 06:26 πμ | tolisss 

I can think many reason why Security is necessary when developing even the simplest online shop backend. I will not elaborate them but I will concentrate on how to empower the application prototype we created for our DXSK8 e-shop with a flexible Security System. Note that after this we really close to first paycheck Winking smile

I remind you that in 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) Design Entity Framework Model for the Security System objects.

XAF’s Security system uses Users, Roles and Permissions to configure both the data access and the UI generation for both platforms! This is done with the help of a few 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 perfect to take the role of XAF’s system user. Therefore, first we need to add all public properties of the user depended interfaces to our Employee entity. Do not worry XAF interfaces are well designed and its just 3 properties as you see below. The UserName in the black frame already existed in our Login entity that's why is not in the Employee entity with the rest of the new fields. However XAF has no problem to understand it as is!

image

Next step is to design the Roles and Permissions objects. I will go only for a Type Permission system although XAF supports member level and criteria based as well. So I only need the bellow Roles, TypePermissionObject entities.

image

The database migration should be done as suggested from EF and I will not elaborate but I followed a standard technic as the one described in Code First Migrations. 

Note: We also need to use partial classes to implement the consumed interfaces however their implementation is rather easy and reusable for example let’s see how easy it is to implement the Employee interfaces. For Role, TypePermissionObject implementation please check post’s sample (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)  Install 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 above snippet will apply 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 platforms,

 

image

image

 

In addition XAF will detect the custom Security EF Entities we designed in step 1 and will auto populate the navigation menu.

 

Win
image
Web
image
   

 

3) Supply initial data

Always when installing a security system make sure that some one knows the password Smile. We forgot to add at least a user with admin privileges. For this job an appropriate event to use is XafApplication’s CustomCheckCompatibility event inside our platform agnostic module.

 

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();

    }

}

In post’s sample you can explore the implementation of the rest of the methods which is really simple.

 

The rest of the job needs a business user to simply associate Employees with Roles using XAF’ well thought UI. For example in the next two shots we see how to assign a Content Manager Role to a list of users.

 

image

image

Conclusion

Trying to focus in solving business problems with the help of technology is hard. Therefore tools like XAF that bridge those two worlds are like god gifts. We saw how easy was to integrate a complex and sensitive feature like security while working with EF as datalayer. Thanks to the flexible and well designed XAF our product now can be market easier since it features a complete security system.

This time I will close with a phrase I hear constantly from our customers lately:

XAF really works!

Download sample from here and attach the mdf file found in DXSK8.Service/App_Data folder to your SQL instance. Also make sure you already visit How to: Get Started with the Entity Framework Model First in XAF to be sure you know the basics.

.

Δημοσίευση στην κατηγορία: ,

Σχόλια:

Χωρίς Σχόλια
Έχει απενεργοποιηθεί η προσθήκη σχολίων από ανώνυμα μέλη

Search

Go

Το Ιστολόγιο

Ιστορικό Δημοσιεύσεων

Συνδρομές