I'm trying to implement a password-based login for a Vue app. Everything seems to work fine, but when I try this:
this.auth0.client.login(
{
realm: 'Username-Password-Authentication',
username: 'user#whatever.com',
password: 'totallyValidpassw0rd',
audience: 'https://my-site.eu.auth0.com/userinfo',
scope: 'read:order write:order'
},
(err, authResult) => {
console.log(err);
});
the result is a cryptic Suspicious request requires verification error message. What exactly is suspicious, and what should be verified?
It's supposed to mean that the captcha hasn't been solved. As I found, password based login (Password Grant or Resource Owner Password flow) can't be used together with the Bot detection feature, which is a fancy name for a captcha. Turning off Bot detection solves the problem.
Of course now a third party captcha (like Google reCaptcha) will have to be added to the login form.
Related
I have an application to test that requires MFA. I am trying to get my UI tests through Cypress to hit the application already authenticated.
I've seen a few posts about setting up a new Cypress command to handle logging in where it sends auth details to the 3rd party, gets the details back and puts this into local storage using something like cy.setLocalStorage.
But I already have an external method that I use for my API tests where it grabs me a valid Bearer token. This works fine for API calls on the application. So I'm wondering, is there a place I can simply insert this valid token for my UI tests with Cypress or do I need to go the kind of way as defined in the linked article below where I build a cy.login() command?
Edit: Should add that we actually have a service principal account for the API calls to bypass MFA.
https://auth0.com/blog/end-to-end-testing-with-cypress-and-auth0/
Without having more information about the exact login and your application, if the token for your API tests is the same and sufficient for the login, then you can probably store it in the local or session storage depending on where your app is looking for the valid token.
The only important thing then is that you do this before the first cy.visit command to show your app that you are already authenticated / logged in like:
describe('Your Test', () => {
it('Login and page visit', () => {
// or sessionStorage.setItem()
localStorage.setItem('your_token_name', yourToken);
cy.visit('your app url')
})
})
However, I'm not sure if the MFA requires additional login steps that you might not cover with it. If in doubt, you can also think about disabling MFA for a test user used in your Cypress tests.
Besides that, as you've already written, it's often a good way to log in via request to avoid having to test third-party UIs that you have no control over changing, such as here an example for Azure AD Login.
You can also add session caching to the login command, or a wrapper command for your external method that grabs the token.
The request is only fired once, then the results are cached so the same token is restored each time you call the command.
Cypress.Commands.add('login', (username, password) => {
cy.session([username, password], () => {
cy.request({
method: 'POST',
url: '/login',
body: { username, password },
}).then(({ body }) => {
window.localStorage.setItem('authToken', body.token)
})
})
})
I am trying to create a web app whose main task is fixing appointment.
I do not want to access any mail data of the logged in user.
I only want to implicitly login using an outlook account (my account) to which I have admin access. I want to connect with this account, fetch its calendar events and display the events to the logged in user so that the user can select any available spots.
I have registered my app in the azure portal and provided all the application permissions (earlier I tried with Delegated permissions as well; but I guess delegated permissions are not for my use case).
Thereafter, I tried to fetch the token for my profile using:
this.http.post(`https://login.microsoftonline.com/f8cdef31-a31e-4b4a-93e4-5f571e91255a/oauth2/v2.0/token`,
{
client_id: 'my-client-uuid',
scope: 'https://graph.microsoft.com/.default',
grant_type: 'client_credentials',
client_secret: '****myclientsecret****'
},
{
headers: {
Host: 'login.microsoftonline.com',
'Content-type': 'application/x-www-form-urlencoded'
}
}
).subscribe(resp => {
console.log(resp);
});
as suggested in this article.
However, my request fails while doing this and states that the request body must contain 'grant_type' when I am clearly sending that.
Can someone please suggest me how I can implicitly get data from my own outlook account in a web app.
Update: I used the suggestion from this, appears that the request is going through now. However, the browser throws CORS error saying that the server didn't have appropriate headers.
Update 2: Found this link, which seems to address the exact issue I am facing. I however already have the redirect URI for SPA. The issue still persists.
I'm unable to authenticate / sign-in via AzureAD when running testCafe.
const testrole = Role(
'https://login.microsoftonline.com/',
async t => {
await t
.typeText(Selector('input').withAttribute('type', 'email'), *******)
.click(Selector('#idSIButton9'))
.typeText(Selector('input').withAttribute('type', 'password'), ********)
.click(Selector('#idSIButton9'));
},
{ preserveUrl: true }
);
The above steps work fine, however after entering the password I get a message saying:
"Unable to sign in to Outlook account, Error: AADSTS900561: The endpoint only accepts POST requests. Received a GET request."
From my initial search, it seems like something to do with 3rd party cookies on the browser. However, I'm unable to find a solution at this time.
Any idea how I get around this issue?
The Azure AD product team has always reminded me that it is a bad idea to try to automate sign in like that.
They will probably detect that you are a bot and start blocking your requests, even if you succeed.
Instead, to acquire access tokens you need to use either the client credentials flow (for app-only tokens) or the resource owner password credentials flow (for delegated user tokens).
Client credentials flow: https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-client-creds-grant-flow
ROPC flow: https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-oauth-ropc
You have to take good care to secure the credentials used for testing.
And use a test tenant if possible.
I need to ask user for a password each time he using Google OAuth.
There was an option I have used "max_auth_age", but it stops working.
Is there any replacement for this option. If not - could you please suggest where can I submit something like "feature request" to Google to restore this feature.
Thanks.
UPD
I have read possible duplicate topic and tried to use max_age instead max_auth_age. It did not help.
p.s I know that the main idea of OAuth2 not to use any passwords prompts, but its customer requirement. He is afraid that person, who not allowed to use system can have access on shared computer if someone forgot to logout from Gmail.
Aside from BCM and ehsan s' concerns, it is possible to revoke access to your application AND ask for a password on subsequent login attempts.
Following is a NodeJS example with googleapis, but is simple enough to work for all applications:
const google = require('googleapis').google;
const oauth2Client = new google.auth.OAuth2(
'client_id',
'client_secret',
'redirect_uri'
);
// Sign-in code (omitted) here
async function signOut() {
return await oauth2Client.request({
url: 'https://accounts.google.com/Logout',
method: 'GET'
});
}
Unlike oauth2Client.revokeCredentials, requesting https://accounts.google.com/Logout will make google ask for password on subsequent sign-in attempts.
Bare in mind that this request will sign the user out of all google services on the client.
This wont affect other clients on the device however - i.e. sign-out of NodeJS app will not cause the user to be logged out of gmail in Chrome browser running on the same machine and under the same user.
Hope this helps :)
In my MVC application, I have below code in JQuery to check if user is connected to Facebook app or not
FB.login(function (response) {
switch (response.status) {
case "connected":
case "unknown":
break;
}
}, { scope: "#MyPermissions" });
Now, when I do FB login through my app, it authenticates and immediately starts FB app authorization and finally it comes to Connected case, when authorization is done.
My Question is : Can I detect when Facebook authentication in done and before authorization starts ? So that my debugger can catch the position before authorization takes place. I have to actually avoid the authorization.
Actually oAuth is two steps authorization you cannot stop it at authentication.
You can do a trick, Usually people are at already login to facebook therefore you can try getLoginStatus() on first load which will sure surely return you not_authorized as it has not yet authorize your app, You can perform your check their and then get user authorize.
FB.getLoginStatus(function(response) {
if (response.status === 'not_authorized') {
// the user is logged in to Facebook,
// but has not authenticated your app
} else {
// the user isn't logged in to Facebook.
}
});
EDIT: is this what you what? Facebook account delink or deauthorize facebook app and check status of linking from facebook app
Otherwise
Firstly Facebook login and app auth are inseparable for security reasons. Being logged into Facebook and being logged into Facebook through an app are different. To login using Facebook from an external site you are actually logging in through an app that requires the user to allow the app to access certain parts of their profile.
So when a user clicks login. First they will be asked to login to Facebook if they are not already. You can check this before login using FB.getLoginStatus https://developers.facebook.com/docs/reference/javascript/FB.getLoginStatus/
Once the user is logged into Facebook they will have to authenticate your app for you to gain access to their info. This info is also available using FB.getLoginStatus
What you need tough is an accessToken to make calls to the api with. The fb js sdk stores this internally when you run the login dialog. So if you don't login using it. The api calls will fail unless you build them yourself.
Based on the information give, I am assuming you want to avoid showing the logging / auth dialog every time a previously logged in user visits the page. This is the only situation I can think of that you might what to avoid showing the dialogs.
In this case you can use cookies and access tokens to keep a logged in state across page visit.
Use a cookie to store the accessToken locally after the first login. Then code your login logic to check for and validate the token on load or login.
This way returning to the site wont launch the login / auth dialog unless the accessToekn session runs out, but will just change the user state to logged in. Then using your access token build your graph api calls.
I use https://graph.facebook.com/oauth/access_token_info with parameter client_id: APPID, access_token: token to validate the token.
If the token is valid The the session is good, the user is logged in and has authorized the app. If this fails, the cookie is deleted and i kick of the login dialog.
There are a few more cases where you should delete the cookie, like authResponseChange or log out.
On that note; I believe what you want for post authorization is to subscribe to the authResponseChange event https://developers.facebook.com/docs/facebook-login/login-flow-for-web/. Here is a gutted implementation:
FB.Event.subscribe('auth.authResponseChange', function(response) {
if (response.authResponse) {
if (response.status === 'connected') {
// User logged in and User has authorized the app
}
else if (response.status === 'not_authorized') {
// User logged in but has not authorized app
}
else {
// User logged out
}
} else {
// No valid authResponse found, user logged out or should be logged out
}
});
There is more doco here https://developers.facebook.com/docs/reference/javascript/FB.Event.subscribe/
And there are other events that you may be able to take advantage of
auth.login - fired when the auth status changes from unknown to connected
auth.authResponseChange - fired when the authResponse changes
auth.statusChange - fired when the status changes (see FB.getLoginStatus for additional information on what this means)
I haven't tried this for myself but a look through the FB.getLoginStatus page in the documentation suggests the following.
FB.getLoginStatus
FB.getLoginStatus allows you to determine if a user is logged in to
Facebook and has authenticated your app. There are three possible
states for a user:
the user is logged into Facebook and has authenticated your application (connected)
the user is logged into Facebook but has not authenticated your application (not_authorized)
the user is not logged into Facebook at this time and so we don't know if they've authenticated your application or not (unknown)
If I understand your question correctly, you may check the status for a case being not_authorized which will allow you to break out, in case the user is indeed logged in but has not authorized your application yet.
Make sure you place this case above the connected case though.
Also, this should work even though you're using FB.login instead of FB.getLoginStatus since according to the following quote from the same page,
The response object returned to all these events is the same as the
response from FB.getLoginStatus, FB.login or FB.logout. This response
object contains:
status The status of the User. One of connected, not_authorized or
unknown.
authResponse The authResponse object.
the returned object is the same.