浏览器读取超级狗(superdog)实现身份认证(前端)

1.根据开发狗设置好超级狗的authCode和challenge;

2.前端代码(vue):

    data() {
      scope: '<dogscope/>',
      challenge: '', // 后台返回挑战数据
      authCode: '', // 后台返回authCode
    },

    checkDog() { // 检查超级狗
      let stat = '';
      if (this.authCode === '') {
        this.getAuthCode();
      }

      objAuth = getAuthObject();
      if (navigator.userAgent.indexOf('Chrome') > 0) {
        objAuth.GetUserNameEx(this.scope, this.authCode);
      } else {
        if (objAuth.hasOwnProperty('Open') === false) {
          this.$message.info('您未安装系统必需的控件');
          setTimeout(this.checkDog, 5000);
          return;
        }
        stat = objAuth.Open(this.scope, this.authCode);
        if (stat != 0) {
          this.$message.info(reportStatus(stat));
        }
        stat = objAuth.GetUserName();
        if (stat != 0) {
          objAuth.Close();
          this.$message.info(reportStatus(stat));
          return false;
        }
        this.uKeyForm.username = objAuth.UserNameStr;
      }
      setTimeout(this.checkDog, 2000);
    },

    loadFunc() { // 加载相关函数
      if (navigator.userAgent.indexOf('Window') > 0) {
        if (navigator.userAgent.indexOf('Chrome') > 0) { // Chrome
          emitter.$on('message', (event) => {
            if (event.source !== window) {
              return;
            }
            if (event.data.type === 'SNTL_FROM_HOST') {
              let ReturnText = event.data.text;
              // 获取超级狗中返回的用户名
              if ('GetUserNameEx' === ReturnText.InvokeMethod) {
                if (ReturnText.Status === '0') {
                  this.uKeyForm.username = ReturnText.UserNameStr;
                } else {
                  this.uKeyForm.userName = '';
                  this.$message.info(reportStatus(parseInt(ReturnText.Status)));
                }
              } else if (ReturnText.InvokeMethod === 'GetDigestEx') { // 获取超级狗中返回的摘要加密串,发送到服务端验证
                if (ReturnText.Status === '0') {
                  // 获取digest做验证操作
                  this.uKeyDoAuth(ReturnText.DogIdStr, ReturnText.DigestStr);
                } else {
                  this.$message.info(reportStatus(parseInt(ReturnText.Status)));
                }
              }
            }
            return;
          }, false, window);
        } else if (window.ActiveXObject || 'ActiveXObject' in window) { // IE
          // $scope.objAuth.SetCheckDogCallBack('insertDog', 'removeDog');
        }
        setTimeout(this.checkDog, 2000);
      } else if (navigator.userAgent.indexOf('Mac') > 0 || navigator.userAgent.indexOf('Linux') > 0) {
        setTimeout(this.checkDog, 2000);
      }
    },
    
    uKeyLogin(formName) { // 超级狗登录
      this.$refs[formName].validate((valid) => {
        if (valid) {
          if (this.uKeyForm.password.length < 6 || this.uKeyForm.password.length > 16) {
            this.$message.info(reportStatus(905));
            return false;
          }
          // Get Object
          objAuth = getAuthObject();

          // Get Auth Code
          if (this.authCode === '') {
            this.getAuthCode();
          }
          if (navigator.userAgent.indexOf('Chrome') > 0) { // Chrome
            // Get challenge string
            if (this.challenge === '') {
              this.getChallenge();
            }
            if (this.challenge.indexOf('error') !== -1) {
              if (this.challenge.indexOf('undefined function dog_auth_get_challenge') !== -1) {
                this.$message.info(reportStatus(920));
              } else {
                this.$message.info(reportStatus(917));
              }
              objAuth.Close();
              return false;
            } else if (-1 !== this.challenge.indexOf('session_start')) {
              if (-1 !== this.challenge.indexOf('No such file or directory')) {
                this.$message.info(reportStatus(919));
              } else {
                this.$message.info(reportStatus(917));
              }
              objAuth.Close();
              return false;
            }
            objAuth.GetDigestEx(this.scope, this.authCode, this.uKeyForm.password, this.challenge);
            return false;
          }
          if (!!window.ActiveXObject || 'ActiveXObject' in window) { // IE
            let stat = '';
            let dogID = '';
            // let digest = '';
            // Open the dog
            stat = objAuth.Open(this.scope, this.authCode);
            if (stat != 0) {
              this.$message.info(reportStatus(stat));
              return false;
            }

            // Verify the password
            stat = objAuth.VerifyUserPin(this.uKeyForm.password);
            if (stat != 0) {
              objAuth.Close();
              this.$message.info(reportStatus(stat));
              return false;
            }

            // Get the DogID
            stat = objAuth.GetDogID();
            if (stat != 0) {
              objAuth.Close();
              this.$message.info(reportStatus(stat));
              return false;
            }
            dogID = objAuth.DogIdStr;
            if (this.challenge === '') {
              this.getChallenge();
            }
            if (this.challenge.indexOf('error') !== -1) {
              if (this.challenge.indexOf('undefined function dog_auth_get_challenge') !== -1) {
                this.$message.info(reportStatus(920));
              } else {
                this.$message.info(reportStatus(917));
              }
              objAuth.Close();
              return false;
            } else if (-1 !== this.challenge.indexOf('session_start')) {
              if (-1 !== this.challenge.indexOf('No such file or directory')) {
                this.$message.info(reportStatus(919));
              } else {
                this.$message.info(reportStatus(917));
              }
              objAuth.Close();
              return false;
            }
            // 获取digest
             stat = objAuth.GetDigest(this.challenge);
             if (stat != 0) {
               objAuth.Close();
               this.$message.info(reportStatus(stat));
               return false;
             }
             digest = objAuth.DigestStr;
            this.uKeyDoAuth(dogID, digest);
          }
        } else {
          return false;
        }
      });
    },

    uKeyDoAuth(dogId, digest) { // 超级狗验证
      loginService.uKeyLogin({
        dogid: dogId,
        digest: digest,
        challenge: this.challenge,
      }).then((res) => {
       // 验证成功 
      }).catch((err) => {
        this.$message.error('验证失败');
      });
    },

