Custom Webhook Receiver in .Net core 2.1 - asp.net-core-webapi

I'm trying to create webhooks receiver for bigcommerce webhooks.
[HttpPost("customer_update")]
public void GetCustomerUpdateHook()
{
d_logger.Information("Process Webhook reply Web Response Hit");
}
my function is getting hit without any issues. But I don't know how to access the receiving data. I'm not sure how to use WebHookHandler.
framework => .Net core 2.1
controller => API Controller

I was able to receive the data, without using webhook handler or receiver. I just created a "POST" method in my controller by getting data from request body.
[HttpPost("customer_update")]
public void GetCustomerUpdateHook([FromBody] WebhookResponse p_data)
{
d_logger.Information("Process Webhook reply Web Response Hit");
var dataAsString = Newtonsoft.Json.JsonConvert.SerializeObject(p_data);
d_logger.Information("Response ==> {#data}", dataAsString);
}
But WebhookResponse class must match the data you are getting. for sender authentication, I added custom headers in Bigcommerce webhooks registration.

Related

.NET Core Identity - How generate token from another place than path/connect/token

in my web api application I get the acess token from http:applicationpath/connect/token with some parameters (this endpoint is from Identity I think, since we dont create it neither can see it).
But now I need to generate the token from a specific controller but cant see how to do this.
Someone knows how this can be made? Or even if it's possible?
Thanks
Some more info:
My application is an integrator (is this the word?) between an android app(app1) and other web application(app2).
1- The app1 user will send the login and password to my application .
2- Then my application will send then to the app2 who will, if everything goes well, return the app2 token .
3- Then I have to save this token in my db.
4- Then verify if the user exists in my db, and if not, save it.
5- And finally generate an token for my application and return it to the user.
Based on your comment:
But can I, instead of change de default endpoint, make another
endpoint that do the same (generate the token)?
it seems that you are rather looking for Extending discovery. This is quite easy actually.
Add a custom entry in the configuration of startup:
services.AddIdentityServer(options =>
{
options.Discovery.CustomEntries.Add("custom_token", "~/customtoken");
});
And add a controller that handles the request:
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
// In case a token is required for login, like the UserInfo endpoint:
//[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
[ApiController]
public class CustomTokenController : ControllerBase
{
[Route("customtoken")]
public IActionResult CustomTokenEndpoint()
{
return Ok();
}
}
Update
You can 'replace' the endpoint by disabling the default authorization endpoint and adding a custom endpoint as described above.
Disable the endpoint:
services
.AddIdentityServer(options =>
{
options.Endpoints.EnableAuthorizeEndpoint = false;
})
You may want to use the Authorize path constant.
public const string Authorize = ConnectPathPrefix + "/authorize";
Add the new endpoint:
services.AddIdentityServer(options =>
{
options.Discovery.CustomEntries.Add("authorization_endpoint", $"~/{Authorize}");
});
Please note, I didn't test it, but I think this should work.

Handle Unauthorized Request and Return Status Code 404

