-->
当前位置:首页 > DayDayUp > 正文内容

大华平台登录过程两次鉴权python demo

Luz2年前 (2022-07-03)DayDayUp4198

客户说按照接口文档死活无法鉴权,自己试了一下

官方文档

第一次鉴权

功能说明

第一次鉴权必然会报401错误,原因是请求入参还没有平台的令牌,这次鉴权的目的是获取到平台的加密领域、随机密钥、加密方式以及平台RSA加密公钥,以便于计算出签名,签名是作为第二次鉴权的入参之一。

接口调用请求说明

http请求方式:POST

请求地址:https://10.35.210.133:443/admin/API/accounts/authorize 

请求数据示例

POST /admin/API/accounts/authorize HTTP/1.1

Host: 10.35.210.133

Connection: close

Content-Type: application/json;charset=UTF-8

Content-Length: 70

{

"userName": "system",

"ipAddress": "",

"clientType": "WINPC_V1"

}

请求参数

image.png


返回数据示例

{

"realm": "f689ed8c43530d68bf7d6e95a62f7f87",

"randomKey": "8011f60ea78547ee",

"encryptType": "MD5",

"publickey": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAkCdJdUy6Hd6OQyMDe1dNH8Pb9mRGxKuoLGIQ8xQ6AGYC/TZ+fnC4ton7l/qDcsHrvAGZJQtk7pUOrvQgzHbIsh1qEY5xfQYzP1Sah25NYkT1Vo4Z7vCYPASKjsVerzZrd7kvEX5kA3GBWwTRFE4dw4R33/Nr4TJM916m99sN7Nba1JdyLno7DauBIc4dQp6CbqovyK0hhCHTNoX5WIOj6iElgANW22ukgKYrHVxlJ6SxbyAd9pCNq85yz3QIZ3QsGDI/xHI+zibD3qAlqSsJEAtVBmlyLKf8jT0NKhLfY6lglt3F0YmxvCsVjErtZvduLkuv8i6nbHBfpA5urUa+GQIDAQAB"

}

返回参数

image.png


 

第二次鉴权

功能说明

第二次鉴权请求前需要根据第一次鉴权的返回值计算出签名signature的值

根据用户提供的用户名(userName)、密码(password),第一次鉴权返回的域信息(realm),随机值(randomKey)和加密方式(encryptType,MD5加密),采用如下方式计算出签名(signature) 伪代码示例:

temp = md5(password)

temp = md5(userName + temp)

temp = md5(temp)

temp = md5(userName + ":" + realm + ":" + temp)

signature = md5(temp + ":" + randomKey)

如上述伪代码所示,一共需要进行5次MD5加密,其中参数和结果值均为字符串,md5加密结果值的字母都为小写。 假定值为如下:

image.png


各个阶段的计算值如下所示:

image.png


最后得到07d3ae5ea480de187c2ca0f77742e3ce就是签名signature的值,它将作为第二次鉴权的入参之一。

注意:第二次鉴权得到token值后,后续要调用平台的其他业务接口都需要把token放在请求头里, 字段名称为X-Subject-Token,没有放令牌或者令牌过期,请求都会返回401。

接口调用请求说明

http请求方式:POST

请求地址:https://10.35.210.133:443/admin/API/accounts/authorize 

请求数据示例

POST /admin/API/accounts/authorize HTTP/1.1

Host: 10.35.210.133

Connection: close

Content-Type: application/json;charset=UTF-8

Content-Length: 652

 

{

"mac": "2C:F0:5D:44:6F:8B|02:00:4C:4F:4F:50",

"signature": "07d3ae5ea480de187c2ca0f77742e3ce",

"userName": "system",

"randomKey": "8011f60ea78547ee",

"publicKey": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA156uLLwO6FzulZtt7KxJDV2P2BKNptc++1RLaM09uhPjDfYcwHrG5jvZLfJRbU0lg/rT0XqBdUcYiUfivJID4jINXEAkJ4S9f28cXv9AUJctud/6cY9Hmi1O6LCbaoENhUdKiI57uRG68X8fABcMWODa4Pj/2Zudj6Q7o8osDh5OK8HjG5gO8ZiNHH3M7mzsa8SpUUAza+A9QJxS5fQ5RuKW3IvCjYgdP8Ka2vLOgwBMAradJRl8vAa9l0E0s6wTDJCszK/Kgzb1sXeFryaPoOSyZGvXGeNeYc5+hxJSFkuyK5ILPYo86dDUBGlQIBukKuyzK17cngpFToWb5ELE0QIDAQAB",

"encryptType": "MD5",

"ipAddress": "",

"clientType": "WINPC_V1",

"userType": "0"

}

请求参数

image.png


返回数据示例

