【问题标题】:Umbraco 7 custom membership and role providersUmbraco 7 自定义成员和角色提供者
【发布时间】:2015-04-17 16:10:34
【问题描述】:

我浏览了 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>

Membershipprovider 类看起来像这样

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

请原谅这个冗长的问题,但我想涵盖我的所有步骤。提前谢谢你。

【问题讨论】:

  • 您的登录视图如何?
  • 你能解释一下你的意思是什么吗?这是一个正常的登录页面。但正如我上面提到的,它设置在不同的项目中,因为它是架构上的单一标志。

标签: .net umbraco membership-provider umbraco7 roleprovider


【解决方案1】:

不能'评论所以它会回答:) 希望这会有所帮助。我的示例基于使用 umbraco 登录的用户,并且您希望外部提供商处理会员登录。如果是相反的,我道歉。

我在 umbraco 7.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();
            }
        }

希望对你有帮助。

【讨论】:

  • 嗨,刘,谢谢你的回答,我有一个类似的实现,但为了理解你的场景,如果用户登录你是根据你自己的数据库而不是 umbraco 检查用户名和密码?跨度>
  • 是的,用户存储在 SAP 中,因此它是一个外部系统。 SAPMembershipUser 只是继承自 System.Web.Security.MembershipUser。我的想法是,也许您缺少 FormsAuthentication.SetAuthCookie 或者您的 ApplicationName 或初始化实现是不必要的。只是一个想法。您应该能够接受我写的内容并替换 SAPMembershipUser SU = LoginS.Login(username, password);使用您自己的代码... FrieLib.CacheHelper.StoreCache(username.ToLower(), SU,true,20);意味着我在服务器上缓存用户,以便我可以在 GetSapUser 中再次获取他
  • 我明白了,我还注意到您正在实施 Umbraco.Web.Security.Providers.MembersRoleProvider,但我正在实施 asp.net 会员资格提供程序。你认为这是问题吗? ps:我在登录中设置了authcookie。
  • 抱歉忘了提到,在我的示例中,我在 umbraco 中创建了一个我称为标准的角色。然后,我使用该角色保护页面。所以我的示例角色提供者然后询问 isuserinrole。所以角色实际上并不是来自外部系统。您可以将它们与您的外部数据库一对一匹配。我说得有道理吗? ?
  • 这是有道理的,但我的意思是你使用的是 Umbraco.Web.Security.Providers.UsersMembershipProvider,而我使用的是会员提供者,我不能使用 UsersMembershipProvider,因为它要求我将 umbraco 更新到更新的版本这是我目前无法真正做到的事情。所以如果你像这样实现public class SAPMembershipProvider : MembershipProvider 而不是SAPMembershipProvider : Umbraco.Web.Security.Providers.UsersMembershipProvider 那还能用吗??
猜你喜欢
  • 1970-01-01
  • 2017-07-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多