Link to home
Start Free TrialLog in
Avatar of abraxas-si
abraxas-si

asked on

ASP 2.0 IsInRole function returning False when turning on SSL on IIS, otherwise it works ok.

I've got an ASP.NET 2.0 Web site using Forms Authentication on top of custom Membership and Role providers. Impersionation is not used.
The setup works without a problem if I don't use SSL on IIS.
With SSL, calling .IsInRole(...) function always returns false. Since this happens only with SSL, it is very hard to debug - I used logging to find that the function, which returns the user's roles of my RoleProvider never gets called, when the site is running under SSL.
I've checked and confirmed in log that at runtime current Role and Membership providers are set to my custom ones properly.
I have a feeling the issue is related to ASP.NET behind-the-scenes caching of roles.
Does anyone have a suggestion, how to tackle the problem? Is there a way to force the membership/roles infrastructure to force read the roles? Or can I somehow fill the cache manually after login?
(Or is the problem not related to caching but something else?)
Avatar of Fareed Ali Khan
Fareed Ali Khan
Flag of Australia image

hi, have you set the
  requireSSL="true"

in web.config file, where you declare the authentication method?
Avatar of abraxas-si
abraxas-si

ASKER

I did not have it set before.
I've tried setting it to true just to see what happens - it is the same as before. :) thx anyway.
I would advice you take a look at the new ASP.NET AJAX Control Toolkit developed by Microsoft. Check the accordion control and the tab control.
http://ajax.asp.net/ajaxtoolkit/
Infinite Recursion: I fail to see, how your suggestion could be helpful. I know ajax, use ajax, and I've even gone and checked the site to see if there would be some comments present at the link you gave, which would be related to the problem at hand. There are none!
Your response looks like automated spam, used to farm reputation. Kudos to the Master rank (zomg wtf).
Hi, you can set the require SSL in  :

    <authentication mode="Forms">
      <forms loginUrl="default.aspx" requireSSL="true" defaultUrl="Home.aspx">
      </forms>
    </authentication>

These are web.config settings.
Thanks for your effort Fareed. I've checked this about 20 minutes after you've first suggested it.
It does not change the behavior of the SSL served page. But it does effectively disable anyone trying to set the site up without the SSL :), so I've kept the setting in.
Hi, please look into the following link :

http://msdn.microsoft.com//msdnmag/issues/04/06/aspnet20security/default.aspx

read the heading "An Ounce of Prevention".
The above explains you about whenever you use simple http on ssl the functions of authentication will always return false. I think may be this is your case.
Again, thank you for a good link.
But that's not it :)
The web is served fully under SSL, no mixing with unsecure sources. The linked article explains the extra feature, of instructing browser to only send the cookie when the request is made via SSL.
I actually get the auth cookie ok. The username is available and the .IsAuthenticated returns true.
The problem is limited to the behavior of roles - the built-in .IsInRole(rolename) keeps returning false, no matter what.
If I resolve the custom role provider manually and resolve the role directly, it responds as expected.
The issue here is that ASP 2.0 builtin architecture fails to ever use the role provider when the site runs under SSL. Under normal http, calling .IsInRole, results in the call to role provider, but under SSL, no call is made at all and the function simply returns false.
One more note: I've now set the cacheRolesInCookie="false", but again to no avail.
Do you want to disable the cookies? or just want to prevent it store in cache?
This is a sample test of the membership/roles:

    TextBox1.Text = "AuthType: " & Page.User.Identity.AuthenticationType & vbCrLf
    TextBox1.Text &= "IsAuthenticated: " & Page.User.Identity.IsAuthenticated.ToString() & vbCrLf
    TextBox1.Text &= "Name: " & Page.User.Identity.Name & vbCrLf
    TextBox1.Text &= "IsAdmin: " & Page.User.IsInRole("admin") & vbCrLf
    TextBox1.Text &= "-----------------------------------------" & vbCrLf
    Dim mp As MyMbrProvider = Membership.Provider
    TextBox1.Text &= "MembershipProvider:" & mp.Name & vbCrLf
    Dim hu As MyUser = Membership.GetUser()
    TextBox1.Text &= "UserInstUid:" & hu.UserInstUid.ToString() & vbCrLf
    TextBox1.Text &= "-----------------------------------------" & vbCrLf
    Dim rp As MyRoleProvider = CType(System.Web.Security.Roles.Provider, _
            MyRoleProvider)
    TextBox1.Text &= "RoleProvider:" & rp.Name & vbCrLf
    TextBox1.Text &= "IsAdmin:" & rp.IsUserInRole(hu.UserName, "admin") & vbCrLf

This is the output on non-SSL served page:

AuthType: Forms
IsAuthenticated: True
Name: cm
IsAdmin: True
-----------------------------------------
MembershipProvider:myMP
UserInstUid:127
-----------------------------------------
RoleProvider:myRP
IsAdmin:True

This is the output on SSL served page:

AuthType: Forms
IsAuthenticated: True
Name: cm
IsAdmin: False
-----------------------------------------
MembershipProvider:myMP
UserInstUid:127
-----------------------------------------
RoleProvider:myRP
IsAdmin:True
I don't really want to disable anything, but try to make the ASP roles work, when the site is served via SSL. I hoped that disabling caching in cookies would force ASP to call MyRP every time, but it still doesn't get called at all.
Are you doing these things on a ActiveDirectory?
ASKER CERTIFIED SOLUTION
Avatar of Fareed Ali Khan
Fareed Ali Khan
Flag of Australia image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Thank you Fareed.
http://support.microsoft.com/kb/311495/
Provides a means of a workaround:

  Protected Sub Application_AuthenticateRequest(ByVal sender As Object, ByVal e As System.EventArgs)
    If Not HttpContext.Current.User Is Nothing Then
      If HttpContext.Current.User.Identity.AuthenticationType = "Forms" Then
        Dim id As System.Web.Security.FormsIdentity
        id = CType(HttpContext.Current.User.Identity, System.Web.Security.FormsIdentity)
        Dim myRoles(2) As String
        myRoles(0) = "manager"
        myRoles(1) = "admin"
        HttpContext.Current.User = New System.Security.Principal.GenericPrincipal(id, myRoles)
      End If
    End If
  End Sub

This is so wrong in so many ways, but at least it works. The worst of it is, it's called several times per a single page render, so performance using a direct DB query would be abysmal. But it's a starting point :).
It pisses me off, to be using MS ASP 2.0 provided architecture by the book and to be then forced to do a manual Global.asax hack anyway. MS at it's best again.
Thx Fareed.