Ocelot handle HTTP request API with body - ocelot

I have a HTTP POST API in ASP.NET core as below.
[Route("{code}/bank")]
public IHttpActionResult Get([FromUri] string code, [FromBody] BankFilter bank)
{
return Ok();
}
How do configure the downstream and upstream in ocelot for the BankFilter model class?
"DownstreamPathTemplate": "/{code}/bank" -- how to accept the bank filter model class?
"UpstreamPathTemplate": "/{code}/bank" -- how to accept the bank filter model class?

You don't need to configure anything. Ocelot would pass the request body to the downstream service.

Related

Block server-to-server or Postman calls to ASP.NET Core 3.1 API

I have a ASP.NET Core 3.1 API where I have not used CORS. As I understand, CORS is a browser thing. And as my ajax calls from another site on another origin is blocked to the API endpoints (which is great), I can still reach the same endpoints by using Postman or a HttpClient and GetAsync() calls.
My question is of it's possible to also block server-to-server calls (or Postman calls) to my API? Or like CORS, only allow certain origins?
Most of my endpoints are protected by a bearer JWT token, but I have an anonymous endpoint that I would like to let only origins I control (or can configure) to have access to that anonymous API.
I solved it after i bumped in to this post on stackoverflow:
How do you create a custom AuthorizeAttribute in ASP.NET Core?
I simply made a custom Authorize attribute [ApiAuthorize()], that I call this way:
[ApiController]
[ApiAuthorize(new string[] { "https://localhost:44351", "https://mysite.onthe.net" })]
public class MyInternalApiController : ControllerBase
{
...
}
It may also be implemented on the Action instead of the Controller. The implementation was done like this:
public class ApiAuthorizeAttribute : TypeFilterAttribute
{
public ApiAuthorizeAttribute(string[] origins) : base(typeof(ApiAuthorizeFilter))
{
Arguments = new object[] { origins };
}
}
public class ApiAuthorizeFilter : IAuthorizationFilter
{
readonly string[] _origins;
public ApiAuthorizeFilter(string[] origins)
{
_origins = origins;
}
public void OnAuthorization(AuthorizationFilterContext context)
{
if (_origins == null)
return;
string referer = context.HttpContext.Request.Headers["Referer"].ToString();
if (string.IsNullOrWhiteSpace(referer) || !_origins.Any(origin => referer.StartsWith(origin, StringComparison.OrdinalIgnoreCase)))
context.Result = new ForbidResult();
}
}
Things to consider:
The implementation and check of the referer could be exact match instead of StartsWith
The handling could use RegEx or any good alternative to handle subdomains, wildcards etc
The referer could be translated to a Uri objects to get better results and variations
A jQuery ajax call gets a "403 - Forbidden" as expected, but Postman gets a "404 - Not Found". To me that does not matter, but that's something to look into if it matters.
But it covers what I need, so I'm happy with this.

Is there a helper method to extract origin host from request (to build a link)

I receive request via a router :
#Bean
public RouterFunction<ServerResponse> routerFunction() {
return nest(path(API_PATH), route(GET("/"), indexHandler::getIndex));
}
handle by a method :
public Mono<ServerResponse> getIndex(ServerRequest request) {
...
}
I need to extract the url use to request the service, I have different cases, sometimes request are direct to service, sometimes request go through proxy (and add X-Forwarded-Path,X-Forwarded-Path headers).
Is there a helper method, to extract this details from ServerRequest object ?

How can I pass parameter of type HttpContent in web api?

The back story is I have a web api that simply serves as a gateway to invoke external services. The reason for this is I don't want to expose the real business API to external services. So, in this gateway controller, it simply receives the information from the business API, calls external services and returns the response to the client, which is the business API.
In my gateway controller I have a POST action that takes a parameter of type HttpContent, something like this:
[Route("api/test")]
public void Test(HttpContent content)
{
}
but the web API infrastructure doesn't know how to serialize and deserialize HttpContent type. Is there a way to support my scenario? Thanks.
Accessing the content of the request in any controller's handler is quite natural. Just call Request.Content inside. You can't have it as a parameter because it is not a mapping as an URI segment would nor a serialized content.
Try something like:
using System.Net;
using System.Net.Http;
// namespace + controller definition...
[Route("api/test")]
public HttpResponseMessage GetTest() // This is a GET handler
{
var myRequestContext = Request.Content;
// Do something with the content e.g
if (!myRequestContext.IsMimeMultipartContent())
{
Request.CreateResponse(HttpStatusCode.UnsupportedMediaType);
}
}
BTW, assuming you are creating a REST API controller from what you said, don't forget to indicate the verb this handler is mapped to, either by using the [Http<REST_verb>] attribute in System.Web.Http on the handler or by prefixing the handler name by the verb.
Hope that helps!

How to handle PROPFIND HTTP Verb requests (or other) in ASP.NET Core?

I am looking for implementation options how to handle requests with more exotic HTTP verbs like PROPFIND or MKCOL with ASP.NET Core or ASP.NET Core MVC.
In ASP.NET Core MVC you can decorate your action methods with
[HttpGet]
[HttpPut]
[HttpPost]
[HttpDelete]
[HttpHead]
[HttpOptions]
[HttpPatch]
For a REST API or web applications these HTTP verbs are sufficient. For WebDav for example PROPFIND or MKCOL verbs have to be handled somehow, too.
Is there a possibility to extend ASP.NET Core MVC to support more HTTP verbs than the ones listed above ?
Or do you think that writing an own middleware component is the better approach to add WebDav capabilities to a ASP.NET Core app ?
I have looked into the ASP.NET Core Source Repositories to get some ideas. But I am stuck in the moment.
The solution is easier than I thought. You can invoke Controller Actions by a HTTP verb like this
public class WebDavController : Controller
{
[HttpGet]
[Route("/dav/{fileName}")]
public IActionResult Get(string fileName)
{
// a classic Get method
....
}
[Route("/dav/{fileName}")]
public IActionResult Propfind(string fileName)
{
// this is invoked if http verb is PROPFIND
// (framework searches for corresponding action name)
....
}
[AcceptVerbs("LOCK")]
[Route("/dav/{fileName}")]
public IActionResult MyLockAction(string fileName)
{
// this is invoked if http verb is LOCK
// (framework searches annotated action method)
....
}
}

Adding Authorize Headers and validate in controller

In my ASP.Net Web API Project, i added [Authorize] attribute to the controller. So when i call the method it is returning error as
"Message": "Authorization has been denied for this request."
How to send Authorize Headers along with my request.
Controller
[Authorize]
[HttpPost]
public HttpResponseMessage Settings(SettingModel data)
{
--Do i need to check authorize headers manually here?
--code goes here
}
Here it is called
http://localhost/sample/api/Settings
Headers
{
Content-Type: application/json
Authorization: What value need to be send here?
}
check the answers of Darin : How to do role based authorization for asp.net mvc 4 web api
I guess you need to register the handler..