ASP.NET 使用jQuery和XML的密码强度指示器

代码下载:Password_Strength_Indicator.zip

介绍

本文开发一个JQuery插件来制作一个密码强度指示器,以帮助用户创建密码。密码策略存储到一个XML文件中。用户可以很方便根据自己的需求来改变密码策略。

特点如下:

1.使用文字和进度条显示密码强度。
2.密码策略,进度条颜色和宽度存储在XML文件中。
3.使用XSLT将XML文件的密码策略转换成HTML显示。


图1



图2


 代码结构


 

  • Default.aspx  -- ASP.NET代码示例使用MasterPage模版
  • Default2.aspx -- ASP.NET代码示例不使用模版
  • Password_strength_Indicator.asp -- ASP代码示例
  • JQuery_Password_Strength_Incicator.htm -- HTML代码示例
  • PasswordPolicy.xml -- 密码策略内容
  • Password.xslt -- 转换 PasswordPoclicy.xml 文件到HTML格式
  • JQuery.password-strength.js -- 密码验证的 JQuery插件

 
密码长度策略插件
在本节中,我们简要介绍JQuery.password-strength.js文件内容。它实现的功能是使用JQuery的Ajax请求来读取XML文件,使用XML文件中的数据来填充一些局部变量。getStrengthInfo()函数包含检查密码强度的逻辑,根据用户输入,并返回相应的消息。密码强度栏和文本的位置是TextBox的相对位置。下面显示的是JQuery.password.strength.js文件中的代码:

