Windows登录认证简单实现

实现原理

首先需要了解Windows登录认证的流程,如下图所示,双方持有相同的口令,客户端请求登录,然后主域控制器产生8字节质询,并发送给客户端,双方都需要将口令散列对质询进行散列,然后客户端将最后的散列值发送给主域控制器,比对两个质询,相同则成功登录,否则失败。

前后端的简单实现(模拟流程)

前端请求

function loginPost() {
    let request = new XMLHttpRequest();
    request.open("POST","/user/authentication0")
    let formData = new FormData();
    let loginName = encrypt($(".l_user").val());
    let password = encrypt($("#password").val();
    let SHA1LoginName=sha1(loginName);
    let SHA1Password=sha1(password);
    formData.append("loginName", loginName);
    formData.append("SHA1LoginName",SHA1LoginName);
    request.send(formData);
    request.onreadystatechange = function () {
        if (request.readyState == 4 && request.status == 200) {
            let data=request.responseText;
            console.log(data);
            if(data.includes("no")){
                window.alert("用户名或密码错误!");
                window.location.reload();
            }else{
                let temp=SHA1Password+data;
                let digest=sha1(temp);
                let request2=new XMLHttpRequest();
                request2.open('POST','/user/authentication1');
                let formData2=new FormData();
                formData2.append('digest',digest);
                request2.send(formData2);
                request2.onreadystatechange=function(){
                    let data2=request2.responseText;
                    if(data2.includes("no")){
                        window.alert("登录失败,请重试");
                        window.location.reload();
                    }else{                   
                        window.location.replace("/productCategory/main");
                    }
                }
            }
        }
    }
}

后端产生8字节质询

public class GenUtil {
    public static String generate(){
        byte[] bytes=new byte[8];
        new SecureRandom().nextBytes(bytes);
        StringBuilder result0=new StringBuilder();
        for(byte item:bytes){
            result0.append(String.format("%02x", item));
        }
        return result0.toString();
    }
}

后端处理请求

    /**
     * 用户登录认证
     */
    @PostMapping("/authentication0")
    @ResponseBody
    public String Auth0( String loginName,String SHA1LoginName,HttpServletResponse response,HttpSession httpSession) throws NoSuchAlgorithmException {

        UserLoginForm userLoginForm=new UserLoginForm();
        userLoginForm.setLoginName(loginName);
        userLoginForm.setSHA1LoginName(SHA1LoginName);
        String userName=AESUtil.decrypt(userLoginForm.getLoginName(),"uUXsN6okXYqsh0BB");
        String password="";
        String ack;
        //判断用户名是否存在
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("login_name", userName);
        User user = this.userMapper.selectOne(queryWrapper);
        if (user == null) {
            ack="no";
            log.info("【用户登录】用户名不存在");
            throw new EcommerceException(ResponseEnum.USERNAME_NOT_EXISTS);
        } else{
            password=user.getPassword();
            userLoginForm.setPassword(password);
            userLoginForm.setSHA1Password(SHA1.sha1(password));
            Cookie cookie0=new Cookie("username",userName);
            Cookie cookie1=new Cookie("password",password);
            response.addCookie(cookie0);
            response.addCookie(cookie1);
            ack= GenUtil.generate();
            inquiry=ack;
        }
        User login = this.userService.login(userLoginForm);
        httpSession.setAttribute("user" ,login);
        return ack;
    }

    @PostMapping("/authentication1")
    @ResponseBody
    public String Auth1(HttpServletRequest request, String digest) throws NoSuchAlgorithmException {
        System.out.println(digest);
        Cookie[] cookies=request.getCookies();
        String hashcode="";
        for(Cookie cookie:cookies){
            if (cookie.getName().equals("username")) {

                //hashcode=cookie.getValue();
                String name =cookie.getValue();
                QueryWrapper<User> queryWrapper=new QueryWrapper<>();
                queryWrapper.eq("login_name",name);
                User user = this.userMapper.selectOne(queryWrapper);
                String password=user.getPassword();
                hashcode=SHA1.sha1(password);
                System.out.println("6666666666666666666666666666");
            }
        }
        String digest2= SHA1.sha1(hashcode+inquiry);
        if(digest2.equals(digest)){
            return "yes";
        }else{
            return "no";
        }
    }

这里面存在一些缺陷,在图中流程是用口令散列对质询进行散列,但是散列使用的手段是SHA-1,

(其中实现方式为http://t.csdn.cn/1C1LO

无法实现此步,所以在其中只是简单的将口令散列和质询连接在一起,然后对整体进行SHA-1散列,得到digest。

其余流程和图中基本一致,或许有些地方有些不同,或者实现方式有误,感谢指正。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值