How do I configure stand alone Blazor WebAssembly app to allow incoming cross origin redirect? - asp.net-core

Objective is to integrate payment gateway to from Stand alone Blazor WebAssembly application. My payment page component has a form that submit directly to the payment gateway like this:
<form action="https://gateway.bank.com" method="POST">
Clicking submit button in the form redirects correctly. After the user complete payment transaction on the bank page, user is redirected back to my app along with response header. Although the redirected url is correct, browser throws 404. Reading more, I found out that since the request is originated from another domain, it gets blocked by CORS. Read many articles about configuring CORS policy for server, but how do I configure it on the client app to allow incoming requests?
Tried the following:
Added Nuget package Microsoft.AspNetCore.Cors
Inserted [DisableCors] attribute on the page
Added CORS policy on Main()
builder.Services.AddCors(options =>
{
options.AddPolicy("Open",
builder => builder.AllowAnyOrigin().AllowAnyHeader());
});
None of these worked though.
Just to ensure the approach is correct I have implemented solution using razor pages with [IgnoreAntiforgeryToken] on page model; it is successful. Help appreciated to find where am I going wrong with WebAssembly. Kindly note that I don't have a server project, only a stand alone WebAssembly project.

If the request is being blocked by CORS, there is nothing you can do on your website to avoid this. CORS is a security mechanism of browsers inspecting the response from a server. If the server does not add the proper CORS header to the response, the browser blocks the response from getting to the site loaded in the browser.
This is an intentional and good (if sometimes frustrating) part of the internet. You would need to contact the bank and request your website be added to the list of allowed origins. They would add your website's URL to the Allow-Access-Allow-Origin header. Because your URL is now part of the cool-kids list, the browser will allow the response to reach your site and will no longer throw a CORS error.

Related

app.MapFallbackToFile causes reload the entire SPA site if the URL typed manually

I use the latest recommended SPA + .Net Core-based Web APi pattern where the FE referenced to BE, FE serves proxy to BE during development, and app.UseDefaultFiles()serves index.html where the SPA resides during production. This pattern means no proxy middleware is required as it was in opposite direction when the BE serves FE as a proxy.
app.UseDefaultFiles(); <-- Here the site is loaded first time
app.UseStaticFiles();
app.MapControllers();
app.MapFallbackToFile("/index.html"); <-- Here the site is reloaded if URL typed(changed) manually
Client-side routing is the point. Specifically, I use Vue Router and IIS hosting. When the site is already opened, and a user types URL in the browser, it falls down to app.MapFallbackToFile("/index.html") and then Vue router handles the route.
The problem is that the site is always completely reloading when the URL is just changed (let say from mysite.com/a to mysite.com/b) in this scenario, as I would press F5. It's not always necessarily bad but I would like to control it.
The question is: how to get rid of app.MapFallbackToFile("/index.html") and somehow pass the captured URL to the SPA, as it would be naked SPA without backend which now stays in front of frontend.
If have tried Vue Spa with ASP.NET Core 6 minimal setup and it seems for me, that there is no way to achieve what you want.
When user enters or changes the URL address, the browser navigate away from the page and do a GET request to BE (Backend).
Here is the catch-all fallback route required, otherwise the user gets the 404 error from the web server.
I presume you use the HTML5 History Mode. Here is a part from the Vue Router Docs about this problem.
Since our app is a single page client side app, without a proper
server configuration, the users will get a 404 error if they access
https://example.com/user/id directly in their browser. Now that's
ugly.
Not to worry: To fix the issue, all you need to do is add a simple
catch-all fallback route to your server. If the URL doesn't match any
static assets, it should serve the same index.html page that your app
lives in. Beautiful, again!
If somebody yet knows the solution, please post a new answer.
It would be great to know how to do it!

Redirect to frontend URL with POST after external payment

