If you wish to use Windows Integrated Authentication, you are assuming that the user who will be connecting to the Web server has a domain account with that Web server and will supply the correct credentials to that server. If the correct credentials are not supplied, the user will be denied access to the Web Service. Credentials can only be supplied through creating an instance of the NetworkCredential class in the .NET Framework and supplying a user ID, password, and domain name.
You will now create a very simple Web Service that will be used to test our integrated security. This Web Service will simply return a string and the name of the process under which this service is running. Follow these steps:
Create a new Web Service named WSSecure.
Create a method as shown in Listing 31.1.
Listing 31.1 Create a Simple Web Service That Returns the Identity of the Process Under Which the Web Service Is Running
<WebMethod()> Public Function WindowsSecure() As String Dim id As WindowsIdentity = WindowsIdentity.GetCurrent Return "Hello from Windows Secured Service: " & _ id.Name() End Function
Make sure you build this Web Service project before proceeding with the next steps. You will now create a client-side application to connect to this service.
Start a new instance of VS .NET and create an ASP.NET Web application. Name this application Jumpstart/TestSecurity.
Add a button to the default Web page. Set the name to btnTest.
Add a label below this button and set the name to lblResponse.
Add a Web reference in this project to the WSSecure Web Service.
Double-click the Button control and write the code shown in Listing 31.2.
Listing 31.2 Call a Secure Windows Service by Creating Credentials and Passing Them to the Service
Private Sub btnTest_Click( _ ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles btnTest.Click Dim ws As New WebSecure.Service1() Dim cc As CredentialCache = New CredentialCache() Dim nc As NetworkCredential lblResponse.Text = "" ' Create a new instance of NetworkCredential ' using the client credentials. nc = New _ NetworkCredential("AUser", "password", _ "CORP-WEBSERVER") ' Add the NetworkCredential to the CredentialCache. cc.Add(New Uri(ws.Url), "Basic", nc) cc.Add(New Uri(ws.Url), "NTLM", nc) ' Add the CredentialCache to the ' web service class credentials. ws.Credentials = cc Try ' Call the Web Service lblResponse.Text = ws.WindowsSecure() Catch exp As Exception lblResponse.Text = exp.Message End Try End Sub
You will need to replace "AUser", "Password", and "CORP-WEBSERVER" with a valid user ID, password, and domain, respectively, that will authenticate on your machine.
You now need to turn off the anonymous access to your Web Service site in the IIS Properties dialog box.
Bring up IIS, right-click your Web Service Web site, and select Properties.
Click the Directory Security tab.
Click the Edit button under the Anonymous Access and Authentication Control frame.
Uncheck the Anonymous Access check box.
You are now ready to test the Web Service and see whether you can connect to it. Run your test project and click the button. If you have entered a valid user ID, password, and domain, you should see a response come back, such as CORP-WEBSERVER\ASPNET. If you change the user ID to an invalid user on your system, you should see an error message such as "Access Denied."
This tells us that even though you are passing valid credentials to IIS, the site will not run under those credentials; it will normally run under the "ASPNET" user credentials. This is a user created when the .NET Framework is installed.
You'll want to include some sort of exception handling, either displaying an error message (as in this example) or redirecting the user to another page, in case an error occurs. You really don't want general users to see the error message they'd otherwise receive.
No changes need to be made to the Web.config file because the default authentication mode when you create a Web Service project is Windows. If you open the Web.config file in your Web Service project and locate the <authentication> tag in this file, you should see something like the following:
<authentication mode="Windows" />
The only authentication modes you can use with a Web Service are Windows and None. You cannot use the Forms-based authentication because there is no user interface and no forms to redirect a user to. Passport-based authentication is not an option because it is also not set up to authenticate users without a user interface.
Authorization of Users
By default, all users are authorized by ASP.NET to access a Web Service if they are authenticated. If you locate the <authorization> tag in the Web.config file, you will find that it looks like the following code fragment:
<authorization> <allow users="*" /> <!-- Allow all users --> <!-- <allow users="[comma separated list of users]" roles="[comma separated list of roles]"/> <deny users="[comma separated list of users]" roles="[comma separated list of roles]"/> --> </authorization>
By leaving "*" in the <allow users> tag, you are letting anyone with valid credentials run any Web Service in this site. If you are using Windows integrated security, you may specify only certain users and/or roles within the domain to run the Web Services within this site. For example, if you wanted to restrict a user named Charlie within the domain CORP-WEBSERVER, you would change the <authorization> tag as shown in the following code fragment:
<authorization> <deny users="CORP-WEBSERVER\Charlie" /> <allow users="*" /> <!-- Allow all users --> </authorization>
You must explicitly deny access to a user by placing the deny tag before the <allow users="*"> tag. If you do not, the allow all users tag will take precedence.
There are many scenarios in which you might allow or restrict access to users and/or roles in your Web Service. You will have to decide what will be the best for your particular situation.