超级狗身份认证功能

设备:一个开发狗,n个超级狗

一、安装环境:安装超级狗供应商提供的开发套件。我拿到的是2.4版本的。

二、生成开发商认证码:用于写入读取超级狗信息操作。打开开发套件的超级狗工具包,点击身份认证方案->认证代码生成工具,插入开发狗,点击生成认证代码,选择文件路径。生成的认证代码中包含开发商id(vendor),超级狗认证码(authcode)

三、初始化超级狗:初始化超级狗的帐号、口令。打开开发套件的超级狗工具包,点击身份认证方案->初始化工具。

      1、点击Auth Code File 后面的open按钮选择第二步中生成的认证代码文件。

       2、在Current SO PIN后面的输入框,输入默认的管理员密码abcdefgh。

       3、如果不需要修改管理员默认密码,请忽略这一点。如果需要修改管理员的默认密码,请勾选Change SO PIN,在New SO PIN和Confirm SO PIN后面的输入框分别输入新密码和确认密码。注意:若修改管理员密码,请记住新的密码。

     4、设置超级狗用户口令:勾选 Set USER PIN,在New USER PIN和Confirm USER PIN后面的输入框分别输入新密码和确认密码。

     5、设置超级狗用户名:勾选Set UserName,在User Name后面的输入框输入对应财政部门管理员的帐号。

     6、完成以上步骤后,点击Init按钮。若弹窗提示“Init SuperDog Success!”,则初始化成功。

四、安装浏览器插件:打开开发套件的超级狗工具包,点击身份认证方案->浏览器插件安装工具。

五、开发代码:

    1、前端代码(angular):

    
//超级狗begin

                $scope.dogMessage = "";
                $scope.dogScope = "";
                //获取超级狗配置信息
                $http.get('/web/superdog/authentication/getSuperDogConfig', null).then(function (data) {
                    var data = data.data;
                    if (data.status && data.code === 200) {
                        //挑战数据
                        $scope.challenge = data.info.challenge;
                        //默认口令
                        $scope.superdogDefalutPass = data.info.superDogDefaultPass;
                        //超级狗认证码
                        $scope.authCode = data.info.superDogAuthcode;
                    }
                });
                //非ie、谷歌浏览器下在html页面里面添加object
                superDogService.embedTag();
                //获取超级狗插件对象
                $scope.objAuth = superDogService.getAuthObject();


                loadFunc();

                function checkDog()
                {
                    var stat = "";
                    //谷歌浏览器
                    if (navigator.userAgent.indexOf("Chrome") > 0) {
                        //获取超级狗中的用户名
                        $scope.objAuth.GetUserNameEx($scope.dogScope, $scope.authCode);
                    }
                    else {
                        //判断是否安装控件
                        if($scope.objAuth.hasOwnProperty("Open")==false){
                            $scope.dogMessage ="您未安装系统必需的控件";
                            setTimeout(checkDog, 5000);
                            return;
                        }
                        //打开超级狗
                        stat = $scope.objAuth.Open($scope.dogScope, $scope.authCode);
                        if(0 != stat)
                        {
                            $scope.model.use.useName ="";
                            $scope.dogMessage = superDogService.reportStatus(stat);
                        }
                        else
                        {
                            $scope.dogMessage ="";
                            //获取超级狗中的用户名
                            stat = $scope.objAuth.GetUserName();
                            if (stat != 0) {
                                $scope.model.use.useName ="";
                                $scope.dogMessage = superDogService.reportStatus(stat);
                            }else {
                                $scope.model.use.useName = $scope.objAuth.UserNameStr;
                                if($scope.model.use.useName==''){
                                    $scope.dogMessage ="设备未绑定帐号!";
                                }
                            }
                            $scope.objAuth.Close();
                        }
                    }
                    setTimeout(checkDog, 1000);
                }

                function loadFunc()
                {
                    if (navigator.userAgent.indexOf("Window") > 0)
                    {
                        if (navigator.userAgent.indexOf("Chrome") > 0)  //Chrome
                        {
                            window.addEventListener("message", function (event) {
                                if (event.source != window) {
                                    return;
                                }
                                if (event.data.type == "SNTL_FROM_HOST") {
                                    var ReturnText = event.data.text;
                                    //获取超级狗中返回的用户名
                                    if ("GetUserNameEx" == ReturnText.InvokeMethod) {
                                        if (0 == ReturnText.Status) {
                                            $scope.model.use.useName = ReturnText.UserNameStr;
                                            $scope.dogMessage ="";
                                            if($scope.model.use.useName==''){
                                                $scope.dogMessage ="设备未绑定帐号!";
                                            }
                                        }
                                        else {
                                            $scope.model.use.useName ="";
                                            $scope.dogMessage = superDogService.reportStatus(parseInt(ReturnText.Status));
                                        }
                                    }
                                    //获取超级狗中返回的摘要加密串,发送到服务端验证
                                    else if ("GetDigestEx" == ReturnText.InvokeMethod) {
                                        if (0 == ReturnText.Status) {
                                            $http.get('/web/superdog/authentication/verifyDigest', {params:{dog_id:ReturnText.DogIdStr,challenge:$scope.challenge,digest:ReturnText.DigestStr}}).then(function (data) {
                                                var data = data.data;
                                                if (data.status && data.code === 200) {
                                                    if (data.info != 0) {
                                                        $scope.dogMessage = superDogService.reportStatus(data.info);
                                                    }
                                                    else {
                                                        //验证通过做登录操作
                                                        $scope.events.submitUse();
                                                    }
                                                }
                                            });
                                        }
                                        else {
                                            $scope.dogMessage = superDogService.reportStatus(parseInt(ReturnText.Status));
                                        }
                                    }
                                }
                                return;
                            }, false);
                        }
                        else if (window.ActiveXObject || "ActiveXObject" in window)  //IE
                        {
                            //$scope.objAuth.SetCheckDogCallBack("insertDog", "removeDog");
                        }
                        setTimeout(checkDog, 1000);
                    }
                    else if (navigator.userAgent.indexOf("Mac") > 0 || navigator.userAgent.indexOf("Linux") > 0)
                    {
                        setTimeout(checkDog, 1000);
                    }
                }

 

