allow signin but not signup using Google Sign-In - firebase-authentication

I'm using Google Sign-In for user authentication. Currently, anyone can log in but I'd like to manually add the users to the firebase authentication and only allow those users to sign in using Google Sign-in.
I can check if the currently signed-in user is new or existing by checking additionalUserInfo.isNewUser
const creds = await auth().signInWithCredential(googleCredential);
if (creds.additionalUserInfo?.isNewUser) {
await auth().signOut();
await auth().currentUser?.delete();
}
but by the time I get that information, onAuthStateChanged executes and redirects the user to the protected route.

It's counterintuitive to what we know as user flow but it is actually better to allow users to sign up and set conditions that will allow them to use your app. I wouldn't use isNewUser since it only fires once and an app refresh makes this defunct.
I suggest looking at custom claims, for example: allow users to access the page and content if the user has a 'isMember' set to true on their profile.
Custom claims can be read by the client and rules freely, and can only be edited through the admin-sdk. so an admin can setup a function to execute a command that updates the user, you could also do this with a node app with the admin-sdk installed.
you can read about Custom claims here.

Related

Configure Silent Authentication in Open ID Connect

client type: Spa
grant type: implicit or code(pkce)
As a user, I want to be able to get silently authenticated if I have already logged with my identity provider. If not stay on the client side just like a guest user. And if I want to login to the client I should be able to get authenticated manually through the login page.
This has both manual sign-in and automatic sign-in scenarios. How would you handle such cases in Open ID Connect?
By adding the prompt=none in client settings will silently get a new token if user has a valid session. But if not I want the user to be able to manually authenticate through the login page upon his/her wish.
If I set prompt=none this will never have any user interaction such as authentication.
tags: Silent authentication oidc, automatic login, SSO
It is quite a deep subject, and the flow typically works like this:
CLASSIC OIDC SOLUTION
User is redirected for each SPA
If signed in already at the IDP there is no login prompt
OAuth state is stored in local storage (though it is recommended to only store actual tokens in memory)
When an access token expires (or before) do an iframe token renewal with prompt=none
When a new browser tab is opened do an iframe token renewal to get tokens for that tab - to avoid a full redirect
When the user logs out remove OAuth state from local storage
The most widely used library is OIDC Client which will do a lot of the hard work for you. See also my blog post + code sample for how this looks visually.
PROBLEM AREAS
It is worth being aware also that iframe silent renewal does not work by default in the Safari browser in 2020. Some notes on this here.
Alternatively, you can use signinSilent(). I have used it on my login page ngOnInit (since AuthGuard will anyway redirect the user to login, I thought it will be the perfect place in my scenario).
// login.ts
ngOnInit(): void {
this.authService.signinSilent().then(_ => {}).catch(_ => {});
}
// authService
public signinSilent() {
return this.userManager.signinSilent();
}
signinSilent method will return the user object if user already has a valid session with idp. else it will throw an error, probably login_required.

Auth0 asks for consent to access tenent when logging in

I am developing an Angular2 app which uses auth0 for authentication. I used the auth0 lock widget to authenticate users.
Now, I want to use auth0-js instead of the lock widget for authentication. I followed this guide to add auth0-js to the app.
After adding auth-js, when a new user tries to log in to the app, Auth0 displays following consent screen to the user.
I want the users to be able to directly access my app, without needing to accept a consent screen. The consent question asked in this dialog can be confusing to users since it mentions about tenants.
When I searched for a solution, the solution mentioned in various places was to make the client a first party client. But, I cannot find any place in the management console to make the client a first party client.
How can I disable this consent screen?
Following is the auth-js config I used in the app.
auth0 = new auth0.WebAuth({
clientID: 'my_client_id',
domain: 'my_domain.auth0.com',
responseType: 'token id_token',
audience: 'https://my_domain.auth0.com/userinfo',
redirectUri: window.location.origin + '/auth_loading',
scope: 'openid'
});
In Auth0 Dashboard, under APIs -> Auth0 Management API -> Settings (tab)
If you are using a specific audience for a Resource API you have defined yourself in the Dashboard, then there is a similar Allow Skipping User Consent toggle for that particuar API. Use that. audience specifies the target API for your access token. If you don't want to call a specific API, keep it set to https://my_domain.auth0.com/userinfo
Re. question about First Party. If you created your client in the Auth0 Dashboard, then it is Firsty Party by default. Only first-party clients can skip the consent dialog, assuming the resource server they are trying to access on behalf of the user has the "Allow Skipping User Consent" option enabled. The Auth0 Dashboard does not offer a flag for this, but if you use the Auth0 Management API v2 Get Clients endpoint, then you will see the flag (boolean) value listed for your client eg.
"is_first_party": true
See https://auth0.com/docs/api/management/v2#!/Clients/get_clients for details.
Finally, please note the following: https://auth0.com/docs/api-auth/user-consent#skipping-consent-for-first-party-clients - in particular note that consent cannot be skipped on localhost. As per the docs (link above), During development, you can work around this by modifying your /etc/hosts file (which is supported on Windows as well as Unix-based OS's) to add an entry such as the following:
127.0.0.1 myapp.dev

