Tuesday, January 26, 2016

Getting the client name and IP address from WCF

One of the concerns we have where I work is that users keep sharing logons and passwords. Then later we get support calls such as "The change history says I did this but I wasn't even here that day". So I decided to see what it would take to track IP Addresses.

Obviously the client knows its own IP Address and can send it to the WCF endpoints that actually do all the work. However we have a lot of endpoints and I didn't want to have to change all the contracts so I looked for a way for the end point to know the IP Address of the client that it is talking to. I turns out to be quite easy if you are targeting framework 3.5 or later.

Imports System.ServiceModel
Dim context As OperationContext
Dim prop As Channels.MessageProperties
Dim endpoint As Channels.RemoteEndpointMessageProperty

context = OperationContext.Current
prop = context.IncomingMessageProperties
endpoint = CType(prop(Channels.RemoteEndpointMessageProperty.Name), Channels.RemoteEndpointMessageProperty)

Return endpoint.Address

So this works great, but IP Addresses can change over time as they are released and renewed. Even better would be the client name, but that requires a reverse DNS lookup from the IP Address. Here is the completed code to get the IP Address from the conversation and perform a reverse DNS lookup. If the lookup fails the IP Address is returned instead.

Note that when the client and the WCF endpoint are on the same computer as is the case when you are debugging, the conversation doesn't even use TCP/IP so this all fails and returns "n/a".

Imports System.ServiceModel
Public Shared Function GetClientName() As String

    Dim context As OperationContext
    Dim prop As Channels.MessageProperties
    Dim endpoint As Channels.RemoteEndpointMessageProperty
    Dim addr As Net.IPAddress
    Dim entry As Net.IPHostEntry

    Try
        context = OperationContext.Current
        prop = context.IncomingMessageProperties
        endpoint = CType(prop(Channels.RemoteEndpointMessageProperty.Name), Channels.RemoteEndpointMessageProperty)

        Try
            addr = Net.IPAddress.Parse(endpoint.Address)
            entry = Net.Dns.GetHostEntry(addr)
            Return entry.HostName
        Catch ex As Exception
            Return endpoint.Address
        End Try
    Catch ex As Exception
        Return "n/a"
    End Try
End Function

No comments:

Post a Comment