Spring Security:如何验证密码长度

时间:2016-12-10 11:37:01

标签: java spring-mvc spring-boot spring-security

我有一个Maven,Spring Boot,Spring MVC,AngularJS堆栈项目。对于登录页面,我使用Spring Security来处理用户名/密码表单提交验证(来自angularJS客户端)。它工作正常,但我还需要验证传入密码字段不长于特定长度(甚至在检查验证之前)(我读到这会在使用ByCrypt时暴露出一定的安全风险,因为用户可以发送极长的密码,这需要花费太多时间进行散列)

无论如何,有没有办法用Spring Security实现这一目标?可能我可以在我的CustomUserDetailService或SpringSecurityConfiguration类中完成它,但无法弄清楚如何。

2 个答案:

答案 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