When users first connect to my sessionful service, they provide a user name in the form of a string. If multiple users have provided the same user name, the server appends all new users with a number that increments based on how many exist on the service already.
These user names are the value in a Dictionary<IChatCallback, string> dictionary. Whenever a user calls a method such as SendMessage on the server, the server detects who the caller is by doing a dictionary lookup based on OperationContext.Current.GetCallbackChannel<IChatCallback>() as the key.
My question is... can this channel be spoofed? Can somebody somehow call methods on the service under someone elses callback channel, and the server is oblivious?
Related
I looked around to see if the issue was already covered, but it appears that there are no good coverages for such situations, or that I was unable to find any.
So, I'm attempting to set up a private chat between two individuals. Currently, I can't create a group because I don't have the receiver's connectionId, which can only be obtained when the user joins the hub, but in any adequate chat application (say, Instagram), the sender selects the receiver, sends the message to them, and then the receiver chooses whether or not to join the chat.
So, I'm wondering whether there's another way to get the connectionId, and if not, what's the standard procedure for making such a chat?
No, You can only get the connectionId after user joins the hub. Because in general, User even don't know his own connectionId. The SignalR Hubs API provides the OnConnectedAsync and OnDisconnectedAsync virtual methods to manage and track connections. You can create a mapping table between name and connectionId and save it in memory or any place you want. When user join the hub, Get the name and connectionid, Then override OnConnectedAsync/OnDisconnectedAsync to add/remove record about this mapping table. Finally, In your Add group method, you can get the connectionId by receiver's name in this mapping table.
I have a per call service, and in my client proxy, I close the proxy when the method has finished. So when I want to call another method, I instantiate a new proxy.
In this second call, I can see that the uuid part of the sessionId is the same in the two calls, but the id part is different.
So if I tried to compared the two sessionId are different.
I would like to know if really the id part is important or not, of if the uuid is the same, really is the same client although the id part is different.
Thanks so much.
If you close proxy then, regardless of whether the session was supported or not, service is destroyed and session is terminated, if any existed.
If you wish to share the same sessionId across many calls you need to make sure both binding and service supports session (either SessionMode.Allowed or SessionMode.Required) and perform calls within the same client.
New client = new session
is there any way to get current signalR request user outside the hub? I can use Hub.Context.User inside of hub methods, but if hub method calls any other underlying layer? Wcf service call - an additional BehaviorExtensionElement is used to add wcf message header with current user identity name.
public object BeforeSendRequest(ref Message request, IClientChannel channel)
{
request.Headers.Add(MessageHeader.CreateHeader(
Constants.HeaderNames.SessionId,
Constants.HeaderNames.HeaderNamespace,
_hubManager.ResolveHub(Constants.Hubs.MessengerHub).
Context.User.Identity.Name));
}
Yes, i found that the DefaultHubManager gets the Hub, but i'm not sure it will be the hub from current request, not the concurrent one or a new one, 'cause at the end of ResolveHub i see the following code runs
return (DependencyResolverExtensions.Resolve(this._resolver, descriptor.HubType)
?? Activator.CreateInstance(descriptor.HubType)) as IHub;
Obviuosly i can pass user from hub method to wcf call but it requires refactoring to move from wcf behaviour to setting request field with user name explicitly.
Also can i rely on HttpContext.Current to get the info from cookie?
No you cannot. The only way to retrieve the currently active user outside of the hub itself would be to pass the users information to whatever method you call in the hub.
A common pattern is to track your users by adding them to some sort of dictionary in OnConnected and removing them in OnDisconnected. You can then have an entirely separate way of identifying your users while having required information that's associated with them.
What is the best way to go about calling various services that are internally only (i.e. no client code can invoke the logic)?
IProcessService - will run various things and make changes to a domain entity, however when certain data changes on this domain entity we want to send out a notification (add a new record to notification table, record the current user and type of notification, and maybe even send out email).
E.g. Add a client, as soon as we add a client - we want to save a record in the db that a client has been added, if we have a supplier confirmed, we have a delivery date confirmed we want to fire off notifications.
My notifications are a way of logging all activity related to the process of a Order...
Is using a pub sub approach common/ event listers etc?
NOTE: I am using Linq To Sql, and a service layer to communicate with my asp.net mvc app, all my business logic/validation/rules etc reside inside my service layer...
Check out Domain Events.
When you call client.ConfirmDeliveryDate(), it would raise a domain event (DeliveryDateConfirmed). You'd then have a class listening to this event: EmailCustomerWhenDeliveryDateConfirmed.
I'm creating a smart client application using .NET 3.5. A Winforms client connecting through WCF services to retrieve data from SQL Server 2008. I need to pass a username/password (encrypted and over HTTPS) and return information such as:
Is this user (e-mail address) under a current subscription
What server should we go to next for all subsequent calls (poor man's load balancing)
What server/database should be used in the connection string (credentials not required), as people could be using different databases depending on their subscription, etc.
So my first call when signing on sends the credentials which a lookup is performed. A serializable class will be used to create a token object (I assume this is the way to handle this) which will return the expiration, server info, database info.
The question is on all subsequent calls do I pass this token as a parameter to every service contract (web method) or can I leave all my current contracts as is and pass the token in a header or some other more universal method?
How do you suggest implementing a token system such as I describe?
Thank you
For one, I would only return a TokenID - some unique ID to clearly identify the user and his subscription in question - from your first "authentication" call. No need to send back and forth the whole set of information all the time - only the service on the server side needs those details, so you can leave that info on the server and only consult it in your server code when needed.
So that first call - the authentication call - would most likely check the credentials being sent against a database table, against a subscription table, and then put that information (who's calling in, based on what subscription) and possibly some kind of an expiration date/time into a "Valid Callers" table and generate an ID from that (a GUID or something). You might want limit the "lifespan" of a TokenID - e.g. it's valid for 30 minutes or so - so that it can't be hijacked and used perpetually after a first successful call. That generated GUID is then returned as the TokenID from the Authentication call and can be used as an identifier in each subsequent call.
Things like what database server to use have really no place in messages going back and forth - they're strictly important to the server-side service code - just leave it there!
It is definitely preferred practice to put such "meta information" that isn't the real value information for your calls into headers and go search for it there. WCF supports this quite nicely and easily - with either message inspectors (sample for that here and here) on client and service side, or by using the OperationContextScope (sample blog post here and here) - both work just fine.