(function($) {
    var password_Strength = new function() {
 
        //return count that match the regular expression
        this.countRegExp = function(passwordVal, regx) {
            var match = passwordVal.match(regx);
            return match ? match.length : 0;
        }
 
        this.getStrengthInfo = function(passwordVal) {
            var len = passwordVal.length;
            var pStrength = 0; //password strength
            var msg = "", inValidChars = ""; //message
 
            //get special characters from xml file
            var allowableSpecilaChars =
                new RegExp("[" + password_settings.specialChars + "]", "g")
 
            var nums = this.countRegExp(passwordVal, /\d/g), //numbers
                  lowers = this.countRegExp(passwordVal, /[a-z]/g),
                  uppers = this.countRegExp(passwordVal, /[A-Z]/g), //upper case
                  specials = this.countRegExp(passwordVal, allowableSpecilaChars),
                  //special characters
                  spaces = this.countRegExp(passwordVal, /\s/g);
 
            //check for invalid characters
            inValidChars = passwordVal.replace(/[a-z]/gi, "") +
                inValidChars.replace(/\d/g, "");
            inValidChars = inValidChars.replace(/\d/g, "");
            inValidChars = inValidChars.replace(allowableSpecilaChars, "");
 
            //check space
            if (spaces > 0) {
                return "No spaces!";
            }
 
            //invalid characters
            if (inValidChars !== '') {
                return "Invalid character: " + inValidChars;
            }
 
            //max length
            if (len > password_settings.maxLength) {
                return "Password too long!";
            }
 
            //GET NUMBER OF CHARACTERS left
            if ((specials + uppers + nums + lowers) < password_settings.minLength) {
                msg += password_settings.minLength - (specials + uppers + nums + lowers)
                + " more characters, ";
            }
 
            //at the "at least" at the front
            if (specials == 0 || uppers == 0 || nums == 0 || lowers == 0) {
                msg += "At least ";
            }
 
            //GET NUMBERS
            if (nums >= password_settings.numberLength) {
                nums = password_settings.numberLength;
            }
            else {
                msg += (password_settings.numberLength - nums) + " more numbers, ";
            }
 
            //special characters
            if (specials >= password_settings.specialLength) {
                specials = password_settings.specialLength
            }
            else {
                msg += (password_settings.specialLength - specials) + " more symbol, ";
            }
 
            //upper case letter
            if (uppers >= password_settings.upperLength) {
                uppers = password_settings.upperLength
            }
            else {
                msg += (password_settings.upperLength - uppers) +
                " Upper case characters, ";
            }
 
            //strength for length
            if ((len - (uppers + specials + nums)) >= (password_settings.minLength -
                password_settings.numberLength - password_settings.specialLength -
                password_settings.upperLength)) {
                pStrength += (password_settings.minLength -
                password_settings.numberLength - password_settings.specialLength -
                password_settings.upperLength);
            }
            else {
                pStrength += (len - (uppers + specials + nums));
            }
 
            //password strength
            pStrength += uppers + specials + nums;
 
            //detect missing lower case character
            if (lowers === 0) {
                if (pStrength > 1) {
                    pStrength -= 1; //Reduce 1
                }
                msg += "1 lower case character, ";
            }
 
            //strong password
            if (pStrength == password_settings.minLength && lowers > 0) {
                msg = "Strong password!";
            }
 
            return msg + ';' + pStrength;
        }
    }
 
    //default setting
    var password_settings = {
        minLength: 12,
        maxLength: 25,
        specialLength: 1,
        upperLength: 1,
        numberLength: 1,
        barWidth: 200,
        barColor: 'Red',
        specialChars: '!@#$', //allowable special characters
        metRequirement: false,
        useMultipleColors: 0
    };
 
    //password strength plugin
    $.fn.password_strength = function(options) {
 
        //check if password met requirement
        this.metReq = function() {
            return password_settings.metRequirement;
        }
 
        //read password setting from xml file
        $.ajax({
            type: "GET",
            url: "PasswordPolicy.xml", //use absolute link if possible
            dataType: "xml",
            success: function(xml) {
 
                $(xml).find('Password').each(function() {
                    var _minLength = $(this).find('minLength').text(),
                    _maxLength = $(this).find('maxLength').text(),
                    _numsLength = $(this).find('numsLength').text(),
                    _upperLength = $(this).find('upperLength').text(),
                    _specialLength = $(this).find('specialLength').text(),
                    _barWidth = $(this).find('barWidth').text(),
                    _barColor = $(this).find('barColor').text(),
                    _specialChars = $(this).find('specialChars').text(),
                    _useMultipleColors = $(this).find('useMultipleColors').text();
 
                    //set variables
                    password_settings.minLength = parseInt(_minLength);
                    password_settings.maxLength = parseInt(_maxLength);
                    password_settings.specialLength = parseInt(_specialLength);
                    password_settings.upperLength = parseInt(_upperLength);
                    password_settings.numberLength = parseInt(_numsLength);
                    password_settings.barWidth = parseInt(_barWidth);
                    password_settings.barColor = _barColor;
                    password_settings.specialChars = _specialChars;
                    password_settings.useMultipleColors = _useMultipleColors;
                });
            }
        });
 
        return this.each(function() {
 
            //bar position
            var barLeftPos = $("[id$='" + this.id + "']").position().left + $("[id$='" +
                this.id + "']").width();
            var barTopPos = $("[id$='" + this.id + "']").position().top + $("[id$='" +
                this.id + "']").height();
 
            //password indicator text container
            var container = $('<span></span>')
            .css({ position: 'absolute', top: barTopPos - 6, left: barLeftPos + 15,
                'font-size': '75%', display: 'inline-block',
                width: password_settings.barWidth + 40 });
 
            //add the container next to textbox
            $(this).after(container);
 
            //bar border and indicator div
            var passIndi = $('<div id="PasswordStrengthBorder"></div>
                <div id="PasswordStrengthBar" class="BarIndicator"></div>')
            .css({ position: 'absolute', display: 'none' })
            .eq(0).css({ height: 3, top: barTopPos - 16, left: barLeftPos + 15,
                 'border-style': 'solid', 'border-width': 1, padding: 2 }).end()
            .eq(1).css({ height: 5, top: barTopPos - 14, left: barLeftPos + 17 }).end()
 
            //set max length of textbox
            //$("[id$='" + this.id + "']").attr('maxLength',
                password_settings.maxLength);
 
            //add the boder and div
            container.before(passIndi);
 
            $(this).keyup(function() {
 
                var passwordVal = $(this).val(); //get textbox value
 
                //set met requirement to false
                password_settings.metRequirement = false;
 
                if (passwordVal.length > 0) {
 
                    var msgNstrength = password_Strength.getStrengthInfo(passwordVal);
 
                    var msgNstrength_array = msgNstrength.split(";"),
                        strengthPercent = 0,
                        barWidth = password_settings.barWidth,
                        backColor = password_settings.barColor;
 
                    //calculate the bar indicator length
                    if (msgNstrength_array.length > 1) {
                        strengthPercent = (msgNstrength_array[1] /
                        password_settings.minLength) * barWidth;
                    }
 
                    $("[id$='PasswordStrengthBorder']")
                        .css({ display: 'inline', width: barWidth });
 
                    //use multiple colors
                    if (password_settings.useMultipleColors === "1") {
                        //first 33% is red
                        if (parseInt(strengthPercent) >= 0
                            && parseInt(strengthPercent) <= (barWidth * .33)) {
                            backColor = "red";
                        }
                        //33% to 66% is blue
                        else if (parseInt(strengthPercent) >= (barWidth * .33)
                            && parseInt(strengthPercent) <= (barWidth * .67)) {
                            backColor = "blue";
                        }
                        else {
                            backColor = password_settings.barColor;
                        }
                    }
 
                    $("[id$='PasswordStrengthBar']").css({ display: 'inline',
                       width: strengthPercent, 'background-color': backColor });
 
                    //remove last "," character
                    if (msgNstrength_array[0].lastIndexOf(",") !== -1) {
                        container.text(msgNstrength_array[0].substring(0,
                        msgNstrength_array[0].length - 2));
                    }
                    else {
                        container.text(msgNstrength_array[0]);
                    }
 
                    if (strengthPercent == barWidth) {
                        password_settings.metRequirement = true;
                    }
                }
                else {
                    container.text('');
                    $("[id$='PasswordStrengthBorder']").css("display", "none"); //hide
                    $("[id$='PasswordStrengthBar']").css("display", "none"); //hide
                }
            });
        });
    };
})(jQuery);
 

