jersey利用filter和Dynamic binding來實(shí)現(xiàn)token攔截過濾請(qǐng)求

背景描述

做app后端服務(wù)的coder都知道,很多服務(wù)都是無狀態(tài)的,所謂的無狀態(tài),在這里我們可以簡(jiǎn)單的理解為(與傳統(tǒng)web不同點(diǎn))沒有session。

那么這個(gè)時(shí)候怎么保證我們的請(qǐng)求安全性呢(這里我們所提到的安全性即用戶請(qǐng)求來源和判斷的安全性圆丹,不涉及驗(yàn)簽只估,加密等數(shù)據(jù)來源之類的安全)。

需求描述

我們要實(shí)現(xiàn)一個(gè)基于token令牌的請(qǐng)求攔截系統(tǒng)捏鱼,針對(duì)我們的每一次的請(qǐng)求進(jìn)行攔截蕾额。以此來判斷用戶數(shù)據(jù)的完整性崭庸,安全性梳玫。
那么我們的攔截系統(tǒng)是什么樣子的呢谍珊?
首先我們按照auth2.0的協(xié)議進(jìn)行一個(gè)偽auth2.0設(shè)計(jì)一個(gè)權(quán)限分發(fā)驗(yàn)證的模式(因?yàn)槲艺J(rèn)為規(guī)則是人制訂的治宣,沒必要所有的事都按照規(guī)則進(jìn)行,方便即可)

那么我們的token鑒權(quán)是什么樣的過程呢砌滞?

  1. 客戶端登錄->server
  2. 登錄成功后頒發(fā)token令牌給客戶端
  3. 客戶端每次請(qǐng)求時(shí)候攜帶token
  4. server端針對(duì)需要鑒權(quán)的請(qǐng)求進(jìn)行攔截
  5. server端對(duì)token進(jìn)行鑒權(quán)
  6. 鑒權(quán)成功的話進(jìn)行請(qǐng)求分發(fā)(既侮邀,繼續(xù)請(qǐng)求),鑒權(quán)失敗的話把請(qǐng)求攔截下來返回相應(yīng)的失敗狀態(tài)碼

關(guān)鍵點(diǎn)分析

整個(gè)過程中最重要的是3點(diǎn):

  1. token的生成算法
  2. token的驗(yàn)證方式
  3. 針對(duì)需要鑒權(quán)的請(qǐng)求進(jìn)行攔截

今天我們要做的就是第三點(diǎn)贝润,如何實(shí)現(xiàn)針對(duì)需要鑒權(quán)的請(qǐng)求進(jìn)行攔截

針對(duì)需要鑒權(quán)的請(qǐng)求進(jìn)行攔截的實(shí)現(xiàn)過程

整個(gè)攔截的過程中主要有這么兩個(gè)點(diǎn):

  1. Server filters(服務(wù)器的過濾器)
  2. Dynamic binding(動(dòng)態(tài)的過濾器攔截器綁定)

Server filters簡(jiǎn)述

Server filters主要是一個(gè)什么作用呢绊茧,這我們這里,他主要是負(fù)責(zé)兩個(gè)地方:

  1. 攔截請(qǐng)求
  2. 業(yè)務(wù)內(nèi)對(duì)token鑒權(quán)

整個(gè)這一塊的代碼如下

public class AuthorizationFilter implements ContainerRequestFilter {

    @Override
    public void filter(ContainerRequestContext requestContext) throws IOException {

        //獲取客戶端Header中提交的token
        String token = requestContext.getHeaderString("Authorization");
        if (StringUtil.isEmpty(token)) {
            // TODO:攔截響應(yīng)
        }
        //判斷該用戶是否已登陸
        User user = TokenUtils.sign(token);
        if (user == null) {
            // TODO:攔截響應(yīng)
        } 
    }

}

那么大家可能注意到我加了todo的地方打掘,因?yàn)檫@些都是需要把請(qǐng)求攔截下來的地方按傅,那么我們?cè)趺磳?shí)現(xiàn)吧這個(gè)請(qǐng)求攔截下來呢
我們采用了拋異常的方式,具體做法如下:
首先我們先聲明一個(gè)auth驗(yàn)證失敗的異常

public class AuthorizationException extends RuntimeException {
    private String response = ErrorCode.NOT_AUTHED.getMsg();
    public String getResponse(){
        return this.response;
    }
}

然后在全局捕獲這個(gè)異常并輸出提示信息

@Provider
public class AuthExceptionMapper implements ExceptionMapper<AuthorizationException> {
    @Override
    public Response toResponse(AuthorizationException exception) {
        return Response.ok(exception.getResponse()).build();
    }

}

Dynamic binding