My VueJS application relies on a Java backend. This Java backend serves all REST endpoints for providing the data.
When a user performs a checkout the backend responds with a redirect url and redirects the user to that URL. This is done simply like that:
window.location.href = redirectUrl;
As soon as the payment process is finished on the external page the payment provider redirects the user to a return_url which in this case is my VueJS front-end. However the external system sends the return_url in a POST request directly to the front-end which cannot be processed in the as there is no endpoint listening.
What would be an approriate way handling this? As far as I know, VueJS doesn't have any possibility accepting POST requests.
TLDR; It is the responsibility of any external payment gateway system or similar system like OAuth/OpenID to redirect to the calling app via simple browser redirects (via HTTP 302 and 303). So, you should ask/configure external payment provider to follow the standard workflow.
In theory, you should never encounter this problem as POST is typically an Ajax request. Imagine you are on external payment page and when the payment succeeds, external JS is making the POST call and hence the payment page should then take responsibility of redirecting to the appropriate page by reading the reponse.
Now, the second possibility is that payment page is using traditional FORM submission via POST method type and giving back response as JSON or equivalent body. In this case, you should have a server side script (on your ui-server) that would listen for this call and then load the front-end application built with Vue.
If your UI is being served by Java back-end, then it should be simple job of having a Servelet or JSP.

Windows Authentication issue with .Net Reverse Proxy using IIS custom HTTP module

We use a custom HTTP module in IIS as a reverse proxy for web applications. Generally this works well and has done for some time, but we've come across an issue with Windows Authentication (WA). We're using IE 11, IIS 10 and Server 2016.
When accessing the target site directly, WA works fine - we get a browser login dialog when the initial HTML page is requested and the subsequent requests (CSS, JS, etc) go through fine.
When accessing via our proxy, the same (correct behaviour) happens for the initial html page, the first CSS/JS request authenticates ok too, but the subsequent ones cause a browser login to popup.
What seems to happen on the 'bad' requests (i,.e. those that cause the login dialog) is:
1) Browser decides it needs to authenticate, so sends an Authorization header (Negotiate, with an NTLM token)
2) Server responds (401) with a WWW-Authenticate: Negotiate response with a full NTLM token
3) Browser re-requests with an Authorization header (Negotiate, with a full NTLM token)
4) Server responds (401) with a WWW-Authenticate: Negotiate (with no token), which causes the browser to show the login dialog
5) With login credentials entered, Browser sends the same request as in (1) - identical NTLM token, server responds as in (2), Browser re-requests as in (3), but this time it works!
We've set up a test web site with one html page, requesting 3 JS and 2 CSS files to replicate this. On our test server we've got two sites, one using our reverse proxy and one using ARR. The ARR site works fine. Also, since step (5) above works, we believe that the proxy pass-through is fundamentally working, i.e. NTLM tokens are not being messed up by dodgy encoding, etc.
One thing that does work, is that if we use Fiddler and put breakpoints on each request, we're able to hold back on the 5 sub-requests (JS & CSS files), letting one go through at a time. If we let each sequence (i.e. NTLM token exchange for each URL/file, through to the 200 response), then it works. This made us think that there is some inter-leaving effect (e.g. shared memory corruption) in our proxy, this is still a possibility.
So, we put code at the start of BeginRequest and end of EndRequest with a Synclock and a shared var to store the Path (AppRelativeCurrentExecutionFilePath). This was for our code to 'Single Thread' each of these request/exchanges. This does what we expected, i.e. only allowing one auth exchange to happen and resulting in a 200 before allowing the next. However, we still have the same problem of the server rejecting the first exchange. So, does this indicate something happening in/before BeginRequest, where if we hold the requests back in Fiddler then they work, but not if we do it in our http module?
Or is there some sort of timing issue where the manual breakpoints in Fiddler also mean we’re doing it at ‘human’ speed and therefore allowing things to work better?
One difference we can see is the ‘Connection: Keep-Alive’. That header is in the request from the browser to our proxy site, but not passed from our proxy to the base site, yet the ARR site does pass that through... It’s all using HTTP 1.1. and so we can't find a way to set Keep-Alive on our outgoing request - could this be it?
Regarding 'things to try', we think we've eliminated things like having the site in the Intranet Zone for IE by having the ARR site work ok, and having the same IE settings for that site. Clearly, something is not right, so we could have missed something here!
In short, we've been working on this for days, and have tried most of what we can find on SO and elsewhere, but can't figure out what the heck is going on.
Any suggestions - let me know if you want any further info. All help will be very gratefully received!

$.get request shopify error

