This example demonstrates how to access data protected by the Security System from a Console App (.NET Core) with Entity Framework Core. The application outputs secured data to the console.
For simplicity, the instructions include only C# code snippets. For the complete C# and VB code, see the CS and VB sub-directories.
-
.NET Core SDK 3.1+ and EF Core 3.1 (EF Core 5 is to be supported).
-
Download and run a unified installer for .NET Framework (v20.1+) or obtain a DevExpress NuGet Feed URL.
We recommend that you select all products when you run the DevExpress installer. It will register local NuGet package sources and item / project templates required for these tutorials. You can uninstall unnecessary components later. -
Open the ConsoleApplication.EFCore.sln solution and edit the EFCore/DatabaseUpdater/App.config file so that
DBSERVER
refers to your database server name or its IP address (for a local database server, uselocalhost
,(local)
or.
):<connectionStrings> <add name="ConnectionString" connectionString="Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=EFCoreTestDB;Integrated Security=True;MultipleActiveResultSets=True" /> </connectionStrings>
-
Build and run the DatabaseUpdater project. This console application will create a database with user, role, permission and other data based on the
ApplicationDbContext
andUpdater
classes and the ORM data model in the BusinessObjectsLibrary project. For more information, see Predefined Users, Roles and Permissions.
-
Create a new Console App (.NET Core) project and add the EFCore/BusinessObjectsLibrary project reference. BusinessObjectsLibrary adds important NuGet dependencies:
<PackageReference Include="DevExpress.ExpressApp.EFCore" Version="20.1.5" /> <PackageReference Include="Microsoft.EntityFrameworkCore" Version="3.1.2" />
The
DevExpress.ExpressApp.EFCore
NuGet package contains the PermissionPolicyUser, PermissionPolicyRole and other XAF's Security System API. -
Add NuGet packages for Entity Framework Core with SQL Server:
<PackageReference Include="Microsoft.EntityFrameworkCore.Proxies" Version="3.1.2" /> <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="3.1.2" />
-
In YourConsoleApplication/Program.cs, create a
SecurityStrategyComplex
instance using AuthenticationStandard (a simple Forms Authentication with a login and password) and password options (EnableRfc2898 and SupportLegacySha512).using BusinessObjectsLibrary.EFCore.BusinessObjects; using DevExpress.EntityFrameworkCore.Security; using DevExpress.ExpressApp; using DevExpress.ExpressApp.Security; using DevExpress.Persistent.Base; using DevExpress.Persistent.BaseImpl.EF.PermissionPolicy; using Microsoft.Data.SqlClient; using Microsoft.EntityFrameworkCore; //... static void Main() { PasswordCryptographer.EnableRfc2898 = true; PasswordCryptographer.SupportLegacySha512 = false; AuthenticationStandard authentication = new AuthenticationStandard(); SecurityStrategyComplex security = new SecurityStrategyComplex( typeof(PermissionPolicyUser), typeof(PermissionPolicyRole), authentication ); }
-
Create a
SecuredEFCoreObjectSpaceProvider
instance using theEFCoreDatabaseProviderHandler
delegate and theUseSqlServer
extension:static void Main() { // ... string connectionString = ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString; SecuredEFCoreObjectSpaceProvider objectSpaceProvider = new SecuredEFCoreObjectSpaceProvider(security, typeof(ApplicationDbContext), (builder, _) => builder.UseSqlServer(connectionString)); }
-
In YourConsoleApplication/App.config, add the same connection string as in Prerequisites.
This provider allows you to create secured IObjectSpace instances to perform secured CRUD (create-read-update-delete) operations. Object Space is an ORM-independent implementation of the well-known Repository and Unit Of Work design patterns (for instance,
SecuredEFCoreObjectSpace
is an IObjectSpace implementation for EF Core that wraps DbContext).
static void Main() {
// ...
authentication.SetLogonParameters(new AuthenticationStandardLogonParameters(userName: "User", password: string.Empty));
IObjectSpace loginObjectSpace = objectSpaceProvider.CreateNonsecuredObjectSpace();
try {
security.Logon(loginObjectSpace);
}
catch(SqlException sqlEx) {
if(sqlEx.Number == 4060) {
throw new Exception(sqlEx.Message + Environment.NewLine + ApplicationDbContext.DatabaseConnectionFailedMessage, sqlEx);
}
}
}
To log off or sign out, call the security.Logoff
method.
Create a SecuredEFCoreObjectSpace
instance to access protected data and use its data manipulation APIs (for instance, IObjectSpace.GetObjects
). Note that SecuredEFCoreObjectSpace
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 Protected Content placeholder in the UI.
static void Main() {
// ...
using(IObjectSpace securedObjectSpace = objectSpaceProvider.CreateObjectSpace()) {
foreach(Employee employee in securedObjectSpace.GetObjects<Employee>()) {
bool canRead = security.CanRead(securedObjectSpace, employee, memberName: nameof(Employee.Department));
var department = canRead ? employee.Department.Title : "*******";
Console.WriteLine($"{employee.FullName,-40}{department,-40}");
}
}
security.Logoff();
}
The same implementation steps can be used in other .NET apps.
Our console application will display employees and mask departments if their titles do not contain 'Development'.