Skip to main content
All docs
V24.2
.NET Framework 4.6.2+

Add EF Core Middle Tier Security to an Existing WinForms Application

  • 5 minutes to read

This topic contains step-by-step instructions on how to add a Middle Tier Security project with an Entity Framework Core DbContext to a XAF Windows Forms application with EF Core and Security.

Use XAF Solution Wizard to Add a Middle Tier Security Project

  1. Use the Solution Wizard to add a Middle Tier Security project to your application. Right-click the solution in the Solution Explorer and choose Add DevExpress Item | New Project….

    Solution

  2. Select the .NET platform and run the XAF Solution Wizard.

    Launch Wizard

  3. Choose the Middle Tier Security option and specify the project name.

    Select Middle Tier Security

  4. Select the EF Core ORM for your application.

    Select ORM

  5. Choose Standard authentication on the Choose Security page. The wizard generates JWT authentication scaffolding code.

    Enable the JWT authentication

    On the next page, skip selecting additional modules and click Finish.

    The wizard adds the MySolution.MiddleTier project to the solution.

Configure the Application

  1. If the name of the EF Core DbContext class in the generated Middle Tier Security project differs from the DbContext name in the the main module project (MySolution.Module), change the DbContext class name in the following files:

    • MySolution.MiddleTier\Startup.cs

    • MySolution.MiddleTier\MiddleTierSetup.cs

  2. Add the following NuGet package to the MySolution.Win project: DevExpress.ExpressApp.Security.EFCore.Extensions.Win.

  3. Because the Middle Tier Security uses the XAF Security System, it requires that the ApplicationUser and ApplicationUserLoginInfo persistent classes are defined within your application to store user account data. If the MySolution.Module project does not contain these classes, add them manually as described in the following topic: Use the Security System.

  4. If the MySolution.Win\Program.cs contains the following autogenerated code lines, delete them:

    static class Program { 
        [STAThread] 
        public static int Main(string[] args) { 
            // ... 
            // Delete the code below.
            // if (ContainsArgument(args, "updateDatabase")) { 
            //     using var dbUpdater = new WinDBUpdater(() => winApplication); 
            //     return dbUpdater.Update( 
            //         forceUpdate: ContainsArgument(args, "forceUpdate"), 
            //         silent: ContainsArgument(args, "silent")); 
            // } 
        } 
    } 
    
  5. If the WinForms application’s Startup.cs file contains the following code used to update the database, remove the code.

    public class ApplicationBuilder : IDesignTimeApplicationFactory { 
        public static WinApplication BuildApplication(string connectionString) { 
            var builder = WinApplication.CreateBuilder(); 
            // ... 
            // Remove the code below.
            // builder.AddBuildStep(application => { 
            //  application.ConnectionString = connectionString; 
    #if DEBUG 
            //  if(System.Diagnostics.Debugger.IsAttached && application.CheckCompatibilityType == CheckCompatibilityType.DatabaseSchema) { 
            // application.DatabaseUpdateMode = DatabaseUpdateMode.UpdateDatabaseAlways; 
            //    } 
    #endif 
            //  }); 
        } 
    } 
    
  6. If the application’s Startup.cs file contains code that adds EF Core ObjectSpace providers, delete the line that configures the database provider’s connection string and replace it with code that configures the connection to the Middle Tier Security server. Additionally, replace the code that registers the secured object space with the version without security:

    public class ApplicationBuilder : IDesignTimeApplicationFactory {
        public static WinApplication BuildApplication(string connectionString) { 
            var builder = WinApplication.CreateBuilder(); 
            // ... 
            builder.ObjectSpaceProviders 
                // Remove the code below.
                //.AddSecuredEFCore() 
                // .WithDbContext<MySolutionEFCoreDbContext>((application, options) => { 
                //    options.UseSqlServer(connectionString); 
                //    options.UseChangeTrackingProxies(); 
                //    options.UseObjectSpaceLinkProxies(); 
                //}) 
    
                // Add the code below.
                .AddEFCore() 
                    .WithDbContext<MySolutionEFCoreDbContext>((application, options) => { 
                    options.UseMiddleTier(application.Security); 
                    options.UseChangeTrackingProxies(); 
                    options.UseObjectSpaceLinkProxies(); 
                })
        }
    } 
    
  7. If the application’s Startup.cs file contains code that adds Integrated Security or Windows Security, remove this code.

    public static WinApplication BuildApplication(string connectionString) { 
        var builder = WinApplication.CreateBuilder(); 
        // ... 
        // Remove the code below.
        //builder.Security 
        //    .UseIntegratedMode(options => { 
        //        options.RoleType = typeof(PermissionPolicyRole); 
        //        options.UserType = typeof(DXApplication1.Module.BusinessObjects.ApplicationUser); 
        //        options.UserLoginInfoType = typeof(DXApplication1.Module.BusinessObjects.ApplicationUserLoginInfo); 
        //    }) 
        //    .UsePasswordAuthentication(); 
        // ... 
    } 
    
  8. In the same file, add code that initializes Middle Tier Security.

    public static WinApplication BuildApplication(string connectionString) { 
        var builder = WinApplication.CreateBuilder(); 
        // ... 
        builder.Security 
            .UseMiddleTierMode(options => {
                // The Middle Tier Server URL in the code below is the default setting for debug mode and may be different in your application. 
                // You can check this setting in the Middle Tier project's Properties/launchSettings.json file. 
                options.BaseAddress = new Uri("https://localhost:44319/"); 
                options.Events.OnHttpClientCreated = client => client.DefaultRequestHeaders.Add("Accept", "application/json"); 
                options.Events.OnCustomAuthenticate = (sender, security, args) => { 
                    args.Handled = true; 
                    HttpResponseMessage msg = args.HttpClient.PostAsJsonAsync("api/Authentication/Authenticate", (AuthenticationStandardLogonParameters)args.LogonParameters).GetAwaiter().GetResult(); 
                    string token = (string)msg.Content.ReadFromJsonAsync(typeof(string)).GetAwaiter().GetResult(); 
                    if(msg.StatusCode == HttpStatusCode.Unauthorized) { 
                        throw new UserFriendlyException(token); 
                    } 
                    msg.EnsureSuccessStatusCode(); 
                    args.HttpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("bearer", token); 
                }; 
            }) 
            .UsePasswordAuthentication(); 
            // ... 
    } 
    
  9. If the WinForms application uses the Audit Trail module, remove the code that registers it from the WinForms application.

    In the Startup.cs file, modify the code in the ApplicationBuilder.BuildApplication method so that the DbContext is configured without the audit feature:

    public static WinApplication BuildApplication(string connectionString) { 
        //... 
        builder.ObjectSpaceProviders 
            .AddEFCore() 
                // Remove the code below. 
                //.WithAuditedDbContext(contexts => { 
                //    contexts.Configure<MySolutionEFCoreDbContext, MySolutionAuditingDbContext>( 
                //        (application, businessObjectDbContextOptions) => { 
                //            businessObjectDbContextOptions.UseSqlServer(connectionString); 
                //            businessObjectDbContextOptions.UseChangeTrackingProxies(); 
                //            businessObjectDbContextOptions.UseObjectSpaceLinkProxies(); 
                //        }, 
                //        (application, auditHistoryDbContextOptions) => { 
                //            auditHistoryDbContextOptions.UseSqlServer(connectionString); 
                //            auditHistoryDbContextOptions.UseChangeTrackingProxies(); 
                //            auditHistoryDbContextOptions.UseObjectSpaceLinkProxies(); 
                //        }); 
                //}) 
                // Add the code below.
                .WithDbContext<MySolutionEFCoreDbContext>((application, options) => { 
                    options.UseMiddleTier(application.Security); 
                    options.UseChangeTrackingProxies(); 
                    options.UseObjectSpaceLinkProxies(); 
                }) 
    }
    

Run the Application

Right-click the Solution node in the Solution Explorer and choose Properties. In the Solution Property Pages dialog, expand the Common Properties node and select Startup Project. Choose the Multiple Startup Projects option and select the Start action for the Web API and MySolution.Win projects.

Run a WinForms Application with Middle Tier Security

Click the Run button to run the application.

See Also
Add EF Core Middle Tier Security to an Existing WinForms Application