We have a requirement to enable WCF client that uses WS2007FederationHttpBinding over AWS' Application Load Balancer with stickiness enabled.
Client --> ALB --> Server1, Server2
ALB attaches a ALB cookie each time so that the client can always talk to the same server during the life of session. The client performs several roundtrips per session, and each time it can receive a ALB cookie but unable to send them back when making a subsequent request, as if it doesn't care about HTTP Cookies at all. Is there a way to enable HTTP Cookies on WCF Client using WS2007FederationHttpBinding?
We can use cookies in WCF client by controlling http header:
using ( new OperationContextScope( client.InnerChannel ) )
{
HttpRequestMessageProperty request = new HttpRequestMessageProperty();
request.Headers["Cookie"] = "value";
OperationContext.Current.OutgoingMessageProperties[
HttpRequestMessageProperty.Name] = request;
client.Test();
}
We interact directly with HTTP messages exchanged with web services, reading and writing cookies as strings in the appropriate headers.
In situations where cookies must be managed in the same way for all web services called from client applications, the best option is to choose a centralized solution by applying a very useful feature (message inspector) in WCF.
We can implement the IClientMessageInspector interface on the client to handle cookies, For more information on how to use cookies in WCF clients, you can refer to this link:
https://megakemp.com/2009/02/06/managing-shared-cookies-in-wcf/
Related
I'm using signalr core and am expect to be sending and receiving messages with the client frequently over mobile, so I've been trimming off the fat to minimize my message sizes. One thing I've simply been curious about is, when making requests from a hub that requires authentication, does every request sent to the hub also sends it's asp.net core authentication cookie, or does the client only send the cookie once when they initiate their connection to the hub and then all subsequent requests no longer need a cookie?
does every request sent to the hub also sends it's asp.net core authentication cookie, or does the client only send the cookie once when they initiate their connection to the hub and then all subsequent requests no longer need a cookie?
The cookies would be sent with the POST [endpoint-base]/negotiate request that is used to establish a connection between the client and the server, like below.
If a connection is established and the WebSockets transport is used, exchanging messages between server and client would be on WebSockets protocol.
If WebSockets is not available, and Long Polling transport is used, while client communicates with hub, cookies are sent with each request.
Besides, as mentioned in this doc: cookie authentication isn't recommended unless the app only needs to authenticate users from the browser client.
From reading the Microsoft docs on authentication with SignalR, it looks like the only way to authenticate using a bearer token is to send it in the query string on the WebSocket connection.
Upon inspecting the SignalR handshake, it looks like the Authorization header is included in the Negotiate call. Since the connection ID is returned in the negotiate response, the server could keep track of whether that connection ID has authenticated.
Why is it required to add the bearer token to the Websocket connection query string as well?
It seems this is the clue for your question.
When using WebSockets or Server-Sent Events, the browser client sends the access token in the query string. Receiving the access token via query string is generally secure as using the standard Authorization header. Always use HTTPS to ensure a secure end-to-end connection between the client and the server.
Security considerations in ASP.NET Core SignalR
This is the alternative:
SignalR can be used with ASP.NET Core authentication to associate a user with each connection. In a hub, authentication data can be accessed from the HubConnectionContext.User property. Authentication allows the hub to call methods on all connections associated with a user. For more information, see Manage users and groups in SignalR. Multiple connections may be associated with a single user.
Authenticate users connecting to a SignalR hub
Additional:
However, I think you can also try some injection for both server and client. On server eg. use websocket helper and on client eg. use Promise vs XMLHttpRequest.
We are using Improbable's gRPC-Web library to expose a gRPC service (implemented in Go) to a Javascript client running in-browser. This service will sit alongside an existing front-end Go service which hosts a REST-based API. The existing service uses session-based authentication to authenticate its users (session cookies + XSRF protection with double-submit cookies, which are also verified using some per-session server-side state).
The front-end Go service hosts various API endpoints which are either handled locally or fulfilled by proxying the request to other services. All endpoints are exposed via a Gin middleware handler chain, which implements the aforementioned session authentication and XSRF protection checks. It has been proposed that we host gRPC-Web's gogrpcproxy component behind this existing middleware to expose our gRPC service to the world.
I am interested in ensuring the approach for authenticating the incoming gRPC-Web requests is secure. The following methods have been proposed:
Token-based authentication – i.e. passing bearer tokens in the gRPC request metadata, which are verified by the back-end gRPC service. This matches the authentication model by which native gRPC calls would be authenticated if gRPC-Web was not involved.
In this model, gRPC-Web's responsibility is the implementation of the transport abstraction between browser and server, and marshalling requests to/from the native gRPC representation; authentication is delegated to the backing gRPC service. The gRPC-Web proxy is hosted as a separate endpoint external to the existing REST API.
Session-based authentication – re-use of the existing session authentication middleware. In this model, the grpcweb proxy server is hosted behind the Gin handler chain. Gin performs its usual checks to verify existence of the relevant cookies and XSRF headers prior to admitting the request.
This approach re-uses much of the existing authentication logic. However, it requires the passing of the XSRF header to ensure the request is admitted by the Gin middleware. This is possible in the current implementation by setting request metadata, which is (currently) implemented by setting headers on the outbound HTTP request. However, it is unclear to me whether this:
is appropriate, as it appears to be a layer violation by exploiting the implementation detail that metadata is currently passed as HTTP headers. This is not documented and could conceivably change;
is compatible with gRPC-Web's websocket transport, which does not appear to propagate metadata into headers, as the websocket transport is dialled prior to any requests being transmitted;
suffers potential security issues in future, as the long-lived gRPC-Web transport connection to the front-end service is only authenticated by the front-end proxy when first established, rather than continually on every request (unless the gRPC service also validates the request metadata).
My understanding is that gRPC-Web seeks to emulate the gRPC transport between a browser and server, so accordingly implements no specific authentication logic. The standard gRPC mechanisms for passing authentication details make no allowance for implicit session-based state, so my preference is the token-based approach.
Is this a reasonable analysis of the available options?
I've been using wcf for a while and its authentication mechanisms, Windows, UserName/Password, Client certificate for a while.
I'd like to better understand how WCF uses these authentication mechanisms internally when creating SOAP messages and sending them.
Specifically, are the authentication credentials passed by wcf in every SOAP request, or does it only pass the authentication credentials in the first request and then some kind of token is issued and passed back and forth during subsequent sessions?
Are these authentication credentials (username+password, windows, client certificate) passed in a different manner depending on whether the security mode is transport or message? Is it that in message mode, the authentication credentials are inside the SOAP message, while in the transfer mode, http headers are other transport protocol specific are used to pass the authentication credentials?
Lets just assume that the SOAP message is secured using https when Transport mode is used and encrypted when using Message Mode and not worry about message privacy or tampering for this question.
You've asked several big qeustions, but I'll try to answer the question about sessions.
Session and authentication handling depend on the binding you're using. If you're using basichttpbinding, for instance, the host basically acts like a web server and no persistant "sessions" are created; as a result each SOAP request you send must contain everything necessary for authentication on the host. However, there are some bindings available like WSHTTPBinding that allow for the creation of security and reliability sessions that persist after the initial authentication using a token.
Wrapping the message in SSL should prevent problems.
I have a .NET client application that needs to communicate with a server using two distinct user credentials.
Lets say that the application runs two threads. When start running, every thread sends the user & password to authenticate and the server in return stores a cookie on the http session. The subsequent calls send the authentication cookie and not the user credentials.
We have two cookies for the same process. How does wininet "knows" to send the appropriate cookie for each thread?
Does wininet manage the cookies collection per thread? per http session? per process?
Thanks
Wininet uses cookies per process.
However in a .NET client you can use a Cookie container with the HttpWebRequest object.
You create one cookie container for each "session". Assign the appropriate container to each HttpWebRequest when making the various requests for each session.