Question

I have developed my own classes for Custom Membership and Role providers.

Everything works locally. Nonetheless, after deploying the solution to IIS for testing, my login action seems to work (at least, the action validates the username+password and the user appears to be authenticated) but whenever I try to access actions that are decorated with annotations like

  [Authorize(Roles="Employee, Admin")]

I keep getting redirected to the login page, as if the user didn't have the necessary role (he does, though).

So locally, the application succeeds in validating users and checking the authenticated user's roles before executing actions (thus, I assume that my methods on both classes are correct) but on IIS it looks like the role provider isn't working properly. Anyone happens to know where might I be wrong or how can I get a better view on my problem?

In my Web.Config:

<system.web>
(...)
<authentication mode="Forms">
  <forms loginUrl="~/Account/Login" timeout="2880" />
</authentication>
<membership defaultProvider="CustomMembershipProvider">
  <providers>
    <clear />
    <add name="CustomMembershipProvider" type="MyApplication.Infrastructure.CustomMembershipProvider" connectionStringName="DBEntities" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="false" maxInvalidPasswordAttempts="5" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10" applicationName="/" />
  </providers>
</membership>
<roleManager enabled="true" defaultProvider="CustomRoleProvider">
  <providers>
    <clear />
    <add name="CustomRoleProvider" type="MyApplication.Infrastructure.CustomRoleProvider" connectionStringName="DBEntities" applicationName="/" />
  </providers>
</roleManager>
(...)
</system.web>

Thanks in advance.

EDIT: Aditional Info.

  • I just modified one of my actions' anotation to simply [Authorize] and it works. So, I believe that the authentication works and the problem must be related to the Role provider.

  • I'm using Entity Framework for my Data Model, the con. string is as follows:

  • I managed to register a user and log in using the that newly created account, which would mean that the DB connection and the Custom Membership Provider(?) are working properly.

  • A "@foreach (String str in Roles.GetRolesForUser(User.Identity.Name)){@str} prints the roles locally and doesn't print anything when deployed.

Was it helpful?

Solution

Ok, I fixed it. Here's the explanation in case someone needs it in the future:

After narrowing out the causes (as seen in my edits), I figured out that the problem must be related to my CustomRoleProvider.

That class has methods like this one:

  public override string[] GetRolesForUser(string Username)
  {
        List<string> roles = new List<string>();

        using (DBEntities _db = new DBEntities())
        {
            try
            {
                var dbRoles = from r in _db.UserRole
                              where r.Users.Username == Username
                              select r;

                foreach (var role in dbRoles)
                {
                    roles.Add(role.Role.Name);
                }
            }
            catch 
            {
            }
        }

        return roles.ToArray();
  }

So I was catching an exception and not doing anything with it. I removed the try-catch block, and got this message:

  There is already an open DataReader associated with this Command which must be closed first.

A bit of stackoverflowing and I found this: There is already an open DataReader associated with this Command which must be closed first

Turns out my local connection string had MultipleActiveResultSets=true but the connection string on my publish settings didn't. I modified my publish settings and voilà, seems to be working now.

I don't really know the advantages/disadvantages of having that setting, but it is working and I really need to move on. Thank you all for your help anyway.

OTHER TIPS

I have had the similar issue. After adding machineKey to web.config everything works all right.

<system.web>
<machineKey validationKey="2E417D4AC04F20FA6CE1CF1EFE23FBF1695BF6981B605B1B8628D2182C43D0B10E48C4A83FDCE0D1D6300095D9EE1B8746A37E2C3256554405983DCAA7622875" decryptionKey="FA6D35C22BF7E5E9E4438052B924CCC017521137C5EB017D07C7038B80C5F726" validation="SHA1" decryption="AES" />
  </system.web>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top