Protect WCF service by password
Wcf service is my liked type of projects for communication, this is fastest and simplest type of communication, in most case I select this type of communication for my project, for example - Типовий SOAP/WSDL сервіс., Складська прога на WCF-сервісах зі сканером., Создание асинхронного прокси для обращения к WCF средствами Adobe flex builder., WCF_CLIENT - клиент Web-сервиса (первая версия) and so on.
But internal authentication concept of WCF is so hard, therefore I use my own secure conception of protection in application layer.
I use have two version of protection - with full digital sign of whole transfered data and only adding a protection hash to identify a client of WCF services.
Below I describe simplest (second case) of protection - in first step WCF client require a Bearer from server, what must be unique for each next request with data, than client add to Bearer secret Password and return MD5-hash of both of they to server. Server identify unique Bearer, check sign and allow perform request.
1: Imports System.Security.Cryptography
2: Imports System.Runtime.Caching
3:
4: Public Class WcfAU
5:
6: Const Valid As String = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"
7: Dim CachingPolicy As CacheItemPolicy
8: Dim DebugMode As Boolean
9: Dim Password As String
10:
11: Public Sub New()
12: CachingPolicy = New CacheItemPolicy()
13: ReadConfig()
14: End Sub
15:
16: Public Overridable Overloads Sub ReadConfig()
17: CachingPolicy.AbsoluteExpiration = DateTimeOffset.Now.AddSeconds(ConfigurationManager.AppSettings("BearerExperiedSec"))
18: DebugMode = CBool(ConfigurationManager.AppSettings("DebugMode"))
19: Password = ConfigurationManager.AppSettings("Password")
20: End Sub
21:
22: Public Function RandomString(ByVal Length As Integer) As String
23: Dim Res = New StringBuilder()
24: Using Rng As RNGCryptoServiceProvider = New RNGCryptoServiceProvider()
25: Dim uintBuffer As Byte() = New Byte(3) {}
26: While Math.Max(System.Threading.Interlocked.Decrement(Length), Length + 1) > 0
27: Rng.GetBytes(uintBuffer)
28: Dim num As UInteger = BitConverter.ToUInt32(uintBuffer, 0)
29: Res.Append(Valid(CInt((num Mod CUInt(Valid.Length)))))
30: End While
31: End Using
32: System.Runtime.Caching.MemoryCache.Default.Add(New CacheItem(Res.ToString(), New Object()), CachingPolicy)
33: Return Res.ToString()
34: End Function
35:
36: Public Function CreateMD5(ByVal Input As String) As String
37: Dim Sb = New StringBuilder()
38: Using Md5 As System.Security.Cryptography.MD5 = System.Security.Cryptography.MD5.Create()
39: Dim InputBytes As Byte() = System.Text.Encoding.ASCII.GetBytes(Input)
40: Dim HashBytes As Byte() = Md5.ComputeHash(InputBytes)
41: For I As Integer = 0 To HashBytes.Length - 1
42: Sb.Append(HashBytes(I).ToString("X2"))
43: Next
44: Return Sb.ToString()
45: End Using
46: End Function
47:
48: 'more secure need to add request input parameters to ExpectedString - this will be signature of parameters
49: Public Function CheckSign(Token As String, Sign As String) As Boolean
50: If Not DebugMode Then
51: If System.Runtime.Caching.MemoryCache.Default.Contains(Token) Then
52: System.Runtime.Caching.MemoryCache.Default.Remove(Token)
53: Dim ExpectedString As String = Password & Token
54: Dim MD5 As String = CreateMD5(ExpectedString)
55: If String.Equals(Sign, MD5) Then
56: Return True
57: Else
58: Return False
59: End If
60: Else
61: Return False
62: End If
63: Else
64: Return True
65: End If
66: End Function
67:
68: End Class
This is schema of WCF service to using my WcfAu class.
1: Imports System.ServiceModel.Activation
2:
3: <AspNetCompatibilityRequirements(RequirementsMode:=AspNetCompatibilityRequirementsMode.Allowed)>
4: Public Class Service1
5: Implements IService1
6:
7: Dim Au1 As WcfAU
8: Public Sub New()
9: If Au1 Is Nothing Then Au1 = New WcfAU
10: End Sub
11:
12: Public Function GetToken() As String Implements IService1.GetToken
13: Return Au1.RandomString(20)
14: End Function
15:
16: Public Function Test(Token As String, Sign As String, value As Integer) As String Implements IService1.Test
17: If Au1.CheckSign(Token, Sign) Then
18: Return value.ToString
19: Else
20: Throw New Exception("Error")
21: Return value.ToString
22: End If
23: End Function
...
For client WCF service with my AU still look as stateless WCF service, despite cache stored Bearer.
|