3.func函数:

function getAuthObjectChrome() {
  let obj = new AuthObject();
  return obj;
}

function AuthObject() {
  if (typeof AuthObject._initialized === 'undefined') {
    // GetUserNameEx
    AuthObject.prototype.GetUserNameEx = function(scope, authCode) {
      window.postMessage({
        type: 'SNTL_FROM_PAGE',
        text: {'InvokeMethod': 'GetUserNameEx', 'Scope': scope, 'AuthCode': authCode}}, '*');
      return 0;
    };

    // GetDigestEx
    AuthObject.prototype.GetDigestEx = function(scope, authCode, password, challenge) {
      window.postMessage({
        type: 'SNTL_FROM_PAGE',
        text: {'InvokeMethod': 'GetDigestEx', 'Scope': scope, 'AuthCode': authCode, 'UserPin': password, 'Challenge': challenge}}, '*');
      return 0;
    };

    // RegisterUserEx
    AuthObject.prototype.RegisterUserEx = function(scope, authCode, username, password) {
      window.postMessage({
        type: 'SNTL_FROM_PAGE',
        text: {'InvokeMethod': 'RegisterUserEx', 'Scope': scope, 'AuthCode': authCode, 'Name': username, 'UserPin': password}}, '*');
      return 0;
    };

    // ChangeUserPinEx
    AuthObject.prototype.ChangeUserPinEx = function(scope, authCode, oldPassword, newPassword) {
      window.postMessage({
        type: 'SNTL_FROM_PAGE',
        text: {'InvokeMethod': 'ChangeUserPinEx', 'Scope': scope, 'AuthCode': authCode, 'OldPin': oldPassword, 'NewPin': newPassword}}, '*');
      return 0;
    };

    // SetUserDataEx
    AuthObject.prototype.SetUserDataEx = function(scope, authCode, password, type, offset, data) {
      window.postMessage({
        type: 'SNTL_FROM_PAGE',
        text: {'InvokeMethod': 'SetUserDataEx', 'Scope': scope, 'AuthCode': authCode,
          'UserPin': password, 'Type': type, 'Offset': offset, 'Data': data}}, '*');
      return 0;
    };

    // GetUserDataEx
    AuthObject.prototype.GetUserDataEx = function(scope, authCode, type, offset, size) {
      window.postMessage({
        type: 'SNTL_FROM_PAGE',
        text: {'InvokeMethod': 'GetUserDataEx', 'Scope': scope, 'AuthCode': authCode, 'Type': type, 'Offset': offset, 'Size': size}}, '*');
      return 0;
    };

    // EnumDog
    AuthObject.prototype.EnumDog = function(authCode) {
      window.postMessage({
        type: 'SNTL_FROM_PAGE',
        text: {'InvokeMethod': 'EnumDog', 'AuthCode': authCode}}, '*');
      return 0;
    };

    AuthObject._initialized = true;
  }
}