function loginCheck(){

var stat = "";

if (window.ActiveXObject || "ActiveXObject" in window) //IE
{
	//Add onfocus event
	var obj = document.getElementById("password");
	if (Object.hasOwnProperty.call(window, "ActiveXObject") && !window.ActiveXObject) {// is IE11
		obj.addEventListener("onfocus", function () {
			$scope.dogMessage = "";
		}, false);
	}
	else {
		obj.attachEvent("onfocus", function () {
			$scope.dogMessage = "";
		});
	}
}

//Chrome
if (navigator.userAgent.indexOf("Chrome") > 0) {
	//超级狗口令验证
	$scope.objAuth.GetDigestEx($scope.dogScope, $scope.authCode, $scope.superdogDefalutPass, $scope.challenge);
	return false;
} else {
	//打开超级狗
	stat = $scope.objAuth.Open($scope.dogScope, $scope.authCode);
	if (stat != 0) {
		$scope.dogMessage = superDogService.reportStatus(stat);
		return false;
	}

	//超级狗口令验证
	stat = $scope.objAuth.VerifyUserPin($scope.superdogDefalutPass);
	if (stat != 0) {
		$scope.objAuth.Close();
		$scope.dogMessage = superDogService.reportStatus(stat);
		return false;
	}

	//获取超级狗id
	stat = $scope.objAuth.GetDogID();
	if (stat != 0) {
		$scope.objAuth.Close();
		$scope.dogMessage = superDogService.reportStatus(stat);
		return false;
	}

	//获取超级狗摘要加密串
	stat = $scope.objAuth.GetDigest($scope.challenge);
	if (stat != 0) {
		$scope.objAuth.Close();
		$scope.dogMessage = superDogService.reportStatus(stat);
		return false;
	}

	//服务端验证摘要加密串
	$http.get('/web/superdog/authentication/verifyDigest', {
		params: {
			dog_id: $scope.objAuth.DogIdStr,
			challenge: $scope.challenge,
			digest: $scope.objAuth.DigestStr
		}
	}).then(function (data) {
		var data = data.data;
		if (data.status && data.code === 200) {
			stat = data.info;
			if (stat != 0) {
				$scope.objAuth.Close();
				$scope.dogMessage = superDogService.reportStatus(stat);
				return;
			}
			else {
                //验证通过做登录操作
				$scope.events.submitUse();
			}
		}
	});

	$scope.objAuth.Close();
	
	return true;
}
}
//超级狗end

 上面superDogService对应的js文件代码




//超级狗
define (['angular', 'angularUiRouter', 'uiRouterExtras', 'oclazyload'], function (angular) {

    return angular.module ('superDogFunc', ['ui.router', 'oc.lazyLoad',
            'ct.ui.router.extras'])
        .factory('superDogService',['$rootScope',function($rootScope){
            var superDogService={

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

                if (typeof AuthObject._initialized == "undefined") {

                    // GetUserNameEx
                    AuthObject.prototype.GetUserNameEx = function (scope, authCode) {
                        //console.log("enter GetUserNameEx()");
                        window.postMessage({ type: "SNTL_FROM_PAGE", text: { "InvokeMethod": "GetUserNameEx", "Scope": scope, "AuthCode": authCode} }, "*");
                        return 0;
                    };

                    // GetDigestEx
                    AuthObject.prototype.GetDigestEx = function (scope, authCode, password, challenge) {
                        //console.log("enter GetDigestEx()");
                        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) {
                        //console.log("enter RegisterUserEx()");
                        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) {
                        //console.log("enter ChangeUserPinEx()");
                        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) {
                        //console.log("enter SetUserDataEx()");
                        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) {
                        //console.log("enter GetUserDataEx()");
                        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) {
                        //console.log("enter EnumDog()");
                        window.postMessage({ type: "SNTL_FROM_PAGE", text: { "InvokeMethod": "EnumDog", "AuthCode": authCode} }, "*");
                        return 0;
                    };

                    AuthObject._initialized = true;
                }
            }

            superDogService.embedTag = function(){
                if (window.ActiveXObject || "ActiveXObject" in window) {//IE
                    ;
                }
                else if (navigator.userAgent.indexOf("Chrome") > 0) {//Chrome
                    ;
                }
                else {
                    var temp = document.body.innerHTML;
                    var tag = "";
                    document.body.innerHTML = tag + temp;
                }
            };

            superDogService.getAuthObject = function(){

                var 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;
            };

            superDogService.reportStatus = function(status){
                var 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 820: text = "Hardware internal error!";
                     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;
            };



            return superDogService;
        }])


});

    2、后端代码:

 

