Buck Hodges

Visual Studio Online, Team Foundation Server, MSDN

July, 2004

  • Buck Hodges

    Authentication in web services with HttpWebRequest


    Hatteras has three tiers: client, middle, and data.  The middle tier is an ASP.NET web service on a Windows 2003 Server running IIS 6.  When the client (we use C# for both it and the middle tier) connects to the middle tier, it must authenticate with IIS 6.  Depending upon the IIS configuration, that may be negotiate, NTLM, Kerberos, basic, or digest authentication.  Here's a page on Internet Authentication in .NET.

    NOTE:  The code below uses the .NET 2.0 framework (Visual Studio 2005).

    In order to authenticate, the client must have credentials that the server recognizes as valid.  For Windows Integrated Authentication (comprising NTLM and Kerberos) using the current logged-on user, the client can use CredentialCache.DefaultCredentials.  Here's how it looks in code.

    using System;
    using System.IO;
    using System.Net;
    class Creds
        public static void Main(string[] args)
            Uri uri = new Uri(args[0]);
            HttpWebRequest req = (HttpWebRequest)WebRequest.Create(uri);
            req.Credentials = CredentialCache.DefaultCredentials;
            // Get the response.
            using (HttpWebResponse res = (HttpWebResponse)req.GetResponse())
                StreamReader sr = new StreamReader(res.GetResponseStream());

    You can find that same type of sample code in MSDN.  However, it gets more interesting if you want to use basic or digest authentication or use credentials other than the current logged-on user.

    One interesting fact is that the HttpWebRequest.Credentials property is of type ICredentials, but it only uses instances of NetworkCredential and CredentialCache.  If you implement ICredentials on your own class that is not one of those two classes, you can assign it to the Credentials property, but HttpWebRequest will silently ignore it.

    To go further, we need to look at the CredentialCache class itself.  This class is used to hold a set of credentials that are associated with hosts and authentication types.  It has two static properties, one of which we used above, that are the "authentication credentials for the current security context in which the application is running," which means the logged-on user in our case.

    The difference is very subtle.  The documentation for DefaultCredentials says, "The ICredentials instance returned by DefaultCredentials cannot be used to view the user name, password, or domain of the current security context."  The instance returned by DefaultNetworkCredentials, being new in .NET 2.0 and of type NetworkCredential, would presumably let you get the user name and domain, but it didn't work for me when I tried it with the following code (UserName returned an empty string).

    Console.WriteLine("User name: " + CredentialCache.DefaultNetworkCredentials.UserName);

    The NetworkCredential class implements both the ICredentials (NetworkCredential GetCredential(Uri uri, String authType)) and ICredentialsByHost (NetworkCredential GetCredential(String host, int port, String authType)) interfaces.  The ICredentialsByHost interface is new in .NET 2.0.

    The CredentialCache class has methods that let you add, get, and remove credentials for particular hosts and authentication types.  Using this class, we can manually construct what setting req.Credentials = CredentialCache.DefaultCredentials accomplished in the original example.

            CredentialCache credCache = new CredentialCache();
            credCache.Add(new Uri("http://localhost"), "Negotiate",
            HttpWebRequest req = (HttpWebRequest)WebRequest.Create(uri);
            req.Credentials = credCache;

    The authentication type can also be explicitly specified as "NTLM" and "Kerberos" in separate calls to Add().  This page on authentication schemes explains using Negotiate as follows.

    Negotiates with the client to determine the authentication scheme. If both client and server support Kerberos, it is used; otherwise NTLM is used.

    Let's say you want to work with basic or digest authentication.  The documentation for CredentialsCache.DefaultCredentials and CredentialsCache.DefaultNetworkCredential says that neither will work with basic or digest.  If we add basic to credentials cache, we get a runtime exception.

            credCache.Add(new Uri("http://localhost"), "Basic",

    The exception is thrown by the Add() method.

    Unhandled Exception: System.ArgumentException: Default credentials cannot be supplied for the Basic authentication scheme.
    Parameter name: authType
    at System.Net.CredentialCache.Add(Uri uriPrefix, String authType, NetworkCredential cred)

    So, in order to use basic or digest, we must create a NetworkCredential object, which is also what we need to do in order to authenticate as some identity other than the logged-on user.  To do that, we create NetworkCredential object and add it to the CredentialCache as follows.

            credCache.Add(new Uri("http://localhost"), "Basic" /* or "Digest" */,
                          new NetworkCredential("me", "foo", "DOMAIN"));

    Basic authentication sends the password across the wire in plain text.  That's okay for a secure connection, such as one using SSL, and for situations where you don't need much security.  Digest authentication hashes the password along with other data from the server before sending a response over the wire.  It's a significant step up from basic.

    Now we need to have the user name and password to create the NetworkCredential object.  There are two parts to this.  First is prompting the user for the name and password.  The second is storing the information.  For prompting there is the Windows dialog that pops up any time you go to a web site that requires authentication.  That dialog includes a "Remember my password" checkbox.  I don't yet know what the managed API is for that.

    To store and retrieve the information, there is the new managed DPAPI explained by Shawn Farkas in several blog postings.

    [Update 3:44pm]  The Windows dialog used when IE prompts for name and password is created by the CredUIPromptForCredentials() function.  CredUIConfirmCredentials() is used to save credentials that authenticated successfully, if desired.  Duncan Mackenzie's MSDN article Using Credential Management in Windows XP and Windows Server 2003 explains how to use it from .NET.

    [UPDATE 4/10/2006]  I updated the MSDN links that were broken.

  • Buck Hodges

    Authentication and SOAP proxies


    My last post discussed authentication in web service calls using HttpWebRequest.  That caused one reader to wonder how this ties back to SOAP requests.

    If you are using wsdl.exe to generate a SOAP proxy class, it derives from System.Web.Services.Protocols.SoapHttpClientProtocol.  That class has a Credentials property. If you want to use the currently logged-in user's credentials, you would assign CredentialCache.DefaultCredentials to the Credentials property.  The same comment about having to assign an instance of NetworkCredential or CredentialCache apply as the proxy uses the HttpWebRequest class.

    [Updated 8/05/2004]  Check out the article on MSDN about the new SOAP proxy generation support in Whidbey Beta 1, including generating the proxy assembly at build time and how to turn on compression.

  • Buck Hodges

    Using pushd to get to network paths


    A short while ago I saw someone at the office use pushd to cd into a network path.  I've used pushd/popd on Windows for some time, but I never thought to try it on a network path or actually read the help for it.  Pushd will actually map the path to a drive letter automatically and then take you there.  The latter part is expected, but mapping the drive is really cool.  Maybe it should be obvious (how else would the command line do it?), but it wasn't to me.  It's a lot more convenient than “net use“ or anything else that I know of.

    C:\>pushd /?
    Stores the current directory for use by the POPD command, then
    changes to the specified directory.
    PUSHD [path | ..]
      path        Specifies the directory to make the current directory.
    If Command Extensions are enabled the PUSHD command accepts
    network paths in addition to the normal drive letter and path.
    If a network path is specified, PUSHD will create a temporary
    drive letter that points to that specified network resource and
    then change the current drive and directory, using the newly
    defined drive letter.  Temporary drive letters are allocated from
    Z: on down, using the first unused drive letter found.
  • Buck Hodges

    Scoble is everywhere


    I got the July issue of Triangle TechJournal and opened it up to find an interview of Robert Scoble by Andy Beal (the interview doesn't appear to be on the web site yet). So even my mail box has been Scobleized.

    Among other things, he mentions taking 7400 pictures over the last 18 months.  Even for digital, that seems like a lot.  I wonder how Longhorn compares to one of the many apps on the market for organizing the pictures (giving both the same metadata of course)?

  • Buck Hodges

    The story on why Team System is not in Beta 1


    Someone on the newsgroups asked for an official answer on why Team System is not in Whidbey Beta 1.  The short answer is that it's not beta quality, so it didn't belong in a beta.  Keep your eyes open for another CTP release in the next few months.  The current plans for this upcoming CTP are for it to include the server portions of Team System that were not in the May release.

    Rick LaPlante personally replied to the post with the following answer.

    While Paul provides a skeptical, yet possible explanation, as I made the decision, I'll tell you what the real logic was. 

    CTPs (community technology previews) are about getting bits out regularly to customers for early feedback and discussion.  With this release of VS, we are trying to be more open about what we are building and give earlier access to folks to the bits.  By definition, these bits are basically stable builds from our own source trees with minimal additional quality checks built into the process.  They are <NOT> beta quality.  they are interim builds.  As such, it was appropriate to put parts of the Team System into the CTP because we met the quality bar and certainly needed to start getting feedback asap about the feature set and implementation.  As Paul correctly points out (and we've said many times) the Team System is not currently at beta quality and as such we did not include it in Beta 1 of VS.  We will have another CTP in the next few months based on the VS Beta 1 bits that will include the Team System (again not a beta quality build, but expected to be much better than the May CTP) and then follow on with VS Beta 2 which will contain a full, beta quality version of the Team System.

    Hope this answers your question.

  • Buck Hodges

    Python on .NET just got more support

    Jim Hugunin, who has been writing IronPython, has been hired by Jason Zander (CLR PUM).  He joins the CLR team on Monday, August 2, to work full time on IronPython and generally supporting dynamic/scripting languages on the CLR.  That's really great news for Python on .NET.  Check out the slide from his presentation at OSCON (July 28, 2004).
  • Buck Hodges

    May CTP to appear again


    The May 2004 CTP that contained Team System (but not Team Foundation, which includes source control and work item tracking) is supposed to be up on MSDN by Monday.  There were a number of requests for it in the newsgroups after it was mistakenly removed from MSDN.

Page 1 of 1 (7 items)