0

So, a user is registering in my application (ASP .NET MVC 3). If registration is succesful, is assign him a role named "unreg" (meaning his society isn't yet registered). Completion of registration will redirect him to the specified action (RegisterSociety). If he registers successfully his society then I give him the "user" role. Anyway, User.IsInRole("user") returns FALSE even if my database changed correctly ( I'm using custom authentication and authorization).

Where and what is the issue and how can I solve it?

UPDATE:

I've got 2 tables use for authentication/authorization: - user and roles. Roles.id_role is a foreign key in the user table(user.id_role).

-- My Authentication provider...

    public class Authentication: MembershipProvider
    {
    public InMVC3.Models.useri CreateUser(string username, string password, string nume, string SCI, string NCI, string CNP, string email, int id_tip_user, out MembershipCreateStatus status)
    {
        useri us = new useri();

        us.username = username;
        us.parola = password;
        us.nume = nume;
        us.serie_ci = SCI;
        us.nr_ci = NCI;
        us.CNP = CNP;
        us.email = email;
        us.id_tip_user = id_tip_user;

        ValidatePasswordEventArgs args = new ValidatePasswordEventArgs(username, password, true);
        OnValidatingPassword(args);

        if (args.Cancel)
        {
            status = MembershipCreateStatus.InvalidPassword;
            return null;
        }

        useri u = _user.GetUserByUsername(username);

        if (u == null)
        {
            _user.Add(us);
            status = MembershipCreateStatus.Success;
            return _user.GetUserByUsername(username);
        }

        else
        {
            status = MembershipCreateStatus.DuplicateUserName;
        }
        return null;
    }
} 

-- My Role Provider

   public class Autorizatie : RoleProvider
{
    IUserRepository _user;
    IRolRepository _rol;

    public Autorizatie() : this(null) { }

    public Autorizatie(IUserRepository provider)
    {
        _user = new UserRepository();
        _rol = new RolRepository();
    }

    public override string[] GetRolesForUser(string username)
    {
        useri user = _user.GetUserByUsername(username);
        tip_useri rol = _rol.GetRolById(user.id_tip_user);

        string[] roles = new string[1];
        roles[0] = rol.rol;

        return roles;
    }

    public override bool IsUserInRole(string username, string roleName)
    {
        useri user = _user.GetUserByUsername(username);
        tip_useri rol = _rol.GetRolByRoleName(roleName);

        if (user != null && rol != null)
        {
            if (user.tip_useri.id_tip_user == rol.id_tip_user)
                return true;
            else return false;
        }
        return false;
    }


    public override void AddUsersToRoles(string[] usernames, string[] roleNames)
    {
        useri user = _user.GetUserByUsername(usernames[0]);
        tip_useri rol = _rol.GetRolByRoleName(roleNames[0]);
        if (user != null && rol != null)
        {
            user.id_tip_user = rol.id_tip_user;
            _user.Update();
        }
    }
}

--User Registration

[HttpPost]
public ActionResult Register(RegisterModel model)
{
        Autentificare provider = (Autentificare)Membership.Provider;
        IUserRepository _user = new UserRepository();
        IRolRepository rol = new RolRepository();
        IClientiRepository _client = new ClientiRepository();

        var us = rol.GetRolByRoleName("unreg").id_tip_user;
        if (ModelState.IsValid)
        {
            // Attempt to register the user
            MembershipCreateStatus createStatus;
            provider.CreateUser(model.UserName, model.Password, model.Nume, model.SCI, model.NCI, model.CNP, model.Email, us, out createStatus);


            if (createStatus == MembershipCreateStatus.Success)
            {
                FormsService.SignIn(model.UserName, false /* createPersistentCookie */);
                return RedirectToAction("RegisterFirma", "Account");
            }
            else
            {
                ModelState.AddModelError("", AccountValidation.ErrorCodeToString(createStatus));
            }
        }

        return View(model);
    }

--Society Registration

