Request to b2c login is blocked by CORS policy - javascript

I'm developing a web application, where the user is given a challenge from the web app that contains a URL to another website, where he's asked to sign-up.
The sign-up page is made using the sign-up flow in Azure AD B2C.
The response sent from my ASP.NET Core API looks like this:
var redirectUrl = Url.Action(nameof(SignupController.Return), "Signup");
var properties = new AuthenticationProperties { RedirectUri = redirectUrl };
properties.Items[AzureAdB2COptions.PolicyAuthenticationProperty] = AzureAdB2COptions.SignUpPolicyId;
return Challenge(properties, OpenIdConnectDefaults.AuthenticationScheme);
The challenge is requested using Fetch API in Javascript, which looks like this:
fetch(`/api/invitations/${invitationId}`, {
method: 'PUT',
mode: 'cors'
}).then(response => {
// HTTP 301 response
if (response.redirected) {
console.log(response.url);
window.location.href(response.url);
}
})
.catch(function (err) {
console.log(err);
});
However I keep getting this error:
As far as I understand this is a server problem, but I suppose its on b2clogin? I can't really see how I'm supposed to update the CORS policy. I can easily access the fetch URL as shown above by clicking on it, but the javascript code itself cannot redirect to it. I'm sure it's just a simple fix. I hope someone will help.

I am not sure what you are trying to achieve here because of limited context. But, to fix this error, run below Azure CLI command in your Local:
az webapp cors add --resource-group myResourceGroup --name api-name --allowed-origins 'http://localhost:44315'
Check out more about CORS policies in App service here.

Related

async req to load/render new page

Im working on a project, using firebase auth for login i.e. login with google; if logged in then redirect to /app where real functionalities of webapp exists.
login page js:
document.getElementById('login').addEventListener('click', e => {
var provider = new firebase.auth.GoogleAuthProvider();
firebase.auth()
.signInWithPopup(provider)
.then((result) => {
firebase.auth().currentUser.getIdToken(true).then(function(token) {
// make request to backend to get /app page where main app exists
axios.get('/app', {
headers: { 'Authorization': `Bearer ${token}` }
})
.then(res => {
console.log(res.data);
});
});
});
});
now my main motive is, user can't access pages other than / (landing page) without JWT token in header.
so here when user log in using login With google it will give token when logged in and then it will make req to backend with token and backend will return /app page pre-rendered!
PROBLEM: using this is code, when i make req to backend it just return HTML code in res.data BUT i want actual page!!
Axios is well and good to fetch data from my backend api but i cant figure out how to attach header and make req, And get page instead of source code in response;
Same problem is occurring everywhere in application. I just don't want users to access pages other than landing page without JWT in header!
backend: nodeJs
firebase auth
ejs template engine for view
EDIT:
meaning of returning source code is:
img of console log
any help, ideas or approach are welcome 🙏🏻
Login as before
Write the token into a cookie instead of the Authorization header
Redirect the browser to /app
In the backend read the cookie instead of the Authorization header
This way the browser will solve the problem for you by rendering the response. Using cookies is the usual way to implement a login without AJAX.
It's not possible to make a redirect and set the Authorization header.

How to authenticate ngrok password automatically using Python and or Javascript?

I am using ngrok to expose my localhost on a raspberry pi, and ngrok is password protected. I am using Django on another computer outside my network to access a webpage(simple server) on this raspberry pi. I don't want to manually type in the username and password to ngrok.
How can I automatically fill in the ngrok user/password, which is a popup in chrome asking for user and password?
What I've tried:
I first tried using JS in my template, just using a fetch request:
https://user:password#myngrokdomain.ngrok.io but chrome threw an error in the console saying I can't pass in credentials in plain text like this, rightfully so...
I then tried to use python requests:
UN= "myuser"
PWD = "mypassword"
loginURL = "https://myngrokdomain.ngrok.io"
client = requests.session()
login_data = dict(username=UN, password=PWD,)
r = client.post(loginURL, data=login_data)
This returned a 401 access denied
r.headers + r.reason returns:
401 Unauthorized Unauthorized {'Content-Length': '16', 'Content-Type': 'text/plain', 'Www-Authenticate': 'Basic realm="ngrok"', 'Date': 'Tue, 16 Mar 2021 15:22:15 GMT'}
The authentication method used by ngrok is called HTTP Basic Auth. To use it with the requests library you pass login and password as a tuple in the auth argument:
r = client.post(loginURL, auth=(UN, PWD))
Docs: Basic Authentication — Requests
Try doing a get on the login page first. Perhaps it's setting some cookies that it expects to be present on the post :
UN= "myuser"
PWD = "mypassword"
loginURL = "https://myngrokdomain.ngrok.io"
client = requests.session()
login_data = dict(username=UN, password=PWD,)
client.get(loginURL )
r = client.post(loginURL, data=login_data)
You need to distinguish whether you're making the request from a browser or from a server application.
Browser
If you're doing it from a browser you're hitting a CORS issue and ngrok doesn't support that when providing --auth. From the docs:
you cannot use ngrok's -auth option. ngrok's http tunnels allow you to specify basic authentication credentials to protect your tunnels. However, ngrok enforces this policy on all requests, including the preflight OPTIONS requests that are required by the CORS spec. In this case, your application must implement its own basic authentication
In this case, your only option is to implement authentication in your application instead of using ngrok's --auth.
Server
If you're sending the request from a server application you won't get into any CORS issue but you need to provide the Basic Authentication credentials properly.
Say you have your application exposed via ngrok at http://myapp.ngrok.io protected via --auth user:pass.
In plain Node.js you would do something like this:
const http = require('http')
http.get('http://myapp.ngrok.io', { auth: 'user:pass' }, res => {
const chunks = []
res.on('data', chunk => {
chunks.push(chunk)
})
res.on('end', () => {
console.log(Buffer.concat(chunks).toString('utf-8'))
})
})
Note that to hit the https url you would use Node's https module instead of http, or a higher level library that handles that for you, like node-fetch.
In Python you can do something similar and this question will probably get you on the right path.

