java Authorization HMAC-SHA256 OAuth2.0身份认证接口访问

项目已经正常跑的代码

常量定义

/**
 * NS全局常量定义
 *
 * @author zhangbs
 * @version 2021-05-28
 */
public class NsConstant {
    public final static String URL = "xxxx";
    public final static String REALM = "xxx";
    public final static String ACCESS_TOKEN = "xxx";
    public final static String TOKEN_SECRET = "xxx";
    public final static String CONSUMER_KEY = "xxx";
    public final static String CONSUMER_SECRET = "xxx";
    public final static String SUCCESS_OK = "200";
}

请求工具类

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import xxx.MapUtils;
import xxx.DateUtils;
import xxx.StringUtils;
import xxx.NsAuthInfo;
import xxx.EipDateUtils;
import org.apache.commons.codec.binary.Base64;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * NS请求工具类
 *
 * @author zhangbs
 * @version 2021-05-28
 */
public class NsRequestUtils {


    /**
     * 发送请求并返回响应结果
     *
     * @param url           请求url
     * @param requestMethod 请求方式
     * @param paramsMap     参数
     * @param authInfo      认证信息
     * @return 请求响应结果
     */
    public static Map<String, Object> executeRequest(String url, String requestMethod, Map<String, Object> paramsMap, NsAuthInfo authInfo) {
        Map<String, Object> resultMap = MapUtils.newHashMap();
        try {
            String authorization = NsRequestUtils.constructAuthHeader(authInfo, requestMethod);

            CloseableHttpClient httpClient = HttpClientBuilder.create().build();
            HttpPost httpPost = new HttpPost(url);
            httpPost.setHeader("Content-Type", "application/json");
            httpPost.setHeader("Accept", "*/*");
            httpPost.setHeader("Authorization", authorization);

            String jsonParams = JSON.toJSONString(paramsMap);
            HttpEntity entityParam = new StringEntity(jsonParams, ContentType.create("application/json", "UTF-8"));
            httpPost.setEntity(entityParam);
            HttpResponse response = httpClient.execute(httpPost);

            // 状态码
            resultMap.put("code", response.getStatusLine().getStatusCode() + "");
            // 返回结果
            resultMap.put("result", EntityUtils.toString(response.getEntity(), "utf-8"));
        } catch (Exception e) {
            resultMap.put("code", "400");
        }

        return resultMap;
    }

    /**
     * 生成签名并组合Authorization头
     * 如"/", 编码后为: %2F
     *
     * @return 编码后的字符串
     */
    public static String constructAuthHeader(NsAuthInfo auth, String method) throws Exception {
        // 基础信息
        String url = auth.getUrl();
        // 时间戳
        long timestamp = new Date().getTime() / 1000;
        // 转成大写
        method = method.toUpperCase();
        // 签名方法
        String signatureMethod = "HMAC-SHA256", signatureMethodCode = "HmacSHA256";
        // 基础信息
        String accessToken = auth.getAccessToken(), tokenSecret = auth.getTokenSecret(),
                consumerKey = auth.getConsumerKey(), consumerSecret = auth.getConsumerSecret(),
                realm = auth.getRealm(), nonce = StringUtils.getRandomStr(32);
        // 组合Key
        String key = consumerSecret + '&' + tokenSecret;
        // 截取问号前的URL
        String encodeURL = url.split("\\?")[0];

        // 获取URL参数
        Map<String, String> parameters = urlSplit(url);
        parameters.put("oauth_consumer_key", consumerKey);
        parameters.put("oauth_nonce", nonce);
        parameters.put("oauth_signature_method", signatureMethod);
        parameters.put("oauth_timestamp", String.valueOf(timestamp));
        parameters.put("oauth_token", accessToken);
        parameters.put("oauth_version", "1.0");
        String parameterString = sortAndConcat(parameters);
        // 组合待签字符串
        StringBuilder signatureBaseString = new StringBuilder(100);
        signatureBaseString.append(method.toUpperCase());
        signatureBaseString.append('&');
        signatureBaseString.append(urlEncode(encodeURL));
        signatureBaseString.append('&');
        signatureBaseString.append(urlEncode(parameterString));
        // 转换成String类型
        String signatureString = signatureBaseString.toString();
        // 生成签名
        byte[] bytesToSign = signatureString.getBytes("UTF-8");
        byte[] keyBytes = key.getBytes("UTF-8");
        SecretKeySpec signingKey = new SecretKeySpec(keyBytes, signatureMethodCode);
        Mac mac = Mac.getInstance(signatureMethodCode);
        mac.init(signingKey);
        byte[] signedBytes = mac.doFinal(bytesToSign);
        String signature = urlEncode(new String(Base64.encodeBase64(signedBytes, false)));

        return new StringBuilder().append("OAuth ")
                .append("realm").append("=\"").append(realm)
                .append("\",").append("oauth_consumer_key").append("=\"").append(consumerKey)
                .append("\",").append("oauth_token").append("=\"").append(accessToken)
                .append("\",").append("oauth_signature_method").append("=\"").append(signatureMethod)
                .append("\",").append("oauth_timestamp").append("=\"").append(timestamp)
                .append("\",").append("oauth_nonce").append("=\"").append(nonce)
                .append("\",").append("oauth_version").append("=\"").append("1.0")
                .append("\",").append("oauth_signature").append("=\"").append(signature)
                .append("\"").toString();
    }


