Change of Security Stamp - asp.net-core

When a user's password is updated I want the Security stamp value to be updated every time that happens. I believe that is how Security stamp works from my research.
I place this code in the ApplicationUserManager.cs but this isn't working:
private static string NewSecurityStamp()
{
return Guid.NewGuid().ToString();
}
What and where do I need to get the security stamp value to change each time an update is made to the user's account?

That is what happens. However, the security stamp is only re-validated on an interval (every 30 minutes, by default), to reduce the number of database queries being made. You can lower this interval, even to zero, which effectively makes the stamp be re-validated with each request. However, that will increase the chatter back and forth to the database.
services.Configure<SecurityStampValidatorOptions>(o =>
{
// WARNING: this will issue a query for every request
// You might want to rather just compromise with an interval
// less than 30 minutes (5 minutes, 10 minutes, etc.)
o.ValidationInterval = TimeSpan.Zero;
});
An alternative option is to simply log the user out after such a change. If the goal is to simply make them re-login, that should do the trick much better. Just inject SignInManager<TUser>, and then call SignOutAsync on that instance. You'll need to redirect the user afterwards. That could be directly to the sign in page or to some area of the site that is protected, which will then cause them to be taken to the sign in page to authenticate. In either case, a redirect is necessary to have the auth cookie actually be deleted.

Related

Local storage clearing for select users

What could cause specific users to have their local storage cleared, but the rest of the users are unaffected? Is it their firewalls? Is it their anti-virus? Browser? Browser version?
Any help would be greatly appreciated.
The application -
I have a website that requires login. Certain routes require the user receive a token(from the login step) if not they will be redirected to the login page.
The run down-
Two users have come forward and mentioned they couldn't log in. After some trouble shooting and looking at logs I found they were successfully logging in. So I screen shared with one user and I watched the localstorage in the dev console. I saw that they acquired a token successfully. Then they go to navigate to the myorderCards page and suddenly the token is cleared from the storage and they are routed back to the login page. This then puts them in a loop because every time they login successfully I have a return parameter which sends them back to myorderCards which then clears the token etc...
So the problem I am facing is that I can not recreate this issue. I have tested locally and on the published site. I have tested on and off network. I have tested 3 different browsers and even tested on a mac device(the two users in question are using macs) This issue only happens for the two users that have submitted a ticket. Still I can not figure out how the local storage is clearing. the only place that clears the token are the two lines you see below.
Additional Information-
I have tried changing my browser settings to have a high security setting. However, it continues to work for me. I have changed the browser settings to not allow cookies at all but that breaks the entire website.
P.S there are no errors or exceptions to go off of. Either on the server or the browser side.
app.module.ts
RouterModule.forRoot([
{ path: 'myorderCards/:id', component: MyOrderComponent,canActivate:[MyAuthGuard] },]),
In auth guard class
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
const token = this.storage.getLocalStorageValue('mycurrentUser');
if (token != null && Object.keys(token).length != 0) {
const exTime = token.expires;
if (new Date(exTime.toString()) > new Date(Date.now())) {
return true;
}
else {
this.storage.clearLocalStorage('mycurrentUser');
this.router.navigate(["/mylogin"], { queryParams: { returnUrl: state.url } });
return false;
}
}
else {
this.storage.clearLocalStorage('mycurrentUser');
this.router.navigate(["/mylogin"], { queryParams: { returnUrl: state.url } });
return false;
}
}
}
Your token's expiration time comparison isn't timezone agnostic.
The issue is: If, one way or another, your token includes a time that doesn't provide its timezone assumption, like 9/13/21 5:30 PM (or epoch format not based in UTC), then it would already be expired to the end user who's 1 hour ahead of you. Etc.
As a solution, you could provide all datetimes in UTC, and even then convert it to Unix epoch to discourage people trying to manually 'read' it in their local time.
But for OAuth2, it's more common to include 'expires in' rather than 'expires at'. So the body of an OAuth2 access token is typically this:
{
"access_token":"MTQ0NjJkZmQ5OTM2NDE1ZTZjNGZmZjI3",
"token_type":"bearer",
"expires_in":3600,
"refresh_token":"IwOGYzYTlmM2YxOTQ5MGE3YmNmMDFkNTVk",
"scope":"create"
}
expires_in is how long (seconds) the token is valid/alive. When the client receives this token, they assume it expires that long from 'now' (where 'now' is subjective depending on geography). So they calculate the expiration date/time themselves and store it, which sidesteps the issue of timezone conversion altogether.
Then, for two customers authenticating at the same time, one in New York may store 6:00 PM while the one in Chicago may store 5:00 PM as an expiration date, even though they both expire the same moment.

