java Authorization HMAC-SHA256 OAuth2.0身份認證接口訪問

項目已經(jīng)正常跑的代碼

常量定義

/**
 * 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 {


    /**
     * 發(fā)送請求并返回響應(yīng)結(jié)果
     *
     * @param url           請求url
     * @param requestMethod 請求方式
     * @param paramsMap     參數(shù)
     * @param authInfo      認證信息
     * @return 請求響應(yīng)結(jié)果
     */
    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);

            // 狀態(tài)碼
            resultMap.put("code", response.getStatusLine().getStatusCode() + "");
            // 返回結(jié)果
            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 {
        // 基礎(chǔ)信息
        String url = auth.getUrl();
        // 時間戳
        long timestamp = new Date().getTime() / 1000;
        // 轉(zhuǎn)成大寫
        method = method.toUpperCase();
        // 簽名方法
        String signatureMethod = "HMAC-SHA256", signatureMethodCode = "HmacSHA256";
        // 基礎(chǔ)信息
        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參數(shù)
        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));
        // 轉(zhuǎn)換成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();
    }


    /**
     * 返回參數(shù)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;
    }

    /**
     * 獲取加上指定月份的開始日期 格式y(tǒng)yyy/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;
    }

    /**
     * 獲取加上指定月份的結(jié)束日期 格式y(tǒng)yyy/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參數(shù)中的鍵值對
     * 如 "restlet.nl?script=248&deploy=1",解析出script:24,deploy:1存入map中
     *
     * @param URL url地址
     * @return url請求參數(shù)部分
     */
    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] != "") {
                    //只有參數(shù)沒有值,不加入
                    mapRequest.put(arrSplitEqual[0], "");
                }
            }
        }
        return mapRequest;
    }

    /**
     * 去掉url中的路徑,留下請求參數(shù)部分
     *
     * @param strURL url地址
     * @return url請求參數(shù)部分
     */
    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參數(shù)進行排序
     * 如"script:248,deploy:1", 排序后deploy=1&script=248
     *
     * @param parameters 參數(shù)的鍵值對
     * @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);
        }
    }

認證參數(shù)信息


/**
 * 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;
    /**
     * 執(zhí)行定時任務(wù)(默認跑昨天至今天的數(shù)據(jù))
     */
    public void execute(String systemCode, String date) {
        // 參數(shù)放置
        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";
        // 構(gòu)建認證信息
        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);

        // 構(gòu)建保存信息
        if (NsConstant.SUCCESS_OK.equals(result.get("code"))) {
            // 做業(yè)務(wù)處理
        }
    }

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末荆陆,一起剝皮案震驚了整個濱河市烈炭,隨后出現(xiàn)的幾起案子亡呵,更是在濱河造成了極大的恐慌,老刑警劉巖抚芦,帶你破解...
    沈念sama閱讀 221,430評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件率拒,死亡現(xiàn)場離奇詭異崩泡,居然都是意外死亡,警方通過查閱死者的電腦和手機俏橘,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,406評論 3 398
  • 文/潘曉璐 我一進店門允华,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人寥掐,你說我怎么就攤上這事×资瘢” “怎么了召耘?”我有些...
    開封第一講書人閱讀 167,834評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長褐隆。 經(jīng)常有香客問我污它,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,543評論 1 296
  • 正文 為了忘掉前任衫贬,我火速辦了婚禮德澈,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘固惯。我一直安慰自己梆造,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 68,547評論 6 397
  • 文/花漫 我一把揭開白布葬毫。 她就那樣靜靜地躺著镇辉,像睡著了一般。 火紅的嫁衣襯著肌膚如雪贴捡。 梳的紋絲不亂的頭發(fā)上忽肛,一...
    開封第一講書人閱讀 52,196評論 1 308
  • 那天,我揣著相機與錄音烂斋,去河邊找鬼屹逛。 笑死,一個胖子當(dāng)著我的面吹牛汛骂,可吹牛的內(nèi)容都是我干的煎源。 我是一名探鬼主播,決...
    沈念sama閱讀 40,776評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼香缺,長吁一口氣:“原來是場噩夢啊……” “哼手销!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起图张,我...
    開封第一講書人閱讀 39,671評論 0 276
  • 序言:老撾萬榮一對情侶失蹤锋拖,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后祸轮,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體兽埃,經(jīng)...
    沈念sama閱讀 46,221評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,303評論 3 340
  • 正文 我和宋清朗相戀三年适袜,在試婚紗的時候發(fā)現(xiàn)自己被綠了柄错。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,444評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡苦酱,死狀恐怖售貌,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情疫萤,我是刑警寧澤颂跨,帶...
    沈念sama閱讀 36,134評論 5 350
  • 正文 年R本政府宣布,位于F島的核電站扯饶,受9級特大地震影響恒削,放射性物質(zhì)發(fā)生泄漏池颈。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,810評論 3 333
  • 文/蒙蒙 一钓丰、第九天 我趴在偏房一處隱蔽的房頂上張望躯砰。 院中可真熱鬧,春花似錦携丁、人聲如沸琢歇。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,285評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽矿微。三九已至,卻和暖如春尚揣,著一層夾襖步出監(jiān)牢的瞬間涌矢,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,399評論 1 272
  • 我被黑心中介騙來泰國打工快骗, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留娜庇,地道東北人。 一個月前我還...
    沈念sama閱讀 48,837評論 3 376
  • 正文 我出身青樓方篮,卻偏偏與公主長得像名秀,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子藕溅,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,455評論 2 359

推薦閱讀更多精彩內(nèi)容