[HttpPost]
 public ActionResult RegisterFirma(RegisterFirma client)
 {
        Autentificare provider = (Autentificare)Membership.Provider;
        IUserRepository _user = new UserRepository();
        IClientiRepository _client = new ClientiRepository();
        RoleService = new Autorizatie();

        clienti cl = new clienti();

        if (ModelState.IsValid)
        {
            // Attempt to register the user
            try
            {
                cl.denumire = client.Firma;
                cl.cod_fiscal = client.CodFiscal;
                cl.reg_comert = client.Registrul;
                cl.id_grupa = 1;
                cl.id_localitate = Convert.ToInt32(client.Loc);
                cl.adresa = client.Address;
                cl.email = client.Email;
                cl.telefon = client.Telefon;
                cl.fax = client.Fax;
                cl.pers_contact = client.PersContact;
                cl.id_banca = Convert.ToInt32(client.Banca);
                cl.cont_bancar = client.ContBancar;
                cl.id_user = _user.GetUserByUsername(User.Identity.Name).id_user;

                string[] usn = new string[1];
                usn[0] = User.Identity.Name;
                string[] rls = new string[1];
                rls[0] = "user";

                RoleService.AddUsersToRoles(usn, rls);
               // _user.GetUserByUsername(User.Identity.Name).id_tip_user = 3;
               // _user.Update();

                _client.Add(cl);
                FormsService.SignOut();
                FormsService.SignIn(usn[0], false); -- even after sign out and sign in
                return RedirectToAction("Index", "Home");
            }
            catch
            {
                //  return View(client);
                return RedirectToAction("LogOn", "Account");
            }

        }

Inside the database, user.id_role is changed according to the "user" role. Few minutes after the change, when I run again my application, the roles seem to be working according to the database.

UPDATE 2

 <roleManager defaultProvider="Autorizatie"  enabled="true" cacheRolesInCookie="false" >
  <providers>
    <clear/>
    <add name="Autorizatie"  type="InMVC3.Models.Autorizatie"/>
   </providers>
  </roleManager>

I used "true" and then changed to "false" and still the same (for chacheRolesInCoockie).

Joel Coehoorn
  • 399,467
  • 113
  • 570
  • 794
davvidd
  • 73
  • 2
  • 10
  • 1
    Please post some code, so that the community can help you better. – Mahesh Velaga Jun 14 '11 at 13:43
  • 2
    Are you trying to solve this problem without looking at the code? That's what you are asking us to do... – mdm Jun 14 '11 at 13:44
  • similar to this question? http://stackoverflow.com/questions/2451068/user-isinrole-returning-false – lhan Jun 14 '11 at 13:44
  • Do you cache the roles in a cookie? Could you show the configuration of the role provider in your config? – Tz_ Jun 14 '11 at 14:14

1 Answers1

1

I think the reason is that GetRolesForUser returns only 1 role for the user. Hence User.IsInRole will not find the second role in the string array.

UPDATE: You're right, you have always just 1 role assigned, sorry.

Another tip: what does the following call do? RoleService.AddUsersToRoles(usn, rls); Does it call your provider directly?

AFAI see the roles are cached by the role provider infrastructure even if you don't use cookies, but the cache is set dirty in the System.Web.Security.Roles.AddUsersToRole() static method. Can you please check if you call this method? Maybe you called your role provider directly that then does not set the cache dirty.

Tz_
  • 2,949
  • 18
  • 13
  • I've got only one role for each user. I simply replace the previous one with AddUsersToRoles. So obviously, my GetRolesForUser returns a single role. What I've noticed is that my database is changing correctly: User.id_role is 3 (meaning he is a "user") but User.GetRolesForUser doesn't get that information but the previous one, before the change in database. It's like the application is getting the changes with a delay because even if a reset the role to 2 for that user ("unreg") with sql server and I run again my application, that user now has the "user" role inside the application. – davvidd Jun 14 '11 at 15:31
  • Autorizatie RoleService = new Autorizatie(); - where Autorizatie is my custom Role Provider which I described under "--MyRoleprovider". So, RoleService.AddUsersToRole is a call of the method described there. It changes inside the database User.id_role to the id of the new role(from the table roles where role.name = the string parameter for new role). If I'm not, what should I do in order to set the cache dirty? – davvidd Jun 14 '11 at 16:33
  • Actually called System.Web.Security.Roles.AddUsersToRole(username, rolename) instead of my RoleService.AddUsersToRoles(username, role) and works. Thanks a lot. – davvidd Jun 14 '11 at 16:52
  • Yes, that's what I wrote in my answer (that only the static method will invalidate the cache, and if you call your provider directly it will be not invalidated) – Tz_ Jun 14 '11 at 21:00