How do I make user authentication api for laravel

I tried this using jwt-auth, but the thing is token gets expired. I want to remember the user with token that never gets expired. Is their any possible way to do it in Laravel 5.2.
Should I send email and password for each request to api instead of saving session and token.
I will implement this way:
If the user selects Remember me, set the ttl to a longer time ,say 1 year OR month. To do this we need to publish
php artisan vendor:publish --provider="Tymon\JWTAuth\Providers\JWTAuthServiceProvider"
Then we can override the default ttl value which is 60 mins to our desired value.
$jwt = \Illuminate\Support\Facades\Config::get('jwt');
$jwt['ttl'] = 60*24*30; // 30 days
\Illuminate\Support\Facades\Config::set('jwt',$jwt);
Hope this helps!

Maintain Session when logged in across all Pages, End session after set time (OWA_COOKIE)

I need to maintain a session for session credentials throughout the web pages I have made. I have next to no experience using OWA_COOKIE and am unsure how to go about it.
I just need it to maintain the session, Finish session if
inactive for 15 mins OR 2. they log out
I have had a whirl at it and this what I have but it doesn't work and am at a lose, can someone help or point me in the right direction?
FUNCTION maintain_session_cookie
AS
TYPE vc_arr IS TABLE OF varchar2(4000)
INDEX BY BINARY_INTEGER.
TYPE cookie IS RECORD (
NAME varchar2(4000),
vals vc_arr,
num_vals integer);
BEGIN
owa_util.mime_header('', FALSE);
owa_cookie.send(
NAME=>'Session_Cookie',
VALUE=>LOWER(),
expires => SYSDATE + 365);
-- Set the cookie and redirect to another page
owa_util.redirect_url();
EXCEPTION
WHEN OTHERS THEN
NULL;
END;
I have been just fiddling to see how it works and provide the functionality that I need.
First of all, it is a quite awkward way to set session lifetime by cookies. You can setup the parameter timeout-secs in either web.xml or weblogic.xml (see Oracle docs).
Your both requirements should be processed by the HTTP server, that's my point of view.
Now, let's say you still want to use cookies (maybe you do not use WebLogic or another reason, whatever). You will face following problems:
You will need to specify these cookies on every page you will display to the user, and not only pages, every ajax call should also have the cookies. So, everything which shows user activity should have this cookie.
Expires parameter should, obviously, be sysdate + interval '15' minute, then your cookie will work exactly for 15 minutes and if you do like it is written in point 1 the cookie will be lost only if there is no activity.
You will have to close the session by yourself if the cookie is not more presented in HTTP request, this is an additional problem.
The thing I want to say is: do it with server configuration and not with cookies. This will save your time and nerves.

Symfony Extend Authentication Timeout on Request

