Tải bản đầy đủ
Objective 3.4: Secure a WCF Service

Objective 3.4: Secure a WCF Service

Tải bản đầy đủ

Think of how you interact with your bank. You make deposits and withdrawals that are
your business and no one else’s (at least no one you don’t approve of). Some people don’t
care about personal privacy, but in general, you wouldn’t want just anyone to have access to
your bank transactions. By having access to them, they’d know how much money you make,
how much you spend, where you shop, what you buy, and a lot of other information that
most people consider private.
When you make a deposit, you want to make sure that the correct amount is reflected and
that it’s credited to your account correctly. You wouldn’t want the teller to be able to give you
a receipt showing you deposited $10,000 but have only $1,000 of it actually deposited in your
account.
Similarly, you expect that the bank ensures that you or authorized parties are the only
ones who can conduct transactions with your account. If all someone had to do was go to
your bank and say they were you in order to withdraw money, it’s pretty much a certainty
someone who is less-than-honest would help themselves to your savings.
WCF and its security infrastructure handle these elements if you configure it to do so.
However, it’s important also to take measures of your own in most cases to ensure each of
these objectives—but such measures are to be done in addition to, not in place of these
features. This objective isn’t concerned with security in general; it is concerned with security
specifically related to WCF (and in this section, messages).
To secure the message, you simply need to set the Security.Mode property to the corresponding binding’s SecurityMode enumeration indicating that message security should
be set. Each of the binding examples illustrated earlier showed one of the constructors that
enabled you to set the respective security mode. For the wsHttpBinding, for example, you can
use either of these approaches:
public void ShowMessageSecurity(){
// Set Security Mode to Message in Constructor
WSHttpBinding WsHttpSecurity = new WSHttpBinding(SecurityMode.Message);
// Use default constructor
WSHttpBinding wsHttpSecurity2 = new WSHttpBinding();
// Set the Security property manually
wsHttpSecurity2.Security.Mode = SecurityMode.Message;
}

The actual Mode property type for the wsHttpBinding is the SecurityMode enumeration. If
you were trying to accomplish the same goal with the basicHttpBinding, the Mode property is
of type BasicHttpSecurityMode. If it’s a netNamedPipeBinding, the Mode property is of type
NetNamedPipeSecurityMode.
The alternative approach is to specify it through configuration. For any binding that you
have configured, the WCF Service Configuration Editor has both a Binding and a Security
tab. The Security tab features a Mode drop-down list, and you simply specify Message as the
mode for the binding you’re configuring. Figure 3-19 shows the value set via the WCF Service
Configuration Editor.

228

CHAPTER 3

Designing and implementing WCF Services

FIGURE 3-19  Configuring message level security

If you examine the configuration file after setting this particular value, you won’t see any
mention of security, mode, or message because wsHttpBinding enables message level security by default. However, if you want to declare it explicitly, it works just as you expect it to:






Implementing transport level security
Transport security works virtually identically, except that you need to set the Mode property
to Transport instead of Message. Using the same examples as before, the following enables
transport level security instead of message security.
public void ShowMessageSecurity()
{
// Set Security Mode to Message in Constructor
WSHttpBinding WsHttpSecurity = new WSHttpBinding(SecurityMode.Transport);
// Use default constructor
WSHttpBinding WsHttpSecurity2 = new WSHttpBinding();
// Set the Security property manually
WsHttpSecurity2.Security.Mode = SecurityMode.Transport;
}



Objective 3.4: Secure a WCF service

CHAPTER 3

229

Using the WCF Service Configuration Editor, you simply flip the Mode property from
Message to Transport, as shown in Figure 3-20.

FIGURE 3-20  Configuring transport level security

The resulting XML in the configuration file would look like this:






For transport level security to be implemented, you must choose either Transport or
TransportWithMessageCredential for the Mode value of the binding. Using the WCF Service
Configuration Editor or hard-coding it, it works exactly the same way.

Implementing certificates
To use certificates, you need to add a reference to the System.Security.dll. After a certificate is installed, the rest of the process is all downhill. Assume that you have a
netHttpBinding already added to your service. You simply need to tweak the
and bindings associated with it so the Mode value of the Security property is
“TransportWithMessageCredential,” and the ClientCredentialType property of the message
element is a certificate. After configuration, the only remaining step is ensuring that the

