從零開始學YC-Framework之鑑權

一、YC-Framework鑑權是基於哪一個開源框架做的?

YC-Framework鑑權主要基於Dromara開源社區組織下的Sa-Token。

1.什麼是Sa-Token?

Sa-Token是一個輕量級Java權限認證框架,主要解決:登錄認證、權限認證、Session會話、單點登錄、OAuth2.0、微服務網關鑑權等一系列權限相關問題。

2.Sa-Token目前具有哪些功能?

  • 登錄認證 —— 單端登錄、多端登錄、同端互斥登錄、七天內免登錄。
  • 權限認證 —— 權限認證、角色認證、會話二級認證。
  • Session會話 —— 全端共享Session、單端獨享Session、自定義Session。
  • 踢人下線 —— 根據賬號id踢人下線、根據Token值踢人下線。
  • 賬號封禁 —— 指定天數封禁、永久封禁、設定解封時間。
  • 持久層擴展 —— 可集成Redis、Memcached等專業緩存中間件,重啓數據不丟失。
  • 分佈式會話 —— 提供jwt集成、共享數據中心兩種分佈式會話方案。
  • 微服務網關鑑權 —— 適配Gateway、ShenYu、Zuul等常見網關的路由攔截認證。
  • 單點登錄 —— 內置三種單點登錄模式:無論是否跨域、是否共享Redis,都可以搞定。
  • OAuth2.0認證 —— 基於RFC-6749標準編寫,OAuth2.0標準流程的授權認證,支持openid模式。
  • 二級認證 —— 在已登錄的基礎上再次認證,保證安全性。
  • Basic認證 —— 一行代碼接入 Http Basic 認證。
  • 獨立Redis —— 將權限緩存與業務緩存分離。
  • 臨時Token驗證 —— 解決短時間的Token授權問題。
  • 模擬他人賬號 —— 實時操作任意用戶狀態數據。
  • 臨時身份切換 —— 將會話身份臨時切換爲其它賬號。
  • 前後臺分離 —— APP、小程序等不支持Cookie的終端。
  • 同端互斥登錄 —— 像QQ一樣手機電腦同時在線,但是兩個手機上互斥登錄。
  • 多賬號認證體系 —— 比如一個商城項目的user表和admin表分開鑑權。
  • 花式token生成 —— 內置六種Token風格,還可:自定義Token生成策略、自定義Token前綴。
  • 註解式鑑權 —— 優雅的將鑑權與業務代碼分離。
  • 路由攔截式鑑權 —— 根據路由攔截鑑權,可適配restful模式。
  • 自動續簽 —— 提供兩種Token過期策略,靈活搭配使用,還可自動續簽。
  • 會話治理 —— 提供方便靈活的會話查詢接口。
  • 記住我模式 —— 適配[記住我]模式,重啓瀏覽器免驗證。
  • 密碼加密 —— 提供密碼加密模塊,可快速MD5、SHA1、SHA256、AES、RSA加密。
  • 全局偵聽器 —— 在用戶登陸、註銷、被踢下線等關鍵性操作時進行一些AOP操作。
  • 開箱即用 —— 提供SpringMVC、WebFlux等常見web框架starter集成包,真正的開箱即用。

3.爲什麼要選擇Sa-Token?

我在從單體架構到分佈式微服務架構的思考這篇文章中所強調技術選型的八點如業務相關性、框架流行度、學習曲線、文檔豐富程度、社區支持、單元測試、可擴展性、許可證等。Sa-Token均滿足。

4.Sa-Token的相關資料有哪些?

Sa-Token官方文檔:
https://sa-token.dev33.cn/doc/#/

Sa-Token Github源代碼:
https://github.com/dromara/sa-token

Sa-Token Gitee源代碼:
https://gitee.com/dromara/sa-token

基本上結合自己的業務需求,整體過一遍Sa-Token官方文檔,就能學會如何使用Sa-Token。

開源不易,如果Sa-Token對你幫助,不妨點個star鼓勵一下對應的開源小夥伴們!!!

二、如何運行YC-Framework相關的鑑權服務?

