七牛回调验证(java,php源码)

来源:互联网 发布:php cookie存储目录 编辑:程序博客网 时间:2024/06/01 16:55

1,七牛的客户可以对七牛回调过来的信息做验证。防止其他网站的信息冒充七牛。

2,安全性

*由于回调地址是公网可任意访问的,回调服务如何确认一次回调是合法的呢?
七牛云存储在回调时会对请求数据签名,并将结果包含在请求头Authorization字段中,示例如下:
Authorization:QBox iN7NgwM31j4-BZacMjPrOQBs34UG1maYCAQmhdCV:tDK-3f5xF3SJYEAwsll5g=
其中QBox为固定值,iN7Ngw…dCV为用户的Accesskey,tDK-3f…5g=为签名结果(encoded_data)
回调服务器可以通过以下方法验证其合法性:
获取AUTHORIZATION字段值中的签名结果部分encoded_data
根据Accesskey选取正确的SecretKey
获取明文:data = Request.URL.Path +”\n” +Request.Body
部分语言或框架无法直接获取请求body的原始数据,在自行拼接时应当注意,body中的数据是经过URL编码的
采用HMAC-SHA1签名算法,对明文data签名,秘钥为SecretKey,比较签名结果是否与Authorization中的encoded_data字段相同,如相同则表明这是一个合法的回调请求
以PHP语言为示例,验证代码如下:*

/***C('accessKey')取得 AccessKey*C('secretKey')取得 SecretKey  *callback.php 为回调地址的Path部分  *file_get_contents('php://input')获取RequestBody,其值形如:  *name=sunflower.jpg&hash=Fn6qeQi4VDLQ347NiRm-RlQx_4O2\*&location=Shanghai&price=1500.00&uid=123*/function IsQiniuCallback(){    $authstr = $_SERVER['HTTP_AUTHORIZATION'];    if(strpos($authstr,"QBox ")!=0){        return false;    }    $auth = explode(":",substr($authstr,5));    if(sizeof($auth)!=2||$auth[0]!=C('accessKey')){        return false;    }    $data = "/callback.php\n".file_get_contents('php://input');    return URLSafeBase64Encode(hash_hmac('sha1',$data,C("secretKey"), true)) == $auth[1];}

注意:如果回调数据包含用户的敏感数据,建议回调地址使用HTTPS协议

3,java源码

package com.qiniu.isValidCallback;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.io.PrintWriter;import javax.servlet.ServletContext;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import com.qiniu.util.Auth;import com.qiniu.util.StringUtils;public class IsValidCallback extends HttpServlet {    /**     * The doGet method of the servlet. <br>     *     * This method is called when a form has its tag value method equals to get.     *      * @param request the request send by the client to the server     * @param response the response send by the server to the client     * @throws ServletException if an error occurred     * @throws IOException if an error occurred     */    public void doGet(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {        String ak = "****";        String sk = "****";        Auth auth = Auth.create(ak,sk);             ServletContext context = getServletContext( );          String charset = request.getCharacterEncoding();                String Authorization = request.getHeader("Authorization");        String contentType = request.getHeader("Content-Type");                     String line = "";        BufferedReader br = new BufferedReader(new InputStreamReader(request.getInputStream()));        StringBuilder sb = new StringBuilder();        while ((line = br.readLine()) != null) {            sb.append(line);        }                       String url = "https://14190f2ca55e.b.passageway.io/IsValidCallback/servlet/IsValidCallback";        boolean check = false;         check= auth.isValidCallback(Authorization,url,StringUtils.utf8Bytes(sb.toString()),contentType);        String authorization2 = "QBox " + auth.signRequest(url, StringUtils.utf8Bytes(sb.toString()), contentType);        context.setAttribute("Authorization", Authorization);        context.setAttribute("Authorization", Authorization);        context.setAttribute("authorization2", authorization2);        context.setAttribute("body", sb.toString());        context.setAttribute("contentType", contentType);                           if(check){            context.log("签名通过    ok!");            context.setAttribute("check", "签名通过   ok");        }else{            context.log("No ok!");            context.setAttribute("check", "no ok");        }               response.setContentType("application/json");        response.setCharacterEncoding("utf-8");                String out = "{\"success\":\"ok\",\"name\":\"test1\"}";        response.getOutputStream().print(out);;    }    /**     * The doPost method of the servlet. <br>     *     * This method is called when a form has its tag value method equals to post.     *      * @param request the request send by the client to the server     * @param response the response send by the server to the client     * @throws ServletException if an error occurred     * @throws IOException if an error occurred     */    public void doPost(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {        doGet(request, response);    }}
0 0
原创粉丝点击