Skip to content

Latest commit

 

History

History

Console

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 

This example demonstrates how to access data protected by the Security System from your Non-XAF application using EF Core for data access. The application outputs secured data to the console.

If you are using XPO ORM for data access, follow this tutorial.  

Prerequisites

NOTE

If you have a pre-release version of our components, for example, provided with the hotfix, you also have a pre-release version of NuGet packages. These packages will not be restored automatically and you need to update them manually as described in the Updating Packages article using the Include prerelease option.

Step 1. Initialization. Create a Secured Data Store and Set Authentication Options

  1. Create a new .NET 6 console application or use an existing application.

  2. Add DevExpress NuGet packages to your project:

    <PackageReference Include="DevExpress.ExpressApp.EFCore" Version="22.2.3" />
    <PackageReference Include="DevExpress.Persistent.BaseImpl.EFCore" Version="22.2.3" />
  3. Install Entity Framework Core, as described in the Installing Entity Framework Core article.

  4. Open the application configuration file (App.config_. Add the following line to this file.

    <add name="ConnectionString" connectionString="Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=EFCoreTestDB;Integrated Security=True;MultipleActiveResultSets=True"/>

    NOTE

    The Security System requires Multiple Active Result Sets in EF Core-based applications connected to the MS SQL database. We do not recommend that you remove MultipleActiveResultSets=True; from the connection string or set the MultipleActiveResultSets parameter to false.

  • Create an instance of TypesInfo required for the correct operation of the Security System.

    TypesInfo typesInfo = new TypesInfo();
  • Initialize the Security System.

    AuthenticationStandard authentication = new AuthenticationStandard();
    SecurityStrategyComplex security = new SecurityStrategyComplex(typeof(PermissionPolicyUser), typeof(PermissionPolicyRole), authentication, typesInfo);
  • Create a SecuredEFCoreObjectSpaceProvider object. It allows you to create a EFCoreObjectSpace to ensure a secured data access.

    string connectionString = ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;
    var objectSpaceProvider = new SecuredEFCoreObjectSpaceProvider<ApplicationDbContext>(security,
        typesInfo, connectionString, (builder, connectionString) => builder.UseSqlServer(connectionString).UseChangeTrackingProxies());
  • Call CreateDemoData method at the beginning of the Main method of Program.cs:

    private static void CreateDemoData(string connectionString, TypesInfo typesInfo) {
        using (var objectSpaceProvider = new EFCoreObjectSpaceProvider<ApplicationDbContext>(typesInfo, connectionString,
    (builder, connectionString) => builder.UseSqlServer(connectionString).UseChangeTrackingProxies()))
        using (var objectSpace = objectSpaceProvider.CreateUpdatingObjectSpace(true)) {
            new Updater(objectSpace).UpdateDatabase();
        }
    }

    For more details about how to create demo data from code, see the Updater.cs class.

Step 2. Authentication. Log in as a 'User' with an Empty Password

  • Perform a logon. The code below demonstrates how to do this as a user named "User" who has an empty password.

    string userName = "User";
    string password = string.Empty;
    authentication.SetLogonParameters(new AuthenticationStandardLogonParameters(userName, password));
    IObjectSpace loginObjectSpace = objectSpaceProvider.CreateNonsecuredObjectSpace();
    security.Logon(loginObjectSpace);

Step 3. Authorization. Access and Manipulate Data/UI Based on User/Role Rights

  • Create ObjectSpace instance to access protected data and use its data manipulation APIs (for instance, IObjectSpace.GetObjects) OR if you prefer, the familiar DbContext object accessible through the EFCoreObjectSpace.DbContext property.

    StringBuilder stringBuilder = new StringBuilder();
    stringBuilder.Append("List of the 'Employee' objects:\n");
    using(IObjectSpace securedObjectSpace = objectSpaceProvider.CreateObjectSpace()) {
            // The EFCore way:
            // var dbContext = ((EFCoreObjectSpace)securedObjectSpace).DbContext;
            // 
            // The XAF way:
        foreach(Employee employee in securedObjectSpace.GetObjects<Employee>()) {
            stringBuilder.Append(string.Format("Full name: {0}\n", employee.FullName));
            if(security.CanRead(employee, nameof(Department))) {
                stringBuilder.Append(string.Format("Department: {0}\n", employee.Department.Title));
            }
            else {
                stringBuilder.Append("Department: *******\n");
            }
        } 
    }

Note that ObjectSpace returns default values (for instance, null) for protected object properties - it is secure even without any custom UI. Use the SecurityStrategy.CanRead method to determine when to mask default values with the "*******" placeholder in the UI.

Run and Test the App

Our console application will display employees and mask departments if their titles do not contain 'Development'.