cas5.3.2單點(diǎn)登錄-Cas Server自定義Oauth2.0的用戶信息

前言

目前我們系統(tǒng)中腋逆,用戶登陸旁壮,API調(diào)用是融合在一起的监嗜,API后面是調(diào)用各個dubbo服務(wù)。為了保證各個系統(tǒng)能夠鑒權(quán)抡谐,目前的做法是裁奇,用用戶登陸后,生成token,將token存在redis中麦撵,各個系統(tǒng)通過讀取reids的token作為驗(yàn)證刽肠。

幾個問題:

  1. 登陸體系和業(yè)務(wù)代碼混合在一起,不是特別規(guī)范免胃。
  2. 自定義的token機(jī)制音五,缺點(diǎn)很多。
  3. 所有服務(wù)都是直接讀取redis,安全性很差羔沙。
  4. 擴(kuò)展性比較差躺涝。

準(zhǔn)備

目前業(yè)務(wù)系統(tǒng)完全耦合在一起的,我們需要將登陸?yīng)毩⒊鰜怼?br> 很多大公司都有自己的CAS系統(tǒng)扼雏,這樣公司的其他系統(tǒng)不必要建立自己的賬號體系坚嗜,直接接入CAS即可。
之前我不是特別能夠區(qū)分CAS,SSO,OAUTH2這些概念诗充,經(jīng)過了幾個星期的探索重要理清楚了苍蔬。

  • SSO
    SSO是Single Sign On,一次登陸蝴蜓,全部訪問碟绑。對于我們來說,使用了SSO茎匠,多個系統(tǒng)可以完全獨(dú)立蜈敢,所有系統(tǒng)不用關(guān)心用戶體系。
  • OAUTH2
    OAUTH2是一種授權(quán)開放協(xié)議汽抚。官網(wǎng)上面這么介紹.
    An open protocol to allow secure authorization in a simple and standard method from web, mobile and desktop applications.
    
    相關(guān)文章:
    https://oauth.net/
    http://www.ruanyifeng.com/blog/2014/05/oauth_2_0.html
  • CAS
    CAS是Central Authentication Service的縮寫,耶魯大學(xué)開啟的一個開源項(xiàng)目伯病,是企業(yè)級的SSO解決方案造烁。
    https://apereo.github.io/cas/5.3.x/index.html

改造

基于上面的概念,以及我們的需求午笛,我們的用戶系統(tǒng)有SSO和OAUTH2.0兩個功能惭蟋。我們會基于CAS實(shí)現(xiàn)我們的功能,CAS天熱支持SSO,主要是OAUTH2.0的支持药磺,我們查他的文檔發(fā)現(xiàn)他有插件可以支持告组。
對于環(huán)境搭建,可以參考:
https://blog.csdn.net/qq_34021712/article/details/80871015
https://blog.csdn.net/qq_34021712/article/details/82290876

正文

構(gòu)建SSO和OAUTH2.0

按上面文章結(jié)合官網(wǎng)癌佩,我們搭建好環(huán)境木缝。
https://apereo.github.io/cas/5.3.x/installation/OAuth-OpenId-Authentication.html
訪問下面地址
https://server.cas.com:8443/cas/oauth2.0/accessToken?grant_type=password&client_id=20180901&username=casuser&password=Mellon
得到下面結(jié)果:
access_token=AT-1-DrieDtlxv43rEiXIt2uuRvD3YFKTvCE9&expires_in=28800
我們將access_token修改放入下面地址
https://server.cas.com:8443/cas/oauth2.0/profile?access_token=AT-1-DrieDtlxv43rEiXIt2uuRvD3YFKTvCE9
得到下面結(jié)果:
{ "service": "http://localhost:8080", "attributes": {}, "id": "casuser", "client_id": "20180901" }
我們會發(fā)現(xiàn)沒有任何用戶信息便锨,然后我參考cas5.3.2單點(diǎn)登錄-自定義返回信息給客戶端(十九) 這個文章, 發(fā)現(xiàn)結(jié)果沒有任何變化。

