Authenticate Desktop Application with ASP .NET Identity Database

This is one of those rare scenarios which are only applicable to a niche audience. We had a legacy application in VB .NET which with change of requirements was now required to be authenticated with the same credentials as the web application end users were utilizing.

It might not make sense in a day to day operation but it made sense to the business owners and we had to implement it. The website was relatively new and used ASP .NET Identity to authenticate users.

To Authenticate users in the desktop application, we reverse engineered the ASP .NET Authentication and replicated it in our own class to match the password stored in it. We used Entity Framework to connect to the Identity database and used the below code to verify passwords.  You can download the complete code at the end of the post.

Public Shared Function VerifyHashedPassword(ByVal hashedPassword As String, ByVal password As String) As Boolean
	Dim bytes As Byte()
	If (hashedPassword Is Nothing) Then
		Return False
	End If
	If (password Is Nothing) Then
		Throw New ArgumentNullException("password")
	End If
	Dim numArray As Byte() = Convert.FromBase64String(hashedPassword)
	If (CInt(numArray.Length) <> 49 OrElse numArray(0) <> 0) Then
		Return False
	End If
	Dim numArray1(15) As Byte
	Buffer.BlockCopy(numArray, 1, numArray1, 0, 16)
	Dim numArray2(31) As Byte
	Buffer.BlockCopy(numArray, 17, numArray2, 0, 32)
	Using rfc2898DeriveByte As Rfc2898DeriveBytes = New Rfc2898DeriveBytes(password, numArray1, 1000)
		bytes = rfc2898DeriveByte.GetBytes(32)
	End Using
	Return Crypto.ByteArraysEqual(numArray2, bytes)
End Function

We used the below code to authenticate the user from the Windows Form:

Private Function ValidateUser(uName As String, pwd As String) As String
	Dim result As String = String.Empty
	Using db As New IdentitydevMEntities
		Dim user = (From u In db.AspNetUsers Where u.UserName.Equals(uName, StringComparison.InvariantCultureIgnoreCase) 
		Select u).FirstOrDefault()

		If Not (user Is Nothing) Then
			If (Crypto.VerifyHashedPassword(user.PasswordHash, pwd)) Then
				result = user.Id
			End If
		End If

	End Using

	Return result
End Function

NOTE: We used secure SQL Connection to connect to our databases in cloud.

You can download the code here: AuthCode