My back-end server is built using the Microsoft WCF REST Starter Kit Preview 2. I want to add some request processing to all requests, except for those methods I explicitly disable by marking them with an attribute. I have over a hundred service methods and there are only a few I want to exclude from this extra processing. I'll tag them all if I have to, but I'm trying to avoid disrupting what's already written.
I haven't seen anything I can add to WebInvoke, and adding an interceptor won't let me examine the method that the request is routed to.
I am asking for an explanation of how to register HttpOperationHandler object(s) so I can do my extra request processing (i.e. authorization based on information in the request headers) before it is handed off to the method it was routed to. Can someone please explain how to do this, without rewriting my existing codebase to use Web API?
You can't use an HttpOperationHandler with WCF REST Starter Kit. However the Web API is very compatible with ServiceContracts that were created for WCF REST Starter kit. You should be able to re-host them in a Web API host relatively easily. You may have to change places where you access WebOperationContext, but it should not be a huge change.
I solved my problem by adopting another method. It authenticates all requests. I can't control which method it applies to, but I was able to work around that.
I created a custom ServiceAuthorizationManager class to process the Authorization header. The CheckAccess() method returns true to allow the request through or false if the user is not authenticated or not authorized to perform the service. I hooked it up to the ServiceHost for my services by creating a custom WebServiceHostFactory class and assigning an instance to the Authorization.ServiceAuthorizationManager in its CreateServiceHost() methods.
Although I can't directly check method attributes for the service being executed, the Message.Headers member of the object passed to CheckAccess() has a To property that contains the URI of the service being called. If necessary, I could examine it to determine what method the request would be routed to.
The ServiceAuthorizationManager applies to all requests, so no web methods or classes must be marked with any special attributes to enable it.
Related
I am trying to disable the try it out feature of the Swagger UI for certain endpoints only. These are regardless of their http method. I know it is possible to disable either for all endpoints by adding to the Startup configuration:
c.SupportedSubmitMethods(new SubmitMethod[] {});
As part of the UseSwaggerUI options. I also aware of disabling the try it out feature for specific http method endpoints, such as only display the Get methods using:
c.SupportedSubmitMethods(new SubmitMethod[] { SubmitMethod.Get });
However, I need to disable try it out for a selection of endpoints, that are not common for one http method only. The use case is that I am currently in the transition of updating endpoint authentication from API-keys to an OAuth2.0 clients credentials flow. Newly added endpoints are thus, not secured with API-keys - as we would like our customers to be able to integrate towards the new endpoints straight away, and then configure the OAuth flow once this is added. So I have some endpoints, that are configured with API-keys (running over Azure APIM) which cannot be called directly without throwing a 403 code. So to avoid any confusing, until the OAuth authentication is added, I would like to disable the try it out for the older endpoints, while the new ones should have it.
Ideally it would be nice to have a simple decorator, or attribute that could be added to those endpoints that I do want to hide (eg. something like [SubmitMethod(false)] - however this is just a plain pseudo sample to prove my point here).
As a side note, I am developing using .NetCore 3.1.
I wanted to put a situation to you to get your thoughts on the use of Flurl; if I have developed a restful api which is designed to support authentication and sessions from multiple users and you part of the operation of the restful service is that it needs to make authenticated calls to another outside service. If I used the standard flurl implementation of call asyn from a string URL and if I need to set different headers depending on the user that authenticated to my service, would this cause unpredictable behaviour due to it using a single httpclient (as they are all calling the same host).
Doing it the way you describe is completely safe. Setting headers fluently off a URL string or Url object will apply them to the request, not the client. Example:
await url.WithHeader(name, value).PostAsync(body);
This call can be made a zillion times from different threads with different header values and a single shared HttpClient instance with no conflicts. This works because under the hood it sets the header on the HttpRequestMessage, not the default headers on the HttpClient.
I'm working on a legacy ASP classic application. This application also supports an API, written in C# using Web API 2.
I'd like to add functionality to this API that will consume a request (as a resource - which will contain data need to satisfy a workflow), validate that request, and inside the API controller, generate a new request to an ASP page (the workflow is quiet complicated, so rather than re-write that logic, re-using the ASP page provides better business value).
Ideally I'd like to wait for the response inside the controller, and then pass back an Action Result (like a 204) to the consumer of the API.
The idea here is to hide the response of the ASP page, and return something simple to the consumer.
I know how to structure the URL somepage.asp?p1=help&p2=me, however I'm not sure how to create it as a request, execute it, and then consume the response within the API controller.
Is it even possible?
I have an asp.net application that I'm attempting convert the front end to Angular. Getting header information is important to the view. I'm used to getting the header information like so in C#:
httpContext.Request.Headers["USERID"]
How can I do the same thing in an angular controller?
In asp.net each request runs in its own independent context and hence the header access as you have shown in your code make sense.
This does not hold good for angular or in fact any client side framework. You can always get the headers for any request or response made using angular $http but the question is which request? During the lifetime of the app you would make many such requests.
Let's say you want to get the current userid, you can create a service that returns the logged in user. There are two ways to implement such a sevice
create a method on server to return this data. Invoke this method from service and cache results
on the client side assuming there is a login request made through angular, implement a success callback method which can update the service with the logged user id.
You can look at $http documentation here to understand how to access headers.
I have created a custom http handler (IHttpHandler).
This handler can be called from any place in the application.
eg: domain.com/file.handlerExtension or it can be domain.com/folder/file.handlerExtension
I have security on my application, but this handler should be available to anonymous users also. Because of this approach it is a mess to create a location element in web config for every posible location from where the handler can be called.
Is there a way to remove check of Authentication and Authorization on a specific resource or Handler in IIS7?
As far as I know - No - this is handled as an HttpModule (if not using iis authentication) - the application configuration defines urls to protect. The only hope may be to hack it so it thinks the user is already authenticated (not even sure if it would work) prior to the Authentication httpModules running which would mean changing processing order. and even then you would have to have some logic built in to say 'force authentication for a request to THIS uri'
MVC's security handling is a bit better IMHO as you can simply use attributes on your controllers or methods to define security and in that case your app would simply remain anonymous for those request.