Parsing a network path with credentials into base class library types

872 Views Asked by At

Consider the following UNC path to a simple windows network share (SMB protocol):

  • \\host\share

You can easily create an instance of System.Uri or System.IO.DirectoryInfo by passing that path as a string to the constructor.

Now consider the following two paths, leaving all security concerns aside:

  • \\username@host\share
  • \\username:password@host\share

You can't simply pass these to the Uri or DirectoryInfo constructors because they don't know how to handle these paths, which are mostly used by linux systems. Besides, even if they did, they most likely wouldn't preserve the logon credentials.

Ultimately I would like a way to convert these to an instance of System.Uri that represents the actual path, and an instance of System.Net.NetworkCredential that stores the logon information.

So how do I tackle this problem? I don't even know where to begin. Inheriting from System.UriParser seems to be a good place to start but according to MSDN, it is not recommended.

Microsoft strongly recommends that you use a parser shipped with the .NET Framework. Building your own parser increases the complexity of your application, and will not perform as well as the shipped parsers.

Thanks.

EDIT

The simple solution (as posted below) is to just assume that everything before the '@' symbol is part of the logon credential, and everything after it is the actual path. This can be problematic however when filenames contain '@' symbols.

\\credential@host\path: no problem

\\credential@host\path@mystorage: again no problem because everything before the first @ is part of the logon.

\\host\path@mystorage: now we're busted. This will definitely throw argument exceptions when passed as an argument.

1

There are 1 best solutions below

3
On

If those are the only two schemes you need to handle then it seems like overkill to extend a parser. Making your own utility class would be easier anyway.

If it really is as simple as the two examples you gave, I would just brute force it. Make a simple class that can split the path into its respective components (based on the existence and location of "@") and create the Uri and NetworkCredential separately. If the string does not contain "@" then the NetworkCredential can be null.

If it's more complicated than this I might be off base, but this sounds like one of those times when the simple solution is probably going to be fine.

Pardon my hasty code, it's not exactly fault-tolerant but it should make the point.

Public Class CredentialedPath

    Public Property Uri As Uri
    Public Property Credential As NetworkCredential

    Public Shared Function GetFromString(ByVal path As String) As CredentialedPath

        Dim CP As CredentialedPath = New CredentialedPath()

        Dim pathParts() As String = path.Split("@"c)

        If pathParts.Length > 1 Then

            CP.Uri = New System.Uri("\\" & pathParts(1))

            Dim credParts() As String = pathParts(0).TrimStart("\"c).Split(":"c)
            CP.Credential = New NetworkCredential()
            CP.Credential.UserName = credParts(0)
            If (credParts.Length > 1) Then
                CP.Credential.Password = credParts(1)
            End If

        Else
            CP.Uri = New System.Uri(path)
        End If

        Return CP

    End Function

End Class