問題和解決

既然有問題我碟,那么怎么解決放案?之前我走了很多彎路,原因在于兩個方面矫俺,第一吱殉,對CAS本地理解不足,第二厘托,對于官網(wǎng)文檔理解不足友雳。
首先,需要debug一下铅匹,看看問題所在押赊,我們有兩個url,第一個是獲取accessToken,第二個是獲取用戶信息。
跟蹤獲取用戶信息伊群,發(fā)現(xiàn)獲取用戶信息是從session里面獲取的考杉,里面用戶信息就是空,那么我開始會認(rèn)為是accessToken獲取的時候舰始,會將用戶信息放入session,這里出現(xiàn)問題崇棠,才會導(dǎo)致profile沒有效果。
進(jìn)一步跟蹤accessToken,發(fā)現(xiàn)在存儲session的時候丸卷,使用的是UsernamePasswordCredential生成的profile,而這個里面只用username和password兩個屬性枕稀。所以,你用密碼方式登錄的谜嫉,session里面是不會存儲任何用戶信息萎坷。
這個時候,查看官方文檔沐兰,里面開始就有個定制模式哆档,我一直不明白.

package org.apereo.cas.support.oauth;

@Configuration("MyOAuthConfiguration")
@EnableConfigurationProperties(CasConfigurationProperties.class)
public class MyOAuthConfiguration {
  @Bean
  @RefreshScope
  public OAuth20UserProfileViewRenderer oauthUserProfileViewRenderer() {   
  ...
  }}

在跟蹤profile代碼的時候,發(fā)現(xiàn)OAuth20UserProfileViewRenderer是這里面的方法住闯,才恍然大悟瓜浸,官方的意思是,accessToken的時候比原,你不需要做任何修改插佛,但是在獲取用戶信息的時候,你可以自定義量窘,例如從數(shù)據(jù)庫或者 Redis里面讀取用戶信息雇寇。

代碼如下:
配置類

package com.destinym.cas.config;

import com.destinym.cas.custom.CustomOAuth20UserProfileViewRenderer;
import com.destinym.cas.mock.MockUserService;
import com.destinym.cas.service.UserService;
import org.apereo.cas.configuration.CasConfigurationProperties;
import org.apereo.cas.support.oauth.web.views.OAuth20UserProfileViewRenderer;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration("customAuthenticationConfiguration")
@EnableConfigurationProperties(CasConfigurationProperties.class)
public class CustomOAuthConfiguration {
    @Bean
    @RefreshScope
    public OAuth20UserProfileViewRenderer oauthUserProfileViewRenderer() {
        CustomOAuth20UserProfileViewRenderer customOAuth20UserProfileViewRenderer = new CustomOAuth20UserProfileViewRenderer();
        return customOAuth20UserProfileViewRenderer;
    }

    @Bean
    public UserService userService() {
        return new MockUserService();
    }
}

重新render類

package com.destinym.cas.custom;

import com.destinym.cas.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.apereo.cas.support.oauth.util.OAuth20Utils;
import org.apereo.cas.support.oauth.web.views.OAuth20UserProfileViewRenderer;
import org.apereo.cas.ticket.accesstoken.AccessToken;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.Map;

/**
 * Created by mengliang on 2018/12/30.
 */

@Slf4j
public class CustomOAuth20UserProfileViewRenderer implements OAuth20UserProfileViewRenderer {
    @Autowired
    private UserService userService;
    private final String ID ="id";

    @Override
    public String render(Map<String, Object> model, AccessToken accessToken) {
        try {
            String userId = (String) model.get(ID);
            if (userId != null) {
                return OAuth20Utils.jsonify(userService.findByUserName(userId));
            }
        }catch (Exception e){

        }
        return null;
    }
}

自定義用戶接口

package com.destinym.cas.service;

import java.util.Map;

/**
 * Created by mengliang on 2018/12/27.
 */

public interface UserService {
    Map<String, Object> findByUserName(String username);
}

