会员提供者ChangePassword方法的返回类型问题

 2023-02-16    408  

问题描述

我们已经实现了一个自定义会员提供程序,并在使用此提供程序的网页上进行更改密码控件.此成员资格提供商类中的ChangePassword方法通过连接到外部WebService来检查关于密码强度和有效性的一些业务逻辑.如果有(长度问题,特殊字符等),WebService会有能够返回新密码的错误.

现在,要通过自定义提供者覆盖的ChangePassword方法的签名是:

会员提供者ChangePassword方法的返回类型问题

public override bool ChangePassword(string username, string oldPassword, string newPassword)

因此,即使我知道用户提供的新密码确切的问题,我无法在网页上显示它,因为我只能从此方法返回true或false,更改密码控件然后接管根据布尔值返回值,它自己的魔力是否.我可以挂钩ChangePassword控件的OnChangePasswordError事件以显示静态错误消息,或者我甚至可以将此控件的FailureText属性设置为当发生错误时的某些硬编码的字符串,但我无法向用户提供他们所提供的密码究竟有什么问题.

protected void OnPasswordChangeError(object sender, EventArgs e)
        {
            throw new MembershipPasswordException("Tell user what exactly is wrong with the password they supplied");
        }

class有一个ValidatingPassword事件,在密码更改之前提出,我可以通过检查密码是否符合条件来抛出异常,但仍然似乎没有传递异常到ChangePassword控制.以下是validationPassword eventHandler的代码:

void MyMembershipProvider_ValidatingPassword(object sender, ValidatePasswordEventArgs e)
        {
           //if password not valid
           e.Cancel = true;
           e.FailureInformation = new MembershipPasswordException();
           e.FailureInformation;           
        }

如何从隶属度提供程序类的ChangePassword方法发送特定信息到ChangePassword控件以显示正确的,非静态/硬编码密码更改错误消息给用户?有没有办法将ValidatePassWordEventargs连接到OnchangePassword方法的EventHandler中的Eventarg,以便我可以在ChangePassword控制中获取失败信息?

从我的初步研究中,这似乎没有可能.虽然我觉得MS团队不会被忽视,但应该有一种方法.

几个指针:

empersialUser.changePassword没有警告
http://forums.asp.net/t/983613.aspx

推荐答案

好的,所以我终于想到了一个解决方法.它不是最干净的,但我唯一可以默认接近应该遵守的任何地方的唯一一个.

注意:我没有选择在数据库或cookie中保留这一点.

我创建了具有与MembershipProvider ChangePassword方法相同行为的ChangePasswordNew方法,但返回字符串而不是bool.所以我的新方法看起来像这样:

public string ChangePasswordNew(string username, string oldPassword, string newPassword)
{
    //if password rules met, change password but do not return bool as MembershipProvider method does, 
    //return Success or the exact error for failure instead
    if(passwordChangeRequirementsMet == true)  
    {
        //change the password
        return "success";
    }
    else          
        return "exact reason why password cannot be changed";
}

现在,订阅ChangePassword控制的onPasswordChanging事件:

protected void PasswordIsChanging(object sender, LoginCancelEventArgs e)
{
try
    {
      string response = Provider.ChangePasswordNew(username, currentPass, newPass);
      if(response != "success")
      {
        changePwdCtrl.FailureText = response;
      }
     else
    {
    //cancel call to the default membership provider method that will attempt to
    //change the password again. Instead, replicate the 'steps' of AttemptChangePassword(), 
    //an internal method of the ChangePassword control.
    //Performing all the steps instead of calling the method because just calling method
    //does not work for some reason

    e.Cancel = true;
    FormsAuthentication.SetAuthCookie(username, false);
    OnPasswordChanged(sender, e);

    MethodInfo successMethodInfo = changePwdCtrl.GetType().GetMethod("PerformSuccessAction",                                    BindingFlags.NonPublic | BindingFlags.Instance);
    successMethodInfo.Invoke(changePwdCtrl, new object[] { "", "", changePwdCtrl.NewPassword });
}
}
catch(Exception ex)
{
    LogException(ex);
    throw;
}

}

注意:在这种情况下,如果密码更改存在错误,即响应不是”成功”,则Memebership Provider ChangePassword方法仍将调用并再次返回错误.但是我已经将FailureText属性设置为在第一个通话中返回的描述性错误,这是我的目标.我不介意在我的情况下调用两种方法.您的案例可能不同.

希望这有助于某人!

其他推荐答案

您可以执行此操作,这样您就不需要调用ChangePassword方法.

if(response != "success") 
      { 
       e.Cancel = true;
((Literal)changePwdCtrl.ChangePasswordTemplateContainer.FindControl("FailureText")).Text = response;
      }

我创建了一个处理此操作的自定义成员身份提复程序类,Commentship类中的ChangePassword方法抛出和错误消息的特定消息,并且我将其返回到更改密码控件的控制文字.

protected void ChangePassword1_ChangingPassword(object sender, LoginCancelEventArgs e)
    {
        try
        {
            ChangePassword c = (ChangePassword)sender;

            MembershipUser mu = Membership.GetUser(c.UserName);

            bool response;

            try
            {
                response = mu.ChangePassword(c.CurrentPassword, c.NewPassword);
            }
            catch (Exception ex)
            {

                response = false;
                e.Cancel = true;
                //ChangePassword1.ChangePasswordFailureText = ex.Message;
                //ChangePassword1_ChangePasswordError(sender, e);      
                //((Literal)ChangePassword1.ChangePasswordTemplateContainer.FindControl("FailureText")).Visible = true;
                ((Literal)ChangePassword1.ChangePasswordTemplateContainer.FindControl("FailureText")).Text = ex.Message;

            }

            if (response)
            {        
                //cancel call to the default membership provider method that will attempt to 
                //change the password again. Instead, replicate the 'steps' of AttemptChangePassword(),  
                //an internal method of the ChangePassword control. 
                //Performing all the steps instead of calling the method because just calling method 
                //does not work for some reason 

                e.Cancel = true;
                FormsAuthentication.SetAuthCookie(c.UserName, false);
                ChangePassword1_ChangedPassword(sender, e);
                MethodInfo successMethodInfo = ChangePassword1.GetType().GetMethod("PerformSuccessAction", BindingFlags.NonPublic | BindingFlags.Instance);
                successMethodInfo.Invoke(ChangePassword1, new object[] { "", "", ChangePassword1.NewPassword });

            }
        }
        catch (Exception ex)
        {            
            throw;
        }

其他推荐答案

一次,我需要将信息传递出提供商并结束,只需在返回呼叫的另一端返回BOOL之前设置Cookie.工作好.

以上所述是小编给大家介绍的会员提供者ChangePassword方法的返回类型问题,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对77isp云服务器技术网的支持!

原文链接:https://77isp.com/post/34074.html

=========================================

https://77isp.com/ 为 “云服务器技术网” 唯一官方服务平台,请勿相信其他任何渠道。