kbmmw 做REST 服务签名认证的一种方式
一般对外提供提供REST 服务,由于信息安全的问题, 都要采用签名认证,今天简单说一下在KBMMW 中如何
实现简单的签名服务?
整个签名服务,模仿阿里大鱼的认证方式,大家可以根据实际情况自己修改。
没有太多的解释,直接上马
[kbmMW_Rest('method:get, path:getwithcheck')]
[kbmMW_Method]
function getwithcheck(
[kbmMW_Rest('value: "$p1", required: true')] const p1:string;
[kbmMW_Rest('value: "$p2", required: true')] const p2:string;
[kbmMW_Rest('value: "$p3", required: true')] const p3:string;
[kbmMW_Rest('value: "$AccessKeyId", required: true')] const AccessKeyId:string;
[kbmMW_Rest('value: "$Timestamp", required: true')] const Timestamp:string;
[kbmMW_Rest('value: "$Action", required: true')] const Action:string;
[kbmMW_Rest('value: "$Signature", required: true')] const Signature:string):string;
end;
const
AppSecret='sdjhidbTdlfdsj133edyeR';
appkey='xaliontestok';
function MakeSign(const AParams: TStringList; const AppSecret: string): string;
implementation
uses kbmMWExceptions, mainp;
{$R *.dfm}
function specialUrlEncode(const sStr:string):string;
begin
// URLEncode后再增加三种字符替换:加号(+)替换成 %20、星号(*)替换成 %2A、%7E 替换回波浪号(~)
Result :=TNetEncoding.URL.EncodeForm(sStr);
Result.Replace('+','%20').Replace('*','%2A').Replace('%7E','~');
end;
function MakeSign(const AParams: TStringList; const AppSecret: string): string;
var
I: Integer;
sortedQueryString :string;
stringToSign: string;
sSign :string;
outs: TStringList;
pn,pv:string;
skey:Tbytes;
begin
outs:= AParams;
outs.UseLocale:=True;
outs.Sort;
// 参数拼接
sortedQueryString:= '';
for I := to outs.Count - do
begin
pn:=specialUrlEncode(outs.Names[I]);
pv:=specialUrlEncode(outs.Values[outs.Names[I]]);
sortedQueryString:= sortedQueryString +pn + '='+ pv+'&';
end;
setlength(sortedQueryString,length(sortedQueryString)-);
stringToSign :='GET&%2F&' + specialUrlEncode(sortedQueryString);
skey:=THashSHA1.GetHMACAsBytes(Tencoding.UTF8.GetBytes(stringToSign), Tencoding.UTF8.GetBytes(AppSecret+'&'));
sSign := TBase64Encoding.Create.EncodeBytesToString(skey);
Result :=specialUrlEncode(sSign);
end;
function TkbmMWCustomHTTPSmartService1.getwithcheck(const p1, p2, p3,
AccessKeyId, Timestamp, Action, Signature: string): string;
var
inputp:Tstringlist;
inputsign:string;
begin
inputp:=Tstringlist.Create;
inputp.Values['P1']:=p1;
inputp.Values['P2']:=p2;
inputp.Values['P3']:=p3;
inputp.Values['AccessKeyId']:=AccessKeyId;
inputp.Values['Timestamp']:=Timestamp;
inputp.Values['Action']:=Action;
// inputp.Values['Signature']=Signature;
inputsign:= MakeSign(inputp,AppSecret);
if inputsign<>specialUrlEncode(Signature) then
begin
Result:='{result:{"ok":"error","value":"sign error"}}';
exit;
end;
if appkey<>AccessKeyId then
begin
Result:='{result:{"ok":"error","value":"can not find appkey"}}';
exit;
end;
Result:='{"result":{"ok":"ok","value":"'+Action+'"}}';;
end;
客户端也很简单
function TForm1.SendSMS(const AppKey, AppSecret, ReceiveNumber, FreeSignName,
TemplateCode, TemplateContent: string; var ResultMsg: string): Boolean; function specialUrlEncode(const sStr:string):string;
begin
// URLEncode后再增加三种字符替换:加号(+)替换成 %20、星号(*)替换成 %2A、%7E 替换回波浪号(~) Result :=TNetEncoding.URL.EncodeForm(sStr);
Result.Replace('+','%20').Replace('*','%2A').Replace('%7E','~');
end; function MakeSign(const AParams: TStringList; const AppSecret: string;var sortQueryStringTmp :String): string;
var
I: Integer;
sortedQueryString :string;
stringToSign: string;
sSign :string;
outs: TStringList; pn,pv:string; skey:Tbytes;
begin outs:= AParams;
outs.UseLocale:=True;
outs.Sort; //SortString( AParams,outs); // 参数拼接
sortQueryStringTmp := ''; for I := to outs.Count - do
begin pn:=specialUrlEncode(outs.Names[I]); pv:=specialUrlEncode(outs.Values[outs.Names[I]]); sortQueryStringTmp := sortQueryStringTmp +pn + '='+ pv+'&'; end;
setlength(sortQueryStringTmp,length(sortQueryStringTmp)-);
sortedQueryString:=sortQueryStringTmp; stringToSign :='GET&%2F&' + specialUrlEncode(sortedQueryString); skey:=THashSHA1.GetHMACAsBytes(Tencoding.UTF8.GetBytes(stringToSign), Tencoding.UTF8.GetBytes(AppSecret+'&')); sSign := TBase64Encoding.Create.EncodeBytesToString(skey);
Result :=specialUrlEncode(sSign); end; var
HTTP: TNetHTTPClient;
JO: TJSONObject;
Params: TStringList;
Response: string;
code:TGUID;
sortQueryStringTmp :string;
signature :string;
sURL :string; ResponseStr: TStringStream; begin
Result := False; CreateGUID(code);
HTTP := TNetHTTPClient.Create(nil);
Params := TStringList.Create();
ResponseStr :=TStringStream.Create('', TEncoding.ASCII);//中文用UTF8
try
//;
//
//请求参数中不允许出现以Signature为key的参数。参考代码如下```
//String accessKeyId = “testId”;String accessSecret = “testSecret”;
//java.text.SimpleDateFormat df = new java.text.SimpleDateFormat(“yyyy-MM-dd’T’HH:mm:ss’Z’”);
//df.setTimeZone(new java.util.SimpleTimeZone(0, “GMT”));// 这里一定要设置GMT时区
//
//java.util.Map paras = new java.util.HashMap();
//// 1. 系统参数
//paras.put(“SignatureMethod”, “HMAC-SHA1”);
//paras.put(“SignatureNonce”, java.util.UUID.randomUUID().toString());
//paras.put(“AccessKeyId”, accessKeyId);
//paras.put(“SignatureVersion”, “1.0”);
//paras.put(“Timestamp”, df.format(new java.util.Date()));
//paras.put(“Format”, “XML”);
//
//// 2. 业务API参数
//paras.put(“Action”, “SendSms”);
//paras.put(“Version”, “2017-05-25”);
//paras.put(“RegionId”, “cn-hangzhou”);
//paras.put(“PhoneNumbers”, “15300000001”);
//paras.put(“SignName”, “阿里云短信测试专用”);
//paras.put(“TemplateParam”, “{\”customer\”:\”test\”}”);
//paras.put(“TemplateCode”, “SMS_71390007”);
//paras.put(“OutId”, “123”); Params.Values['P2'] := 'HMAC-SHA1';
Params.Values['P3'] := GUIDToString(code);
Params.Values['AccessKeyId'] := AppKey;
Params.Values['P1'] := '1.0';
// Params.Values['Timestamp'] := FormatDateTime('yyyy-mm-dd hh:mm:ss', now - 1/3);
Params.Values['Timestamp'] := FormatDateTime('yyyy-MM-dd''T''HH:mm:ss''Z''', now-/);
// Params.Values['Format'] := 'JSON';
Params.Values['Action'] := 'SendSms';
// Params.Values['Version'] := '2017-05-25';
// Params.Values['RegionId'] := 'cn-hangzhou';
//Params.Values['PhoneNumbers'] := ReceiveNumber; // Params.Values['SignName'] := FreeSignName; // Params.Values['TemplateParam'] := TemplateContent;
// Params.Values['TemplateCode'] := TemplateCode; signature:=MakeSign(Params,AppSecret,sortQueryStringTmp); sURL := 'http://127.0.0.1/xalionrest/getwithcheck?signature='+signature+'&'+sortQueryStringTmp;
Memo1.Lines.Text :=sURL; try resultmsg:=http.Get(sURL).ContentAsString ; Memo2.Lines.add( resultmsg); except
on E: Exception do
begin
ResultMsg := E.Message;
Exit;
end;
end; finally
HTTP.Free;
Params.Free;
ResponseStr.Free;
end; end;
运行结果,有图有真相