Using Office Outlook API with hard-code user name and password

I'm trying to build a (C#) web app that allows clients to make appointments with me.
I'd like the web app to be able to read and add entries to my outlook calendar.
Many users will use the web app, but the web app will only access one outlook calendar - mine.
All of the examples I have been able to get working have involved the web app user interactively authenticating - but my users will not know my password.
I would like to hard code my username/email address and password in the web app.
When trying to acquire a token I get an error:
Microsoft.IdentityModel.Clients.ActiveDirectory.AdalServiceException:
AADSTS65001: The user or administrator has not consented to use the application.
Send an interactive authorization request for this user and resource.
I am not an administrator of the tenant. Is there any way I can get this to work without administrator involvement?
Would using some kind of certificate rather than a user name and password as user credentials help?
My code (currently in a simple C# console application) is as follows:
UserCredential uc = new UserCredential(MyUsername, MyPassword);
var AuthContext = new AuthenticationContext("https://login.windows.net/Common");
// this doesn't work unless an unexpired token already exists
ar = AuthContext.AcquireToken("https://outlook.office365.com/", MyClientId, uc);
// this does work, but requires the app user to know the password
ar = AuthContext.AcquireToken("https://outlook.office365.com/", MyClientId, new Uri(MyReturnURI));
To enable use the username and password to request the token directly, we need to consent to use the app.
We can use the OAuth 2.0 authorization code grant flow to grant the consent by user. Here is an sample use the ADAL authentication library(3.13.1.846) to acquire the delegate token:
static string authority= "https://login.microsoftonline.com/common";
public static string GetDeligateToken(string resource, string clientId,string redirectURL)
{
AuthenticationContext authContext = new AuthenticationContext(authority);
AuthenticationResult authResult= authContext.AcquireTokenAsync(resource, clientId,new Uri(redirectURL), new PlatformParameters(PromptBehavior.Auto)).Result;
return authResult.AccessToken;
}
After we consent the app, now we can use the code in your post to acquire the token.

how to detect after FB authentication and before FB authorization

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.

Twitter API Authenticate vs Authorize

Hi all could you just tell what is the difference between Twitter Authenticate and Authorize
$twitterConnect = new TwitterOAuth(CONSUMER_KEY, CONSUMER_SECRET);
$twitterToken = $twitterConnect->getRequestToken();
$redirect_url = $twitterConnect->getAuthorizeURL($twitterToken, true); // authenticate
$redirect_url = $twitterConnect->getAuthorizeURL($twitterToken, false); //authorize
With oauth/authenticate if the user is signed into twitter.com and has previously authorized the application to access their account they will be silently redirected back to the app.
With oauth/authorize the user will see the allow screen regardless if they have previously authorized the app.
This method differs from GET oauth / authorize in that if the user has already granted the application permission, the redirect will occur without the user having to re-approve the application.
https://dev.twitter.com/oauth/reference/get/oauth/authenticate
Note:
You must enable "Sign in with Twitter" in the application settings to achieve this.
Desktop applications must use this authorize and not authenticate.