Is single Request object instance in REST client okay? - c#

I'm writing a simple REST client for a C# WinForm application. I use RestSharp to make sending requests and getting responses easier. I have a few questions regarding how I should design my client.
The user interacts with the client only once. He pushes a Button and the client is instantiated and passed to private methods to do some logic in the background. It accesses objects from the server and synchronizes them with objects in the user's internal database.
The point is that the client's methods are accessed by private methods called following the user's single action in the GUI. He does not have any control over which of the client's methods are called, and in which order.
So my questions are:
Can I ask the server for a token only once when I instantiate my client, and then store it in the client instance for future reference in the client's following requests? The token is a hash of the username and password, so it should not change over time. Of course, once I create a new instance of the client, it will again ask the server for a token.
Is it okay to keep a single Request object instance in my client? I can then set request header only once and all the methods that access the API will only need to change the request's resource URL and HTTP method. It would reduce repetitiveness in my code.
For example:
public PriceListItem[] GetPriceListItems()
{
string requestUrl = Resources.PriceListItemsUrl;
var request = new RestRequest(requestUrl, Method.GET);
request.AddHeader("SecureToken", _token);
var response = Client.Execute(request) as RestResponse;
JObject jObject = JObject.Parse(response.Content);
var priceListItems = jObject["Data"].ToObject<PriceListItem[]>();
return priceListItems;
}
I have quite a few methods for utilizing different resource URLs, but all have the same header. If I keep only one Request instance in my client I can set the header only once. Is this approach okay? I would like to avoid any delegates and events.

You have to use ParameterType.HttpHeader parameter:
request.AddParameter("Authorization", "data", ParameterType.HttpHeader);

It's perfectly normal to save auth token on client, as long it's encrypted and have expired time on it.
You can improve it with implement session on your REST API, so you just need check if the auth token is still valid or not, and do the authentication if it's not valid.
Clearly you need to manage the way you request to the REST API, I Recommend you to use IDisposable Pattern for this manner, you can utilize some lazy implementation or Singelton.

Related

Reusing HttpClient for different users

I've been reading a lot about best practices when using HttpClient. Most people recommend reusing it for the lifetime of the application, even though it's IDisposable.
My web application is communicating with various APIs, like Facebook Graph API, Twitter API and Instagram API.
The plan is to create an individual HttpClient for each API it communicates to, which is recommended, because then I can reuse some of the headers.
But now to the question, let's take the Twitter API as an example, each user using my web application has its own authorization header (user bound access token). I believe this means that I can't set the authorization header to the DefaultRequestHeaders of the HttpClient object.
What is the best practice when it comes to reusing HttpClient for multiple users who have different authorization headers?
Could I create a HttpRequestMessage object for each request and set the authorization header on the httpRequestMessage object, instead of setting it to the default one, httpClient.DefaultRequestHeaders.Authorization?
Thanks.
Because there is some cost involved in creating a HttpClient (especially the number of sockets) there are some benefits in reusing a HttpClient instance. It is thread-safe as as well.
In order to have no dependencies between multiple concurrent calls with one client instance the key pattern is to use HttpRequestMessage class and invoke the HttpClient.SendAsync method (instead of using the more convenient HttpClient.GetAsync, PostAsync, ...).
Something like this:
var request = new HttpRequestMessage() {
RequestUri = new Uri("http://api.twitter.com/someapiendpoint"),
Method = HttpMethod.Get
}
// set the authorization header values for this call
request.Headers.Accept.Add(...);
var response = await client.SendAsync(request);
Now the request headers of the HttpRequestMessage will be used (and not the DefaultRequestHeaders anymore).

c# mvc reroute request to different server

I have a web application which is a mesh of a few different servers and 1 server is the front-end server which handles all request external incoming requests.
So some of these request will have to be passed along to different servers and ideally the only thing I want to change is the host and Uri fields of these request. Is there a way to map an entire incoming request to a new outgoing request and just change a few fields?
I tried something like this:
// some controller
public HttpResponseMessage get()
{
return this.Request.Rewrite("192.168.10.13/api/action");
}
//extension method Rewrite
public static HttpResponseMessage Rewrite(this HttpRequestMessage requestIn, string Uri) {
HttpClient httpClient = new HttpClient(new HttpClientHandler());
HttpRequestMessage requestOut = new HttpRequestMessage(requestIn.Method, Uri);
requestOut.Content = requestIn.Content;
var headerCollection = requestIn.Headers.ToDictionary(x => x.Key, y => y.Value);
foreach (var i in headerCollection)
{
requestOut.Headers.Add(i.Key, i.Value);
}
return httpClient.SendAsync(requestOut).Result;
}
The issue I am having is that this has a whole slew of issues. If the request is a get Content shouldn't be set. THe headers are incorrect since it also copies things like host which shouldn't be touched afterwards etc.
Is there an easier way to do something like this?
I had to do this in C# code for a Silverlight solution once. It was not pretty.
What you're wanting is called reverse proxying and application request routing.
First, reverse proxy solutions... they're relatively simple.
Here's Scott Forsyth and Carlos Aguilar Mares guides for creating a reverse proxy using web.config under IIS.
Here's a module some dude named Paul Johnston wrote if you don't like the normal solution. All of these focus on IIS.
Non-IIS reverse proxies are more common for load balancing. Typically they're Apache based or proprietary hardware. They vary from free to expensive as balls. Forgive the slang.
To maintain consistency for the client's perspective you may need more than just a reverse proxy configuration. So before you go down the pure reverse proxy route... there's some considerations.
The servers likely need to share Machine Keys to synchronize view state and other stuff, and share the Session Store too.
If that's not consistent enough, you may want to implement session stickiness through Application Request Routing (look for Server Affinity), such that a given session cookie (or IP address, or maybe have it generate a token cookie) maps the user to the same server on every request.
I also wrote a simple but powerful reverse proxy for asp.net / web api. It does exactly what you need.
You can find it here:
https://github.com/SharpTools/SharpReverseProxy
Just add to your project via nuget and you're good to go. You can even modify on the fly the request, the response, or deny a forwarding due to authentication failure.
Take a look at the source code, it's really easy to implement :)

