Q:

How to secure a web API from being accessed from unauthorized SPAs

I am building a B2B service whose API can be accessed by third-parties on a subscription basis. Basically, we provide a customizable widget that our customers can embed on their website to make it available to their customers (e.g. a button that opens a modal). While it is clear how to make this work in a traditional web app, I am not sure how to guarantee this in a single-page app. Is it at all possible to make this work without a redirect URI as used in OAuth? That is, the modal triggers AJAX requests to our API and we want to make sure it comes from a script from an authorized origin without redirects. We could of course simply check Origin header, but what is there to prevent someone from constructing a request with such a header on their backend manually, even though they couldn't do it in the browser.

A:

The Problem

While it is clear how to make this work in a traditional web app, I am not sure how to guarantee this in a single-page app.

From a web app you only need to see the html source code to be able to find the API keys or other secrets. Even if you use a traditional web server, cookies can also be obtained to automate attacks against it.
While this series of articles about Mobile API Security Techniques are in the context of mobile devices, some of the techniques used are also valid in other type of APIs, like APIs for Web/SPAs apps, and you can see how API keys, OUATH tokens and HMAC secrets can be used  to protect an API and bypassed.
Possible Solution
You can try to make it hard to find the API key with a Javascript Obfuscator, but bear in mind that this only delays an attacker in succeeding.
So, how can I block an attacker?
Well the cruel truth is... You can't!!!
But you can try, by using reCAPTCHA V3 from Google, that works in the background, therefore doesn't require user interaction. The drawback here is that all your B2B clients would need to implemente it across all pages of their websites, thus may not be the way to go for your use case...
reCAPTCHA V3:

reCAPTCHA is a free service that protects your website from spam and abuse. reCAPTCHA uses an advanced risk analysis engine and adaptive challenges to keep automated software from engaging in abusive activities on your site. It does this while letting your valid users pass through with ease. 

If your B2B solution really needs to protect it at all costs then you need to employ Web Application Firewalls(WAF) and User Behavior Analytics solutions, also know as UBA, that use Artificial Intelligence and Machine Learning to prevent abuse, but once more they cannot guarantee 100% blocking and both have false positives.
WAF:

A web application firewall (or WAF) filters, monitors, and blocks HTTP traffic to and from a web application. A WAF is differentiated from a regular firewall in that a WAF is able to filter the content of specific web applications while regular firewalls serve as a safety gate between servers. By inspecting HTTP traffic, it can prevent attacks stemming from web application security flaws, such as SQL injection, cross-site scripting (XSS), file inclusion, and security misconfigurations.

UBA:

User behavior analytics (UBA) as defined by Gartner is a cybersecurity process about detection of insider threats, targeted attacks, and financial fraud. UBA solutions look at patterns of human behavior, and then apply algorithms and statistical analysis to detect meaningful anomalies from those patterns—anomalies that indicate potential threats. Instead of tracking devices or security events, UBA tracks a system's users. Big data platforms like Apache Hadoop are increasing UBA functionality by allowing them to analyze petabytes worth of data to detect insider threats and advanced persistent threats. 

Conclusion
In the end of the day you can only protect your B2B back-end in a best effort basis, that must be proportional to the value it holds for the business.
A 100% solution doesn't exist for the web, due to the way it was designed to work!!!

