0

I have a web role hosting a Unity3D application. In the application I have a connection screen. Like any other connection screen you can fill your login and password to access the core of the application (a game for example).

All of those information are stored in a Windows Azure Database and I can create user using an admin panel. This panel is hosted in another Web Role and can access the database.

If I create a new user, I can connect with those information in my application. There is no problem. But now if I want to change the user password using the admin panel the value is well changed in the database but in my application I can't connect with the new password, the old one is always used.

The user creation and password change are done with the Razor Entity Framework.

I don't understand because in my Unity3D application I do a request to the web role and the user controller and the role returns the old password and not the new one. But in my db and my admin panel there is the new one... How can this be ? How can I solve this ?

Is it a Response caching problem ?

How I find and return User:

DatabaseContext db = DatabaseContextProvider.WebDatabase;
string login = Request.Form["login"]; //The login typed by user
var users = from u in db.Users where u.Login == login select u;
User[] userArray = users.ToArray<User>();

Then I fill the Response to Unity3D with some Header like
Response.AddHeader("data", userArray[0].data.ToString());

If you need any information that can help you solving my problem, just ask.

Thanks a lot for your help !

MaT
  • 1,486
  • 2
  • 23
  • 62
  • Please better describe your question (you can edit it). For example it is not clear how you "change the password", where is that "Admin panel" - part of your application, or the Windows Azure Management portal? Also where are you creating the Users in SQL Azure DB? are they SQL Azure Users, or Application users? What is that Unity application you are using? Microsoft Ent.Lib. Unity or something else? have you configured Caching for the Unity if it is MS Ent.Lib? – astaykov Oct 08 '12 at 10:37
  • I added some informations, tell me if you need more. – MaT Oct 08 '12 at 11:58
  • Shouldn't the ID of the user stay the same if you change the password? – Sandrino Di Mattia Oct 08 '12 at 13:46
  • The ID is the same, I think it's linked with this http://social.msdn.microsoft.com/Forums/en-US/adodotnetentityframework/thread/952678c0-11af-4e74-b421-1b612534fcfb/#43420161-3f66-4610-a429-2a23167c41e0 – MaT Oct 08 '12 at 13:47
  • But I don't know how to add the mergeoptions. – MaT Oct 08 '12 at 13:56

2 Answers2

1

Found the problem, this was caused by Entity Framework :
Entity Framework and DbContext - Object Tracking
http://msmvps.com/blogs/kevinmcneish/archive/2010/02/16/setting-entity-framework-mergeoptions-what-works-what-doesn-t.aspx

Before

DatabaseContext db = DatabaseContextProvider.WebDatabase;
string login = Request.Form["login"];
var users = from u in db.Users where u.Login == login select u;
User[] userArray = users.ToArray<User>();

Now

DatabaseContext db = DatabaseContextProvider.WebDatabase;
string login = Request.Form["login"];
ObjectContext objectContext = ((IObjectContextAdapter)db).ObjectContext;
ObjectSet<User> set = objectContext.CreateObjectSet<User>();
set.MergeOption = MergeOption.OverwriteChanges;
var users = from u in set where u.Login == login select u;
User[] userArray = users.ToArray<User>();

@Sandrino Di Mattia : Thanks for helping me finding the answer !

Community
  • 1
  • 1
MaT
  • 1,486
  • 2
  • 23
  • 62
0

If you can see the new password in the database but the controller returns the old password try to disable caching by creating the following ActionFilter and adding it to your Action returning the password (as described here):

public class NoCacheAttribute : ActionFilterAttribute
{  
    public override void OnResultExecuting(ResultExecutingContext filterContext)
    {
        filterContext.HttpContext.Response.Cache.SetExpires(DateTime.UtcNow.AddDays(-1));
        filterContext.HttpContext.Response.Cache.SetValidUntilExpires(false);
        filterContext.HttpContext.Response.Cache.SetRevalidation(HttpCacheRevalidation.AllCaches);
        filterContext.HttpContext.Response.Cache.SetCacheability(HttpCacheability.NoCache);
        filterContext.HttpContext.Response.Cache.SetNoStore();

        base.OnResultExecuting(filterContext);
    }
}

And just on the side, why are you returning the password? The username/password validation should happen server side and should simply return true/false or a token after authentication succeeds. Returning passwords (even if hashed) is not a good idea from a security point of view.

Community
  • 1
  • 1
Sandrino Di Mattia
  • 24,394
  • 2
  • 55
  • 64
  • Unfortunately, it doesn't seems to work. I don't understand because as you said for me it's a cache problem... – MaT Oct 08 '12 at 12:44
  • The reponse headers there are all good entries like: no-cache, no-store, -1 etc...but the hash provided is not the same that the one in the db. Btw your right, i'll change the process of identification. – MaT Oct 08 '12 at 12:50
  • Could you also show some code you're writing when fetching the data? – Sandrino Di Mattia Oct 08 '12 at 12:54