Authentication via headers in WCF REST service

I am new to WCF services and currently testing out things.
I have got a little REST API, which has several methods. Some of them require a user context (session), some others don't. At login, each user gets a session token. The client should supply this token and his user ID on every request via HTTP headers.
At the moment, I wrote a method for getting those two headers and validate the session, calling it on every method which will need a user context. This seems kinda nasty if the API gets bigger.
Is there a better approach for doing this?
You can leverage of following solutions:
Custom class deriving IClientMessageInspector/IDispatchMessageInspector for client and service respectively. Then you add its instance to MessageInspectors. Advantage of having messageInspector is that it's applied to single endpoint so regardless of having many endpoints exposed (both SOAP and REST), messageInspector can be associated only with single one. Whenever message is either received or sent, AfterReceive or BeforeSent method is invoked respectively. There you retrieve headers and if token does not match any expected you can throw an exception. Such a way out provides separation between exposed contract and background checks such as token validation.
Custom class deriving IOperationInvoker. Within custom operation invoker you explicitly call method and thanks to it you can examine headers (OperationContext.Current.IncomingMessage) before any method gets invoced.
I brought up only concepts, extensive information and examples can be looked up on Internet.

Secure WCF REST Webservice and headers

I'm writing a secure WCF REST webservice using C#.
My code is something like this:
public class MyServiceAuthorizationManager : ServiceAuthorizationManager
{
protected override bool CheckAccessCore(OperationContext operationContext)
{
base.CheckAccessCore(operationContext);
var ctx = WebOperationContext.Current;
var apikey = ctx.IncomingRequest.Headers[HttpRequestHeader.Authorization];
var hash = ctx.IncomingRequest.Headers["Hash"];
var datetime = ctx.IncomingRequest.Headers["DateTime"];
...
I use headers (Authorization,Hash,DateTime) to store informations about apikey, current datetime and the hashed request URL while request body contains only URL and webservice parameters.
Example:
http://127.0.0.1:8081/helloto/daniele
Is this the right way or I've to pass and retieve those parameters from URL like this:
http://127.0.0.1:8081/helloto/daniele&apikey=123&datetime=20120101&hash=ddjhgf764653ydhgdhgfjiutu56
are there differences between those two methods?
I think both methods would work for simple cases. However, if you want to make maximum use of native HTTP behaviours, you should go with the headers approach, not the URL query parameters one.
This will allow you to (for example) use HTTP response codes to indicate to client that a resource has been permanently moved (response code 301) so the client can automatically update links. If the URL included the authentication information, it is not clear to a client that two different URLs are actually referring to the same resource. In other redirect scenarios, the headers will be automatically included so you don't have to worry about appending parameters to redirect URLs.
Also, it should allow better caching behaviour on clients (if that is relevant in your scenario).
As another example, using headers would allow you to authenticate a request based just on the headers without requiring the client to send the message body. The idea is that you authenticate with the headers, then send the client an HTTP 100 Continue response. The client should not send the message body until it gets the 100. This could be an important optimisation if you are doing POSTs or PUTs with large message bodies.
There are other examples, but whether any given one is relevant depends on your scenarios and on the clients you expect to serve.
In summary, I would say it is better to make use of elements of the protocol as they were explicitly intended - this gives you the best chance of behaving as a client expects and should make your service more accessible, efficient and usable in the longer term.
Based on your implementation, your required parameters would have to be passed in the HTTP Headers of the request, which would most certainly not be on the query string.

Implementing a client-side cache using WCF, REST and standard HTTP headers

I have a Perl based REST service and I'm using C# and WCF to make a client to talk to the service. I have a few expensive calls and would like to construct a caching system. I need the ability to check and see if newer versions of the cached data exist on the server. I had the idea to use the standard "If-Modified-Since" request header and "304 Not Modified" response status code, however I'm having trouble catching the exception that is thrown on the response.
My client class derives from ClientBase<>. Here is the method that I use to call a service method:
private T RunMethod<T>(ReqHeaderType reqHeaders, ResHeaderType resHeaders, Func<T> meth)
{
//Get request and response headers
var reqProp = GetReqHeaders(reqHeaders);
var resProp = GetResHeaders(resHeaders);
using (var scope = new OperationContextScope(this.InnerChannel))
{
//Set headers
OperationContext
.Current
.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = reqProp;
OperationContext
.Current
.OutgoingMessageProperties[HttpResponseMessageProperty.Name] = resProp;
//Return the result of the call
return meth();
}
}
The exception occurs when the call back, which runs the service method, is executed. Is there a way to catch the exception and check if it is a "Not Modified" response?
In my opinion, you really only want to use WCF channels on the client if you are using non-web WCF bindings on the server.
In your case you are not even using .Net on the server so I think WCF is going to cause you a whole lot of pain.
I suggest you simply use the HttpWebRequest and HttpWebResponse classes in System.Net. If you do that you can also take advantage of the built in caching that is provided by WinINet cache. If you set the caching policy in the client Http client you will get all the caching behaviour you need for free.

Categories