How do I access tables in Azure after authentication?

I have been following the instructions on this page but I am getting stuck after the authentication part. After I login I get the user id and token back but I don't know what to do after that. If I try to access the tables after logging in then it comes back with this error
XMLHttpRequest cannot load sitename.azurewebsites.net/tables/modules.
Redirect from 'sitename.azurewebsites.net/tables/modules' to
'sitename.azurewebsites.net/tables/modules' has been blocked by CORS
policy: Request requires preflight, which is disallowed to follow
cross-origin redirect.
This is the code. It will give me back my userid and then come back with the error above when trying to access tables.
var client = new WindowsAzure.MobileServiceClient('http://sitename.azurewebsites.net');
client.login("facebook").done(function (results) {
console.log("You are now logged in as: " + results.userId);
var table = client.getTable("modules");
table.read().then(success, failure);
}, function (err) {
console.error("Error: " + err);
});
Should it automatically work after I login or do I have to do some extra stuff?
Per documentation you provided,
You also need to add the same loopback URLs to the CORS whitelist
settings:
Navigate back to the Azure portal.
Navigate to your Mobile App backend.
Click CORS in the API menu.
Enter each URL in the empty Allowed Origins text box. A new text box is created.
Click SAVE
After the backend updates, you will be able to use the new loopback URLs in your app.
Eventually, you will see something like this:
Note: You should also use https://sitename.azurewebsites.net instead of http://sitename.azurewebsites.net to request your App Service.
You should allow for Cross Origin Requests.

Firebase auth with Facebook OAuth credential (from Google Extension)

I am just having fun with the new Firebase, but I'm struggling with auth system.
Because I'm trying to login user from options page of google extension, so I can't use signInWithPopup or Redirect method due (some) security reasons.
So I figure out possible solution. From options page I redirect user to my another page, where he can easily login with Firebase (by Facebook provider) - everything is OK - user obtain OAuth FB token and this page send message to extension to cache this token.
There lies the problem.
I have code like this:
firebase.initializeApp(FIREBASE_CONFIG);
var credential = new firebase.auth.FacebookAuthProvider.credential(token);
firebase.auth().signInWithCredential(credential)
.then((data) => {
console.log(data);
})
.catch((err) => {
console.error(err.code);
})
This fire up POST request to https://www.googleapis.com/identitytoolkit/v3/relyingparty/ and in response I can clearly see the error:
message:"INVALID_REQUEST_URI"
This request is fired with requestURI payload, which is in mine situation:
chrome-extension://kefhjfjilmodblnpnekjleceapohasdf/options.html
When I tried to fire this request from terminal with CURL and I faked the requestURI with 'http://localhost' everything is OK and I got correct data.
Do you have any ideas, how can I achieve proper behavior?
Thanks a lot.
P.S: I'm using Firebase.js 3.0.5-rc.2

How to mock the API response with nightwatch.js and sinon.js?

I'm writing e2e test for a single page application with nightwatch.js.
I have some API request like an authentication. So I want to use fakeServer of sinon.js for mocking response data. Here's my code.
import sinon from 'sinon';
const WAIT_TIME = 5000;
const host = 'http://localhost:3000/#/';
const uri = new RegExp(escape('/users/login'));
module.exports = {
'Login Test': function(browser) {
let server;
browser
.windowSize('basicTest', 1440, 710)
.url(host + 'account/login')
.waitForElementVisible('body', WAIT_TIME)
.setValue('input[type=email]', 'sample#sample.com')
.setValue('input[type=password]', 'password')
.execute(function() {
server = sinon.fakeServer.create();
server.respondWith('POST', uri, [
200, { 'Content-Type': 'application/json' }, JSON.stringify(someResponseData),
]);
})
.submitForm('form')
.execute(function() {
server.respond();
})
.waitForElementNotPresent('input.[type=submit]', WAIT_TIME) // the page should be redirected to another page
.execute(function() {
server.restore();
server = null;
})
.end();
},
};
I can't mock response, and got the error below (When the API serve is running, got no error, but the response won't be mocked one).
Error: Origin is not allowed by Access-Control-Allow-Origin
I want to know, first of all, is it correct way to use sinon.js's fakeServer? And is that possible on e2e(and nightwatch.js)?
Please give me a help.
To answer your question I first need to explain the nature of the error you receive.
That's a CORS (cross origin resource sharing) error.
Basically, some service behind your single page app knows not to allow requests which don't originate from your app. The service returning that error (I can't tell what it is from the information you've posted) detects a request coming from not your app, and rejects it.
You could disable the CORS security of the service (I highly recommend you don't do this) or you could attempt to change the origin header of the request. This is tricky, as most modern browsers specifically prevent this change in order to protect users. Since you are using Nightwatch, your environment will, in general, be that of a browser.
Based on this error you must have set up the server incorrectly because it seems as if your request is still hitting your actual API and not the mocked server.
Probably because you when submit the form, the browser will still submit the form to where it is supposed to go (and not your mock server) unless it is told otherwise. Looking at your code, you are setting up a mock server, but from this file alone it is not clear how the browser is supposed to know to send requests to that mocked server.
See nock for an alternative solution, I'm about to start using it :)

Categories

Resources