My thinking was that Symfony2 would extend the ExpireAt on each page request made during the authenticated session. So if the timeout was 100 seconds and you made a page request, the new ExpireAt would be time() + 100. This "use it or lose it" authentication functionality is similar to what you get on a banking website.
The default functionality seems to be when the session timeout is set to 100 in the config.yml, the user only has 100 seconds to do what they can.
I don't think this will be to hard to implement but where should it be done? My first guess is in the isEqualTo method. Once you can determine the user is authentic you can re-up their expireAt. Or does the cookie need to be modified?
The answer lies in the refreshUser method of the UserProvider and the isEqualTo method of the UserClass.
The isEqualTo method tells the user provider whether to refreshUser(UserInstance user).
Step1 : isEqualTo() returns false; (as your understanding grow, so can this logic. But essentially, this triggers refreshUser().
In all the basic user provider examples, the refreshUser & loadUserByUsername are identical. The to do what I'm talking about, the refreshUser() needs to be a little different.
Step2 : modify refreshUser(UserInterface $user). What's being passed into this method is the original userClass. So the refreshUser is responsible for syncing the expiresAt or credentialsExpireAt
I use this logic in my refreshUser() to either extend the expiration date OR set it to the original expiration date (which is expired):
if( time() > $user->getCredentialsExpireAt() ){
$refreshedUser->setCredentialsExpireAt( $user->getCredentialsExpireAt() );
}

How to send out email at a user's local time in .NET / Sql Server?

I am writing a program that needs to send out an email every hour on the hour, but at a time local to the user.
Say I have 2 users in different time zones. John is in New York and Fred is in Los Angeles. The server is in Chicago. If I want to send an email at 6 PM local to each user, I'd have to send the email to John at 7 PM Server time and Fred at 4 PM Server time.
What's a good approach to this in .NET / Sql Server? I have found an xml file with all of the time zone information, so I am considering writing a script to import it into the database, then querying off of it.
Edit: I used “t4znet.dll” and did all comparisons on the .NET side.
You have two options:
Store the adjusted time for the mail action into the database for each user. Then just compare server time with stored time. To avoid confusion and portability issues, I would store all times in UTC. So, send mail when SERVER_UTC_TIME() == storedUtcTime.
Store the local time for each mail action into the database, then convert on-the-fly. Send mail when SERVER_UTC_TIME() == TO_UTC_TIME(storedLocalTime, userTimeZone).
You should decide what makes most sense for your application. For example if the mailing time is always the same for all users, it makes more sense to go with option (2). If the events times can change between users and even per user, it may make development and debugging easier if you choose option (1). Either way you will need to know the user's time zone.
*These function calls are obviously pseudo, since I don't know their invocations in T-SQL, but they should exist.
I'm a PHP developer so I'll share what I know from PHP. I'm sure .NET will include something similar.
In PHP you can get timezone differences for the server time - as you've suggested you'd send the emails at different times on the server.
Every time you add a user save their time offset from the server time (or their timezone in case the server timezone changes).
Then when you specify an update, have an automated task (Cron for LAMP people) that runs each hour checking to see if an email needs to be sent. Do this until there are no emails left to send.
You can complement your solution with this excellent article "World Clock and the TimeZoneInformation class", I made a webservice that sent a file with information that included the local and receiver time, what I did was to modify this class so I could handle that issue and it worked perfect, exactly as I needed.
I think you could take this class and obtain from the table "Users" the time zone of them and "calculate" the appropiate time, my code went like this;
//Get correct destination time
DateTime thedate = DateTime.Now;
string destinationtimezone = null;
//Load the time zone where the file is going
TimeZoneInformation tzi = TimeZoneInformation.FromName(this.m_destinationtimezone);
//Calculate
destinationtimezone = tzi.FromUniversalTime(thedate.ToUniversalTime()).ToString();
This class has an issue in Windows Vista that crashes the "FromIndex(int index)" function but you can modify the code, instead of using the function:
public static TimeZoneInformation FromIndex(int index)
{
TimeZoneInformation[] zones = EnumZones();
for (int i = 0; i < zones.Length; ++i)
{
if (zones[i].Index == index)
return zones[i];
}
throw new ArgumentOutOfRangeException("index", index, "Unknown time zone index");
}
You can change it to;
public static TimeZoneInformation FromName(string name)
{
TimeZoneInformation[] zones = EnumZones();
foreach (TimeZoneInformation tzi in zones)
{
if (tzi.DisplayName.Equals(name))
return tzi;
}
throw new ArgumentOutOfRangeException("name", name, "Unknown time zone name");
}