How to know if a given user is already logged in with MSAL? - msal

With msal.js library (The Microsoft Authentication Library), which is the way to know if a given user is already logged in? My intention is to avoid to show login pop-up if the user's credentials are already saved in browser's storage
My current approach:
function isUserLoggedIn(username) {
const agent = msal.UserAgentApplication(...);
const user = agent.getUser();
return user != null && user.displayableId === username);
}
But I'm not sure if I have to check if the user credentials are outdated/expired. Which is the proper way to go?

With the MSAL agent instance, you can get user information because it is cached. Getting information (such as the userId) doesn't mean that the user's credentials are still valid (logged in).
To be 100% sure that the user is logged in, ask for a token
const promise = agent.acquireTokenSilent(...)
If the user is not logged in, the promise will be rejected with the error code user_login_error
If, on the other hand, the user is still logged in, the promise will be resolved

From MSAL samples, they were checking this way:
let isLoggedIn = this.authService.instance.getAllAccounts().length > 0;

Related

How to prevent multiple login to the same account in ASP.NET Core

I'm using ASP.NET Core 6 Identity for login system. I want to prevent multiple login to the same account.
My Identity settings are:
//For custom Identity
string connection = configuration.GetConnectionString("DefaultConnection");
builder.Services.AddIdentity<AppUser, AppRole>(options =>
{
options.User.RequireUniqueEmail = false;
options.Password.RequireDigit = true;
options.Password.RequireUppercase = false;
options.Password.RequiredUniqueChars = 0;
options.Password.RequireUppercase = false;
options.Password.RequireNonAlphanumeric = false;
options.Password.RequiredLength = 6;
options.Lockout.MaxFailedAccessAttempts = 10;
options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(15);
options.Tokens.PasswordResetTokenProvider = TokenOptions.DefaultProvider;
}).AddEntityFrameworkStores<IdentityAppContext>().AddDefaultTokenProviders();
I searched some similar questions but none of them could help me to implement this feature in ASP.NET Core 6.
Please guide me.
What is the Use Case for denying access while logged in?
"When someone logged in, no body can log in to that account until he closes the browser or logs out manually"
That would require logic like:
On Login, throw error if tokenHasBeenIssued, by querying the server db.
On Login, if no server token for user, createToken.
On Logout, a clean db, removeUserToken
but, when someone closes their browser there is no message sent to the server, so you'd never clear the token, so you'd get one login granted and then they would be logged out forever.
Maybe this scenario is fixable with a hack of a 'Timed cron job to clear all old tokens'?
I would suggest implement two factor authentication or even delegate your auth needs to third party provider, eg Auth0 or Azure AD, etc.
If you mean to stay signed in, you need to implement a token(for example, JWT Token) and use User ID or username directly without logging in again.

StrapiJs- User authentication and user profile

1) I built profile information content type in strapijs. Added user relation to it. Profile has and belongs to one user". Like a simple social media.
2)I added couple users/profile information. Connected it for spesific user.
3) Tested api with postman. Authentication works i can see profile information. But the problem is, when a user authenticated could access other users profile information.
How can i restrict one user to see only related profile?
Thank you
Okay so for your use case you have to restrict GET /users/ to all your users.
With that, no one will access to other data users.
But you can access to GET /users/me/ route. And you will be able to access to the Auth User data.
You can easily create custom policy which will compare authenticated user.id and requested profile user id and respond only if they are the same - read about creating policy here - Strapi Policy Help
module.exports = async (ctx, next) => {
const { body } = ctx.request
if (ctx.state.user.id == ctx.request.query.userid || ctx.state.user.id == body.userid) {
return await next();
}
ctx.unauthorized(`You're not allowed to perform this action!`);
};
Note that you have to insert userid field to the profile model. I had to use logical OR because I have different types of requests - it depends on your request only..

Auth0 and Google API, access token expired, howto write files to Google Drive

