0

My WCF Webservice provide all data manipulation operations and my ASP .Net Web application present the user interface.

I need to pass user information with many wcf methods from ASP .Net app to WCF app.

Which one in is better approach regarding passing user info from web app to web service?

1) Pass user information with SOAP header?

ASP .Net Application has to maintain the number of instances of WCF Webservice client as the number of user logged in with the web application. Suppose 4000 user are concurrently active, Web app has to maintain the 4000 instances of WCF webserice client. Is it has any performance issue?

2) Pass user information with each method call as an additional parameter?

Every method has to add this addtional paramter to pas the user info which does not seems a elegant solution.

Please suggest.

regards, Dharmendra

1 Answers1

2

I believe it's better to pass some kind of user ID in a header of every message you send to your WCF service. It's pretty easy to do, and it's a good way to get info about user + authorize users on service-side if needed. And you don't need 4000 instances of webservice client for this.

You just need to create Behavior with Client Message Inspector on client side(and register it in your config). For example:

public class AuthClientMessageInspector: IClientMessageInspector
{

    public void AfterReceiveReply(ref Message reply, object correlationState)
    {            
    }

    public object BeforeSendRequest(ref Message request, IClientChannel channel)
    {            
        request.Headers.Add(MessageHeader.CreateHeader("User", "app", "John"));
        return null;
    }
}

public class ClientBehavior : IEndpointBehavior
{

    public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
    {            
    }

    public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
    {
        foreach (var operation in endpoint.Contract.Operations)
        {
            operation.Behaviors.Find<DataContractSerializerOperationBehavior>().MaxItemsInObjectGraph = Int32.MaxValue;
        } 

        var inspector = new AuthClientMessageInspector();
        clientRuntime.MessageInspectors.Add(inspector);
    }

    public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
    {            
    }

    public void Validate(ServiceEndpoint endpoint)
    {            
    }
}

And extract it from your service-side:

var headers = OperationContext.Current.IncomingMessageHeaders;
var identity = headers.GetHeader<string>("User", "app");
alekseevi15
  • 1,732
  • 2
  • 16
  • 20
  • That inspector use a fixed username. How can I change it to use the current user ? – DkAngelito Jan 07 '15 at 14:56
  • I've used "fixed" user just not to complicate example too much. Instead of it your should use whatever user identity info you have in your project. It could be current user Id, extracted from database, for instance. Unfortunately not knowing internal details of your project it's hard to give you example that will work as it is. – alekseevi15 Jan 07 '15 at 15:30
  • IS an ASP.NET MVC 5 Portal, and I want to use the identity of the current logged user that is calling an action on the controller and that action is calling a the WCF Service. Is it clear and enough info? Thanks – DkAngelito Jan 07 '15 at 19:25
  • Try to use *HttpContext.Current.User.Identity.GetUserId()* in your client message inspector. – alekseevi15 Jan 07 '15 at 19:35
  • please add how to register wcf behavior and Inspector in MVC application? – JRA Oct 20 '18 at 05:52
  • @ialekseev, Thanks very much for your suggestion. What if the user info is from winform(fetch user from custom db), how can I pass these value to WCF AuthClientMessageInspector? I used global variables, but I don't think this is safe – Spencer Mar 03 '19 at 14:56