230

CHAPTER 3

Designing and implementing WCF Services

certificate is installed on the client, getting a reference to it, and adding it to the Certificate
property of the ClientCertificate property of the Credentials property of your host.
A typical sample looks like this:
var MyFactory = new ChannelFactory("*");
MyFactory.Credentials.ClientCredentials.Certificate = X509.CurrentUser.
My.SubjectDistinguishedName.Find("CN=CLIENT").FirstOrDefault();

Thought experiment
How much should you secure?
In the following thought experiment, apply what you’ve learned about this objective to secure a WCF Service. You can find answers to these questions in the “Answers” section at the end of this chapter.
You are building several WCF Services, and some will employ sensitive information.
Others transfer information that is completely public and are intended to be as easy
to use as possible. Your service will be hosted internally, so you have full access to it
without any real restrictions.
With this in mind, answer the following questions:

1. For the secure information, would you choose message level security, transport
level security, or both?

2. For the less-sensitive information, would you still want to implement any
security?

3. Would certificate-based security be a good fit for either scenario?

Objective summary
■■

■■

■■



The three goals of security in this context can be remembered by the acronym CIA:
confidentiality, integrity, and authentication.
Messages can be secured. This means that the message is not viewable without the
corresponding key, but the cypher text can be viewed directly while it’s being transported over the wire.
The transport can be secured as well. In this case, the message could be left in plain
text, but everything transferred across the channel is encrypted, thereby making it difficult (not impossible, but difficult to the point of being impractical) for prying eyes to
watch what’s going on.

Objective 3.4: Secure a WCF service

CHAPTER 3

231

■■

■■

You have to be careful not to give away information accidentally. Although you want
to secure the message or channel or both, don’t forget to validate user input, which is
often malicious and one of the most open attack vectors.
Remember that security is always a trade-off. You can spend $1,000,000 on a state-ofthe-art safe that guards the contents of your refrigerator. Although it would certainly
keep your food safe, the cost far outweighs the value. Most mistakes are made by
overlooking security, not overdoing it, but there’s a balance that needs to be achieved
between user-friendliness and security, and that balance point will likely change dramatically through the life of the application.

Objective review
Answer the following questions to test your knowledge of the information in this objective.
You can find the answers to these questions and explanations of why each answer choice is
correct or incorrect in the “Answers” section at the end of this chapter.
1. You are using IIS to host a WCF Service. Which of the following would help implement

transport security over http (https) without removing previously existing functionality?
A. The new Https protocol mapping feature
B. Use of a wsHttpsBinding instead of a wsHttpBinding
C. Enabling https for the virtual directory that contained the WCF Service items
D. Ensuring that a metadata is enabled for the service
2. Which of the following are true regarding WCF security? (Choose all that apply.)
A. You can implement message level security
B. You can implement transport level security
C. You can implement both transport level and message level security
D. Transport security can be enabled, and message security can be enabled, but they

cannot both be enabled at the same time
3. You are developing a WCF Service. The service must implement transport security,

NTLM authentication, and NetTcpBindings. Which of the following do you need?
(Choose all that apply.)
A. binding value of netTcpBinding
B. clientCredentialType of netTcpBinding
C. clientCredentialType of Transport
D. security mode value of Transport

232

CHAPTER 3

Designing and implementing WCF Services

Objective 3.5: Consume WCF services
To consume a service, you need some basic information about it. That information can come
from the vendor, or from the service, or it can be dynamically discovered. From a consumption perspective, though, you typically create a proxy class and communicate with that class.
The proxy, in conjunction with information provided about the service details, handles all the
communication. Ultimately, dealing with a WCF Service should be no different from dealing with any statically referenced library. There are three ways to interact with the service,
two of which accomplish the same task, just doing it slightly differently. The first is using the
Svcutil.exe application to generate a proxy class. The next is to generate the proxy using the
Add Service Reference feature of Visual Studio. These two do the same thing, but entail different actions on your part. The final way is to use the ChannelFactory class.

This objective covers how to:
■■

Generate proxies using Svcutil.exe

■■

