SameSite attribute cannot be changed - asp.net-mvc

So it is not a "My PC" problem. I deployed the app on our test server and the changes still don't get applied. Next step is to dig deeper and see if some identity related configuration was overwritten somewhere.
I've set the `Cookie.SameSite` value to `SameSiteMode.Lax` inside`services.ConfigureApplicationCookie(...)`. Now I'm still getting the cookie with the SameSite value set to strict after I restarted the app and signed in.
services.ConfigureApplicationCookie(...):
services.ConfigureApplicationCookie(options =>
{
options.Cookie.Name = "sessionCookie";
options.Cookie.HttpOnly = true;
options.Cookie.SameSite = SameSiteMode.Lax;
options.Cookie.MaxAge = TimeSpan.FromHours(5);
options.SlidingExpiration = true;
options.LogoutPath = $"/SignOut";
options.AccessDeniedPath = $"/Account/AccessDenied";
});
Tested in both Chrome and Firefox - same behaviour.
Cookies were cleared and I also restarted everything.
Yes, also my PC.
I can change any other attribute.
I've changed the name, secure and other attributes without fail.
We are using IdenityServer4 with our own implementation of IdentityUser:
services.AddDefaultIdentity<ApplicationUser>()
.AddDefaultUI()
.AddRoles<ApplicationRole>()
.AddEntityFrameworkStores<AppIdentityDbContext>();

The problem was the following line of code which came way before the lines shown in the question:
services.AddCookieConfiguration();
This was an method with return type IServiceCollection, which was written by another developer a few months ago. Because of this "error" I realized how messy our Startup.cs actually is and extracted some configurations into their own methods.

Related

ASP.NET Caching appears to be very limited after Windows Creators Update

I'm not sure I have a specific question other than--have other people seen this? And if so, is there a known workaround / fix? I have failed to find anything on Google on this topic.
Basically, we have an ASP.NET MVC application that we run on localhost that extensively uses the ASP.NET in memory cache. We cache many repeated requests to the Db.
Yesterday, we upgraded two of our dev machines to Windows 10 Creators Update. After that update, we noticed that the page requests on just those machines started to craw. Upwards of 30 seconds per page.
After some debugging and viewing logs, we are seeing that the system is making the same request to the Db 200-300 times per request. Previously, this would just be cached the first time, and that request would not happen again until the cache expired it.
What we are seeing is that this code:
var myObject = LoadSomethingFromDb();
HttpRuntime.Cache.Insert("test", myObject);
var test = HttpRuntime.Cache.Get("test");
at some point, the Get would be returning NULL even if it is right after the Insert in code and even though there is no way the cache is even close to full. The application is just starting.
Anybody else see this?
Nevermind. We got bit by the Absolute Cache Expiration parameter which I neglected to include in the question's code because I didn't think that was relevant.
We were using an absolute cache expiration of:
DateTime.Now.AddMinutes(60)
instead, we should have been using:
DateTime.UtcNow.AddMinutes(60)
Not sure why the former was fine in Windows prior to Creator's Update, but the change to UtcNow seems to make the cache work again.
It appears that after the windows creators update that the behavior of cache.Insert overload methods behave differently.
[Test]
public void CanDemonstrateCacheExpirationInconsistency()
{
var cache = HttpRuntime.Cache;
var now = DateTime.Now;
var key1 =$"Now{now.Ticks}";
var key2 = key1+"2";
var key3 = $"UtcNow{now.Ticks}";
var key4 = key3 + "2";
cache.Insert(key1, true, null, DateTime.Now.AddHours(1), Cache.NoSlidingExpiration);
cache.Insert(key2, true, null, DateTime.Now.AddHours(1), Cache.NoSlidingExpiration,CacheItemPriority.Default,null);
cache.Insert(key3, true, null, DateTime.UtcNow.AddHours(1), Cache.NoSlidingExpiration);
cache.Insert(key4, true, null, DateTime.UtcNow.AddHours(1), Cache.NoSlidingExpiration, CacheItemPriority.Default, null);
Assert.That(cache.Get(key1), Is.Null); //Using this overload with datetime.now expires the cache immediately
Assert.That(cache.Get(key2), Is.Not.Null);
Assert.That(cache.Get(key3), Is.Not.Null);
Assert.That(cache.Get(key4), Is.Not.Null);
}

