Client Application Services is a .NET Framework feature that bridges the gap between desktop applications and ASP.NET’s built-in authentication and authorization infrastructure. It allows Windows Forms and WPF applications to use ASP.NET membership, roles, and profile services without building a custom authentication system from scratch. This guide explains how the feature works, how to set it up, and what modern alternatives exist.
What Client Application Services Provides
In web applications built with ASP.NET, developers have access to a rich authentication and authorization system including Forms authentication, membership providers, role providers, and profile providers. Client Application Services extends this infrastructure to desktop applications.
The three main services are:
- Authentication: Validates user credentials against the ASP.NET membership database using Forms authentication.
- Roles: Retrieves role membership for the authenticated user to enable role-based authorization in the desktop application.
- Profiles: Accesses user profile properties (settings) stored on the server.
Architecture Overview
The architecture involves two components:
-
ASP.NET Web Application: Hosts the authentication, role, and profile web services. This application uses the standard ASP.NET membership and role providers backed by a database (typically SQL Server with
aspnet_regsql). -
Desktop Application: A Windows Forms or WPF application that uses client-side providers to communicate with the web services over HTTP.
+-------------------+ HTTP +--------------------+
| Windows/WPF App | <------------------> | ASP.NET Web App |
| (Client Providers)| | (Membership/Roles/ |
| | | Profile Services) |
+-------------------+ +--------------------+
|
+--------+--------+
| SQL Server DB |
| (aspnetdb) |
+-----------------+
Setting Up the ASP.NET Service Host
Create the Membership Database
Use the aspnet_regsql tool to create the ASP.NET services database:
aspnet_regsql -S localhost -E -A all -d MyAppServicesDB
Parameters:
-S: SQL Server instance-E: Use Windows authentication-A all: Add all features (membership, roles, profiles)-d: Database name
Configure the Web Application
In the ASP.NET web application’s web.config, enable the required services:
<configuration>
<system.web>
<authentication mode="Forms">
<forms name=".ASPXAUTH" loginUrl="Login.aspx" />
</authentication>
<membership defaultProvider="SqlMembershipProvider">
<providers>
<add name="SqlMembershipProvider"
type="System.Web.Security.SqlMembershipProvider"
connectionStringName="AppServices"
applicationName="MyApp" />
</providers>
</membership>
<roleManager enabled="true" defaultProvider="SqlRoleProvider">
<providers>
<add name="SqlRoleProvider"
type="System.Web.Security.SqlRoleProvider"
connectionStringName="AppServices"
applicationName="MyApp" />
</providers>
</roleManager>
<profile enabled="true" defaultProvider="SqlProfileProvider">
<providers>
<add name="SqlProfileProvider"
type="System.Web.Profile.SqlProfileProvider"
connectionStringName="AppServices"
applicationName="MyApp" />
</providers>
<properties>
<add name="DisplayName" type="String" />
<add name="Theme" type="String" defaultValue="Default" />
</properties>
</profile>
</system.web>
<connectionStrings>
<add name="AppServices"
connectionString="Data Source=localhost;Initial Catalog=MyAppServicesDB;Integrated Security=True"
providerName="System.Data.SqlClient" />
</connectionStrings>
</configuration>
Configuring the Desktop Application
Enable Client Application Services
In Visual Studio:
- Right-click the Windows Forms or WPF project and select Properties.
- Go to the Services tab.
- Check Enable client application services.
- Configure the service locations:
- Authentication service location:
http://localhost:port/Authentication_JSON_AppService.axd - Roles service location:
http://localhost:port/Role_JSON_AppService.axd - Web settings service location:
http://localhost:port/Profile_JSON_AppService.axd
- Authentication service location:
- Choose Use Forms authentication and specify the URL.
Manual Configuration in app.config
You can also configure the providers directly in the application configuration:
<configuration>
<system.web>
<membership defaultProvider="ClientAuthenticationMembershipProvider">
<providers>
<add name="ClientAuthenticationMembershipProvider"
type="System.Web.ClientServices.Providers.ClientFormsAuthenticationMembershipProvider, System.Web.Extensions"
serviceUri="http://localhost:5000/Authentication_JSON_AppService.axd" />
</providers>
</membership>
<roleManager enabled="true" defaultProvider="ClientRoleProvider">
<providers>
<add name="ClientRoleProvider"
type="System.Web.ClientServices.Providers.ClientRoleProvider, System.Web.Extensions"
serviceUri="http://localhost:5000/Role_JSON_AppService.axd"
cacheTimeout="86400" />
</providers>
</roleManager>
</system.web>
</configuration>
Using Authentication in Code
Validating Credentials
// Validate user credentials
bool isValid = Membership.ValidateUser(username, password);
if (isValid)
{
// User is authenticated
MessageBox.Show($"Welcome, {username}!");
}
else
{
MessageBox.Show("Invalid credentials.");
}
Role-Based Authorization
// Check if the current user is in a specific role
if (Thread.CurrentPrincipal.IsInRole("Administrator"))
{
// Show admin features
adminPanel.Visible = true;
}
else
{
adminPanel.Visible = false;
}
Implementing a Custom Login Form
public class CustomCredentialsProvider : IClientFormsAuthenticationCredentialsProvider
{
public ClientFormsAuthenticationCredentials GetCredentials()
{
var loginForm = new LoginForm();
if (loginForm.ShowDialog() == DialogResult.OK)
{
return new ClientFormsAuthenticationCredentials(
loginForm.Username,
loginForm.Password,
loginForm.RememberMe);
}
return null;
}
}
Offline Support
Client Application Services supports offline credential caching:
<add name="ClientAuthenticationMembershipProvider"
type="System.Web.ClientServices.Providers.ClientFormsAuthenticationMembershipProvider"
serviceUri="http://localhost:5000/Authentication_JSON_AppService.axd"
credentialsProvider="MyApp.CustomCredentialsProvider, MyApp"
savePasswordHashLocally="True" />
When savePasswordHashLocally is True, a hash of the password is cached on the client. If the service is unreachable, the application validates against the cached hash.
Modern Alternatives
Client Application Services is a .NET Framework-only feature. For modern applications, consider these alternatives:
| Approach | Best For |
|---|---|
| ASP.NET Core Identity + Web API | Custom authentication with full control over the user store |
| OAuth 2.0 / OpenID Connect | Delegated authentication using standards-based protocols |
| Azure Active Directory / Entra ID | Enterprise applications using Microsoft’s cloud identity platform |
| MSAL (Microsoft Authentication Library) | Desktop apps authenticating against Azure AD or Azure AD B2C |
| IdentityServer / Duende IdentityServer | Self-hosted OpenID Connect and OAuth 2.0 server |
| Windows Authentication | Intranet applications in Active Directory environments |
Example: Modern Authentication with MSAL
var app = PublicClientApplicationBuilder
.Create(clientId)
.WithAuthority(AzureCloudInstance.AzurePublic, tenantId)
.WithRedirectUri("http://localhost")
.Build();
var result = await app.AcquireTokenInteractive(scopes)
.ExecuteAsync();
// Use result.AccessToken to call APIs
Summary
.NET Client Application Services enables Windows Forms and WPF applications to use ASP.NET’s authentication, roles, and profile services through HTTP web services. The setup requires an ASP.NET web application hosting the membership services backed by a SQL Server database, and a desktop application configured with client-side providers. While this approach was useful for .NET Framework applications, modern development should use OAuth 2.0/OpenID Connect, MSAL, or ASP.NET Core Identity with Web APIs for authentication in desktop applications.