MOCK用戶信息

package com.destinym.cas.mock;

import com.destinym.cas.service.UserService;

import java.util.HashMap;
import java.util.Map;

/**
 * Created by mengliang on 2018/12/30.
 */
public class MockUserService implements UserService {
    @Override
    public Map<String, Object> findByUserName(String username) {
        {
            HashMap hashMap = new HashMap();
            hashMap.put("username", "casuser");
            hashMap.put("tel","18600000000");
            hashMap.put("region","china");
            return hashMap;
        }
    }
}

修改spring.factories
增加

  org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
  org.apereo.cas.config.CasEmbeddedContainerTomcatConfiguration,\
  org.apereo.cas.config.CasEmbeddedContainerTomcatFiltersConfiguration,\
  com.destinym.cas.config.CustomOAuthConfiguration

重新部署后,運(yùn)行結(jié)果為

{
    "tel": "18600000000",
    "region": "china",
    "username": "casuser"
}

大功告成。具體可以參考git地址:
https://github.com/destinym/cas-oauth2-custom

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末锨侯,一起剝皮案震驚了整個濱河市嫩海,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌识腿,老刑警劉巖出革,帶你破解...
    沈念sama閱讀 207,113評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異渡讼,居然都是意外死亡骂束,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評論 2 381
  • 文/潘曉璐 我一進(jìn)店門成箫,熙熙樓的掌柜王于貴愁眉苦臉地迎上來展箱,“玉大人,你說我怎么就攤上這事蹬昌』斐郏” “怎么了?”我有些...
    開封第一講書人閱讀 153,340評論 0 344
  • 文/不壞的土叔 我叫張陵皂贩,是天一觀的道長栖榨。 經(jīng)常有香客問我,道長明刷,這世上最難降的妖魔是什么婴栽? 我笑而不...
    開封第一講書人閱讀 55,449評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮辈末,結(jié)果婚禮上愚争,老公的妹妹穿的比我還像新娘。我一直安慰自己挤聘,他們只是感情好轰枝,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,445評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著组去,像睡著了一般鞍陨。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上从隆,一...
    開封第一講書人閱讀 49,166評論 1 284
  • 那天诚撵,我揣著相機(jī)與錄音,去河邊找鬼广料。 笑死,一個胖子當(dāng)著我的面吹牛幼驶,可吹牛的內(nèi)容都是我干的艾杏。 我是一名探鬼主播,決...
    沈念sama閱讀 38,442評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼盅藻,長吁一口氣:“原來是場噩夢啊……” “哼购桑!你這毒婦竟也來了畅铭?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,105評論 0 261
  • 序言:老撾萬榮一對情侶失蹤勃蜘,失蹤者是張志新(化名)和其女友劉穎硕噩,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體缭贡,經(jīng)...
    沈念sama閱讀 43,601評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡炉擅,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,066評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了阳惹。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片谍失。...
    茶點(diǎn)故事閱讀 38,161評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖莹汤,靈堂內(nèi)的尸體忽然破棺而出快鱼,到底是詐尸還是另有隱情,我是刑警寧澤纲岭,帶...
    沈念sama閱讀 33,792評論 4 323
  • 正文 年R本政府宣布抹竹,位于F島的核電站,受9級特大地震影響止潮,放射性物質(zhì)發(fā)生泄漏窃判。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,351評論 3 307
  • 文/蒙蒙 一沽翔、第九天 我趴在偏房一處隱蔽的房頂上張望兢孝。 院中可真熱鬧,春花似錦仅偎、人聲如沸跨蟹。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽窗轩。三九已至,卻和暖如春座咆,著一層夾襖步出監(jiān)牢的瞬間痢艺,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評論 1 261
  • 我被黑心中介騙來泰國打工介陶, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留堤舒,地道東北人。 一個月前我還...
    沈念sama閱讀 45,618評論 2 355
  • 正文 我出身青樓哺呜,卻偏偏與公主長得像舌缤,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,916評論 2 344

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