Generate proxies by creating a service reference

■■

Create and implement channel factories

Generating proxies using Svcutil.exe
As discussed previously, WCF clients can interact with services by generating a proxy class and
interacting with it. Svcutil.exe is a command-line tool that is used for generating proxy classes,
among other things.
MORE INFO  RUN SVCUTIL.EXE FROM THE VISUAL STUDIO COMMAND PROMPT

Svcutil.exe is a command-line utility, so it is typically called directly from the command
window. However, if you call it from the Windows command window, Windows does not
recognize it unless you first navigate to the directory in which it resides. You can set an
Environment variable that specifies a path to it, but it’s probably not something you’ll use
frequently enough to necessitate doing so. Instead, just remember to launch it from the
Visual Studio command prompt, and it will come right up.

Normally, I recommend doing exactly the opposite of what I recommend here. For one
thing, it’s something you can always just look up; secondly it’s not typically a good way to
prepare for an exam. But based on all the certification exams I’ve taken over the years, I’m
making an exception here. Don’t just know the “big picture” of what Svcutil.exe does and focus
on the conceptual aspects. Look at it in-depth. Create a few different services (they can all be
completely basic and even just provide the template functions that Visual Studio generates)
and then generate proxies for each of them using Svcutil.exe. Seeing the behavior, seeing the
results, and seeing the impact of different switches all help to drive home what the tool does
and how it works. Although memorizing command-line switches is not normally a great use


Objective 3.5: Consume WCF services

CHAPTER 3

233

of time or energy, other command-line tools, such as aspnet_regiis and similar ones, have featured prominently on exams (likely because they are fairly easy to write questions for).
Before going further, take a look at the following list of items the Svcutil.exe tool can do:
■■

Generates proxy classes based on existing services or metadata documents. Keep in
mind that, if you use the same parameters or supply values that correspond to existing
files, vcutil.exe will overwrite the existing items. You can use the /mergeConfig switch
to minimize problems associated with it.

■■

Exports metadata documents from compiled service code.

■■

Validates service code.

■■

Downloads metadata documents from existing services.

■■

Generates serialization code.

Now, take a look at Table 3-7 and pay close attention to each switch and what it accomplishes (note that N/A in the Shortcut section means there is no shortcut available, not that
N/A is the shortcut):
TABLE 3-7  Svcutil.exe command-line options

234

Switch

Behavior

Shortcut

/directory:

Specifies the output directory in which the generated files
will be placed. If no value is specified, it uses the current
directory for the output. If the directory has already been
used, output will be overwritten if the utility is run with this
switch.

/d

/help

Shows the available command-line options. Very unlikely
to appear on the test, but if it does, something in the
stem will mention “help” or indicate “you need to list the
available command-line options for Svcutil.exe, which of the
following….”

/?

/noLogo

Suppresses the “Logo” information (copyright and banner
message).

N/A

/svcutilConfig:

Puts the configuration information in a file other than the
default App.config file. You can also use this option to register the elements without changing
the tool’s configuration file.

N/A

/target:

Instructs the tool to create a specific output. You can use one
of three options:
code
metadata
xmlSerializer

/t

/asnyc

Creates the proxy class with both standard and asynchronous method signatures. By default, just the standard method signatures are included, so if you see any indication that
the asynchronous methods need to be included, anything
without the /async option will not be the answer.

/a

/internal

Generates the methods using the internal access modifier
instead of generating them as public.

/i

CHAPTER 3

Designing and implementing WCF Services

Switch

Behavior

Shortcut

/serializer

Generates data types using a specific serializer. Available
options are these:
Auto
DataContractSerializer
XmlSerializer
Typically, you’ll want to use DataContractSerializer unless
you have a specific need to use XmlSerializer.

/ser

/out

Specifies a file name for the generated code.

/o

/language

Causes the output to be generated in a specific language.
Available options are the following:
c#
cs
csharp
vb
visualbasic
c++
cpp

/l

Generating proxies by creating a service reference
There’s little surface area to test when it comes to this feature. There are only a few things
that can be asked besides just knowing that it’s an option.
To use it, select your project, right-click the project node, and choose the Add Service
Reference option. Or on the Visual Studio menu bar, select the Project menu and then choose
the Add Service Reference option. Figure 3-21 shows this menu.

