java动态口令登录实现过程详解
1.实现一个ItsClient客户端用来实例化调用验证功能
publicclassItsClient{
privatestaticfinalStringrouting="/v1.0/sectoken/otp_validation";
//!HTTPS消息验证地址
privateStringhttpsVerifyUrl="";
//!otpipAddr
privateStringipAddr="";
//!otpport
privateStringport="";
//!otpappID
privateStringappID="";
//!otpappKey
privateStringappKey="";
//!错误码
privateinterrorCode=0;
//!错误消息
privateStringerrorMessage="";
TreeMaperrorCodeTable=newTreeMap(){
{
put(200,"请求成功");
put(400,"输入不合法,比如请求数据不是json");
put(401,"AppID不合法");
put(402,"指纹不合法");
put(410,"非法用户,验证otp时,传入的uid有误,找不到用户");
put(411,"错误的otp");
put(412,"一个周期内动态口令只能使用一次");
put(413,"已达一个周期内最大尝试次数");
put(500,"ITS服务器内部错误");
put(601,"参数错误");
put(602,"sha1签名失败");
put(603,"操作json失败");
put(604,"url访问错误:");
put(605,"较验返回指纹失败");
}
};
publicItsClient(){
this.ipAddr=ItsConf.GetIpAddr();
this.port=ItsConf.GetPort();
this.appID=ItsConf.GetOtpAppID();
this.appKey=ItsConf.GetOtpAppKey();
httpsVerifyUrl="https://"+this.ipAddr+':'+this.port+routing;
}
//获取错误信息
publicSt ringGetErrorMessage(){
returnthis.errorMessage;
}
//获取错误码
publicintGetErrorCode(){
returnthis.errorCode;
}
publicvoidSetError(interrorCode,StringextMessage){
this.errorCode=errorCode;
this.errorMessage=this.errorCodeTable.get(this.errorCode).toString()+extMessage;
}
publicstaticStringSHA1(Stringdecript)throwsNoSuchAlgorithmException{
Stringret="";
MessageDigestsha1=MessageDigest.getInstance("SHA1");
byte[]sha1bytes=sha1.digest(decript.getBytes());
if(sha1bytes!=null){
ret=newBASE64Encoder().encode(sha1bytes);
}
returnret;
}
publicStringEncodeJson(TreeMapmap){
JSONObjectjmap=newJSONObject(map);
returnjmap.toString();
}
publicTreeMapDecodeJson(StringjsonStr)throwsParseException{
JSONObjectjsonObject=newJSONObject(jsonStr);
TreeMapretMap=newTreeMap();
Iteratoriter=jsonObject.keys();
Stringkey=null;
Objectvalue=null;
while(iter.hasNext()){
key=iter.next();
value=jsonObject.get(key);
retMap.put(key,value);
}
returnretMap;
}
publicStringBuildQueryStr(TreeMapparams){
StringqueryStr="";
Iteratoritr=params.keySet().iterator();
while(itr.hasNext()){
Stringkey=itr.next();
queryStr+=(key+"="+params.get(key).toString()+"&");
}
returnqueryStr.substring(0,queryStr.length()-1);
}
publicbooleanIsEmptyOrNull(Stringparam){
returnparam==null||param.length()<=0;
}
/**
*@brief验证otp
*@paramuidITS主账号UID或已配置的从账号
*@paramotp需要验证的动态口令
*@returnbooltrue:成功,false:失败
*/
@SuppressWarnings("serial")
publicbooleanAuthOtp(finalStringuid,finalStringotp){
if(IsEmptyOrNull(this.ipAddr)||IsEmptyOrNull(this.port)||IsEmptyOrNull(this.appID)
||IsEmptyOrNull(this.appKey)||IsEmptyOrNull(uid)||IsEmptyOrNull(otp)){
SetError(601,"");
returnfalse;
}
TreeMapparams=newTreeMap(){
{
put("app_id",appID);
put("app_key",appKey);
put("uid",uid);
put("otp",otp);
}
};
StringqureyStr=this.BuildQueryStr(params);
Stringfingerprint="";
try{
fingerprint=SHA1(qureyStr);
}catch(Exceptionex){
ex.printStackTrace();
SetError(602,ex.getMessage());
returnfalse;
}
params.remove("app_key");
params.put("fingerprint",fingerprint);
StringpostStr="";
try{
postStr=EncodeJson(params);
}catch(Exceptionex){
ex.printStackTrace();
SetError(603,"jsonencode"+ex.getMessage());
returnfalse;
}
HttpsClientconn=null;
Stringres="";
try{
conn=newHttpsClient();
res=conn.post(this.httpsVerifyUrl,postStr);//访问接口调取返回结果
}catch(Exceptionex){
ex.printStackTrace();
SetError(604,ex.getMessage());
returnfalse;
}
TreeMapret=null;
try{
ret=DecodeJson(res);
}catch(Exceptionex){
ex.printStackTrace();
SetError(603,"jsondecode"+ex.getMessage());
returnfalse;
}
intretCode=(Integer)ret.get("status");
if(200!=retCode){
SetError(retCode,"");
returnfalse;
}
returntrue;
}
}
2.实现一个HttpsClient请求工具
publicclassHttpsClient{
finalstaticHostnameVerifierdoNotVerifier=newHostnameVerifier(){
publicbooleanverify(Stringhostname,SSLSessionsession){
returntrue;
}
};
/**
*@brief发送请求
*@paramhttpsUrl请求的地址
*@parampostStr请求的数据
*@throwsException
*/
publicStringpost(StringhttpsUrl,StringpostStr)throwsException{
HttpsURLConnectionconn=null;
StringBufferrecvBuff=newStringBuffer();
StringresData="";
try{
conn=(HttpsURLConnection)(newURL(httpsUrl)).openConnection();
conn.setHostnameVerifier(doNotVerifier);
conn.setDoInput(true);
conn.setDoOutput(true);
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type","application/json");
conn.setRequestProperty("Content-Length",String.valueOf(postStr.getBytes("utf-8").length));
conn.setUseCaches(false);
//设置为utf-8可以解决服务器接收时读取的数据中文乱码问题
conn.getOutputStream().write(postStr.getBytes("utf-8"));
conn.getOutputStream().flush();
conn.getOutputStream().close();
BufferedReaderin=newBufferedReader(newInputStreamReader(conn.getInputStream()));
Stringline;
while((line=in.readLine())!=null){
recvBuff.append(line);
}
resData=recvBuff.toString();
returnresData;
}catch(MalformedURLExceptionex){
throwex;
}catch(IOExceptionex){
throwex;
}catch(Exceptionex){
throwex;
}
}
}
3.实现Its一个配置用来配置Its服务器信息接口访问地址
publicclassItsConf{
//ITS服务器地址1.1.1.1或xxx.xxx.com的形式
privatestaticStringipAddr="";
//ITS服务器端口
privatestaticStringport="";
//OTP服务的AppID
privatestaticStringotpAppID="";
//OTP服务的AppKey
privatestaticStringotpAppKey="";
publicstaticStringGetIpAddr(){
returnipAddr;
}
publicstaticStringGetPort(){
returnport;
}
publicstaticStringGetOtpAppID(){
returnotpAppID;
}
publicstaticStringGetOtpAppKey(){
returnotpAppKey;
}
}
4.接下来就是LoginContorller完成口令认证
//username用户名
//code动态口令密码
ItsClientitsClient=newItsClient();
if(itsClient.AuthOtp(username,code)){
//认证成功,跳转页面
}
5.登陆页面就省略了,自己完成吧
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。