Apply Your Knowledge



Apply Your Knowledge

Exercises

Building a Client for a Secure Web Service

In the chapter, you saw how to configure a Web Service to require authentication. But how do you build a client that can supply credentials? In this exercise, you'll learn how to alter the proxy class in a Web service client project to pass the current user's credentials to a Web service, using the StringProc Web service that you constructed in Chapter 4.

Estimated Time: 15 minutes.

  1. Launch Visual Studio .NET. Select File, New, Blank Solution and name the new solution 320C11Exercises.

  2. Add a new Visual C# .NET Windows application named Exercise11_1 to the solution.

  3. In the Solution Explorer, rename the default Form1.cs to Exercise11_1.cs. Open the form in code view and change all occurrences of Form1 to refer to Exercise11_1 instead.

  4. Right-click the References node in Solution Explorer and select Add Web Reference. Enter http://localhost/StringProc/Strings.asmx as the Address and hit Enter, changing the server name to match that of your own Web server. Click Add Reference to add the Web reference.

  5. Add two TextBox controls (txtInput and txtOutput) and a Button control (btnUpperCase) to the form.

  6. Click the Show All Files button on the Solution Explorer toolbar.

  7. Drill into the Web References node until you locate the Reference.cs file. Double-click the file to open it.

  8. Locate the constructor for the class, and modify its code as follows:

    
    public Strings(): base()
    
    {
    
        base.PreAuthenticate = true;
    
        base.Credentials =
    
            System.Net.CredentialCache.
    
            DefaultCredentials;
    
        this.Url =
    
    "http://localhost/StringProc/Strings.asmx";
    
    }
    
    
  9. Double-click the Button control and add this code to handle the Click event (changing localhost to the name of your own server, if the Web server is not a local server):

    
    private void btnUpperCase_Click(
    
        object sender, System.EventArgs e)
    
    {
    
        localhost.Strings s =
    
            new localhost.Strings();
    
        txtOutput.Text = s.ToUpper(
    
            txtInput.Text);
    
    }
    
    
  10. Set the project as the startup project.

  11. Run the project. Enter a string in the input textbox and click the button. After a pause while the Web service is invoked, you'll see the string in uppercase in the output textbox.