示例
网页中包含一个TextBox控件,JQuery库和插件。根据你的要求改变txtPassword的ID。 使用  "var myPlugin = $("[id$='txtPassword']").password_strength();" 调用插件的功能,使用myPlugin.metReq()函数检测密码强度是否符合要求。

<div style="height:400px">
<br />
<asp:label runat="server" id="lblPassword"
    AssociatedControlId="txtPassword">Enter Password:</asp:label>
<asp:TextBox ID="txtPassword" runat="server"></asp:TextBox>
<br />
<a id="passwordPolicy" href="#">Password policy</a> <br /><br />
<asp:Button ID="btnSubmit" runat="server" Text="Submit" />
 
<br /><br />
 
    <asp:Label ID="ResultLabel" runat="server" Text=""></asp:Label>
</div>
 
<script src="Script/jquery-1.4.4.min.js" type="text/javascript"></script>
<script src="Script/jquery.password-strength.js" type="text/javascript"></script>
 
<script type="text/javascript">
    $(document).ready(function() {
        var myPlugin = $("[id$='txtPassword']").password_strength();
 
        $("[id$='btnSubmit']").click(function() {
            return myPlugin.metReq(); //return true or false
        });
 
        $("[id$='passwordPolicy']").click(function(event) {
            var width = 350, height = 300, left = (screen.width / 2) - (width / 2),
            top = (screen.height / 2) - (height / 2);
            window.open("PasswordPolicy.xml", 'Password_poplicy', 'width=' + width +
            ',height=' + height + ',left=' + left + ',top=' + top);
            event.preventDefault();
            return false;
        });
    });
</script>
 

代码使用XLST来提取和显示PasswordPolicy.xml的内容。如何你想学习如何使用XSLT显示XML请查看这里。


下面正则表达式的数字来自与xml文件。

(?=^.{12,25}$)(?=(?:.*?\d){2})(?=.*[a-z])(?=(?:.*?[A-
Z]){2})(?=(?:.*?[!@#$%*()_+^&}{:;?.]){2})(?!.*\s)[0-9a-zA-Z!@#$%*()_+^&]*$
 

下面的代码显示如何动态生成正则表达式。如何要改变密码只需要改变PasswordPolicy.xml文件中的设置即可。

    void btnSubmit_Click(object sender, EventArgs e)
    {
        PasswordSetting passwordSetting = Helper.GetPasswordSetting();
        StringBuilder sbPasswordRegx = new StringBuilder(string.Empty);
 
        //min and max
        sbPasswordRegx.Append(@"(?=^.{" + passwordSetting.MinLength + "," +
            passwordSetting.MaxLength + "}$)");
 
        //numbers length
        sbPasswordRegx.Append(@"(?=(?:.*?\d){" + passwordSetting.NumsLength + "})");
 
        //a-z characters
        sbPasswordRegx.Append(@"(?=.*[a-z])");
 
        //A-Z length
        sbPasswordRegx.Append(@"(?=(?:.*?[A-Z]){" + passwordSetting.UpperLength + "})");
 
        //special characters length
        sbPasswordRegx.Append(@"(?=(?:.*?[" + passwordSetting.SpecialChars + "]){" +
             passwordSetting.SpecialLength + "})");
 
        //(?!.*\s) - no spaces
        //[0-9a-zA-Z!@#$%*()_+^&] -- valid characters
        sbPasswordRegx.Append(@"(?!.*\s)[0-9a-zA-Z" + passwordSetting.SpecialChars +
          "]*$");
 
        if (Regex.IsMatch(txtPassword.Text, sbPasswordRegx.ToString()))
        {
            ResultLabel.Text = "Password confront password policy!";
        }
        else
        {
            ResultLabel.Text = "Password does not confront password policy!";
        }
    }
 

显示不同颜色的进度条
 

  1. 颜色变化基于密码长度。
  2. 如果密码长度介于0和33%,显示红色。
  3. 如果密码长度在33%-67%之间显示蓝色。
  4. 如果在67%以上则显示PasswordPolicy.xml文件中指定的颜色。

 
可以使用PasswordPolicy.xml文件中的 useMultipleColors属性来指定使用启用或禁用多种颜色。
 
 
翻译参考源文档 <http://aspalliance.com/2043_ASPNET__Password_Strength_Indicator_using_jQuery_and_XML.all>
 

posted @ 2011-08-04 13:04  敏捷学院  阅读(995)  评论(1编辑  收藏  举报