Pig4Cloud之檢驗(yàn)token

前端校驗(yàn)請求

/src/page/index/index.vue

refreshToken() {
      this.refreshTime = setInterval(() => {
        checkToken(this.refreshLock, this.$store)
      }, 10000)
    }

checkToken

/**
 * 校驗(yàn)令牌塘辅,若有效期小于半小時(shí)自動續(xù)期
 * 
 * 定時(shí)任務(wù)請求后端接口返回實(shí)際的有效時(shí)間,不進(jìn)行本地計(jì)算避免 客戶端和服務(wù)器機(jī)器時(shí)鐘不一致
 * @param refreshLock
 */
export const checkToken = (refreshLock, $store) => {
  const token = store.getters.access_token
  // 獲取當(dāng)前選中的 basic 認(rèn)證信息
  let basicAuth = getStore({name: 'basicAuth'})

  if(validatenull(token) || validatenull(basicAuth)){
      return;
  }

  request({
    url: '/auth/token/check_token',
    headers: {
      isToken: false,
      Authorization: basicAuth
    },
    method: 'get',
    params: {token}
  }).then(response => {
    const expire = response && response.data && response.data.exp
    if (expire) {
      const expiredPeriod = expire * 1000 - new Date().getTime()
      console.log('當(dāng)前token過期時(shí)間', expiredPeriod, '毫秒')
      //小于半小時(shí)自動續(xù)約
      if (expiredPeriod <= website.remainingTime) {
        if (!refreshLock) {
          refreshLock = true
          $store.dispatch('RefreshToken')
            .catch(() => {
              clearInterval(this.refreshTime)
            })
          refreshLock = false
        }
      }
    }
  }).catch(error => {
    console.error(error)
  })
}

流程

當(dāng)用戶攜帶token 請求資源服務(wù)器的資源時(shí),Spring Security 攔截token蒜鸡,進(jìn)行token 和 userdetails 匹配過程粪小,把無狀態(tài)的token 轉(zhuǎn)化成具體用戶

image

BearerTokenAuthenticationFilter

https://docs.spring.io/spring-security/site/docs/current/api/org/springframework/security/oauth2/server/resource/web/BearerTokenAuthenticationFilter.html
作為一個(gè)OncePerRequestFilter核心邏輯在doFilterInternal中斯议。

@Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
            throws ServletException, IOException {
        String token;
        try {
            token = this.bearerTokenResolver.resolve(request);
        }
        catch (OAuth2AuthenticationException invalid) {
            this.logger.trace("Sending to authentication entry point since failed to resolve bearer token", invalid);
            this.authenticationEntryPoint.commence(request, response, invalid);
            return;
        }
        if (token == null) {
            this.logger.trace("Did not process request since did not find bearer token");
            filterChain.doFilter(request, response);
            return;
        }

        BearerTokenAuthenticationToken authenticationRequest = new BearerTokenAuthenticationToken(token);
        authenticationRequest.setDetails(this.authenticationDetailsSource.buildDetails(request));

        try {
            AuthenticationManager authenticationManager = this.authenticationManagerResolver.resolve(request);
            Authentication authenticationResult = authenticationManager.authenticate(authenticationRequest);
            SecurityContext context = SecurityContextHolder.createEmptyContext();
            context.setAuthentication(authenticationResult);
            SecurityContextHolder.setContext(context);
            this.securityContextRepository.saveContext(context, request, response);
            if (this.logger.isDebugEnabled()) {
                this.logger.debug(LogMessage.format("Set SecurityContextHolder to %s", authenticationResult));
            }
            filterChain.doFilter(request, response);
        }
        catch (AuthenticationException failed) {
            SecurityContextHolder.clearContext();
            this.logger.trace("Failed to process authentication request", failed);
            this.authenticationFailureHandler.onAuthenticationFailure(request, response, failed);
        }
    }

1.攔截請求進(jìn)行鑒權(quán)

BearerTokenAuthenticationFilter 攔截所有資源服務(wù)器的請求删顶。
解析 header 或者參數(shù)中的 access_token 字段

image

根據(jù)access_token 構(gòu)造出來 BearerTokenAuthenticationToken認(rèn)證對象

image

請求authenticationManager.authenticate(authenticationRequest);進(jìn)行鑒權(quán)雹舀。

image

2.鑒權(quán)操作

BearerTokenAuthenticationFilter解析 Authentication: Bearer {token} 中的token,交給 OpaqueTokenAuthenticationProvider

