I have an issue with public access in Umbraco 7.
I use a custom membership provider to authenticate the users by my CRM database. I set a rule to let access to authenticated (front-end) users only and I used a custom role provider to define authenticated users have the visitors role. If they are not authenticated, they are redirected to the login page.
When I debug the website the user has the role :
I am authenticated and the role for the current user is the good one.
But I am still redirected to the login page ! I don't understand.
My role provider:
public class CustomRoleProvider : Umbraco.Web.Security.Providers.MembersRoleProvider
{
const int SITE_ID = 6;
public override string ApplicationName
{
get
{
return "Site";
}
}
public override string[] GetAllRoles()
{
return new[] { Const.VISITORS_LABEL };
}
public override string[] GetRolesForUser(string username)
{
return new[] { Const.VISITORS_LABEL };
}
/// <summary>
///
/// </summary>
/// <param name="username"></param>
/// <param name="roleName"></param>
/// <returns></returns>
public override bool IsUserInRole(string username, string roleName)
{
//every user is a visitor
if(roleName == Const.VISITORS_LABEL)
{
return true;
}
else
{
return base.IsUserInRole(username, roleName);
}
}
public override string[] GetUsersInRole(string roleName)
{
if(roleName == Const.VISITORS_LABEL)
{
using (var db = new CRMEntities())
{
var usersEmails = db.Customer_View.Where(x => x.SiteID == SITE_ID).Select(x=>x.Email).ToArray();
return usersEmails;
}
}
else
{
return base.GetUsersInRole(roleName);
}
}
}
Here is the controller I use for authentication:
public class MemberLoginSurfaceController : Umbraco.Web.Mvc.SurfaceController
{
// The MemberLogin Action returns the view, which we will create later. It also instantiates a new, empty model for our view:
[HttpGet]
[ActionName("MemberLogin")]
public ActionResult MemberLoginGet()
{
return PartialView("MemberLogin", new MemberLoginModel());
}
// The MemberLogout Action signs out the user and redirects to the site home page:
[HttpGet]
public ActionResult MemberLogout()
{
Session.Clear();
FormsAuthentication.SignOut();
return Redirect("/");
}
// The MemberLoginPost Action checks the entered credentials using the standard Asp Net membership provider and redirects the user to the same page. Either as logged in, or with a message set in the TempData dictionary:
[HttpPost]
[ActionName("MemberLogin")]
public ActionResult MemberLoginPost(MemberLoginModel model)
{
if (Membership.ValidateUser(model.Username, model.Password))
{
FormsAuthentication.SetAuthCookie(model.Username, model.RememberMe);
return RedirectToCurrentUmbracoPage();
}
else
{
TempData["Status"] = "Invalid username or password";
return RedirectToCurrentUmbracoPage();
}
}
}
My role provider is in the web.config and the Visitors role is detected as role in the administration panel.
<roleManager enabled="true" defaultProvider="CustomRoleProvider">
<providers>
<clear />
<add name="UmbracoRoleProvider" type="Umbraco.Web.Security.Providers.MembersRoleProvider" />
<add name="CustomRoleProvider" type="*.UI.Helpers.CustomRoleProvider" />
</providers>
</roleManager>
EDIT: I forgot the membership provider :
public class MyMembershipProvider : Umbraco.Web.Security.Providers.MembersMembershipProvider
{
const int SITE_ID = 6;
//we dont let user change their password using RC website
public override bool AllowManuallyChangingPassword
{
get
{
return false;
}
}
public override bool EnablePasswordReset
{
get
{
return false;
}
}
public override bool EnablePasswordRetrieval
{
get
{
return false;
}
}
public override bool ValidateUser(string username, string password)
{
Customer_View user;
//just to avoid errors with uppercase letters
username = username.ToLowerInvariant();
using (var db = new CRMEntities())
{
user = db.Customer_View.SingleOrDefault(x => x.Email == username && x.SiteID == SITE_ID);
//no user with this email
if (user == null)
return false;
//check if password is same
return user.Password == password;
}
}
public override MembershipUser GetUser(string username, bool userIsOnline)
{
//just to avoid errors with uppercase letters
username = username.ToLowerInvariant();
MembershipUser toReturn;
using (var db = new CRMEntities())
{
Customer_View user = db.Customer_View.SingleOrDefault(x => x.Email == username && x.SiteID == SITE_ID);
toReturn = user != null ? new MembershipUser(
//provider name
"MyMembershipProvider", string.Format("{0} {1}", user.FirstName, user.LastName),
username, username, string.Empty, string.Empty, true, true, user.CreateDate, new DateTime(), new DateTime(), new DateTime(), new DateTime()) :
null;
}
return toReturn;
}
public override MembershipUser GetUser(object providerUserKey, bool userIsOnline)
{
return this.GetUser(providerUserKey as string, userIsOnline);
}
}
Every time I try to access a page that has specific access I get redirected to the login page even if I am authenticated:
How can I solve it ?