Is there a way to rebuild Dexie keys?

I had a working app that uses Dexie. After upgrading to iOS 10.3, lookups by key are not working. (This is actually an indexeddb problem, not Dexie per se, I'm sure.) I'm still in shock but I have been able to confirm that the data is there by doing db.table.each(function(p) {}, and the fields used in keys are there and correct. But if I do
db.table.get(primarykey, function(p) {}
or
db.table.where("somekey").equals(nonprimarykey).first(function(p) {}
p is undefined.
I tried doing .db.table.each and then putting each retrieved object back to see if that would rebuild the keys, and it worked in Firefox, but doesn't work in Safari or Chrome (still can't retrieve by key).
I also tried specifying a new version with the same key structure and an empty upgrade, and that didn't do anything (but I only tried it in Chrome).
Everything is fine if the database is created AFTER installing 10.3 but I'm hoping that my customers won't have to delete their databases.
Is there any way to repair this without losing data?
This seems to be an upgrade bug in Safari and should really be filed on bugs.webkit.org. Assume this is something that will be fixed there as the Safari team is very responsive when it comes to critical bugs. Please file it!
As for a workaround, I would suggest to recreate the database. Copy the database to a new database, delete it, then copy back and delete the intermediate copy. I've not verified the code below, so you have to test it.
function check_and_fix_IOS_10_3_upgrade_issue () {
return (somehowCheckIfWeNeedToDoThis) ?
recreateDatabase() : Promise.resolve();
}
function recreateDatabase () {
copyDatabase("dbName", "dbName_tmp").then(()=>{
return Dexie.delete("dbName");
}).then(()=>{
return copyDatabase("dbName_tmp", "dbName");
}).then(()=>{
return Dexie.delete("dbName_tmp");
});
}
function copyDatabase(fromDbName, toDbName) {
return new Dexie(fromDbName).open().then(db => {
let schema = db.tables.reduce((schema, table) => {
schema[table.name] = [table.schema.primKey.src]
.concat(table.schema.indexes.map(idx => idx.src))
.join(',');
}, {});
let dbCopy = new Dexie(toDbName);
dbCopy.version(db.verno).stores(schema);
return dbCopy.open().then(()=>{
// dbCopy is now successfully created with same version and schema as source db.
// Now also copy the data
return Promise.all(
db.tables.map(table =>
table.toArray().then(rows => dbCopy.table(table.name).bulkAdd(rows))));
}).finally(()=>{
db.close();
dbCopy.close();
});
})
}
Regarding "somehowCheckIfWeNeedToDoThis", I can't answer exactly how to do it. Maybe user-agent sniff + cookie (set persistent cookie when fixed, so that it wont be recreated over and over). Maybe you'll find a better solution.
Then before you open your database (maybe before your app is launched) you'd need to do something like:
check_and_fix_IOS_10_3_upgrade_issue()
.then(()=>app.start())
.catch(err => {
// Display error, to user
});
I ran into the same issue, using the db.js library. All of my app data is wiped on upgrade.
Based on my tests, it looks like the 10.2 -> 10.3 upgrade is wiping any data in tables that have autoIncrement set to false. Data saved in autoIncrement=true tables is still accessible after the upgrade.
If this is the case, it's a pretty serious bug. The autoIncrement function of Safari had a host of troubles and caused a lot of us to switch to managing our own IDs instead.
I haven't tested this theory with vanilla JS yet. if someone wants to do that please add your results to the bugs.webkit.org ticket

Silex/Pimple: app parameter not updated instantly by middleware

I use the Silex/Pimple container to store parameters for my application. Some of those parameters are set using middleware.
Now I have come across the problem where I want to access a parameter value that should have been set through middleware. But when I output it, it still contains the old value.
This is a simplified version of my code:
$app['test'] = 'old value';
$app->before(function (Symfony\Component\HttpFoundation\Request $request, Silex\Application $app){
// logic
$app['test'] = 'new value';
}, Silex\Application::EARLY_EVENT);
echo $app['test'];
outputs:
old value
Does someone know how I can force the middleware to run first and then do the output? Or is there an other way to interact with the request before everything else?

How to overwrite sfConfig setting in functional lime test in symfony 1.4

My Problem is the following i wanted to test some functionality that depended on a certain setting in the sfConfig.
Proposed the setting is app_foo and its default is false.
The "standard" way to test is like:
$browser = new sfTestFunctional(new sfBrowser());
$browser->
get('/path_to/index')->
...
end();
BUT it does not work to change the setting like
sfConfig::set('app_foo', true);
$browser = new sfTestFunctional(new sfBrowser());
The sfConfig cannot be overwritten in the test because the sfConfig is reset on the next request.
BUT a field named 'rawConfiguration' in the browser instance is added to the sfConfig for the request. So the solution is to set this array:
$browserEngine = new sfBrowser();
$browser = new sfTestFunctional($browserEngine);
// overwrite an sfConfig parameter in the browser context
$browserEngine->rawConfiguration = array_merge($browserEngine->rawConfiguration, array('app_foo' => true));
Then the action knows the sfConfig::get('app_foo') with the value true.
The samura answer is nice, you also have to know that config files are environement aware so you can do that in your app.yml:
all:
my_setting: "super"
test:
my_setting: "awesome"
This is also working on the database.yml file, allowing you to run functionnal tests in another database

Symfony: issue with switching context

I am using Symfony 1.2 and I have some issues switching context.
This code was working fine:
require_once(dirname(__FILE__).'/../config/ProjectConfiguration.class.php');
$configuration = ProjectConfiguration::getApplicationConfiguration('account', 'prod', false);
$context = sfContext::createInstance($configuration, 'account-prod');
$userToLogin = PcUserPeer::retrieveByEmailAddress("myemail#example.com");
Auth::login($context->getUser(), $userToLogin, false, false);
echo "all done.";
At some point requirements changed and I needed to use the 'public' application before the 'account' one.
Then I changed to:
require_once(dirname(__FILE__).'/../config/ProjectConfiguration.class.php');
// {{{ new code:
$configuration = ProjectConfiguration::getApplicationConfiguration('public', 'prod', false);
sfContext::createInstance($configuration);
// some code using the public app...
// }}}
$configuration = ProjectConfiguration::getApplicationConfiguration('account', 'prod', false);
$context = sfContext::createInstance($configuration, 'account-prod');
// {{{ new code:
sfContext::switchTo('account-prod');
// }}}
$userToLogin = PcUserPeer::retrieveByEmailAddress("myemail#example.com");
CustomAuth::login($context->getUser(), $userToLogin, false, false);
echo "all done.";
Basically I added a switchTo call.
After the change, the code got broken and the error message is this:
PHP Fatal error: Call to a member function prepare() on a non-object in /var/www/html/myproj/symfony/storage/sfPDOSessionStorage.class.php on line 109
Thanks for your help,
Dan
Symfony is trying to load the session storage object. I suppose there is a problem with your new environment's configuration.
Check
/apps/public/config/factories.yml
Look for "storage" and try to find out how is it different from the other app's configuration.
Hard to know without a backtrace/more info what is triggering the error. It looks like you are using sessions stored in a database, and that a query related to that is failing.
Try setting the third argument to getApplicationConfiguration to true (which will turn debug on) and see if you get more output.
At a guess, it looks like the account app is using PDO session storage, and is failing to connect to the database or something?

Resources