为什么要添加自定义角色提供者。只要保持简单即可。如果您有该网站的注册页面,您可以通过编程方式分配成员类型和成员角色
如果您从后端添加会员,您可以轻松添加“访客”角色。
因此,在这两种情况下,“访客”角色都可以轻松应用于所有成员,并且您可以轻松地将页面保留为访客角色登录(所有身份验证)。
EDIT:我已经删除了以编程方式向用户添加角色的代码,因为您不需要这样做,解决方案如下:
如您所知,自定义角色提供程序和自定义会员资格提供程序是齐头并进的。您已添加自定义会员资格提供商并覆盖ValidateUser
方法,但要使这一切起作用,您需要重写另外两个方法GetUser
请参阅下面的自定义提供程序的代码,它会起作用
会员提供者
public class MyMembershipProvider : MembersMembershipProvider
{
public override bool ValidateUser(string username, string password)
{
if (base.ValidateUser(username,password))
{
//if this is umbraco user validate by base method
return true;
}
else
{
var allow = //add your validation code for CRM, I have checked if username is "tester" and allowed for testing purpose.
return allow;
}
}
// These two methods below which you have not overridden and need to override for public access to work
public override MembershipUser GetUser(object providerUserKey, bool userIsOnline)
{
if(base.GetUser(providerUserKey, false)!=null)
//if this is umbraco user add it as is.
return base.GetUser(providerUserKey,userIsOnline);
else
//Add your CRM user, I do not have database, so added test user
return new MembershipUser("UmbracoMembershipProvider", "tester", 1233, "[email protected] /cdn-cgi/l/email-protection", null, null, true, false, DateTime.Now, DateTime.Now, DateTime.Now, DateTime.Now, DateTime.Now);
}
public override MembershipUser GetUser(string username, bool userIsOnline)
{
if (true)//check if this is CRM user here
{
return new MembershipUser("UmbracoMembershipProvider", "tester", 1233, "[email protected] /cdn-cgi/l/email-protection", null, null, true, false, DateTime.Now, DateTime.Now, DateTime.Now, DateTime.Now, DateTime.Now);
//I am adding test user, you should create user from your CRM database
}
else
return base.GetUser(username,false);
}
}
EDIT2
好的,我已经调试了roleprovider和membershipprovider中的每一位代码,在用户登录后,当用户尝试访问受保护的页面时,首先GetUser(string username, bool userIsOnline)
被调用,如果失败,返回登录页面,成功后GetUser(object providerUserKey, bool userIsOnline)
接到电话。如果返回 null,则显示访问不足页面GetRolesForUser(string username)
被叫。并显示所有成功页面。我在两个文件的每个方法上都设置了断点,所以只涉及这3个方法。正如你看到的登录页面,我的猜测是GetUser(string username, bool userIsOnline)
第一个调用在某个地方失败了。
以下是我的文件,如果有帮助的话
角色配置部分
<roleManager enabled="true" defaultProvider="UmbracoRoleProvider">
<providers>
<clear />
<!--<add name="UmbracoRoleProvider" type="Umbraco.Web.Security.Providers.MembersRoleProvider" />-->
<add name="UmbracoRoleProvider" type="Assembly.Providers.MyRolesProvider" />
</providers>
</roleManager>
会员配置部分
<membership defaultProvider="UmbracoMembershipProvider" userIsOnlineTimeWindow="15">
<providers>
<clear />
<add name="UmbracoMembershipProvider" type="Assembly.Providers.MyMemberShipProvider, Assembly" enablePasswordRetrieval="false" enablePasswordReset="false" requiresQuestionAndAnswer="false" defaultMemberTypeAlias="Member" passwordFormat="Hashed" />
<!--<add name="UsersMembershipProvider" type="Umbraco.Web.Security.Providers.UsersMembershipProvider, Umbraco" minRequiredNonalphanumericCharacters="0" minRequiredPasswordLength="4" useLegacyEncoding="true" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" passwordFormat="Hashed" />-->
<add name="UsersMembershipProvider" type="Assembly.Providers.MyUserMembershipProvider, Assembly" minRequiredNonalphanumericCharacters="0" minRequiredPasswordLength="4" useLegacyEncoding="true" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" passwordFormat="Hashed" />
</providers>
</membership>
账户控制器
public class AccountSurfaceController : Umbraco.Web.Mvc.SurfaceController
{
[HttpPost]
public ActionResult LoginForm(LoginModel model)
{
//model not valid, do not save, but return current umbraco page
if (!ModelState.IsValid)
{
//Perhaps you might want to add a custom message to the TempData or ViewBag
//which will be available on the View when it renders (since we're not
//redirecting)
return CurrentUmbracoPage();
}
// Login
if (Membership.ValidateUser(model.Username, model.Password))
{
FormsAuthentication.SetAuthCookie(model.Username, false);
return RedirectToCurrentUmbracoUrl();
}
else
{
ModelState.AddModelError("Username", "Username is not valid");
return CurrentUmbracoPage();
}
}
}
public class LoginModel
{
[Required]
public string Username { get; set; }
[Required]
[DataType(DataType.Password)]
public string Password { get; set; }
}
角色提供者
public class MyRolesProvider : MembersRoleProvider
{
const string VISITORS_LABEL = "Visitor";
public override string[] GetAllRoles()
{
var roles = base.GetAllRoles().ToList();
roles.Add(VISITORS_LABEL);
return roles.ToArray();
}
public override string[] FindUsersInRole(string roleName, string usernameToMatch)
{
if(roleName== VISITORS_LABEL)
{
var users = ApplicationContext.Current.Services.MemberService
.GetAllMembers().Select(m => m.Email).ToList();
users.Add("[email protected] /cdn-cgi/l/email-protection");
return users.ToArray();
}
return base.FindUsersInRole(roleName, usernameToMatch);
}
public override bool RoleExists(string roleName)
{
if(roleName == VISITORS_LABEL)
{
return true;
}
return base.RoleExists(roleName);
}
public override string[] GetRolesForUser(string username)
{
var roles = base.GetRolesForUser(username).ToList();
roles.Add(VISITORS_LABEL);
return roles.ToArray();
}
public override bool IsUserInRole(string username, string roleName)
{
if(roleName == VISITORS_LABEL)
{
return true;
}
return base.IsUserInRole(username, roleName);
}
public override string[] GetUsersInRole(string roleName)
{
if(roleName == VISITORS_LABEL)
{
var list = ApplicationContext.Current.Services.MemberService
.GetAllMembers().Select(m => m.Email).ToList();
list.Add("[email protected] /cdn-cgi/l/email-protection");
return list.ToArray();
}
return base.GetUsersInRole(roleName);
}
}
EDIT3:
我重现了你的场景,它与 web.config 配置有关
当我按如下方式保留会员资格的网络配置时,除非我致电,否则它不会影响我的提供商
<membership defaultProvider="MyMembershipProvider" userIsOnlineTimeWindow="15">
<providers>
<clear />
<add name="UmbracoMembershipProvider" type="Umbraco.Web.Security.Providers.MembersMembershipProvider, Umbraco" minRequiredNonalphanumericCharacters="0" minRequiredPasswordLength="4" useLegacyEncoding="true" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" defaultMemberTypeAlias="Member" passwordFormat="Hashed" />
<add name="MyMembershipProvider" type="Umbraco724.Providers.MyMembersMembershipProvider, Umbraco724" />
<add name="UsersMembershipProvider" type="Umbraco.Web.Security.Providers.UsersMembershipProvider, Umbraco" minRequiredNonalphanumericCharacters="0" minRequiredPasswordLength="4" useLegacyEncoding="true" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" passwordFormat="Hashed" />
</providers>
</membership>
但是当将其更改为如下所示时,它就起作用了。请仔细检查配置的差异。
<membership defaultProvider="UmbracoMembershipProvider" userIsOnlineTimeWindow="15">
<providers>
<clear />
<add name="UmbracoMembershipProvider" type="Umbraco724.Providers.MyMembersMembershipProvider, Umbraco724" minRequiredNonalphanumericCharacters="0" minRequiredPasswordLength="4" useLegacyEncoding="true" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" defaultMemberTypeAlias="Visitor" passwordFormat="Hashed" />
<add name="UsersMembershipProvider" type="Umbraco.Web.Security.Providers.UsersMembershipProvider, Umbraco" minRequiredNonalphanumericCharacters="0" minRequiredPasswordLength="4" useLegacyEncoding="true" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" passwordFormat="Hashed" />
</providers>
</membership>
我认为 umbraco 只为会员和用户提供一个提供商。也当它的名字应该是Umbraco会员提供商仅有的。当我保持不同时,也会出现错误。