在上面我們看到了如何對(duì)一個(gè)請(qǐng)求進(jìn)行攔截胧卤,并進(jìn)行鑒權(quán)驗(yàn)證唯绍,包括異常處理。
那么有個(gè)關(guān)鍵性的問題來了枝誊,我們?cè)撊绾螖r截需要鑒權(quán)的請(qǐng)求况芒?
例如我登錄的請(qǐng)求是不需要攔截的,獲取個(gè)人信息的請(qǐng)求是需要攔截的
我怎么能做到上面的效果(答:Dynamic binding)

那么我們看一下什么是Dynamic binding叶撒?

讓我們來看一下官方的解釋

Dynamic binding is a way how to assign filters and interceptors to the resource methods in a dynamic manner.

動(dòng)態(tài)綁定就是一個(gè)以動(dòng)態(tài)的方式分配資源方法的篩選器和攔截器绝骚。

那么我們?cè)趺蠢?strong>Dynamic binding來實(shí)現(xiàn)我們的區(qū)分?jǐn)r截的功能呢

具體的需求描述

我想實(shí)現(xiàn)這么樣的一個(gè)功能,通過一個(gè)注解祠够,我只需要把這個(gè)注解標(biāo)注在類或者方法上就能攔截這個(gè)對(duì)應(yīng)的類或者方法

那么我怎么實(shí)現(xiàn)這個(gè)動(dòng)態(tài)的過濾綁定功能呢压汪?
首先,我們聲明一個(gè)自定義的注解古瓤,命名為AuthAnnotation
然后我們亮出我們的實(shí)現(xiàn)辦法

@Provider
public class AuthorizationFilterFeature implements DynamicFeature {

    @Override
    public void configure(ResourceInfo resourceInfo, FeatureContext context) {

        List<Annotation> authzSpecs = new ArrayList<>();

        Annotation classAuthzSpec =
            resourceInfo.getResourceClass().getAnnotation(AuthAnnotation.class);
        Annotation methodAuthzSpec =
            resourceInfo.getResourceMethod().getAnnotation(AuthAnnotation.class);

        if (classAuthzSpec != null)
            authzSpecs.add(classAuthzSpec);
        if (methodAuthzSpec != null)
            authzSpecs.add(methodAuthzSpec);

        if (!authzSpecs.isEmpty()) {
            // 需要攔截的api
            context.register(AuthorizationFilter.class);
        }
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末止剖,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子落君,更是在濱河造成了極大的恐慌穿香,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,657評(píng)論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件绎速,死亡現(xiàn)場(chǎng)離奇詭異皮获,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)纹冤,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,889評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門洒宝,熙熙樓的掌柜王于貴愁眉苦臉地迎上來购公,“玉大人,你說我怎么就攤上這事雁歌『旰疲” “怎么了?”我有些...
    開封第一講書人閱讀 164,057評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵将宪,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我橡庞,道長(zhǎng)较坛,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,509評(píng)論 1 293
  • 正文 為了忘掉前任扒最,我火速辦了婚禮丑勤,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘吧趣。我一直安慰自己法竞,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,562評(píng)論 6 392
  • 文/花漫 我一把揭開白布强挫。 她就那樣靜靜地躺著岔霸,像睡著了一般。 火紅的嫁衣襯著肌膚如雪俯渤。 梳的紋絲不亂的頭發(fā)上呆细,一...
    開封第一講書人閱讀 51,443評(píng)論 1 302
  • 那天,我揣著相機(jī)與錄音八匠,去河邊找鬼絮爷。 笑死,一個(gè)胖子當(dāng)著我的面吹牛梨树,可吹牛的內(nèi)容都是我干的坑夯。 我是一名探鬼主播,決...
    沈念sama閱讀 40,251評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼抡四,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼柜蜈!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起指巡,我...
    開封第一講書人閱讀 39,129評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤跨释,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后厌处,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體鳖谈,經(jīng)...
    沈念sama閱讀 45,561評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,779評(píng)論 3 335
  • 正文 我和宋清朗相戀三年阔涉,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了缆娃。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片捷绒。...
    茶點(diǎn)故事閱讀 39,902評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖贯要,靈堂內(nèi)的尸體忽然破棺而出暖侨,到底是詐尸還是另有隱情,我是刑警寧澤崇渗,帶...
    沈念sama閱讀 35,621評(píng)論 5 345
  • 正文 年R本政府宣布字逗,位于F島的核電站,受9級(jí)特大地震影響宅广,放射性物質(zhì)發(fā)生泄漏葫掉。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,220評(píng)論 3 328
  • 文/蒙蒙 一跟狱、第九天 我趴在偏房一處隱蔽的房頂上張望俭厚。 院中可真熱鬧,春花似錦驶臊、人聲如沸挪挤。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,838評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)扛门。三九已至,卻和暖如春纵寝,著一層夾襖步出監(jiān)牢的瞬間尖飞,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,971評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工店雅, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留政基,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,025評(píng)論 2 370
  • 正文 我出身青樓闹啦,卻偏偏與公主長(zhǎng)得像沮明,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子窍奋,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,843評(píng)論 2 354

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