public class Authentication extends AbstractAction {


    //加载第三方动态链接库
    static {
        try {
            String path = Thread.currentThread().getContextClassLoader().getResource("").toString();
            path = path.replace("file:/", "").replace("classes/", "");
            //判断操作系统
            Properties prop = System.getProperties();
            String os = prop.getProperty("os.name");
            String dataModel = System.getProperty("sun.arch.data.model");
            //linux系统
            if (os != null && os.toLowerCase().indexOf("linux") > -1) {
                log.info("操作系统:" + dataModel + "位linux系统");
                path = "/" + path;
                if (dataModel.equals("64")) {
                    System.load(path + "libdog_auth_srv_x64.so");
                } else {
                    System.load(path + "libdog_auth_srv.so");
                }
            } else {
                log.info("操作系统:" + dataModel + "位windows系统");
                if (dataModel.equals("64")) {
                    System.load(path + "dog_auth_srv_x64.dll");
                } else {
                    System.load(path + "dog_auth_srv.dll");
                }
            }
        } catch (Exception e) {
            log.info("加载动态库异常:" + e);
            throw new RuntimeException(e);
        }
    }

    /**
     * 获取挑战数据
     *
     * @param status
     * @return
     */
    public native static String getChallenge(int status[]);

    /**
     * 验证加密的挑战数据
     *
     * @param vendor_id 开发商 ID
     * @param dog_id    超级狗 ID
     * @param challenge 挑战数据
     * @param digest    由客户端生成的加密的摘要字符串
     * @param factor    认证因子
     * @return
     */
    public native static int verifyDigest(int vendor_id, int dog_id, String challenge, String digest, String factor);


    /**
     * Description:获取超级狗配置信息(包含挑战数据、超级狗默认密码、超级狗认证码)
     *
     * @param
     * @return java.lang.String
     * @Author: wtl
     * @Date: 2019/3/16 16:54
     */
    @ResponseBody
    @RequestMapping("getSuperDogConfig")
    public Object jsonObject() {
        //获取挑战数据
        String challenge = null;
        try {
            int[] dll_status = {0};
            challenge = getChallenge(dll_status);
        } catch (UnsatisfiedLinkError e1) {
            log.info(e1);
            throw new RuntimeException(e1);
        } catch (NoClassDefFoundError e1) {
            log.info(e1);
            throw new RuntimeException(e1);
        } catch (Exception e1) {
            log.info(e1);
            throw new RuntimeException(e1);
        }
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("challenge", challenge);
        //超级狗默认密码
        jsonObject.put("superDogDefaultPass", ConfigConstant.SUPERDOG_DEFALUTPASS);
        //超级狗认证码
        jsonObject.put("superDogAuthcode", ConfigConstant.SUPERDOG_AUTHCODE);
        return jsonObject;
    }

    /**
     * Description:验证加密的摘要字符串
     *
     * @param dog_id     超级狗id
     * @param challenge  挑战数据
     * @param digest     由客户端生成的加密的摘要字符串
     * @return int  返回 0 验证通过 900 用户绑定UKey信息异常 901 认证失败
     * @Author: wtl
     * @Date: 2019/3/16 16:54
     */
    @ResponseBody
    @RequestMapping("verifyDigest")
    public int verifyDigest(int dog_id, String challenge, String digest) {
        int status;
        try {
            status = verifyDigest(ConfigConstant.SUPERDOG_VENDOR_ID, dog_id, challenge, digest, ConfigConstant.SUPERDOG_FACTOR);
            log.debug("超级狗验证结果:" + status);


        } catch (UnsatisfiedLinkError e1) {
            status = 901;
            log.info(e1);
        } catch (NoClassDefFoundError e1) {
            status = 901;
            log.info(e1);
        } catch (Exception e) {
            status = 901;
            log.info(e);
        }

        return status;
    }
}

你可能感兴趣的:(Java,angular)