主要步驟如下:

  • 1.啓動Nacos。
  • 2.啓動網關服務(yc-gateway)。
  • 3.啓動認證服務(yc-auth)。
  • 4.啓動後臺管理服務(yc-admin)。

啓動完畢以後,通過瀏覽器訪問本地地址:
http://localhost:8080/doc.html

可以看到如下效果:
圖一

接下來點擊認證管理會出現如下列表,找到登錄接口,輸入對應的信息,如下所示,就表示登錄成功:
圖二

三、YC-Framework中的鑑權模塊的核心代碼包含哪些?

YC-Framework中的鑑權模塊叫yc-common-security,屬於yc-common模塊下的子模塊。如圖所示:
圖三

其中核心類叫SaTokenConfigure.java,代碼如下:

@Configuration
@Slf4j
public class SaTokenConfigure implements WebMvcConfigurer, StpInterface {

    @Autowired
    private UserApi userApi;

    /**
     * 註冊攔截器
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {

        // 註冊路由攔截器,自定義驗證規則
        registry.addInterceptor(new SaRouteInterceptor((request, response, handler) -> {
            //登錄認證
            SaRouter.match("/**", () -> StpUtil.checkLogin());
            // 角色認證 -- 攔截以 admin 開頭的路由,必須具備 admin 角色或者 super-admin 角色纔可以通過認證
            SaRouter.match("/company/**", () -> StpUtil.checkRoleOr("admin", "super-admin"));
            //權限認證
            SaRouter.match("/company/**", () -> StpUtil.checkPermission("company"));
            SaRouter.match("/user/**", () -> StpUtil.checkPermission("admin"));
            SaRouter.match("/role/**", () -> StpUtil.checkPermission("admin"));

        })).addPathPatterns("/**").excludePathPatterns(
                "/auth/**", "/doc.html", "/webjars/**", "/swagger-resources", "/actuator/**");
    }

    @Override
    public List<String> getPermissionList(Object loginId, String loginType) {
        log.info("loginId:" + loginId + "||" + loginType);
        List<String> permList = new ArrayList<>();
        UserIdReqDTO permReq = new UserIdReqDTO();
        permReq.setUserId(handleUserId(loginId.toString()));
        RespBody<List<String>> resultBody = userApi.getPerm(permReq);
        if (RespCode.SELECT_SUCCESS.getCode().equals(resultBody.getCode())) {
            permList = resultBody.getData();
        }
        return permList;
    }

    @Override
    public List<String> getRoleList(Object loginId, String loginType) {
        log.info("loginId:" + loginId + "||" + loginType);
        List<String> roleList = new ArrayList<>();
        UserIdReqDTO permReq = new UserIdReqDTO();
        permReq.setUserId(handleUserId(loginId.toString()));
        RespBody<List<String>> resultBody = userApi.getRole(permReq);
        if (RespCode.SELECT_SUCCESS.getCode().equals(resultBody.getCode())) {
            roleList = resultBody.getData();
        }
        return roleList;
    }

    /**
     * 處理用戶ID
     *
     * @param userId
     * @return
     */
    private String handleUserId(String userId) {
        return userId.substring(userId.lastIndexOf(ApplicationConst.DEFAULT_FLAG) + 1).replace(ApplicationConst.DEFAULT_FLAG, ApplicationConst.NULL_STR);
    }
}

該代碼存放目錄爲:
https://github.com/developers-youcong/yc-framework/tree/main/yc-common/yc-common-security

不難看出基於攔截器相關。之前寫過一篇叫Java Web之三大利器的文章,所謂Java Web 三大利器指的是攔截器、過濾器、監聽器等。其中攔截器與過濾器在權限認證相關用的比較多。

之前還寫過關於重構某網API服務的文章可供讀者朋友參考,這篇文章是基於公司系統權限重構的背景,在此我提供了兩種方法,一種是基於原生的攔截器,另外一方面是基於Sa-Token。

四、YC-Framework爲何將權限模塊化?

一方面符合YC-Framework的架構思想之一模塊化;另外一方面在於按需引入,哪一個微服務需要,只需引入對應的依賴即可。如下所示:

<dependency>
    <groupId>com.yc.framework</groupId>
    <artifactId>yc-common-security</artifactId>
</dependency>

 

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