The proxy classes that are built by wsdl.exe (which, you'll recall, is invoked when you add a Web reference from within the Visual Studio .NET IDE) are based on the System.Web.Services.Protocols. SoapHttpClientProtocol class. This class exposes two properties that you can use to create authenticated Web services clients.

The most important of these properties is the Credentials property. You can use this property to specify the security credentials that the proxy will use to contact the Web services server. In Exercise 11.1, the code passes the credentials of the current user:


base.Credentials = _

 System.Net.CredentialCache.

 DefaultCredentials;

You can also use this property to pass the credentials of a specific user in a specific domain, provided you know that user's password:


base.Credentials = _

 new NetworkCredential("username",

 "password", "domain");

This second form is convenient for testing, but you should be wary of it in actual development, because it results in a password being embedded in the MSIL for your project in plain text.

The second property used in Exercise 11.1 is the PreAuthenticate property. When you set this property to true, the client will pass the credentials with the initial SOAP request. If it's set to false, then the client will send the credentials only if it receives a 401 Access Denied response from the server, which results in an extra round trip across the network.

Declarative Role-Based Security

Just like code access security, role-based security can be declarative or imperative. This exercise shows how to use declarative role-based security to cause an exception if the user is not in a specified group.

Estimated Time: 15 minutes.

  1. Add a new Visual C# .NET Windows application named Exercise11_2 to the solution.

  2. In the Solution Explorer, rename the default Form1.cs to Exercise11_2.cs. Open the form in code view and change all occurrences of Form1 to refer to Exercise11_2 instead.

  3. Add the following using directive:

    
    using System.Security.Permissions;
    
    using System.Security.Principal;
    
    
  4. Modify the class declaration for the form to include a declarative security line with the PrincipalPermissionAttribute:

    
    [PrincipalPermissionAttribute(
    
        SecurityAction.Demand,
    
        Role="Administrators")]
    
    public class Exercise11_2 :
    
        System.Windows.Forms.Form
    
    
  5. Double-click the form and add code to run when you open the form:

    
    private void Exercise11_2_Load(
    
        object sender, System.EventArgs e)
    
    {
    
        MessageBox.Show("You are a member " +
    
            "of the Administrators group");
    
    }
    
    
  6. Set the project as the startup project.

  7. Run the project. If you're not in the local Administrators group, you should see a security exception. Otherwise, the form should load and the display the message box.

Review Questions

1:

What types of permission requests can an application make?

A1:

An application can request minimum or optional permissions, refuse permissions, or demand permissions of its callers.

2:

What are the three types of permission objects?

A2:

Code-based, identity, and role-based.

3:

What is the difference between declarative and imperative security?

A3:

Declarative security works by assigning attributes to assemblies; imperative security works by instantiating the various security classes and using them directly.

4:

What do the WindowsIdentity and WindowsPrincipal objects represent?

A4:

The WindowsIdentity object represents a logged-on user; the WindowsPrincipal object represents the entire security context of the logged-on user.

5:

What are authentication and authorization?

A5:

Authentication refers to verifying credentials to determine the identity of a user. Authorization refers to granting access to resources to an authenticated user.

6:

What are the default accounts for the ASP.NET process?

A6:

By default ASP.NET runs as a low-privilege user named ASPNET. You can also configure ASP.NET to run as a high-privilege SYSTEM account.

7:

Name four types of authentication that you can specify in an ASP.NET configuration file.

A7:

You can specify None, Windows, Passport, or Forms authentication in an ASP.NET configuration file.

8:

What is meant by impersonation in ASP.NET?

A8:

If you enable ASP.NET impersonation, the ASP.NET user acts as the authenticated user when requesting access to resources.

9:

What should you consider when deciding whether to host a remoting server in ASP.NET or in a Windows service?

A9:

Generally speaking, ASP.NET offers higher security and more flexible authentication options for a remoting server, whereas a Windows service offers better performance.

10:

How can you configure a Web service to require users to log in with their Windows credentials?

A10:

You can configure authentication for a Web service by selecting properties for the IIS server that hosts the service. If you disable anonymous access, users will be required to supply a username and password to access the Web service.

Exam Questions

1:

Your application requires permission to read environment variables and to prompt users with the Open File dialog box to function properly. Which .NET security features should you use to ensure that your code has these capabilities?

  1. Code access security

  2. Role-based security

  3. Encryption

  4. Type safety

A1:

A. Checking whether code has a particular privilege is the function of code access security. For more information, see the section "Understanding Code Access Security" in this chapter.

2:

Your application requires the user to be in the Developers group to activate certain functions. Which .NET security feature should you use to ensure that the user is in this group?

  1. Code access security

  2. Role-based security

  3. Encryption

  4. Type safety

A2:

B. Role-based security enables you to check whether a user is in a particular group. For more information, see the section "Verifying Role Membership" in this chapter.

3:

You are using code access security to verify that your application has permission to access databases via OLE DB. As part of your testing procedure, you created a permission set that denies OLE DB permissions. You also created a code group that uses a hash code membership condition to select your application's executable assembly, and you assigned the permission set to this code group. You set this code group to be an exclusive code group and verified that your program is unable to obtain OLE DB permissions.

To continue development, you change the code group to use the FullTrust permission set and continue adding new code to your application. When you're ready to test the security features, you change back to the permission set without OLE DB permissions. However, you find that your application can access files via OLE DB, even though you have not changed the declarative security within the application.

Why is your code able to use OLE DB even though the code group denies OLE DB permissions?

  1. Changing code within your application changes its hash code, so the compiled assembly is no longer a member of the code group.

  2. After you've assigned the FullTrust permission set to a code group, the code group ignores attempts to set more restrictive permissions.

  3. The Exclusive property on a code group applies only when the code group is first created.

  4. You must reboot your development computer to update the membership records of the code group.

A3:

A. Hash codes are calculated from the MSIL code of an assembly, so changing the assembly's contents changes its hash code. For more information, see the section "Code Groups and Permission Sets" in this chapter.

4:

Assembly A is a member of the following code groups (and only the following code groups):

Level

Code Group

Permission Set

Exclusive

Level-Final

Enterprise

All Code

Everything

No

No

Enterprise

Company Enterprise

LocalIntranet Restricted

No

No

Code

Internet Enterprise

No Restricted

No

 

Enterprise

Restricted Components

Nothing

No

No

What permission does the CLR assign to Assembly A?

  1. Everything

  2. LocalIntranet

  3. Internet

  4. Nothing

A4:

A. Within a level, the permission set granted to an assembly is the union of all the permission sets of code groups on that level to which the assembly belongs. For more information, see the section "Computing Permissions" in this chapter.

5:

Assembly B is a member of the following code groups (and only the following code groups):

Level

Code Group

Permission Set

Exclusive

Level-Final

Enterprise

All Code

Everything

No

No

Enterprise

Company Code

LocalIntranet

No

No

Machine

Restricted Code

Internet

No

No

User

Restricted Components

Nothing

No

No

What permission does the CLR assign to Assembly B?

  1. Everything

  2. LocalIntranet

  3. Internet

  4. Nothing

A5:

D. Across levels, the permission set granted to an assembly is the intersection of all the permission sets of the levels. Because the user level grants no permissions to Assembly B, Assembly B gets no permissions from the Common Language Runtime. For more information, see the section "Computing Permissions" in this chapter.

6:

Assembly C is a member of the following code groups (and only the following code groups):

Level

Code Group

Permission Set

Exclusive

Level-Final

Enterprise

All Code

Everything

No

No

Enterprise

Company Code

LocalIntranet

Yes

No

Machine

Restricted Code

Internet

No

No

User

Restricted Components

Nothing

No

No

What permission does the CLR assign to Assembly C?

  1. Everything

  2. LocalIntranet

  3. Internet

  4. Nothing

A6:

B. The Company Code code group is marked as an exclusive code group, so only its permission set is taken into account when determining the permission set for the assembly. The final permission set is then the union of that group together with the permissions from the Machine and User levels. For more information, see the section "Computing Permissions" in this chapter.

7:

Assembly D is a member of the following code groups (and only the following code groups):

Level

Code Group

Permission Set

Exclusive

Level-Final

Enterprise

All Code

Everything

No

No

Enterprise

Company Code

LocalIntranet

No

No

Machine

Restricted Code

Internet

No

Yes

User

Restricted Components

Nothing

No

No

What permission does the Common Language Runtime assign to Assembly D?

  1. Everything

  2. LocalIntranet

  3. Internet

  4. Nothing

A7:

C. Because the code group on the Machine level is marked with the LevelFinal property, the code group on the user level is not taken into account when determining the permission set for this assembly. For more information, see the section "Computing Permissions" in this chapter.

8:

Your code will be called from the Internet and you want to minimize the chance that it can do unintentional damage to the local computer. As a result, you want to ensure that your code is not granted Registry permissions. Which SecurityAction action should you use with the FileIOPermissionAttribute declaration?

  1. SecurityAction.RequestMinimum

  2. SecurityAction.RequestOptional

  3. SecurityAction.Demand

  4. SecurityAction.RequestRefuse

A8:

D. SecurityAction.RequestRefuse tells the CLR that your assembly does not want to be granted the specified permission. For more information, see the section "Requesting Other Types of Permissions" in this chapter.

9:

Your code wants to ensure that all code in the calling chain has File I/O permissions. Which SecurityAction action should you use with the RegistryPermission object?

  1. SecurityAction.RequestMinimum

  2. SecurityAction.RequestOptional

  3. SecurityAction.Demand

  4. SecurityAction.RequestRefuse

A9:

C. SecurityAction.Demand demands the specified permission of the calling code. For more information, see the section "Requesting Other Types of Permissions" in this chapter.

10:

Which of these tasks requires you to use imperative security rather than declarative security?

  1. Ensuring that your application has access to a specific key in the Windows Registry

  2. Ensuring that your application can open a particular file whose name is specified by a configuration file that can be edited at runtime

  3. Ensuring that your application has access to a specific environment variable whose name is known at design time

  4. Ensuring that your application has access to SQL Server databases

A10:

B. You must use imperative security to check access to resources whose names are not known until runtime. For more information, see the section "Imperative Security" in this chapter.

11:

You have implemented forms-based authentication for your ASP.NET application. Some users report that they cannot access any resources on the site, even though you have verified that these users are entering correct authentication information. What could be the problem?

  1. These users are using a version 4 browser.

  2. These users have disabled cookies for your Web site.

  3. These users do not have a Microsoft Passport.

  4. These users are connecting from the Internet rather than a local intranet.

A11:

B. Forms authentication depends on cookies to indicate that a browser session has been authenticated. For more information, see the section "Configuring Authentication" in this chapter.

12:

You want to allow any authenticated user access to your ASP.NET application, but refuse access to all unauthenticated users. Which setting should you place in the application's web.config file?

  1. 
    <deny users="?" />
    
    
  2. 
    <deny users="*" />
    
    
  3. 
    <allow users="?" />
    
    
  4. 
    <allow users="*" />
    
    
A12:

A. The question mark (?) wildcard matches unauthenticated users, whereas the asterisk (*) wildcard matches all users (authorized or not). If you deny access to all unauthenticated users, only authenticated users will be able to use the application. For more information, see the section "Configuring Authentication" and "Configuring Authorization" in this chapter.

13:

You are allowing anonymous or Windows-integrated authentication on your IIS server. ASP.NET is running with machine-level privileges. Your ASP.NET application uses Windows authentication with impersonation enabled. What account will ASP.NET use when a user attempts to retrieve a page from the application?

  1. The user's own Windows account

  2. The ASPNET account

  3. The IUSR_ComputerName account

  4. An account in the local Administrators group

A13:

C. If you allow anonymous authentication in IIS, users will never be prompted for their Windows credentials. ASP.NET will impersonate the identity of IIS itself, the IUSR_ComputerName account. For more information, see the section "Implementing Impersonation" in this chapter.

14:

Your ASP.NET application contains this setting in the web.config file:


<identity impersonate="true"

  name="MAIN\Charles"

  password="CharlesPassword"/>

You are allowing only digest or Windows integrated authentication in IIS. What identity will ASP.NET use to authorize resources if a user with the Windows account Fred in the MAIN domain logs in?

  1. MAIN\Fred

  2. ASPNET

  3. MAIN\Charles

  4. IUSR_ComputerName

A14:

C. If you specify an account name in the identity element, that account is used to impersonate all authenticated users. For more information, see the section "Implementing Impersonation" in this chapter.

15:

You have created a Windows service that collects event log information from various computers around the network and then consolidates this information into a local disk file. The service does not need system-level privileges on the local computer, but it must be able to authenticate to the remote computers. You run the Windows service on a Windows XP Professional machine. Which security context should you use for this service?

  1. LocalService

  2. NetworkService

  3. LocalSystem

  4. User

A15:

B. The NetworkService account has few privileges on the local computer, but presents the computer's credentials when accessing network resources. The LocalService account, by contrast, uses anonymous credentials with network resources, and the LocalSystem account has high privileges on the local computer. A properly configured user account could work in this scenario, but there's no need to create a user account when one of the built-in accounts will work fine. For more information, see the section "Security for Windows Services" in this chapter.

Suggested Readings and Resources

1. Visual Studio .NET Combined Help Collection

• Securing Applications

2. Brian A. LaMacchia, et al. .NET Framework Security. Addison-Wesley, 2002.

3. Building Secure ASP.NET Applications, msdn.microsoft.com/library/en-us/dnnetsec/html/secnetlpMSDN.asp.