Pro ASP.NET 2.0 In CSharp 2005 (2005) [eng]
.pdf
1208 C H A P T E R 3 4 ■ A D VA N C E D W E B S E R V I C E S
To simplify this task, it helps to create a private method like the one shown here. It checks that a token exists and throws an exception if it doesn’t. Otherwise, it returns the user name.
private string GetUsernameToken()
{
//Although there may be many tokens, only one of these
//will be a UsernameToken.
foreach (UsernameToken token in RequestSoapContext.Current.Security.Tokens)
{
return token.Username;
}
throw new SecurityException("Missing security token");
}
You could call the GetUsernameToken() method at the beginning of a web method to ensure that security is in effect. Overall, this is a good approach to enforce security. However, it’s important to keep its limitations in mind. First, it doesn’t support hashing or encrypting the user credentials. Also, it doesn’t support more advanced Windows authentication protocols such as Digest authentication and Integrated Windows authentication. That’s because the authentication is implemented by the WSE extensions, not by IIS. Similarly, the client always needs to submit a password and user name. The client has no way to automatically submit the credentials of the current user, as demonstrated earlier in this chapter with the CredentialCache object. In fact, the Credentials property of the proxy is ignored completely.
Fortunately, you aren’t limited to the scaled-down form of Windows authentication provided by the default WSE authentication service. You can also create your own authentication logic, as described in the next section.
Custom Authentication
By creating your own authentication class, you can perform authentication against any data source, including an XML file or a database. To create your own authenticator, you simply need to create a class that derives from UsernameTokenManager and overrides the AuthenticateToken() method. In this method, your code needs to look up the user who is trying to become authenticated and return the password for that user. ASP.NET will then compare this password against the user credentials and decide whether authentication fails or succeeds.
Creating this class is quite straightforward. Here’s an example that simply returns hard-coded passwords for two users. This provides a quick-and-easy test, although a real-world example would probably use ADO.NET code to get the same information.
public class CustomAuthenticator : UsernameTokenManager
{
protected override string AuthenticateToken(UsernameToken token)
{
string username = token.Username;
if (username == "dan") return "secret";
else if (username == "jenny") return "opensesame";
else
return "";
}
}
C H A P T E R 3 4 ■ A D VA N C E D W E B S E R V I C E S |
1209 |
The reason you don’t perform the password test on your own is because the type of comparison depends on how the credentials are encoded. For example, if they are passed in clear text, you need to perform a simple string comparison. If they are hashed, you need to create a new password hash using the same standardized algorithm, which must take the same data into account (including the random nonce from the client message). However, the WSE can perform this comparison task for you automatically, which dramatically simplifies your logic. The only potential problem is that you need to have the user’s password stored in a retrievable form on the web server. If you’re storing only password hashes in a back-end database, you won’t be able to pass the original password to ASP.NET, and it won’t be able to re-create the credential hash it needs to authenticate the user.
Once you’ve created your authentication class, you still need to tell the WSE to use it for authenticating user tokens by registering your class in the web.config file. To accomplish this, right-click the project name in the Solution Explorer, and select WSE Settings. Next, select the Security tab (shown in Figure 34-11).
Figure 34-11. Security settings
In the Security Tokens Managers section, click the Add button. This displays the SecurityToken Manager dialog box (see Figure 34-12).
1210 C H A P T E R 3 4 ■ A D VA N C E D W E B S E R V I C E S
Figure 34-12. Configuring a new UsernameTokenManager
In the SecurityToken Manager dialog box, you need to specify three pieces of information:
•Type: Enter the fully qualified class name, followed by a comma, followed by the assembly name (without the .dll extension). For example, if you have a web project named MyProject with an authentication class named CustomAuthenticator, enter MyProject.CustomAuthenticator, MyProject.
•Namespace: Enter the following hard-coded string: http://docs.oasis-open.org/ wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd.
•QName: Enter the following hard-code string: UsernameToken.
You build the client in essentially the same way, no matter how your authentication is performed on the server. However, when you create a custom authentication class, you can choose to use hashed passwords, as shown here:
// Create the proxy.
EmployeesServiceWse proxy = new EmployeesServiceWse();
//Add the WS-Security token. proxy.RequestSoapContext.Security.Tokens.Add(
new UsernameToken("dan", "secret", PasswordOption.SendHashed));
//Bind the results.
GridView1.DataSource = proxy.GetEmployees().Tables[0];
GridView1.DataBind();
The best part is that you don’t need to manually hash or encrypt the user password. Instead, the WSE hashes it automatically based on your instructions and performs the hash comparison on the server side. It even incorporates a random nonce value to prevent replay attacks.
Summary
In this chapter, you learned a variety of advanced SOAP techniques, including how to call web services asynchronously, how to enforce security, and how to use SOAP extensions. The world of web services is sure to continue to evolve, so look for new standards and increasingly powerful capabilities to appear in future versions of the .NET Framework.
■I N D E X 1213
configuring HTTP runtime settings, |
ASPNET accounts, 672 |
651–52 |
ASP.NET coding model. See coding model, |
overview, 647–48 |
ASP.NET |
verifying the ASP.NET installation, 648–49 |
ASP.NET Development Helper, 59–61, 100 |
with Visual Studio, 653, 655 |
ASP.NET pages. See pages, ASP.NET |
extending HTTP pipeline, 182–92 |
ASP.NET website, 146 |
configuring custom HTTP Handler, |
aspnet_Applications table, 807 |
185–86 |
aspnet_Applications_CreateApplications stored |
creating advanced HTTP handler, 187–90 |
procedure, 808 |
creating custom HTTP handler, 184–85 |
aspnet_CheckSchemaVersion stored procedure, |
creating custom HTTP module, 190–92 |
808 |
HTTP handlers and HTTP modules, |
aspnet_compiler.exe tool, 653 |
183–84 |
aspnet_isapi.dll file, 622–23, 639, 659 |
overview, 182 |
aspnet_Profile table, 807 |
registering HTTP handlers without |
aspnet_Profile_DeleteInactiveProfiles stored |
configuring IIS, 186–87 |
procedure, 809 |
global.asax application file, 155–59 |
aspnet_Profile_GetNumberOfInactiveProfiles |
application events, 156–58 |
stored procedure, 809 |
demonstrating application events, 158–59 |
aspnet_Profile_GetProfiles stored procedure, |
overview, 155–56 |
808 |
.NET components, 177–82 |
aspnet_Profile_GetProperties stored procedure, |
overview, 151 |
808 |
web application changes in .NET 2.0, 151 |
aspnet_Profile_SetProperties stored procedure, |
applications, web. See web applications |
809 |
application/xhtml+xml content type, 75 |
aspnet_regiis.exe utility, 639, 649–50 |
ApplyFormatInEditMode property, 338 |
aspnet_regsql.exe tool, 807 |
AppRequestQueueLimit setting, 651 |
aspnet_regsql.exe utility, 415–17, 714–16, 718, |
<appSettings> element, 167–69, 173 |
1045, 1051 |
<area> tag, 1013 |
aspnet_SchemaVersions table, 807 |
ARGB color values, 120 |
aspnet_setreg.exe tool, 626, 770 |
Array class, 369 |
aspnet_Users table, 807 |
ArrayList, 825 |
aspnet_Users_CreateUser stored procedure, 809 |
Arrays data type, 1098 |
aspnet_Users_DeleteUser stored procedure, 809 |
.asax extension, 638 |
aspnet_wp.exe process, 625–26 |
ASCII, 490 |
aspnet_wp.exe utility, 623, 647–48, 664 |
.ascx extension, 506, 508, 638 |
<asp:RoleGroup> tag, 793 |
.ascx file, 36, 508, 518, 522 |
<asp:TreeNode> tag, 584 |
.ashx extension, 638 |
<asp:View> tag, 556 |
.asmx extension, 152, 186–87, 620, 638 |
<asp:WizardStep> tag, 560 |
.asmx file, 36, 1100, 1110 |
.aspx (web form) files, 506 |
ASP (Active Server Pages), 634–35, 637 |
.aspx extension, 152, 400, 506, 508, 584, 620, |
asp prefix, 118 |
638, 648, 692 |
<asp:CreateUserWizardStep> tag, 743 |
.ASPXAUTH cookie, 696 |
aspent_compiler.exe tool, 652 |
<assemblies> element, 165 |
<asp:MultiView> tag, 556 |
assembly cache, global. See GAC |
ASP.NET 1.x, migrating projects to |
assembly references, 41–43 |
ASP.NET 2.0, 15 |
asterisk (*) character, XPath expression, 442, 778 |
ASP.NET 2.0, 15 |
asymmetric encryption, 678–79, 845–46 |
administration, 21 |
asymmetric key pair, 678 |
compatibility with ASP.NET 1.0, 15 |
AsymmetricAlgorithm, 843 |
data source controls, 17–19 |
AsyncCompletedEventArgs class, 1183 |
master pages, 17 |
asynchronous calls |
membership, 19–20 |
asynchronous services, 1185–86 |
personalization, 19 |
concurrent asynchronous calls, 1180–81 |
rich controls, 20–21 |
overview, 1175–76 |
security, 19–20 |
responsive Windows clients, 1181, 1183–84 |
Web parts, 21 |
simple asynchronous call, 1178–79 |
■I N D E X 1217
colon ( : ) character, namespace prefix, xmlns, |
CompilationTempDirectory setting, 652 |
430 |
compilers, .NET, 24–25 |
Color data type, 965 |
Component class, 326 |
Color property, 32, 120 |
Component Object Model (COM), 6, 1089–91 |
Colors class, 120 |
Component property, 967 |
ColorTranslator class, 120 |
component-based technology, 1088–89 |
columns, defining, GridView control, 336–39 |
components, 153, 178–79, 182 |
Columns collection, 279, 292–93 |
composite controls, 899, 923–25 |
Columns property, 339 |
CompositeControl class, 924 |
<Columns> section, 336 |
compression, 498–99 |
ColumnSpan property, 376 |
concurrency strategies, 273–74 |
COM (Component Object Model), 6, 1089–91 |
concurrent asynchronous calls, 1180–81 |
COM objects, backward compatibility, 92 |
.config files, 183 |
COM+ transactions, 254, 1126 |
configuration, ASP.NET, 159–68 |
Combine, Path method, 482–83 |
encrypting configuration sections, 175 |
Command and DataReader classes, 240–53 |
command-line encryption, 176–77 |
command basics, 240–41 |
programmatic encryption, 176 |
DataReader class, 241–42 |
extending configuration file structure, 173–75 |
ExecuteNonQuery( ) method, 247 |
machine.config file, 160–62 |
ExecuteReader( ) method and DataReader, |
overview, 159–60 |
242–46 |
reading and writing configuration sections |
CommandBehavior, 244 |
programmatically, 168–71 |
overview, 243 |
settings, 164–68 |
processing multiple result sets, 244–46 |
<appSettings> element, 167–68 |
ExecuteScalar( ) method, 247 |
<configuration> element, 165 |
overview, 240 |
<connectionStrings> element, 167 |
SQL injection attacks, 248–50 |
<customErrors> element, 166 |
using parameterized commands, 250–51 |
<system.web> element, 166 |
Command classes, ADO.NET |
overview, 164–65 |
(OleDbCommand, SqlCommand), 241 |
web.config file, 162–64 |
Command object, 230, 240–41, 280–81 |
overview, 162–63 |
CommandArgument property, 366 |
using <location> elements, 163–64 |
CommandBehavior, 244 |
Website Administration Tool (WAT), 171, 173 |
CommandField column, 336, 346, 349, 367, 370 |
<configuration /> element, 718 |
command-line encryption, 176–77 |
configuration element, web.config file, 165 |
CommandName property, 366, 370–71, 730, |
configuration files. See also web.config file |
738–40 |
applying master pages through, 549 |
commands, types of, 240 |
applying themes through, 536 |
CommandType enumeration, 240 |
configuration inheritance, 162–63 |
Commit( ) method, 256 |
configuration settings, 152 |
Common Gateway Interface (CGI), 4–5, 635 |
<configuration> element, 165, 781 |
common language runtime (CLR), 5, 9, 11–12, |
ConfigurationSettings class, 167–68 |
152, 154, 237, 599, 607–10, 618, 623–24, |
configured (web.config) impersonation, 765 |
626–27, 651, 843, 942 |
ConflictDetection property, SqlDataSource |
common language specification (CLS), 10–11 |
class, 321, 330, 386 |
Common Name, server certificate (CN), 682 |
Connect mode, 1052, 1081 |
Common Object Request Broker Architecture |
ConnectErrorMessage property, WebPart class, |
(CORBA), 1089–91 |
1056 |
compact HTML (cHTML), 909 |
Connection class, 234–39 |
CompareAllValues property, 330 |
connection pooling, 237–39 |
CompareValidator control, 133, 137–38 |
connection statistics, 239 |
compilation, 8–9, 166 |
connection strings, 235 |
of component source codes, 178 |
overview, 234 |
of custom HTTP handlers, 185–86 |
testing connection, 236–37 |
compilation tag, web.config file, 165–66 |
Connection Lifetime settings, connection |
<compilation> element, 165, 648 |
pooling, 238 |