I've have weird issue, on dev theme (preview mode) $.get request works fine -> https://woolet-co.myshopify.com/blogs/news
but on active theme on main domain https://woolet.co/blogs/news there is an error, I can't figure it out why its happening.
If you try this code in console on both URLs you will see the response code error on main domain:
$.get('/admin/blogs/19692355/articles/229491718.json', function(data) {
console.log(data);
});
I guess that it's connected with domains, on https://woolet-co.myshopify.com/blogs/news $.get request works fine and on https://woolet.co/blogs/news it shows error in console.
I've tried to execute $.get request through Shopify Private App with login and password included but without any result.
This isn't working for you because your XMLHttpRequest is for a different domain than the one the page is on.
For this to properly work, you need to enable CORS. I would also suggest putting in the absolute URL of where this JSON file is located.
It would work on your preview mode. Because there both shop url and admin url are on same domain
https://woolet-co.myshopify.com/blogs/news
But when you try to browse using your real domain "https://woolet.co/". The domain from where you are making the get request and the domain from where the file is coming becomes different. ( https://woolet-co.myshopify.com/admin/blogs/19692355/articles/229491718.json )
As far i know you can not enable cors on shopify
and
It wont work because "https://woolet-co.myshopify.com/admin/blogs/19692355/articles/229491718.json" requires you to be logged it to the store as admin.
Try some other way.

How to understand the Google Redirect URI correctly?

From Google Developer Console page, it explains the meaning of "Google Redirect URI" is :
Determines where the response is sent. The value of this parameter
must exactly match one of the values registered in the APIs Console
(including the http or https schemes, case, and trailing '/').
Not sure, whether this explanation is same as my think or not:
On my app (web application), it allow user to sign-in via Google (Assume, I registered a Google project with ClientID/secrete configured on my web-app, and on Google COnsole page the redirectURI is "http://bbc.co.uk" ).
After I login to Google successfully by my Google account, my Web-app login page will be redirected to "http://bbc.co.uk" as on Google RedirectURI ?
That last sentence is a bit ambiguous. A better description is:
After I login to my Google Account successfully with my Google
credentials, Google will redirect my browser back to
Redirect URI http://bbc.co.uk that is registered for the web app in the Google > API Console.
Just to be sure: this means that the Redirect URI should be part of your web app. It is not actually Google's Redirect URI but it is the Redirect URI that you've configured in the Google API Console for your web app.
Let me see if i cant explain this in a different way.
What would happen if you didn't have a redirect URI?
If you go to the Developer console and create a Client ID for native application by default the redirect URI
This will redirect the Authentication back to where ever it was request from. In the case of native installed applications this is needed because there is no way to know where the user is that has installed the application.
Lets look at this in action
Request authentication:
https://accounts.google.com/o/oauth2/auth?client_id={clientid}.apps.googleusercontent.com&redirect_uri=urn:ietf:wg:oauth:2.0:oob&scope=https://www.googleapis.com/auth/analytics.readonly&response_type=code
If you place the above line in a web browser the user will see something like this
Assuming they select ok then they get this displayed back at them.
That is the Authentication code, not to be confused with the access token. This is just the first step. Once your application has the Authentication code it can then exchanged that for a refresh token and a access token. Most client library handle this step internally. You and your users never see this Authentication code.
Back Redirect URI:
In the case if a web application your web application needs to be able to get a hold of that authentication code. Now I probably shouldn't be telling you this but you could just use a native application client in your web application and it will work. Why because the authentication server will just return the Authentication code back to where ever it was that requested it. For security reasons this is probably a bad practice.
So what do you need to place in the redirect uri. It is the file that you have ready to handle this authentication code. Normally its just the same as the login page, but you can have several. Just put each of them on separate lines.
http://localhost/login.php
http://www.daimto.com/login.php
I like to do this because then it works when i am testing locally vs when its up on the server.
I think the wording "Determines where the response is sent" confuses a lot of beginners as it implies that Google will somehow call that URL directly. Then the word "redirect" leads people to confuse the URL with the page of the app that the user will get to once he's authenticated.
http://bbc.co.uk is definitely NOT the redirect URL. A redirect URL would normally look like https://myapp.com/servlet_or_php_that_i_wrote_to_process_tokens.php
Google will "call" servlet_or_php_that_i_wrote_to_process_tokens.php by redirecting the browser to it. Once servlet_or_php_that_i_wrote_to_process_tokens.php as done whatever is needed with the token, it will then issue its own redirect to (say) bbc.co.uk