I am developing a standalone .Net Core API targeting framework .Net Core 2.2.The authentication scheme is JWTBearerTokens connecting to our ADFS Identify server.
When I call an API endpoing decorated with the [Authorize] attribute I am getting a 401 Unauthorized response, which is expected and default behaviour.
What I want to do next is instead of having that same call return a 401, I would like to return the status code to be 404. (I don't want to get into great details of why 404. Simply, I do not want to expose that the endpoint exists if a valid token is not included in request)
In previous .Net Framework WebAPI you could create your own attribute and override the HandleUnauthorizedRequest method and return the status code you want.
I have reviewed the documentation on policy-based authorization, but have not tried the sample or tried implementing it. The policy handler looks more to do with handling (return success or fail) if a policy is not fulfilled. I do not see anywhere where you can return a different status code on failure. So that only would make sense if I start checking against actual Policies.
Any insights?
Returning 404 instead of 401 is bad practice(as mentioned in the comments by #Chris Pratt) and must be avoided. Consider these cases,
You're leaving the project to someone else and they can't figure why 404 is returned
A 404 is returned when you call the homepage/Index page. Poor ideology.
Later on in the project, you decide to allow post requests without authentication. So on and so forth.
Anyways, as part of the community, I'll give you the answer...
Add this to your global.asax
void Application_EndRequest(object source, System.EventArgs args)
{
if (Response.StatusCode == 401)
{
Response.ClearContent();
Response.RedirectToRoute("ErrorH", (RouteTable.Routes["ErrorH"] as Route).Defaults);
}
}
And in routeConfig, create a route for your errorHandler :
routes.MapRoute(
"ErrorH",
"Error/{action}/{errMsg}",
new { controller = "CustomController", action = "Change401To404", errMsg = UrlParameter.Optional }
);
And in your custom controller :
public class CustomController : Controller //or Base
{
public ActionResult Change401To404(){
//Do whatever you want
}
}
PS: This is not the only way, there are many other ways to do it. But at least in this method, you can differentiate real 404 responses from 401 responses.

ServiceStack Razor Response Filter

I Write a ServiceStack Razor Page named 'default.cshtml'. I want to add a global response filter on it running, but it not work right. how to fixed it?
private static void AddFilters(IAppHost appHost)
{
appHost.GlobalResponseFilters.Add((req, res, dto) =>
{
res.AddHeader("X-Powered-By", "mylvgth");
});
}
GlobalResponseFilters are for requests that populate Request DTOs and are executed by Services. For other requests you can use PreRequestFilters which is executed at the start of a Request.
There are no Response filters for Razor pages as you can’t add Headers to a Request after its already written to the Response, only for “View Pages” which call Services first where the Response filter is executed before the page is rendered.

how to fix 403 error in google authentication at xamarin forms for accessing web resources at Android app

thanks in advance.....
i got this error while connecting to my app with azure cloud via google authentication
"403. that's an error. error: disallowed _useragent this user- agent is not permitted to make on oauth authorization request to google as it is calssified as an embedded user- agent per our policy ,only browsers are permitted to make authorization request to google. we offer several libraries and samples for native apps to perform authorization request in the browser."
how to fix this error.....
This happens from last year because of a change in Google's security policy. The work around is to use Xamarin.Auth and use Interceptors in the native codes to catch the Authentication process. A good example is available in this following link Xamarin Authentication
class ActivityCustomUrlSchemeInterceptor : Activity
{
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
/* global::Android.Net.Uri uri_android = Intent.Data;
//#if DEBUG
// System.Text.StringBuilder sb = new System.Text.StringBuilder();
// sb.AppendLine("ActivityCustomUrlSchemeInterceptor.OnCreate()");
// sb.Append(" uri_android = ").AppendLine(uri_android.ToString());
// System.Diagnostics.Debug.WriteLine(sb.ToString());
//#endif
// Convert iOS NSUrl to C#/netxf/BCL System.Uri - common API
Uri uri_netfx = new Uri(uri_android.ToString());
// load redirect_url Page
AuthenticationState.Authenticator.OnPageLoading(uri_netfx);*/
var uri = new Uri(Intent.Data.ToString());
// Load redirectUrl page
AuthenticationState.Authenticator.OnPageLoading(uri);
this.Finish();
return;
}
}

Stop authentication at an early pipeline stage- unless going to /Login?

I'm writing a MessageHandler to authenticate a user.
If a request is not containing a special header , I want to block it at the MessageHandler stage.
But if the user wants to go to the Users/Login method, he will probably have no header (because he is not Login yet ).
The problem is that I don't want to block him at the [authorize] controller level.
It's pretty simple :
If he doesn't have the header and he is not on the way to login — BLOCK
If he doesn't have the header and he is on the way to login — only then - ALLOW
Question
1) At the MessaageHandler stage , how can I know that he is on a way to do login ? ( NB : I don't mention the {action} in the route. e.g. :
--
public class User :ApiController
{
[HttpPost]
public bool CheckLogin (....) //i'm not specifying action in the route
{
}
}
2) Looking at the command to read the header :
AuthenticationHeaderValue auth = actionContext.Request.Headers.Authorization;
But - Authorization != Authentication.
So why does web api reference the authorization header as an Authentication ?
The MessageHandler executes before routing has occurred. So at this stage you don't know yet which controller action will be executed.
One possibility would be to check the verb and the path being requested and perform the custom verification based on that:
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
string path = request.RequestUri.PathAndQuery;
if (request.Method == HttpMethod.Post && path.StartsWith("/api/checklogin", StringComparison.InvariantCultureIgnoreCase))
{
// Do not enforce the presence of the custom header
return base.SendAsync(request, cancellationToken);
}
// Check for the presence of your custom header
}
So why does web api reference the authorization header as an Authentication ?
At HTTP level, the header is called Authorization.
I believe you are trying to reinvent the wheel while it is already there. You have Autorize and AllowAnonymous (for your Login action) and then you could have a custom authentication filter to read the header and set up the Principal for the request lifetime.
The reason for that is that the term authorization header has been always used in the context of HTTP header-based authentication. Someone who used the tern for the first time was probably not aware that authentication header would probably be slightly more appropriate.

Resources