    /**
     * 返回参数double的空处理
     *
     * @param jsonObject json对象
     * @param key
     * @return
     */
    public static Double killNullDouble(JSONObject jsonObject, String key) {
        Double result = jsonObject.getDouble(key);
        return result == null ? 0.0D : result;
    }

    /**
     * 获取加上指定月份的开始日期 格式yyyy/MM/dd
     *
     * @param month
     * @return
     */
    public static String getStartDate(int month, String append) {
        Date monthAdd = DateUtils.addMonths(new Date(), month);
        String yearMonth = DateUtils.formatDate(monthAdd, "yyyy/MM");
        return yearMonth + append;
    }

    /**
     * 获取加上指定月份的结束日期 格式yyyy/MM/dd
     *
     * @param month
     * @return
     */
    public static String getEndDate(int month) {
        if (month < 0) {
            Date monthAdd = DateUtils.addMonths(new Date(), month);
            String yearMonth = DateUtils.formatDate(monthAdd, "yyyy/MM");
            return yearMonth + "/" + EipDateUtils.getMonthHasDays(monthAdd);
        } else {
            return DateUtils.formatDate(new Date(), "yyyy/MM/dd");
        }
    }

    /**
     * 解析出url参数中的键值对
     * 如 "restlet.nl?script=248&deploy=1",解析出script:24,deploy:1存入map中
     *
     * @param URL url地址
     * @return url请求参数部分
     */
    public static Map<String, String> urlSplit(String URL) {
        Map<String, String> mapRequest = new HashMap<String, String>();
        String[] arrSplit = null;
        String strUrlParam = TruncateUrlPage(URL);
        if (strUrlParam == null) {
            return mapRequest;
        }
        arrSplit = strUrlParam.split("[&]");
        for (String strSplit : arrSplit) {
            String[] arrSplitEqual = null;
            arrSplitEqual = strSplit.split("[=]");
            //解析出键值
            if (arrSplitEqual.length > 1) {
                //正确解析
                mapRequest.put(arrSplitEqual[0], arrSplitEqual[1]);
            } else {
                if (arrSplitEqual[0] != "") {
                    //只有参数没有值,不加入
                    mapRequest.put(arrSplitEqual[0], "");
                }
            }
        }
        return mapRequest;
    }

    /**
     * 去掉url中的路径,留下请求参数部分
     *
     * @param strURL url地址
     * @return url请求参数部分
     */
    private static String TruncateUrlPage(String strURL) {
        String strAllParam = null;
        String[] arrSplit = null;
        strURL = strURL.trim().toLowerCase();
        arrSplit = strURL.split("[?]");
        if (strURL.length() > 1) {
            if (arrSplit.length > 1) {
                for (int i = 1; i < arrSplit.length; i++) {
                    strAllParam = arrSplit[i];
                }
            }
        }
        return strAllParam;
    }


