Chapter 14: Internet - Web to Remote WCF Using Transport Security (Trusted Subsystem, TCP)
Applies To
- Microsoft® Windows Communication Foundation (WCF) 3.5
Scenario
In this scenario, your users do not have Windows accounts and use a Web client to connect over the Internet to an ASP.NET application on an Internet Information Services (IIS) server. The business logic called by the WCF service is backed by a Microsoft SQL Server® data store. The basic model for this application scenario is shown in the following figure.
Figure 1
Web to Remote WCF Using Transport Security (Trusted Subsystem, TCP) – Model
Key Characteristics
This scenario applies to you if:
- Your users have Web clients.
- Your user accounts are stored in SQL Server.
- Your user roles are stored in SQL Server.
- The business logic behind your WCF service does not require fine-grained authorization.
- Your application transmits sensitive data over the network that needs to be protected.
- A high-performance connection between the ASP.NET application and the WCF service is more important than the ability to host the WCF service in IIS.
Solution
Figure 2
Web to Remote WCF Using Transport Security (Trusted Subsystem, TCP) – Solution
Solution Summary Table
In this solution, you will:
- Use a username and password to authenticate users against the SQL Server membership provider.
- Use a service account to call WCF from the ASP.NET application.
- Use a service account to call the SQL Server from WCF.
- Use Secure Sockets Layer (SSL) encryption to protect sensitive data between the Web client and IIS.
- Use transport security to protect sensitive data between the ASP.NET application and the WCF service.
- Use netTcpBinding to support the Transmission Control Protocol (TCP) transport for improved performance.
- Host WCF in a Windows service because IIS does not support the TCP transport.
Web Server
Checks / more information |
---|
IIS—cConfiguration |
A dedicated application pool is created and configured to run under a custom service account. Use a domain account if possible. |
The Web application is configured to run under the service account. Assign the Web application to the custom application pool. |
IIS—authentication |
The IIS virtual directory is configured to use Anonymous access. Users will be allowed to access pages and, if required, will be redirected to the Forms authentication page. |
Checks / more information |
Example |
---|---|
ASP.NET—configuration |
|
An ASP.NET database is created for the SQL Server membership provider and SQL server role provider. Aspnet_regsql.exe creates the SQL Server database to store the user and role information. |
|
The connection string is configured to point to the user and role store in SQL Server. The database connection string includes Integrated Security=SSPI or Trusted Connection=Yes for Windows authentication. |
|
Web application process identity is given access permissions on the ASP.NET database. Your Web application process identity requires access to the aspnetdb database. If you host the Web application in IIS 6.0 on Microsoft Windows Server® 2003, the NT AUTHORITY\Network Service account is used by default to run the Web application. |
|
ASP.NET—authentication |
|
ASP.NET is configured for Forms authentication. The Web application will authenticate the users. |
|
ASP.NET application is configured to deny access to all unauthenticated users. Only authenticated users will be able to access the application. |
|
SqlMembershipProvider is configured to use the membership feature for Forms authentication. The membership feature helps protect credentials, can enforce strong passwords, and provides consistent APIs for user validation and secure user management. The membership feature also automatically creates the authentication ticket for you. |
|
ASP.NET—authorization |
|
The Role Manager feature is enabled and SqlRoleProvider is configured for roles authorization. The Role Manager feature allows you to look up users’ roles without writing and maintaining code. Additionally, the role providers offer a consistent way for you to check the role membership of your users, regardless of the underlying data store. |
|
Role checks are performed using Role Manager APIs. |
|
Checks / more information |
Example |
---|---|
WCF proxy |
|
ASP.NET has a proxy reference to the WCF service. The application has access to the WCF metadata in order to create a service reference. |
|
The proxy invokes services using the security context of service account. The proxy will automatically invoke WCF operations using the security context of the service account. |
|
WCF proxy—caller identity |
|
For auditing purposes, the identity of the caller can be passed in custom message headers during the proxy call. Additionally, custom headers can be defined in message contracts or service contracts. Use transport security to protect against spoofing attacks. |
|
Application Server
Checks / more information |
---|
Windows service—configuration |
The Windows service is configured to run under a custom domain service account. Use a domain account if possible. |
The WCF service is hosted in a Windows service. Because IIS does not support netTcpBinding, host it in Windows service. |
Checks |
Example |
---|---|
WCF service—configuration |
|
Configure the WCF service to use netTcpBinding. netTcpBinding uses the Transmission Control Protocol (TCP) and provides full support for Simple Object Access Protocol (SOAP) security, transactions and reliability. Because the client and WCF service are both located in an Intranet, this is a good choice from a performance perspective. |
|
A metadata exchange (mex) endpoint is created for publishing the metadata. This is required so that the client can add a reference to the WCF service using the SvcUtil utility. |
|
Service metadata is configured in the service behavior. The service metadata entry is required for the Windows service host to start. Both HTTP and HTTPS GET requests are disabled. |
|
WCF service—authentication |
|
netTcpBinding is configured to use Windows authentication and transport security. By default, netTcpBinding is configured to use Windows authentication and transport security. |
|
WCF service—caller Identity |
|
The service retrieves the identity of the caller from the OperationContext for auditing purposes. Use the identity to improve logging and auditing. |
|
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. |
|
The database connection is opened using the WCF process identity’s security context. The service does not impersonate the original caller to benefit from connection pooling. |
Database Server
Checks / more information |
Example |
---|---|
Configuration |
|
A SQL Server login is created for the WCF’s service account (process identity). This grants access to the SQL Server. |
|
The login is mapped to a database user for the Web application. This grants access to the specified database. |
|
A database role is created in the target database. This allows access control and authorization to the databse. |
|
The login is added to the database role. Grant minimum permissions. For example, grant execute permissions to selected stored procedures, and provide no direct table access. |
|
Authentication |
|
SQL Server is configured to use Windows authentication. |
Communication Security
What |
Checks |
More Info |
---|---|---|
Browser to Web server |
SSL is used between the browser and Web server to protect sensitive data on the wire. |
Install a certificate in the Web site. Configure the virtual directory of the Web application to use SSL. |
Application server to database server |
You can use IPSec or SSL between the application server and the database server to protect sensitive data on the wire. |
Analysis
Web Server
Authentication
- Anonymous access in IIS is enabled to allow unauthenticated and unauthorized users to access pages and redirect to the login page.
- Forms authentication is a good choice for this scenario because users come from the Internet and have accounts in SQL Server.
- The Membership feature is a good choice to use with Forms authentication, as it allows you to authenticate users without writing and maintaining custom code.
Authorization
- URL authorization performs role checks against the original caller and restricts access to pages based on role permissions.
- All authorization checks occur in the Web application before it makes calls to the WCF service. The WCF service trusts the Web application to perform this authorization and does not need to make fine-grained authorization decisions of its own.
- The Role Manager is a good choice for this scenario because it allows the application to look up users’ roles without writing and maintaining custom code.
WCF Proxy
- Because you are taking care of all authentication and authorization in the ASP.NET application, all calls through the WCF proxy and into the WCF service use the ASP.NET process identity’s security context.
- If you need to produce audit logs showing what service operations each user called, you can pass the identity of the original caller in a custom header.
Configuration
- In order to reduce the attack surface and minimize the impact of a compromise, the ASP.NET application on the Web server runs under the security context of the service account, using a least-privileged account.
Application Server
Authentication
- WCF is configured to use Windows authentication in order to authenticate the ASP.NET service when it makes calls into the WCF service.
Authorization
- Because the WCF Service trusts the ASP.NET application to authorize the user, the WCF service performs no authorization.
Data Access
- To reduce the risk of stolen database credentials, the database connection string is configured to use Windows authentication. This choice eliminates the need to store credentials in files and pass credentials over the network to the database server.
- The WCF service accesses the database using the WCF process identity. As a result, all calls use the single process account and designated database connection pooling.
Configuration
- This scenario is optimized around transmission performance at the expense of interoperability with clients that expect a legacy Web service and the ability to host the service in IIS. For this reason, the best binding choice is netTcpBinding. By default, netTcpBinding supports Windows authentication with transport security.
- Because IIS 6.0 does not support netTcpBinding, the WCF service is hosted in a Windows service.
- In order to reduce the attack surface and minimize the impact of a compromise, the Windows Service is running under the security context of the service account, using a least-privileged account.
- A mex endpoint is exposed to make it possible for the client to generate a proxy based on the service definition.
Database Server
- SQL Server database user roles are preferred over SQL Server application roles to avoid the password management and connection pooling issues associated with the use of SQL Server application roles. Applications activate SQL Server application roles by calling a built-in stored procedure with a role name and a password. Therefore, you must store the password securely. You must also disable database connection pooling when you use SQL Server application roles, which severely impacts application scalability.
- Creating a new user-defined database role and adding the database user to the role lets you give specific minimum permissions to the role. In this way, if the database account changes, you do not have to change the permissions on all database objects.
Communication Security
- SSL protects sensitive data on the wire between the browser and Web server.
- Transport security protects sensitive data between the Web server and application server.
- You can use IPSec or SSL between the application server and database server to protect sensitive data on the wire.
Example
Web Server
Code
- A form is created in order to perform Forms authentication.
- Role authorization occurs before WCF service invocation.
- ASP.NET calls the WCF service if it is authorized.
- The original caller’s identity is retrieved from the user ticket context.
- A message header containing the caller identity is created and passed to the operation context for auditing purposes.
The following code example shows a form that performs Forms authentication:
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Login.aspx.cs" Inherits="Login" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head >
<title>Untitled Page</title>
</head>
<body>
<form id="form1" >
<div>
</div>
<asp:Login ID="Login1" >
</asp:Login>
<asp:CreateUserWizard ID="CreateUserWizard1" >
<WizardSteps>
<asp:CreateUserWizardStep />
<asp:CompleteWizardStep />
</WizardSteps>
</asp:CreateUserWizard>
</form>
</body>
</html>
//Proxy call invocation
using System.ServiceModel;
using System.ServiceModel.Channels;
…
protected void Button1_Click(object sender, EventArgs e)
{
if (User.IsInRole("accounting"))
{
WCFTestService.MyServiceClient proxy
= new WCFTestService.MyServiceClient();
using (OperationContextScope scope
= new OperationContextScope(proxy.InnerChannel))
{
string identity = User.Identity.Name;
MessageHeader<string> headerIdentity
= new MessageHeader<string>(identity);
MessageHeader untypedMessageHeader
= headerIdentity.GetUntypedHeader("identity", "ns");
OperationContext.Current.OutgoingMessageHeaders.Add(untypedMessageHeader);
proxy.GetData("data");
}
proxy.Close();
} //endif
} //end function
Configuration
- Windows and anonymous authentication are enabled.
- Connection strings to SqlMembershipProvider and SqlRoleProvider are configured.
- SQLMembershipProvider is enabled.
- Only authenticated users are allowed to browse the site.
- Role Manager is enabled.
<configuration>
…
<connectionStrings>
<add name="MyLocalSQLServer" connectionString="Initial
Catalog=aspnetdb;data source=10.3.19.60;Integrated Security=SSPI;"/>
</connectionStrings>
<system.web>
<membership defaultProvider="MySqlMembershipProvider">
<providers>
<clear/>
<add name="MySqlMembershipProvider"
connectionStringName="MyLocalSQLServer"
applicationName="MyAppName"
type="System.Web.Security.SqlMembershipProvider"/>
</providers>
</membership>
<roleManager enabled="true" defaultProvider="MySqlRoleProvider">
<providers>
<clear/>
<add name="MySqlRoleProvider"
connectionStringName="MyLocalSQLServer"
applicationName="MyAppName"
type="System.Web.Security.SqlRoleProvider"/>
</providers>
</roleManager>
<authentication mode="Forms"/>
<authorization>
<deny users="?"/>
<allow users="*"/>
</authorization>
<pages>
<controls>
<add tagPrefix="asp"
namespace="System.Web.UI"
assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
<add tagPrefix="asp"
namespace="System.Web.UI.WebControls" assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
</controls>
</pages>
<httpHandlers>
<remove verb="*" path="*.asmx"/>
<add verb="*" path="*.asmx" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
<add verb="*" path="*_AppService.axd" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
<add verb="GET,HEAD" path="ScriptResource.axd" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" validate="false"/>
</httpHandlers>
<httpModules>
<add name="ScriptModule" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
</httpModules>
</system.web>
Application Server
Code
- The service retrieves the identity of the caller from the operation context if it is required for auditing purposes.
- The service calls SQL Server using the security context of the WCF service.
using System.Data.SqlClient;
public string GetData(string myValue)
{
SqlConnection sqlcon = new
SqlConnection("Server=SqlServer;Database=testdb;Integrated Security=SSPI");
sqlcon.Open();
//do the business operation
string identity = OperationContext.Current.IncomingMessageHeaders.GetHeader<string>("identity", "ns");
return “some data” ;
}
Configuration
- The service has a binding endpoint that uses netTcpBinding with the default settings.
- The service has a service behavior configuration to publish metadata.
- The service has a base address configured.
- The service behavior is configured with the serviceMedata element to allow metadata exposure.
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="BehaviorConfiguration">
<serviceMetadata />
</behavior>
</serviceBehaviors>
</behaviors>
<bindings />
<services>
<service behaviorConfiguration="BehaviorConfiguration"
name="WCFServicecHost.MyService">
<endpoint address="Mex"
binding="mexTcpBinding"
bindingConfiguration=""
name="MexEndpoint"
contract="IMetadataExchange" />
<endpoint address=""
binding="netTcpBinding"
bindingConfiguration=""
name="TcpBinding"
contract="WCFServicecHost.IMyService" />
<host>
<baseAddresses>
<add
baseAddress="net.tcp://perfpres02.npscode.com/MyService" />
</baseAddresses>
</host>
</service>
</services>
</system.serviceModel>
Database Server
Configuration
- A SQL Server login is created for the WCF service account.
- The WCF login name is given access to the database.
- The role is created in the database.
- The WCF login name is added to the role.
-- Create a SQL Server login that matches the WCF machine name
EXEC SP_GRANTLOGIN 'npscode\perfpres02$'
-- Grant the login access to the application database
use testdb
go
exec sp_grantdbaccess 'npscode\perfpres02$'
-- Create the new database role
use testdb
go
exec sp_addrole 'myrole2','db_owner'
-- Add the new login to the role
use testdb
go
exec sp_addrolemember 'myrole2','npscode\aspnethost'
Additional Resources
- For more information on security authentication best practices, see Best Practices for Security in WCF.
- For additional information on message security, see Message Security in WCF.
- For more information on hosting in a Windows service, see How to: Host WCF in a Windows Service Using TCP.
- For more information on WCF hosting considerations, see Hosting Services.
- For more information on netTcpBinding configuration options, see <netTcpBinding>.