WCF was designed to be fully extensible, at all levels. If I want to pass a custom identity (an application-defined username and role and the desired culture) to a WCF web service (not using ASP.NET compatibility mode), this is what I do:
I defined a custom AuthenticateAttribute attribute, which implements IContractBehavior, IClientMessageInspector and IDispatchMessageInspector (a message inspector for both the client and server ends)
I add this attribute to the service interface, at the interface level, next to [ServiceContract]
On the Web.config file, I add a line <serviceAuthorization principalPermissionMode="None" /> to the behavior definition
Please note that on my sample class, I am not currently sending the actual username, role and culture, but it is very easy to do, perhaps through message header properties.
When the web service receives the request, before it is actually forwarded to the apropriate method, it sets the Thread.CurrentPrincipal, Thread.CurrentCulture and Thread.CurrentUICulture properties.