FIGURE 3-21  Add Service Reference menu



Objective 3.5: Consume WCF services

CHAPTER 3

235

You see the dialog box shown in Figure 3-22.

FIGURE 3-22  Add Service Reference dialog box

If the service isn’t hosted, but is in the solution, you can use the Discover button on the
right side of the dialog box, which gives you the option to use services it finds inside of the
current solution. Otherwise, you need to provide a URL that has metadata enabled and then
click the Go button.
After you click Go, the services it finds are listed. In many cases, there is just one, but
multiple services are possible (particularly if you use the Discover option and have multiple
services in your solution). It enables you to specify a namespace, which is something you generally should do. If there’s an error (or an authentication requirement, in some cases), you’ll
either see an error message and the details of the error (if they’re available), or you’ll see the
Authentication dialog box.
EXAM TIP

For test questions, the only things that you might be asked about on this portion are
whether to use the Go feature coupled with a URI, the Discover option, or about specifying
a specific namespace.

Notice the Advanced button on the bottom. If you need to take control and specify items
outside of the default proxy, you can use the Service Reference Settings dialog box, which
displays when you click the Advanced button. It’s shown in Figure 3-23.

236

CHAPTER 3

Designing and implementing WCF Services

NOTE  SVCUTIL.EXE COMMAND-LINE SWITCHES

The previous items are the most commonly used values, but there are some others. A
complete list is available on MSDN, and yes, it’s probably worth the investment to learn
the names of each and what they do. The MSDN coverage is available here http://msdn.
microsoft.com/en-us/library/aa347733.aspx, and you can find more information about it
at http://www.svcutil.com/. In the simplest form, just open up the Visual Studio command
prompt and type the following:
svcutil http://service/metadataEndpoint

Assuming that the metadata exchange is available, call Svcutil and use the URI of the
service. This works without any other command-line parameters because it uses default
values for everything. A more common approach involves specifying at least a few of the
parameters. Assume that you want to generate the proxy class for the TestService discussed throughout the chapter and have the proxy named Test​Service​Proxy. Either of the
following works:
C#
svcutil.exe /language:cs /out:TestServiceProxy.cs /config:app.config
http://www.williamgryan.mobi/487/TestService
svcutil.exe /language:c# /out:TestServiceProxy.cs /config:app.config
http://www.williamgryan.mobi/487/TestService
VB.NET
svcutil.exe /language:vb /out:TestServiceProxy.vb /config:app.config
http://www.williamgryan.mobi/487/TestService
svcutil.exe /language:visualbasic /out:TestServiceProxy.vb /config:app.
config http://www.williamgryan.mobi/487/TestService

It’s not possible to cover every single scenario and show you an example of each. Instead,
read about the features, and then generate multiple files using different switches. Also, try
both mechanisms, generating a proxy based on a live service and generating a proxy based
on assembly references.



Objective 3.5: Consume WCF services

CHAPTER 3

237

FIGURE 3-23  Service Reference Settings dialog box

At the top you’ll notice the option to specify the access modifier. This corresponds to the
/internal command-line switch. The next option is the Allow generation of asynchronous
operations check box. If you choose it, the proxy class generates methods that contain the
methods defined in the service and their asynchronous counterparts.
You have the option to Always Generate Message Contracts, which does what its name
implies: generate message contract types.
The Collection Type option enables you to set the default collection type. If you are using a
.NET client that’s using the .NET Framework 2.0 or later, you can use generic collection types.
However, generics are supported only in .NET (there might be counterparts or similar features
in other languages, but as implemented in the .NET Framework, generics are a technologyspecific feature), so for compatibility, the proxy class generates anything typed as a generic
collection as an array. This helps ensure that other technologies can use the service. Many
people have used List in a service, and noticed that the proxy class ends up creating
Type[] definitions instead. You can change this behavior, but remember that doing so has
consequences. The Reuse Types In Specified Referenced Assemblies option enables type sharing of anything that already exists in a statically referenced assembly on your client. You can
opt to do this globally, which is the default behavior, or specify that only some reuse happens.
238

CHAPTER 3

Designing and implementing WCF Services