我浏览了10个文档,我正在做正确的事情,但我确信这是我遗漏的一个小细节。
我想使用我自己的登录机制来登录我的网站。登录机制在身份服务器中,用于单次登录。
但我想在umbraco中使用公共访问功能,所以我从本地数据库中添加角色。通过更改配置文件
<roleManager enabled="true" defaultProvider="UmbracoRoleProvider">
<providers>
<clear />
<add name="UmbracoRoleProvider" type="rcsedWebServiceBLL.RCSEdRoleProvider" />
</providers>
</roleManager>
并实现RoleProvider
class RCSEdRoleProvider : RoleProvider
{
private string _ApplicationName = "UmbracoRoleProvider";
public override void AddUsersToRoles(string[] usernames, string[] roleNames)
{
throw new NotImplementedException();
}
public override string ApplicationName
{
get { return _ApplicationName; }
set
{
if(string.IsNullOrEmpty(value))
throw new ProviderException("ApplicationName Cacnnot be Empty");
if(value.Length > 0x100)
throw new ProviderException("provider application name too long");
_ApplicationName = value;
}
}
public override void CreateRole(string roleName)
{
throw new NotImplementedException();
}
public override bool DeleteRole(string roleName, bool throwOnPopulatedRole)
{
throw new NotImplementedException();
}
public override string[] FindUsersInRole(string roleName, string usernameToMatch)
{
throw new NotImplementedException();
}
public override string[] GetAllRoles()
{
return UBISRoles.GetRoleList();
}
public override string[] GetRolesForUser(string username)
{
// code to return user role access
try
{
//ool isAuthenticateSession = RCSEd.UolsSecurity.CommonFunctions.CheckAuthenticateSessionOrNot();
if (HttpContext.Current.Session["UOSStudent"] != null)
{
return (String[])HttpContext.Current.Session["userRoles"];
}
else
{
List<String> retval = new List<string>();
retval.Add("Public");
return retval.ToArray();
}
}
catch (Exception ex)
{
// AppLogWriter _objApplog = new AppLogWriter();
// _objApplog.WriteLogMessages(ex.Message.ToString());
//TODO catch Error
List<String> retval = new List<string>();
retval.Add("Public");
return retval.ToArray();
}
}
public override string[] GetUsersInRole(string roleName)
{
throw new NotImplementedException();
}
public override bool IsUserInRole(string username, string roleName)
{
try
{
foreach (String role in (String[])HttpContext.Current.Session["userRoles"])
{
if (String.Compare(role, roleName, true) == 0)
return true;
}
return false;
}
catch { }
return false;
}
public override void RemoveUsersFromRoles(string[] usernames, string[] roleNames)
{
throw new NotImplementedException();
}
public override bool RoleExists(string roleName)
{
foreach (string val in UBISRoles.GetRoleList())
{
if (val == roleName)
return true;
}
return false;
}
}
class UBISRoles
{
private static string[] allroles = new string[] { //"Public",
"MembershipCandidate",
"MembershipMember"
};
public static string[] GetRoleList()
{
return allroles;
}
public static void SetRoles(DataTable UBIsRolesResultsTBL)
{
List<String> userRoles = new List<string>();
DataRow rec = UBIsRolesResultsTBL.Rows[0];
switch (rec["Membership"].ToString())
{
case "member":
userRoles.Add("MembershipMember");
break;
case "pending member":
userRoles.Add("MembershipPending");//add
break;
case "public":
userRoles.Add("MembershipPublic");//add
break;
}
HttpContext.Current.Session["userRoles"] = userRoles.ToArray();
}
private static void CheckSimpleFieldVal(List<String> userRoles, DataRow rec, string roleName)
{
try
{
if (string.Compare(rec[roleName].ToString(), "YES", true) == 0)
userRoles.Add(roleName);
}
catch (Exception ex)
{
string msg = ex.Message;
}
}
private static void CheckSimpleFieldValV2(List<String> userRoles, DataRow rec, string roleName)
{
try
{
if (string.Compare(rec[roleName].ToString(), "1", true) == 0)
userRoles.Add(roleName);
}
catch (Exception ex)
{
string msg = ex.Message;
}
}
}
这很好,所有的东西都被加载到umbraco后台的成员组中。
但当我尝试实现MembershipProvider时,我觉得事情不起作用。网络配置看起来像这个
<membership defaultProvider="UmbracoMembershipProvider" userIsOnlineTimeWindow="15">
<providers>
<clear />
<add name="UmbracoMembershipProvider" type="rcsedWebServiceBLL.RCSEdMembershipProvide" />
<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>
Membershiprovider类看起来像这个
class RCSEdMembershipProvide : MembershipProvider
{
string connectionStringName;
private string _ApplicationName = "UmbracoMembershipProvider";
public override void Initialize(string name, System.Collections.Specialized.NameValueCollection config)
{
base.Initialize(name, config);
/* if (config["ConnectionStringName"] != null)
connectionStringName = config["connectionStringName"];*/
}
public override string ApplicationName
{
get { return _ApplicationName; }
set
{
if (string.IsNullOrEmpty(value))
throw new ProviderException("ApplicationName Cacnnot be Empty");
if (value.Length > 0x100)
throw new ProviderException("provider application name too long");
_ApplicationName = value;
}
}
public override bool ChangePassword(string username, string oldPassword, string newPassword)
{
throw new NotImplementedException();
}
public override bool ChangePasswordQuestionAndAnswer(string username, string password, string newPasswordQuestion, string newPasswordAnswer)
{
throw new NotImplementedException();
}
public override MembershipUser CreateUser(string username, string password, string email, string passwordQuestion, string passwordAnswer, bool isApproved, object providerUserKey, out MembershipCreateStatus status)
{
throw new NotImplementedException();
}
public override bool DeleteUser(string username, bool deleteAllRelatedData)
{
throw new NotImplementedException();
}
public override bool EnablePasswordReset
{
get { throw new NotImplementedException(); }
}
public override bool EnablePasswordRetrieval
{
get { throw new NotImplementedException(); }
}
public override MembershipUserCollection FindUsersByEmail(string emailToMatch, int pageIndex, int pageSize, out int totalRecords)
{
throw new NotImplementedException();
}
public override MembershipUserCollection FindUsersByName(string usernameToMatch, int pageIndex, int pageSize, out int totalRecords)
{
throw new NotImplementedException();
}
public override MembershipUserCollection GetAllUsers(int pageIndex, int pageSize, out int totalRecords)
{
throw new NotImplementedException();
}
public override int GetNumberOfUsersOnline()
{
throw new NotImplementedException();
}
public override string GetPassword(string username, string answer)
{
throw new NotImplementedException();
}
public override MembershipUser GetUser(string username, bool userIsOnline)
{
try
{
User user = (User)HttpContext.Current.Session["user"];
if (user != null)
return new MembershipUser("RCSEdMembershipProvider", user.DisplayName, username, user.Email, "", "", true, false, DateTime.Now, DateTime.Now, DateTime.Now, DateTime.Now, DateTime.Now);
else
return null;
}
catch
{
return null;
}
}
public override MembershipUser GetUser(object providerUserKey, bool userIsOnline)
{
try
{
User user = (User)HttpContext.Current.Session["user"];
if (user != null)
return new MembershipUser("RCSEdMembershipProvider", user.DisplayName, providerUserKey, user.Email, "", "", true, false, DateTime.Now, DateTime.Now, DateTime.Now, DateTime.Now, DateTime.Now);
else
return null;
}
catch
{
return null;
}
}
public override string GetUserNameByEmail(string email)
{
throw new NotImplementedException();
}
public override int MaxInvalidPasswordAttempts
{
get { throw new NotImplementedException(); }
}
public override int MinRequiredNonAlphanumericCharacters
{
get { throw new NotImplementedException(); }
}
public override int MinRequiredPasswordLength
{
get { throw new NotImplementedException(); }
}
public override int PasswordAttemptWindow
{
get { throw new NotImplementedException(); }
}
public override MembershipPasswordFormat PasswordFormat
{
get { throw new NotImplementedException(); }
}
public override string PasswordStrengthRegularExpression
{
get { throw new NotImplementedException(); }
}
public override bool RequiresQuestionAndAnswer
{
get { throw new NotImplementedException(); }
}
public override bool RequiresUniqueEmail
{
get { throw new NotImplementedException(); }
}
public override string ResetPassword(string username, string answer)
{
throw new NotImplementedException();
}
public override bool UnlockUser(string userName)
{
throw new NotImplementedException();
}
public override void UpdateUser(MembershipUser user)
{
throw new NotImplementedException();
}
public override bool ValidateUser(string username, string password)
{
return true;
}
}
我甚至一直将validateUser设置为true。
因此,当用户登录到我的身份服务器时,我在HttpContext.Current.Session["userRoles"]
中加载用户角色,并限制对我的页面的公共访问,并将用户重定向到正确的页面。
当用户未登录时,用户被重定向到登录页面,这很好,但当用户返回并加载他/她的角色并尝试访问受限制的页面时,会员资格提供商ValidateUser
不会被击中,用户被一次又一次地重定向回登录页面。
PS。我正在使用umbraco 7.1.3
抱歉问了这么长的问题,但我想把所有的步骤都说清楚。提前谢谢。
Cant'注释,所以它将是答案:)希望这会有所帮助。我的例子是基于使用umbraco登录的用户,并且您想要一个外部提供者来处理成员登录。如果是相反的话,我道歉。
我在umbraco7.2中有一个角色提供者和用户提供者,我希望您可以使用我的实现进行比较。它对我有用。
Web.config看起来像:
<membership defaultProvider="UmbracoMembershipProvider" 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="UsersMembershipProvider" type="Umbraco.Web.Security.Providers.UsersMembershipProvider, Umbraco" minRequiredNonalphanumericCharacters="0" minRequiredPasswordLength="4" useLegacyEncoding="true" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" passwordFormat="Hashed"/>
<add name="UmbracoMembershipProvider" type="XXX.Model.Membership.SAPMembershipProvider" enablePasswordRetrieval="false" enablePasswordReset="false" requiresQuestionAndAnswer="false" defaultMemberTypeAlias="_umbracoSystemDefaultProtectType" passwordFormat="Hashed"/>
</providers>
</membership>
<!-- Role Provider -->
<roleManager enabled="true" defaultProvider="UmbracoRoleProvider">
<providers>
<clear/>
<add name="UmbracoRoleProvider" type="XXX.Model.Membership.SAPRoleProvider"/>
<!--<add name="UmbracoRoleProvider" type="Umbraco.Web.Security.Providers.MembersRoleProvider"/>-->
</providers>
</roleManager>
我的角色提供者看起来像这个
public class SAPRoleProvider : Umbraco.Web.Security.Providers.MembersRoleProvider
{
public override bool IsUserInRole(string username, string roleName)
{
if (roleName.ToLower() == "standard")
return true;
else
return base.IsUserInRole(username, roleName);
}
public override string[] GetRolesForUser(string username)
{
return new[] { "Standard" };
}
}
像这样的会员提供商:
public class SAPMembershipProvider : Umbraco.Web.Security.Providers.UsersMembershipProvider
{
public override bool ChangePassword(string username, string oldPassword, string newPassword)
{
ILoginService Loginss = new LoginService();
return Loginss.ChangePassword(oldPassword, newPassword, username);
}
public override string ResetPassword(string username, string answer)
{
ILoginService Loginss = new LoginService();
return Loginss.ResetPassword(username).ToString();
}
public override MembershipUser GetUser(object providerUserKey, bool someonelinestuff)
{
return GetSapUser(providerUserKey);
}
/// <summary>
/// It is not the username but providerUserKey i ask for herem just to test since I am not sure what SAP want right now, regarding request of userdata
/// </summary>
/// <param name="providerUserKey"></param>
/// <param name="someonelinestuff"></param>
/// <returns></returns>
public override MembershipUser GetUser(string username, bool someonelinestuff)
{
return GetSapUser(username);
}
public SAPMembershipUser GetUser(string username)
{
return (SAPMembershipUser)GetUser(username, false);
}
public override bool ValidateUser(string username, string password)
{
try
{
ILoginService LoginS = new LoginService();
SAPMembershipUser SU = LoginS.Login(username, password);
if (SU != null)
{
FrieLib.CacheHelper.StoreCache(username.ToLower(), SU,true,20);
return true;
}
}
catch { return false; }
return false;
}
protected override bool PerformChangePassword(string username, string oldPassword, string newPassword)
{
ILoginService Loginss = new LoginService();
return Loginss.ChangePassword(oldPassword, newPassword, username);
}
private SAPMembershipUser GetSapUser(string username)
{
try
{
SAPMembershipUser SU = (SAPMembershipUser)FrieLib.CacheHelper.RetrieveCache(username.ToLower());
if (SU != null)
{
return SU;
}
else
{
HttpContext.Current.Response.Redirect("/umbraco/Surface/MemberLoginSurface/MemberLogout");
}
}
catch (Exception es)
{
HttpContext.Current.Response.Redirect("/umbraco/Surface/MemberLoginSurface/MemberLogout");
}
return null;
}
private SAPMembershipUser GetSapUser(object providerUserKey)
{
return GetSapUser(providerUserKey.ToString());
}
}
我还有一个额外的步骤,我不知道你是否错过了我确保最终用户登录的地方
[HttpPost]
[ActionName("MemberLogin")]
public ActionResult MemberLoginPost(MemberLoginModel model)
{
if (Membership.ValidateUser(model.Username, model.Password))
{
FormsAuthentication.SetAuthCookie(model.Username.ToLower(), model.RememberMe);
return RedirectToCurrentUmbracoUrl();
}
else
{
TempData["Status"] = "danger";
TempData["StatusMessage"] = "login_fail_message";
return RedirectToCurrentUmbracoPage();
}
}
我希望它能有所帮助。