{

"duration": 30,

"token": "9b3ddf2993e34f15acd7f870784617ad",

"userId": "1",

"versionInfo": {

"lastVersion": "26007",

"updateUrl": "/client/x86/General_DAEDSS-MobileCenter_Client-x86_V2.001.0000001.0.R.20210819.exe;/client/x64/General_DAEDSS-MobileCenter_Client-x64_V2.001.0000001.0.R.20210819.exe"

},

"tokenRate": 1800,

"secretKey": "h76Ori5QieFD0ijbKIiC4zNj+3d6JOAjIotCO/Uq51HXi+Z2oFaIhFbwHYjKjZYNhhB4cH6OHsChKziksrD3kyhw5mCzl2ZkrH8qY/DC+u1k69mdTkq2Zj/CKhYgoSpRedltIMI/ZTfumqTHT3vIwgJEzijhacETycqydMyVdqTSv6dDLI4kd5CHM51mc9zGE8zcQp2Tm53z6yLQgVTFHn21bYJWMaGynKuH036m69kQMUaPu4tOAt/VzjZTq+H/rHyoRlCcVSKaun/i08CZvXyPUDr0zdsq0Y3Ar5fqbvTEOmv5Fqwp3EbDZKGiSA/UlHkrtopbLeB38Am/b6pCZg==",

"secretVector": "hMqJus90nrYI1LKdujTa387LEl0s61DvD0zdmTpoQvHKyE463ThqFnWiAJ2TCpIQCGsAuhXsl7Zcqfd+1hqumgZU6phhfR0VGnYow+m2PR9MX2Rj4ZvSpCwQy/sDy5VaxhyCWnYFMFKLeP6rOOhoSQoxVaMKGF9FywHCCqSRr1HgImSNDKOaUdGwq1IEe1sLfW0/DOUNfA3ZK//9mozlZ0plAxR5YTbQ0Z6NEg/5vGz7oyaj7Ajb+X8ax+762szmNA696kCoHGGTRe8NGxyzCKhgkZ8FOKiGoyWR7sBuY2ZYKekCVVMqbdsUB39rBtqAerxiSOA0Tr1vu3CuRTVE+A==",

"reused": "1"

}

返回参数

image.png



demo

import requests
import json
import hashlib
ip="https://平台ip:端口/"
username="平台用户名"
passwd="平台密码"

import types
def getmd5(data):
    m = hashlib.md5()
    m.update(data.encode())
    return m.hexdigest()
def first():
    data1={
	"userName":username,
	"ipAddress":"",  #无所谓
	"clientType":"WINPC_V1"  #无所谓
    }
    headers={
    'Server': 'openresty',
    'Date': 'Fri, 01 Jul 2022 09:30:41 GMT', 
    'Content-Type': 'text/html;charset=UTF-8',
    'Transfer-Encoding': 'chunked',
    'Connection': 'keep-alive',
    'Set-Cookie': 'JSESSIONID=D05889B64730C3DEFDEE627D115DB4D9; Path=/admin; Secure; HttpOnly',
    'X-Frame-Options': 'SAMEORIGIN',
    'Pragma':'no-cache',
    'Cache-Control': 'no-cache',
    'Expires': 'Thu, 01 Dec 1994 16:00:00 GMT',
    'Content-Language': 'zh-CN'
    }
    print(data1)
    r=json.loads(requests.post(ip+"admin/API/accounts/authorize",json=data1,verify=False).text)   #没有证书,又要使用https,因此所有请求需要加入verify=False
    return r['realm'],r['randomKey'],r['encryptType'],r['publickey']
def second(signature,realm,randomKey,encryptType,publickey):
    data={
    "mac":"2C:F0:5D:44:6F:8B|02:00:4C:4F:4F:50",  #无所谓
    "signature":signature,
    "userName":	username,
    "randomKey":randomKey,
    "publicKey":publickey,
    "encryptType":	encryptType,
    "ipAddress":	"",
    "clientType":	"WINPC_V1",  #无所谓
    "userType":	"0"
    }
    r=json.loads(requests.post(ip+"admin/API/accounts/authorize",json=data,verify=False).text)
    return r['duration'],r['token'],r['userId'],r['versionInfo'],r['secretKey'],r['secretVector']
def getgps(token):
    headers={
    "X-Subject-Token":token
    }
    data={
    "capTimeStrStart": "2022-07-01 00:00:00",
    "capTimeStrEnd": "2022-09-15 23:59:59",
    "plateNo": "浙E000000",
    "page": 1,
    "pageSize": 20
    }
    r=json.loads(requests.post(ip+"/vehicleServer/api/getGpsDetailInfo?nowTime=1631711885503",json=data,headers=headers,verify=False).text)
    return r
realm,randomKey,encryptType,publickey=first()
print(realm,randomKey,encryptType,publickey)

temp = getmd5(passwd)
temp = getmd5(username + temp)
temp = getmd5(temp)
temp = getmd5(username + ":" + realm + ":" + temp)
signature = getmd5(temp + ":" + randomKey)
print("\n\n")
print(signature)
duration,token,userId,versionInfo,secretKey,secretVector=second(signature,realm,randomKey,encryptType,publickey)
print(duration,token,userId,versionInfo,secretKey,secretVector)
print("轨迹:"+str(getgps(token)))


first函数进行第一次鉴权并获得 realm,randomKey,encryptType,publickey,进而计算出signature,并由second函数二次鉴权后获得token,最后getgps调用了一个GPS轨迹获取接口检测权限有效性


运行结果

image.png


发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。