(NET) NET (2014)

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.





Comments ( )
<00>  <01>  <02>  <03>  <04>  <05>  <06>  <07>  <08>  <09>  <10>  <11>  <12>  <13>  <14>  <15>  <16>  <17>  <18>  <19>  <20>  <21>  <22>  <23
Link to this page: //www.vb-net.com/WCFBearer/Index.htm
<SITEMAP>  <MVC>  <ASP>  <NET>  <DATA>  <KIOSK>  <FLEX>  <SQL>  <NOTES>  <LINUX>  <MONO>  <FREEWARE>  <DOCS>  <ENG>  <CHAT ME>  <ABOUT ME>  < THANKS ME>