function getAuthObject() {
  let objAuth;
  if (window.ActiveXObject || 'ActiveXObject' in window) { // IE
    objAuth = document.getElementById('AuthIE');
  } else if (navigator.userAgent.indexOf('Chrome') > 0) {
    objAuth = getAuthObjectChrome();
  } else {
    objAuth = document.getElementById('AuthNoIE');
  }
  return objAuth;
}
function embedTag() {
  if (window.ActiveXObject || 'ActiveXObject' in window) { // IE
  } else if (navigator.userAgent.indexOf('Chrome') > 0) { // Chrome

  } else {
    let temp = document.body.innerHTML;
    let tag = '<embed id=\'AuthNoIE\' type=\'application/x-dogauth\' width=0 height=0 hidden=\'true\'></embed>';
    document.body.innerHTML = tag + temp;
  }
}

function reportStatus(status) {
  let text = '未知的认证状态代码';
  switch (status) {
    case 0: text = '请求已成功完成';
      break;
    case 1: text = '请求超出数据文件的范围';
      break;
    case 3: text = '系统内存不足';
      break;
    case 4: text = '打开的登录会话数目过多';
      break;
    case 5: text = '访问被拒绝';
      break;
    case 7: text = '请您插入U-key设备!';
      break;
    case 8: text = '加密/解密的数据长度太短';
      break;
    case 9: text = '输入函数的句柄无效';
      break;
    case 10: text = '无法识别文件标识符';
      break;
    case 15: text = '无效的 XML 格式';
      break;
    case 18: text = '未找到待升级的超级狗';
      break;
    case 19: text = '未找到所需的 XML 标记,或者二进制数据的内容已丢失或无效';
      break;
    case 20: text = '该超级狗不支持升级请求';
      break;
    case 21: text = '升级计数器设置不正确';
      break;
    case 22: text = '输入的开发商代码无效';
      break;
    case 24: text = '输入的时间值超出被支持的数值范围';
      break;
    case 26: text = '升级要求回执数据,但输入参数ack_data 为 NULL';
      break;
    case 27: text = '程序在终端服务器上运行';
      break;
    case 29: text = 'V2C 文件中使用了未知算法';
      break;
    case 30: text = '签名验证失败';
      break;
    case 31: text = '特征不可用';
      break;
    case 33: text = 'API 和超级狗运行环境(License Manager)通讯错误';
      break;
    case 34: text = 'API 不识别开发商代码';
      break;
    case 35: text = '无效的 XML 格式';
      break;
    case 36: text = '无效的 XML 范围';
      break;
    case 37: text = '当前连接的超级狗数目过多';
      break;
    case 39: text = '会话被中断';
      break;
    case 41: text = '特征已失效';
      break;
    case 42: text = '超级狗的运行环境版本太旧';
      break;
    case 43: text = '与超级狗通讯中出现 USB 通信错误';
      break;
    case 45: text = '系统时钟已被篡改';
      break;
    case 46: text = '安全通道中发生了通信错误';
      break;
    case 50: text = '不能找到与范围匹配的特征';
      break;
    case 54: text = '文件中的升级计数器的数值小于超级狗中的升级计数器的数值,不允许安装 V2C文件';
      break;
    case 55: text = '文件中的升级计数器的数值大于超级狗中的升级计数器的数值,不允许安装 V2C文件';
      break;
    case 400: text = '未找到 API 的动态库';
      break;
    case 401: text = 'API 的动态库无效';
      break;
    case 500: text = '对象的初始化不正确';
      break;
    case 501: text = '无效的函数参数';
      break;
    case 502: text = '两次登录到同一对象';
      break;
    case 503: text = '从同一对象注销两次';
      break;
    case 525: text = '系统或平台的使用不正确';
      break;
    case 698: text = '未实施所请求的功能';
      break;
    case 699: text = 'API 中内部错误';
      break;
    case 802: text = '参数为空';
      break;
    case 803: text = '认证代码长度不正确';
      break;
    case 804: text = '请先登录';
      break;
    case 810: text = '口令长度不正确';
      break;
    case 811: text = '参数长度不正确';
      break;
    case 812: text = '用户数据长度不正确';
      break;
    case 813: text = '用户名长度不正确';
      break;
    case 814: text = '认证因子长度不正确';
      break;
    case 821: text = '请先验证管理员口令';
      break;
    case 822: text = '请先验证用户口令';
      break;
    case 823: text = '缓冲区长度不足';
      break;
    case 824: text = '认证动态库初始化失败';
      break;
    case 825: text = '用户口令被锁定';
      break;
    case 831: text = '验证用户口令失败(累计:1 次)';
      break;
    case 832: text = '验证用户口令失败(累计:2 次)';
      break;
    case 833: text = '验证用户口令失败(累计:3 次)';
      break;
    case 834: text = '验证用户口令失败(累计:4 次)';
      break;
    case 835: text = '验证用户口令失败(累计:5 次)';
      break;
    case 836: text = '验证用户口令失败(累计:6 次)';
      break;
    case 837: text = '验证用户口令失败(累计:7 次)';
      break;
    case 838: text = '验证用户口令失败(累计:8 次)';
      break;
    case 839: text = '验证用户口令失败(累计:9 次)';
      break;
    case 840: text = '验证用户口令失败(累计:10 次)';
      break;
    case 841: text = '验证用户口令失败(累计:11 次)';
      break;
    case 842: text = '验证用户口令失败(累计:12 次)';
      break;
    case 843: text = '验证用户口令失败(累计:13 次)';
      break;
    case 844: text = '验证用户口令失败(累计:14 次)';
      break;
    case 845: text = '验证用户口令失败(累计:15 次),用户口令被锁定';
      break;
    case 900: text = '用户绑定UKey信息异常,请联系管理员';
      break;
    case 901: text = '认证失败';
      break;
    case 902: text = '生成挑战数据失败';
      break;
    case 903: text = '用户名包含不支持的字符';
      break;
    case 904: text = '请输入口令';
      break;
    case 905: text = '口令长度须在 6-16 字节之间';
      break;
    case 906: text = '口令包含不支持的字符';
      break;
    case 907: text = '请输入用户名';
      break;
    case 908: text = '请再次输入口令';
      break;
    case 909: text = '口令长度须在 6-16 字节之间';
      break;
    case 910: text = '口令包含不支持的字符';
      break;
    case 911: text = '口令和确认口令不一致';
      break;
    case 912: text = '请输入当前口令';
      break;
    case 913: text = '请输入新口令';
      break;
    case 914: text = '用户名长度须在 1-32 字节之间';
      break;
    case 915: text = '此超级狗已经注册过,不支持再次注册';
      break;
    case 916: text = '在 java.library.path 指定的文件夹找不到dog_auth_srv 库文件';
      break;
    case 917: text = '获取挑战数据失败';
      break;
    case 918: text = '获取挑战数据失败';
      break;
    case 919: text = '找不到会话文件,请确认会话文件夹已经正确创建和设置。';
      break;
    case 920: text = '加载动态库失败:dog_auth_srv_php.dll,请确认配置文件已经正确设置';
      break;
  }
  return text;
}

 


版权声明:本文为blueXh原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。