@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
    if (!(authentication instanceof BearerTokenAuthenticationToken)) {
        return null;
    }
    BearerTokenAuthenticationToken bearer = (BearerTokenAuthenticationToken) authentication;
    OAuth2AuthenticatedPrincipal principal = getOAuth2AuthenticatedPrincipal(bearer);
    AbstractAuthenticationToken result = convert(principal, bearer.getToken());
    result.setDetails(bearer.getDetails());
    this.logger.debug("Authenticated token");
    return result;
}
    
private OAuth2AuthenticatedPrincipal getOAuth2AuthenticatedPrincipal(BearerTokenAuthenticationToken bearer) {
    try {
        return this.introspector.introspect(bearer.getToken());
    }
    catch (BadOpaqueTokenException failed) {
        this.logger.debug("Failed to authenticate since token was invalid");
        throw new InvalidBearerTokenException(failed.getMessage(), failed);
    }
    catch (OAuth2IntrospectionException failed) {
        throw new AuthenticationServiceException(failed.getMessage(), failed);
    }
}

OpaqueTokenAuthenticationProvider 委托 OpaqueTokenIntrospectorintrospect 去校驗(yàn) token著恩。

PigRedisOAuth2AuthorizationService 通過token value 查詢 認(rèn)證中心下發(fā)令牌時(shí) 存儲的用戶認(rèn)證信息.

image

調(diào)用RedisOAuth2AuthorizationServicefindByToken

    @Override
    @Nullable
    public OAuth2Authorization findByToken(String token, @Nullable OAuth2TokenType tokenType) {
        Assert.hasText(token, "token cannot be empty");
        Assert.notNull(tokenType, "tokenType cannot be empty");
        redisTemplate.setValueSerializer(RedisSerializer.java());
        return (OAuth2Authorization) redisTemplate.opsForValue().get(buildKey(tokenType.getValue(), token));
    }

CSDN
騰訊云
掘金
博客園

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市箫荡,隨后出現(xiàn)的幾起案子魁亦,更是在濱河造成了極大的恐慌,老刑警劉巖羔挡,帶你破解...
    沈念sama閱讀 211,042評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件洁奈,死亡現(xiàn)場離奇詭異,居然都是意外死亡婉弹,警方通過查閱死者的電腦和手機(jī)睬魂,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,996評論 2 384
  • 文/潘曉璐 我一進(jìn)店門终吼,熙熙樓的掌柜王于貴愁眉苦臉地迎上來镀赌,“玉大人,你說我怎么就攤上這事际跪∩谭穑” “怎么了喉钢?”我有些...
    開封第一講書人閱讀 156,674評論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長良姆。 經(jīng)常有香客問我肠虽,道長,這世上最難降的妖魔是什么玛追? 我笑而不...
    開封第一講書人閱讀 56,340評論 1 283
  • 正文 為了忘掉前任税课,我火速辦了婚禮,結(jié)果婚禮上痊剖,老公的妹妹穿的比我還像新娘韩玩。我一直安慰自己,他們只是感情好陆馁,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,404評論 5 384
  • 文/花漫 我一把揭開白布找颓。 她就那樣靜靜地躺著,像睡著了一般叮贩。 火紅的嫁衣襯著肌膚如雪击狮。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,749評論 1 289
  • 那天益老,我揣著相機(jī)與錄音彪蓬,去河邊找鬼。 笑死捺萌,一個(gè)胖子當(dāng)著我的面吹牛寞焙,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播互婿,決...
    沈念sama閱讀 38,902評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼捣郊,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了慈参?” 一聲冷哼從身側(cè)響起呛牲,我...
    開封第一講書人閱讀 37,662評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎驮配,沒想到半個(gè)月后娘扩,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,110評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡壮锻,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年琐旁,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片猜绣。...
    茶點(diǎn)故事閱讀 38,577評論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡灰殴,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出掰邢,到底是詐尸還是另有隱情牺陶,我是刑警寧澤伟阔,帶...
    沈念sama閱讀 34,258評論 4 328
  • 正文 年R本政府宣布,位于F島的核電站掰伸,受9級特大地震影響皱炉,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜狮鸭,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,848評論 3 312
  • 文/蒙蒙 一合搅、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧歧蕉,春花似錦历筝、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,726評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至蒸痹,卻和暖如春春弥,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背叠荠。 一陣腳步聲響...
    開封第一講書人閱讀 31,952評論 1 264
  • 我被黑心中介騙來泰國打工匿沛, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人榛鼎。 一個(gè)月前我還...
    沈念sama閱讀 46,271評論 2 360
  • 正文 我出身青樓逃呼,卻偏偏與公主長得像,于是被迫代替她去往敵國和親者娱。 傳聞我的和親對象是個(gè)殘疾皇子抡笼,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,452評論 2 348

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