    /**
     * 对URL参数进行排序
     * 如"script:248,deploy:1", 排序后deploy=1&script=248
     *
     * @param parameters 参数的键值对
     * @return 排序后的字符串
     */
    private static String sortAndConcat(Map<String, String> parameters) {
        StringBuilder encodedParams = new StringBuilder(100);
        Object[] arr = parameters.keySet().toArray();
        Arrays.sort(arr);
        for (Object key : arr) {
            if (encodedParams.length() > 0) {
                encodedParams.append('&');
            }
            encodedParams.append(key).append('=').append(parameters.get(key));
        }
        return encodedParams.toString();
    }

    /**
     * 对字符串进行URL编码
     * 如"/", 编码后为: %2F
     *
     * @param str 传入字符串
     * @return 编码后的字符串
     */
    private static String urlEncode(String str) {
        try {
            return URLEncoder.encode(str, "UTF-8")
                    .replace("+", "%20")
                    .replace("*", "%2A")
                    .replace("%7E", "~");
        } catch (UnsupportedEncodingException e) {
            throw new IllegalArgumentException(e);
        }
    }

认证参数信息


/**
 * NS认证信息
 *
 * @author zhangbs
 * @version 2021-05-28
 */
public class NsAuthInfo {

    public NsAuthInfo(String realm, String url, String accessToken, String tokenSecret, String consumerKey, String consumerSecret) {
        setRealm(realm);
        setUrl(url);
        setAccessToken(accessToken);
        setTokenSecret(tokenSecret);
        setConsumerKey(consumerKey);
        setConsumerSecret(consumerSecret);
    }

    private String url;
    private String accessToken;
    private String tokenSecret;
    private String consumerKey;
    private String consumerSecret;
    private String realm;

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public String getAccessToken() {
        return accessToken;
    }

    public void setAccessToken(String accessToken) {
        this.accessToken = accessToken;
    }

    public String getTokenSecret() {
        return tokenSecret;
    }

    public void setTokenSecret(String tokenSecret) {
        this.tokenSecret = tokenSecret;
    }

    public String getConsumerKey() {
        return consumerKey;
    }

    public void setConsumerKey(String consumerKey) {
        this.consumerKey = consumerKey;
    }

    public String getConsumerSecret() {
        return consumerSecret;
    }

    public void setConsumerSecret(String consumerSecret) {
        this.consumerSecret = consumerSecret;
    }

    public String getRealm() {
        return realm;
    }

    public void setRealm(String realm) {
        this.realm = realm;
    }

请求参考

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import xxx.NsAuthInfo;
import xxx.NsConstant;
import xxx.NsRequestUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.Map;
    /**
     * 执行定时任务(默认跑昨天至今天的数据)
     */
    public void execute(String systemCode, String date) {
        // 参数放置
        Map<String, Object> paramsMap = MapUtils.newHashMap();
        String startDate = StringUtils.isNotEmpty(date) ? date : DateUtils.formatDate(DateUtils.addDays(new Date(), -1), "yyyy/MM/dd");
        String endDate = StringUtils.isNotEmpty(date) ? date : DateUtils.formatDate(DateUtils.addDays(new Date(), -0), "yyyy/MM/dd");

        paramsMap.put("startDate", startDate);
        paramsMap.put("endtDate", endDate);
        paramsMap.put("subsidiary", systemCode);

        String url = NsConstant.URL + "&script=701";
        // 构建认证信息
        NsAuthInfo authInfo = new NsAuthInfo(NsConstant.REALM, url, NsConstant.ACCESS_TOKEN, NsConstant.TOKEN_SECRET,
                NsConstant.CONSUMER_KEY, NsConstant.CONSUMER_SECRET);

        Map<String, Object> result = NsRequestUtils.executeRequest(url, "POST", paramsMap, authInfo);

        // 构建保存信息
        if (NsConstant.SUCCESS_OK.equals(result.get("code"))) {
            // 做业务处理
        }
    }

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容