I've written an online converter and integrated Auth0 to my website. What I'm trying to achieve is to auto-upload the converted file to the Google Drive of a logged in user. I set up Google oauth in Auth0 and everything seemed to work fine.
The problem is, Google's access_token expires after 60min and I don't have a refresh_token. Therefore, the user needs to log in via the Google Login-page again. That is not, what I want, because the user is in fact logged in way longer than just 60min on my site, but Google refuses API-calls (because the Google token expired).
I know I can request a refresh_token by setting access_type=offline but this will add the permission Have offline access. I don't want that, I just want to upload data to the user's Drive, if he clicked the convert button on my page. I don't want to ask the users for permissions I don't need. If I (as a user) would link my Google account on a similar page and the tool asks for offline access I wouldn't approve, to be honest - the permission sounds like the tool creator can do whatever he wants with your account whenever he wants... There are many tools out there that have write access to a user's Drive without asking for offline access and with one single login until the user revokes the permission. How is that done?
Is there a way to make Google API calls without asking for offline access and without forcing the user to approve the app (that is already approved by him) again and again every 60min?
Thanks in advance,
phlo
Is there a way to make Google API calls without asking for offline access and without forcing the user to approve the app (that is already approved by him) again and again every 60min?
Yes there are ways, but it depends on the specifics of your use case. For example, is your code in Java/php/etc running on a server, or is it JavaScript running in the browser?
Running your auth in the browser is probably the simplest solution as the Google library (https://developers.google.com/api-client-library/javascript/features/authentication) does all the work for you.
By asking for offline access you are requesting a refresh token. Google is going to tell the user that you are requesting offline access. You can request something without telling the user what they are authorizing.
No there is no way to request a refresh token without displaying that message. Nor is there a way for you to change the message it's a standard Google thing.
I found the solution!
Prerequirements
Enable Use Auth0 instead of the IdP to do Single Sign On in your client's Dashboard
Create a new Angular-route to handle the silent login callback (e.g. /sso)
Add
$rootScope.$on("$locationChangeStart", function() {
if ($location.path().indexOf("sso") == -1) {
authService.relogin(); //this is your own service
}
});
to your run-function and set the callbackURL in angularAuth0Provider.init() to your new Angular-route (<YOUR_DOMAIN>/sso). Add this URL to your accepted callbacks in the Auth0 dashboard - this won't end in an infinite loop, because the locationChangeStart-event won't call authService.relogin() for this route
Add $window.close(); to the controller of the Angular-route (/sso) to auto-close the popup
Authenticate the user via Auth0 and save the timestamp and the Auth0-access_token somewhere
On reload:
Check, if the Auth0-token is still valid in authService.relogin(). If not, the user has to login again either way. If the token is valid and the Google token is about to expire (check this with the saved timestamp to prevent unnecessary API calls) check for SSO-data and login silently, if present
/* ... */
if (validToken && googleExpired) {
angularAuth0.getSSOData(function (err, data) {
var lastUsedConnection = data.lastUsedConnection;
var connectionName = (_.isUndefined(lastUsedConnection) ? undefined : lastUsedConnection.name);
var isGoogle = (_.isUndefined(connectionName) ? false : connectionName == "google-oauth2");
if (!err && data.sso && isGoogle) {
authManager.authenticate();
localStorage.setItem("last-relogin", new Date().getTime());
angularAuth0.signin({
popup: true,
connection: data.lastUsedConnection.name
});
}
});
}
Now you will find a fresh Google access_token for this user (without asking for offline access)
Resources:
https://auth0.com/docs/quickstart/spa/angularjs/03-session-handling
https://auth0.com/docs/quickstart/spa/angularjs/11-sso

Getting logged in identities with an id token via Xamarin's Auth0.SDK

The Auth0User object returned from LoginAsync() contains a list of the logged in identities.
But how do I get this upon without seeing the login dialog LoginAsync presents - I'd just like to use the id token saved from the previous login?
There seems to be a tokeninfo endpoint for this, but Xamarin's Auth0.SDK seems to eliminate dealing with REST - so feel like I'm missing something.
If the user has already logged in, you can do a refresh:
var client = new Auth0.SDK.Auth0Client ("XXXXXXX.auth0.com", "XXXXXXXXXXXXXXXXX");
await client.RefreshToken();
Console.Writeline(client.CurrentUser);

Firebase 3.x - Token / Session Expiration

Does anyone know how long would it take for the token to expire? There no option now to set the token validity on the console.
Since May 2016 Firebase Authentication login sessions don't expire anymore. Instead they use a combination of long-lived account tokens and short-lived, auto-refreshed access/ID tokens to get the best of both worlds.
If you want to end a user's session, you can call signOut().
Its does expire. After one hour logged in the token id expire. If you try to verify sdk returns a error "Error: Firebase ID token has expired. Get a fresh token from your client app and try again. See https://firebase.google.com/docs/auth/server/verify-id-tokens for details on how to retrieve an ID token."
Is There such a way to change expiration time to Firebase token, not custom token.
Anybody that know how this really works.
For anyone that is still confused, it is all explained in great detail here
If your app includes a custom backend server, ID tokens can and should
be used to communicate securely with it. Instead of sending requests
with a user’s raw uid which can be easily spoofed by a malicious
client, send the user's ID token which can be verified via a Firebase
Admin SDK (or even a third-party JWT library if Firebase does not have
an Admin SDK in your language of choice). To facilitate this, the
modern client SDKs provide convenient methods for retrieving ID tokens
for the currently logged-in user. The Admin SDK ensures the ID token
is valid and returns the decoded token, which includes the uid of the
user it belongs to as well as any custom claims added to it.
If the above answer is still confusing to you,
This is what i did:
firebase.auth().onAuthStateChanged(async user => {
if (user) {
const lastSignInTime = new Date(user.metadata.lastSignInTime);
const lastSignInTimeTimeStamp = Math.round(lastSignInTime.getTime() / 1000);
const yesterdayTimeStamp = Math.round(new Date().getTime() / 1000) - (24 * 3600);
if(lastSignInTimeTimeStamp < yesterdayTimeStamp){
await firebase.auth().signOut()
this.setState({
loggedIn: false
});
return false;
}
this.setState({
loggedIn: true,
user
});
}
})

Resources