我有一个Maven,Spring Boot,Spring MVC,AngularJS堆栈项目。对于登录页面,我使用Spring Security来处理用户名/密码表单提交验证(来自angularJS客户端)。它工作正常,但我还需要验证传入密码字段不长于特定长度(甚至在检查验证之前)(我读到这会在使用ByCrypt时暴露出一定的安全风险,因为用户可以发送极长的密码,这需要花费太多时间进行散列)
无论如何,有没有办法用Spring Security实现这一目标?可能我可以在我的CustomUserDetailService或SpringSecurityConfiguration类中完成它,但无法弄清楚如何。
答案 0 :(得分:2)
我很好奇你在哪里阅读有关bcrypt和密码长度的信息?算法采用的时间应仅取决于成本因素。该算法使用密码创建18个单词的流,并重复循环。因此实际上可用的密码大小在理论上限制为72字节。除此之外的任何事情都将被忽略。
这是一个快速测试(在Haskell repl中,因此不代表二进制时间)来演示:
Data.ByteString> hashPassword 5 p :: IO ByteString
"$2a$05$D2.hLTr0U1xMul/Y2Wsbjeddxp9SNumh5rAe.1oyaZUL4SceCZqUK"
(0.46 secs, 1,673,001,216 bytes)
Data.ByteString> hashPassword 5 tags :: IO ByteString
"$2a$05$bu9zO6ricNsrDTynjLm72emmiIdxulTXFGz0F11WOpSkh/R5viSmC"
(0.43 secs, 1,672,997,088 bytes)
Data.ByteString> Data.ByteString.length p
8
Data.ByteString> Data.ByteString.length tags
1274875
p
是字符串“password”,tags
是我的emacs标签文件,大小为1.2MB。正如您所看到的,每个哈希所用的时间是相同的。正如预期的那样,将成本因子增加一倍会使哈希时间加倍:
Data.ByteString> hashPassword 6 p :: IO ByteString
"$2a$06$UCIg6bMg57zvl2BM38cAeeg028oQ015Kt4V10J9OpZ3NsInOH.KJW"
(0.87 secs, 3,311,739,024 bytes)
Data.ByteString> hashPassword 6 tags :: IO ByteString
"$2a$06$GpqdSvGMJ/v3H9NycKjBceKE.J9VzrwtYneIFyvlLMyAjUI71AnCe"
(0.85 secs, 3,311,748,456 bytes)
所以我认为问题所基于的假设是错误的。一般来说,HTTP请求的大小应该适合您的应用程序,但您可能不必特别担心密码的长度。
答案 1 :(得分:1)
你可以在spring mvc中进行验证,你必须实现Validator接口 像
public class PassValidator implements Validator {
@Override
public boolean supports(Class<?> clazz) {
return yourclass.class.equals(clazz);
}
@Override
public void validate(Object obj, Errors errors) {
YourClass myClass = (YourClass) obj;
if(myClass.getPassword().length() < 8){
errors.rejectValue("password", "myClass.pass", "The name is too short");
}
}
}
并在您的控制器类中定义
@InitBinder
public void initBinder(WebDataBinder binder){
binder.addValidators(new PassValidator());
}
通过使用此方法,您可以使用验证输入,如
@RequestMapping(value="/yourUrl", method=RequestMethod.POST)
public String foo(@Valid @ModelAttribute YourClass myClass , Errors errors){
if(!errors.hasErrors()){
System.out.println("The password validated.");
}else{
System.out.println("the password did not validate");
}
return "somewhere";
}
你也应该添加
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>1.1.0.Final</version>
</dependency>
到你的pom.xml
另一种方法是Bean Validation,您可以向实体添加注释,您可以阅读documentations