写这篇文章主要基于2点:
- 我在百度上没有搜索到关于passay库的文章,因此我希望能通过此文章来弥补这一块的空缺。
- “不要重复造轮子”是十分重要的。
现在开始领略passay的魅力吧!
在passay对应的maven仓库中,一句话形容了passay的作用:Library for checking that a password complies with a custom set of rules.
passay类库就是为了用户自定义密码验证规则而生,它来自弗吉尼亚理工大学开源团队。
为什么要使用passay
很多人会说:“我们公司用的是正则表达式匹配的方案验证密码的有效性”。的确,正则表达式是大多数工程师的第一反应,它能够很方便的限制密码的长度以及允许的字符。但是如果要求更加特殊,例如:需要至少有一个大写字母在密码中,但大写字母的位置不定。 在这样的情况下,正则表达式难以处理,需要更多的代码来加强逻辑,如果逻辑足够复杂,代码极易产生没有考虑完全的状况导致问题频发(e.g.:要求密码不包含空格,但空格的种类繁多,手工枚举容易忽略部分)。
而passay预制了大部分规则,按照责任链模式一步步向下执行,如果验证失败,还能告诉调用者详细信息作为分析依据,十分方便。
使用passay
我们从它的用法开始,回溯使用原理:
public boolean validatePassword(String password) {
PasswordValidator passwordValidator = new PasswordValidator(
Arrays.asList(new LengthRule(5, 18), new WhitespaceRule()));
RuleResult result = passwordValidator.validate(new PasswordData(password));
return result.isValid();
}
我们封装了一个简单的密码验证方法,其中包含两条规则:密码在5-18位之间;不能包含任何种类的空格。
开始测试它的效果:
public static void main(String[] args) {
CustomizedPasswordValidator validator = new CustomizedPasswordValidator();
System.out.println(validator.validatePassword("abc123%*def"));
}
我们使用密码abc123%*def
进行测试。打开debug模式,断点设置在result上:
可以看到result中的valid=true。
当改用密码a313213121313bc12 3%*def
进行测试:
可以看到valid=false,并且无效的原因都被另两个List参数接收到。
rules扩展
类名 | 介绍 |
---|---|
AllowedCharacterRule | 给定一组指定字符,验证密码所有字符均在指定字符list中 或 开头的几个字符均在指定字符list中 或 结尾的几个字符均在指定字符list中 |
IllegalCharacterRule | 与AllowedCharacterRule相反,如果匹配到无效字符则密码无效 |
AllowedRegexRule | 给定正则表达式,验证表达式与密码是否匹配 |
IllegalRegexRule | 与AllowedRegexRule相反,如果匹配正则表达式成功,则密码无效 |
CharacterRule | 验证密码是否包含一定数量的字符类型 |
CharacterOccurrencesRule | 验证密码是否含有太多相同字符 |
CharacterCharacteristicsRule | 能够把多个CharacterRule整合为一个List,批量执行,并且能够设置至少n个CharacterRule通过即可作为验证成功处理(当n=1时,可以看作多个CharacterRule的‘或’关系) |
DictionaryRule | 验证密码是否为Dictionary内的单词。如果匹配上,则密码无效 |
DictionarySubstringRule | 与DictionaryRule类似,只要密码中的子字符串为Dictionary内单词,密码无效 |
HistoryRule | 如果用户输入密码与之前选择过的密码相同,则无效 |
IllegalSequenceRule | 如果密码中含有键盘/字母表/数字顺序的连续n个,则无效 |
LengthComplexityRule | 需要密码的复杂度(熵)达到一定值 |
NumberRangeRule | 密码里如果包含一个在范围区间内的数值,则无效 |
RepeatCharactersRule | 如果密码包含多个重复字符序列则无效(e.g.:111aabccc在sequence length = 2且count=3时就无效了,因为出现字符二连的情况有3次及以上) |
UsernameRule | 检测密码是否和userName关联 |
WhitespaceRule | 如果密码中含有任何形式的空格,则无效 |