Bearer Token 一種安全的接口認證方式

因爲HTTP協議是開放的,可以任人調用。所以,如果接口不希望被隨意調用,就需要做訪問權限的控制,認證是好的用戶,才允許調用API。

目前主流的訪問權限控制/認證模式有以下幾種:

1、Bearer Token(Token 令牌)

定義:爲了驗證使用者的身份,需要客戶端向服務器端提供一個可靠的驗證信息,稱爲Token,這個token通常由Json數據格式組成,通過hash散列算法生成一個字符串,所以稱爲Json Web Token(Json表示令牌的原始值是一個Json格式的數據,web表示是在互聯網傳播的,token表示令牌,簡稱JWT)

2、JWT的三部分

第一部分:頭部

{
    "typ" : "JWT",    (typ:類型)
    "alg" : "HS256" (alg:算法,HS256表示哈希算法的mac值。SHA256/HmacSHA256,SHA256表示直接加密,HmacSHA256表示用祕鑰進行加密。SHA(Secure[sɪˈkjʊə(r)]  Hash Algorithm [ˈælgərɪðəm],安全散列算法) HMAC(Hash Message Authentication [ɔ:ˌθentɪ'keɪʃn] Code,散列消息鑑別碼))
}

第二部分(Claim正文部分)

{
    "iss" : "joe",(issuer,發佈者)
    "exp": 1300819380,(expiration[ˌekspəˈreɪʃn]  time 過期時間,毫秒數計算)
    "http://example.com/is_root" :true(主題)
}

第三部分:簽名(將上面的兩個部分組合在一起+本地信息做的一個的簽名(頭部在前)

網絡解釋:簽名是把header和payload(載荷)對應的json結構進行base64url編碼之後得到的兩個串,用英文句點號拼接起來,然後根據header裏面alg指定的簽名算法生成出來的。

https://tools.ietf.org/html/draft-ietf-oauth-json-web-token-19

1,令牌的好處:避免在使用中不斷的輸入賬號和密碼,比較安全

2,如果要測試帶token的接口,首先要進行登錄,登錄成功會有個token信息,向api接口發送請求的時候必須帶上這個token,故需要做2次請求(1,登錄,拿到token 2,正式對接口進行測試)

這個時候頭部會多一個Authorization

Authorization可能在頭部,也可能直接跟在請求行裏面

http://www.xxx.com/ada?token=xxxxx

要麼是用post請求,然後放在參數裏面

 

3、Bearer Token實戰

Bearer Token中的token獲取方式代碼實現,如下所示:

String auth = ctx.getRequest().getHeader("Authorization");
if (StringUtils.isNotBlank(auth) && auth.indexOf("Bearer") >= 0) {
    auth = auth.substring("Bearer ".length() - 1, auth.length());
    Object obj = param.get("param");
    Map<String, Object> paramOld = JSONObject.parseObject(obj.toString());
    paramOld.put("ticketTgt", auth.trim());
    param.put("param", paramOld.toString());
}

過濾器中Token校驗方式,代碼如下所示:

/**
 * @Classname: com.openailab.oascloud.gateway.filter.CasBearerFilter
 * @Description: 組裝cas的bearer token 請求方式,校驗tickets
 * @Author: chenliang
 * @Date: 2020/01/08
 */
@Component
public class CasBearerFilter extends ZuulFilter {

    private static final Logger LOGGER = LoggerFactory.getLogger(CharacterEncodeFilter.class);

    @Autowired
    private IUnifiedOpenService iUnifiedOpenService;

    @Override
    public String filterType() {
        return FilterConstants.PRE_TYPE;
    }

    @Override
    public int filterOrder() {
        return 100;
    }

    @Override
    public boolean shouldFilter() {
        RequestContext ctx = RequestContext.getCurrentContext();
        if (!ctx.sendZuulResponse()) {
            return false;
        }

        String uri = ctx.getRequest().getRequestURI();
        boolean result = (uri.indexOf("/user/tgt-login") > 0 || uri.indexOf("/cas/userinfo") > 0 || uri.indexOf("/cas/cancel") > 0 || uri.indexOf("/cas/serviceTicket") > 0 || uri.indexOf("/cas/serviceUrl") > 0);
        return result;
    }

    @Override
    public Object run() {
        RequestContext ctx = RequestContext.getCurrentContext();
        Map<String, Object> param = ParamUtil.getRequestParams(ctx);

        if (Objects.isNull(param.get("param"))) {
            ResponseUtil.resultFormat(ctx, ResponseEnum.RESPONSE_CODE_UUM_CAS_TICKETS_STATUS_LOST);
            return null;
        }

        //查看是否有ticketTgt屬性
        String map = (String) param.get("param");
        JSONObject paramJson = JSONObject.parseObject(map);
        if (Objects.isNull(paramJson.get("ticketTgt"))) {
            ResponseUtil.resultFormat(ctx, ResponseEnum.RESPONSE_CODE_UUM_CAS_TICKETS_STATUS_LOST);
            return null;
        }

        RequestParameter requestParameter = new RequestParameter();
        requestParameter.setMethodname(UumMethodNameConst.USER_CAS_TICKETS_STATUS);
        requestParameter.setParam(map);
        ResponseResult responseResult = iUnifiedOpenService.checkTicketStatus(requestParameter);
        if (responseResult != null && ResponseEnum.RESPONSE_CODE_SUCCESS.getCode() == responseResult.getCode()) {
            return null;
        } else {
            ResponseUtil.resultFormat(ctx, ResponseEnum.RESPONSE_CODE_UUM_CAS_TICKETS_STATUS_LOST);
            return null;
        }
    }
}

4、注意點:

1)token一般有時間限制。測試前需要跟開發確認token可以用多久,什麼時候算token失效

2)token放在哪兒,怎麼傳回去,需要有開發文檔,或者諮詢開發,登錄成功返回的token需要了解從什麼地方獲取(可以通過錄制進行查看)

Bearer Token 接口認證方式介紹完成。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章