In this scenario, your users do not have Microsoft Windows® accounts but use a Windows Forms client to make calls to the WCF service through either a WCF or ASP.NET Web services (ASMX) client proxy. User accounts are stored in Microsoft SQL Server®, and users are authenticated with username authentication.
The business logic called by the WCF service is backed by a SQL Server data store. The following figure illustrates the basic model for this application scenario.
|
Checks / more information
|
Example
|
|
IIS—configuration
|
|
A dedicated application pool is created and configured to run under a custom service account.
Use a domain account if possible.
| |
|
The WCF service is configured to run under the service account.
Assign the WCF service to the custom application pool.
| |
|
A custom HTTP module is configured in Web configuration.
The custom HTTP module will authenticate the users against the SQL Server membership provider.
|
<httpModules>
…
<add
name="BasicAuthentication Module"
type="Module.UserNameAuthenticator,Authenticator" />
</httpModules>
|
|
An ASP.NET database is created for use with the SQL Server membership provider and SQL Server role provider.
Aspnet_regsql.exe creates the SQL database to store the user and role information.
|
aspnet_regsql -S .\SQLExpress -E -A r m
|
|
The connection string is configured to point to the user and role stored in SQL Server.
The database connection string includes Integrated Security=SSPI or Trusted Connection=Yes for Windows authentication.
|
<add
name="MyLocalSQLServer"
connectionString="Initial
Catalog=aspnetdb;data
source=localhost;Integrated
Security=SSPI;" />
|
|
The SQL Server membership provider is configured as a membership provider.
The membership feature helps protect credentials, can enforce strong passwords, and provides consistent APIs for user validation and secure user management.
|
<membership defaultProvider="MySqlMembershipProvider">
<providers>
<clear/>
<add name= "MySqlMembershipProvider" connectionStringName="MyLocalSQLServer" applicationName="MyAppName" type="System.Web.Security.SqlMembershipProvider"/>
</providers>
</membership>
|
|
The Role Manager feature is enabled and the SQL Server role provider is configured for roles authorization.
The Role Manager allows you to look up users’ roles without writing and maintaining custom code.
|
<roleManager enabled="true" defaultProvider="MySqlRoleProvider" >
<providers>
<clear/>
<add name="MySqlRoleProvider" connectionStringName="MyLocalSQLServer" applicationName="MyAppName" type="System.Web.Security.SqlRoleProvider" />
</providers>
</roleManager>
|
|
The WCF service process identity is given access permissions to the ASP.NET database.
Your WCF service process identity requires access to the Aspnetdb database.
|
-- Create a SQL Server login for the Network Service account
sp_grantlogin '<<Custom Service Account>>'
-- Grant the login access to the membership database
USE aspnetdb
GO
sp_grantdbaccess '<<Custom Service Account>>', '<<Custom Service Account>>'
-- Add user to database role
USE aspnetdb
GO
sp_addrolemember 'aspnet_Membership_FullAccess', '<<Custom Service Account>>'
sp_addrolemember 'aspnet_Roles_FullAccess', '<<Custom Service Account >>’
|
|
WCF service—configuration
|
|
The WCF Service is configured to use basicHttpBinding.
basicHttpBinding binding uses the HTTP protocol and provides compatibility with ASMX clients.
|
<services>
<service behaviorConfiguration="ServiceBehavior" name="Service">
<endpoint address="" binding="basicHttpBinding" bindingConfiguration="BindingConfiguration"
name="basicEndpoint" contract="IService" />
</service>
</services>
|
|
Service metadata is configured in the service behavior to enable httpsGetEnabled and disable httpGetEnabled.
The service metadata entry is required in order to publish metadata to the clients.
|
<serviceBehaviors>
<behavior name="ServiceBehavior">
<serviceMetadata httpGetEnabled="false" httpsGetEnabled="true" />
</behavior>
</serviceBehaviors>
|
|
The service is configured for ASP.NET compatibility mode, both in configuration and in service implementation.
ASP.NET compatibility mode is necessary because IIS is performing authentication.
|
Configuration
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
…
</system.serviceModel>
Service Implementation
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]
public class Service : IService
|
|
WCF service—authentication
|
|
basicHttpBinding is configured to use transport security and no authentication.
The authentication will be performed by the ASP.NET HTTP module against the SQL Server membership provider.
|
<basicHttpBinding>
<binding name= "BindingConfiguration">
<security mode="Transport">
<transport clientCredentialType="None" />
</security>
</binding>
</basicHttpBinding>
|
|
The SQL Server membership provider is configured to provide user authentication.
The membership feature automatically authenticates and creates the authentication ticket for you.
| |
|
WCF service—authorization
|
|
The Role Manager feature is enabled with aspnetroles, and the provider is configured for roles authorization.
Roles authorization can be performed declaratively or imperatively in the operation contract.
|
<serviceBehaviors>
<behavior name="ServiceBehavior">
<serviceAuthorization principalPermissionMode="UseAspNetRoles" roleProviderName="MySqlRoleProvider" />
</behavior>
</serviceBehaviors>
|
|
A class that derives from IAuthorizationPolicy is implemented to set the principal of the current thread to do declarative authorization, and to set the identity so that it is available in a WCF security context.
The authorization policy class will allow you to assign the principal to the context of WCF, so that users can be authorized. It will also allow you to assign the identity to the context of WCF, so that it can be retrieved from the WCF security context.
| |
|
The authorization policy is included in the configuration file.
|
<authorizationPolicies>
<add policyType="AuthorizationPolicy.HttpContextPrincipalPolicy, AuthorizationPolicy" />
</authorizationPolicies>
|
|
Perform role checks declaratively by using a Windows Identity Token, for checking Microsoft Active Directory group membership.
A declarative role check is preferred over an imperative role check for a service operation.
|
[PrincipalPermission(SecurityAction.Demand, Role = "accounting")]
public string GetData(string message)
{
return "hello";
}
|
|
Perform role checks imperatively using a Windows Identity Token, for checking Active Directory group membership.
If you need more fine-grained authorization control, you can use imperative role checks in the code itself. Use a call to Roles.IsUserInRole to perform the check.
|
public string GetData(string myValue)
{ if(Roles.IsUserInRole(@"Accounting"))
{
//Do something for Accounting role
}
else
{
//Do something for non-accounting role or throw an error
}
}
|
|
WCF service—SQL
|
|
The connection string for the database is configured to use Windows authentication.
The database connection string includes Integrated Security=SSPI or Trusted Connection=Yes.
|
SqlConnection sqlcon = new SqlConnection("Server=SqlServer;Database=Northwind;IntegratedSecurity=SSPI");
|
|
A database connection is opened by using the WCF process identity’s security context.
This happens by default.
| |
The service does imperative or declarative authorization, as shown in the following sections.