views:

109

answers:

2

I am writing an ASP.NET MVC 2 application and don't want to use ASP.NET Membership. I do want to use the Authorize attribute on the Controllers. What I have done so far is ...

Web.config

<roleManager enabled="true" />

<authentication mode="Forms">
  <forms loginUrl="~/Authentication/Login" timeout="2880"/>
</authentication>
<authorization>
  <allow users="*" /> /* This is for testing */
</authorization>

In my Global.asax

 protected void Application_AuthenticateRequest(Object sender, EventArgs e)
    {
        var cookie = Context.Request.Cookies[FormsAuthentication.FormsCookieName];

        if (cookie == null) return;
        var decryptedCookie = FormsAuthentication.Decrypt(cookie.Value);            
        var roles = decryptedCookie.UserData.Split('|');

        var tcmIdentity = new TcmIdentity(decryptedCookie.Name);
        var tcmPrincipal = new GenericPrincipal(tcmIdentity, roles);

        Context.User = tcmPrincipal;
    }

I am using a custom IIdentity so that I can add some custom properties in the future. To test this in my Controller action I did this ...

var testPrincipal = User;

I can see the custom Identity with all of the user information but there are no roles on principal object. Any help with what i have missed would be great. Thanks.

+1  A: 

I believe you need a role provider. Much like how a Membership provider handles the membership of users, create, delete, validate, edit, in order to use roles, you need to use a RoleProvider (ASP.NET Implementing a Role Provider).

Which also requires enabling roles in the web.config, for example:

<roleManager enabled="enabled" defaultProvider="AspNetSqlRoleProvider">
  <providers>
    <clear/>
      <add name="AspNetSqlRoleProvider" 
           type="System.Web.Security.SqlRoleProvider"
           connectionStringName="ApplicationServices" 
           applicationName="/" />
      <add name="AspNetWindowsTokenRoleProvider"
           type="System.Web.Security.WindowsTokenRoleProvider"
           applicationName="/" />
  </providers>
</roleManager>

This might be useful: SO asp-net-mvc-roles-without-database-and-without-role-provider

As Might be: ASP.NET 2.0, Custom Role assignment without a 'Role Provider'

Erik Philips
Erik, Thanks for the info. I was going down the track of implementing a custom role manager when I discovered a reference to add the principal to the current thread. Once I did that I was sweet. Update below. Andrew
abarr
Awesome, I would suggest marking your answer as the answer to keep the Unasnwered questions clean of answered questions.
Erik Philips
A: 

UPDATE:

In the end I got this working by changing

protected void Application_AuthenticateRequest(Object sender, EventArgs e) { var cookie = Context.Request.Cookies[FormsAuthentication.FormsCookieName];

    if (cookie == null) return;
    var decryptedCookie = FormsAuthentication.Decrypt(cookie.Value);            
    var roles = decryptedCookie.UserData.Split('|');

    var tcmIdentity = new TcmIdentity(decryptedCookie.Name);
    var tcmPrincipal = new GenericPrincipal(tcmIdentity, roles);

    Context.User = tcmPrincipal;
}

to

protected void Application_AuthenticateRequest(Object sender, EventArgs e)
{
    var cookie = Context.Request.Cookies[FormsAuthentication.FormsCookieName];

    if (cookie == null) return;
    var decryptedCookie = FormsAuthentication.Decrypt(cookie.Value);            
    var roles = decryptedCookie.UserData.Split('|');

    var tcmIdentity = new TcmIdentity(decryptedCookie.Name);
    var tcmPrincipal = new GenericPrincipal(tcmIdentity, roles);

    Thread.CurrentPrincipal = Context.User = tcmPrincipal;
}
abarr