打完收工。
kbmmw 做REST 服务签名认证的一种方式的更多相关文章
- api接口签名认证的一种方式
请求方 try { using (var client = new HttpClient()) { StringContent content = new StringContent(strParam ...
- Android Studio签名打包的两种方式
签名打包的两种方式: 注:给我们自己开发的app签名,就代表着我自己的版权,以后要进行升级,也必须要使用相同的签名才行.签名就代表着自己的身份(即keystore),多个app可以使用同一个签名. 如 ...
- XFire构建服务端Service的两种方式(转)
XFire构建服务端service的两种方式,一是用xfire构建,二是和spring集成构建. 一,xifre构建,确保把xfire的jar包导入到工程中或classpath. 1,service的 ...
- XFire构建服务端Service的两种方式
1.原声构建: 2.集成spring构建 http://blog.csdn.net/carefree31441/article/details/4000436XFire构建服务端Service的两种方 ...
- 在Spring-Boot中实现通用Auth认证的几种方式
code[class*="language-"], pre[class*="language-"] { background-color: #fdfdfd; - ...
- Android: Android Studio签名打包的两种方式(zz)
注:给我们自己开发的app签名,就代表着我自己的版权,以后要进行升级,也必须要使用相同的签名才行.签名就代表着自己的身份(即keystore),多个app可以使用同一个签名. 如果不知道签名是啥意思, ...
- android studio学习---签名打包的两种方式
注:给我们自己开发的app签名,就代表着我自己的版权,以后要进行升级,也必须要使用相同的签名才行.签名就代表着自己的身份(即keystore),多个app可以使用同一个签名. 如果不知道签名是啥意思, ...
- EasyDarwin实现RTSP播放动态认证的两种方式:Basic/Digest & Token
问题描述 目前为了能够方便开发者,我们将EasyDarwin中的RTSP认证过程直接忽略过了,如果要开启认证的方式,我们可以在代码中打开: case kRoutingRequest: { // Inv ...
- SpringCloud服务消费有哪几种方式?
一.使用LoadBalancerClient LoadBalancerClient接口的命名中,可以看出这是一个负载均衡客户端的抽象定义,spring提供了一个实现 org.springframewo ...
随机推荐
- 在 iOS 上通过 802.11k、802.11r 和 802.11v 实现 Wi-Fi 网络漫游
原文: https://support.apple.com/zh-cn/HT202628 了解 iOS 如何使用 Wi-Fi 网络标准提升客户端漫游性能. iOS 支持在企业级 Wi-Fi 网络上 ...
- autocomplete input
<html> <head> <title>jQuery UI Autocomplete - Combobox</title> <link rel= ...
- Java内存泄漏的几种可能
Java内存泄漏引起的原因: 内存泄漏是指无用对象(不再使用的对象)持续占有内存或无用对象的内存得不到及时释放,从而造成内存空间的浪费称为内存泄漏. 长生命周期的对象持有短生命周期对象的引用就很可能发 ...
- 先 FROM 后 WHERE 再 GROUP BY 再 SELECT 再 order BY
shutdown -r -t 5office:515740906family-asus:786512915office-T420i:837829568 family-T420:868 638 325 ...
- SpringBoot 之 thymeleaf
thymeleaf 的maven 配置我们都知道: <dependency> <groupId>org.springframework.boot</groupId> ...
- 拼接html
var html='<tbody>\ <tr class="print-tr-top">\ <td width="50%" col ...
- java判断是否是数字
1.用JAVA自带的函数 public static boolean isNumeric(String str){ for (int i = 0; i < str.length(); i++){ ...
- vuejs如何在服务器部署
title: vuejs如何在服务器部署 date: 2017-10-31 20:41:03 tags: [vue] --- 上传到网站服务器 Vue 是一个 javascript 的前端框架,它是运 ...
- Resttemplate中设置超时时长方法
为了满足调用需求,需要在使用Resttemplate发送请求时,修改超时时长,网上给出了相关修改方法,代码如下: HttpComponentsClientHttpRequestFactory rf = ...
- layer.js 中弹框显示不全的问题
在使用 layer.js 做弹框的时候,遇到在浏览器缩小时,弹框显示不全的问题,如下: 这是不行的,因为我们有的时候想缩小浏览器视窗,但是一旦缩小到一定程度,就会把弹窗的关闭按钮遮住一部分,并且主体弹 ...