亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Spring Cloud下實現(xiàn)用戶鑒權的方案

 更新時間:2021年11月25日 09:37:59   作者:barry異想世界  
Java下常用的安全框架主要有Spring Security和shiro,都可提供非常強大的功能,但學習成本較高。但在微服務下鑒權又會對服務有一定的入侵性。 因此,本文將介紹Spring Cloud下實現(xiàn)用戶鑒權的方案,感興趣的同學可以關注一下

Java下常用的安全框架主要有Spring Security和shiro,都可提供非常強大的功能,但學習成本較高。在微服務下鑒權多多少少都會對服務有一定的入侵性。 為了降低依賴,減少入侵,讓鑒權功能相對應用服務透明,我們采用網(wǎng)關攔截資源請求的方式進行鑒權。

一、整體架構(gòu)

用戶鑒權模塊位于API GateWay服務中,所有的API資源請求都需要從此通過。

  1. 做身份認證,通過則緩存用戶權限數(shù)據(jù),不通過返回401
  2. 做用戶鑒權,比對當前訪問資源(URI和Method)是否在已緩存的用戶權限數(shù)據(jù)中,在則轉(zhuǎn)發(fā)請求給對應應用服務,不在則返回403

二、實現(xiàn)步驟

1. 用戶登陸

public LoginUser login(String userName, String password){
    // 檢查密碼
    User user = userService.checkUser(userName, password);

    LoginUser loginUser = LoginUser.builder()
            .userName(userName)
            .realName(user.getRealName())
            .userToken(UUID.randomUUID().toString())
            .loginTime(new Date())
            .build();

    // 保存session
    session.saveSession(loginUser);

    // 查詢權限
    List<Permission> permissions = permissionRepository.findByUserName(userName);
    // 保存用戶權限到緩存中
    session.saveUserPermissions(userName, permissions);

    return loginUser;
}

// ...
// 緩存用戶權限到Redis
public void saveUserPermissions(String userName, List<Permission> permissions) {
    String key = String.format("login:permission:%s", userName);

    HashOperations<String, String, Object> hashOperations = redisTemplate.opsForHash();
    hashOperations.putAll(key, permissions.stream().collect(
            Collectors.toMap(p -> p.getMethod().concat(":").concat(p.getUri()),
                    Permission::getName, (k1, k2) -> k2)));

    if (expireTime != null) {
        redisTemplate.expire(key, expireTime, TimeUnit.SECONDS);
    }
}
  • 用戶驗證通過后,下發(fā)userToken,保存當前登陸信息,緩存用戶授權列表
  • 緩存授權列表時,為了方便讀取使用hash方式保存為list,切勿直接將數(shù)組對象保存為一個object

2. 攔截請求

@Slf4j
@Component
public class AuthorizationFilter extends AbstractGatewayFilterFactory {

    @Autowired
    private Session session;

    @Override
    public GatewayFilter apply(Object config) {
        return (exchange, chain) -> {

            ServerHttpRequest request = exchange.getRequest();
            ServerHttpResponse response = exchange.getResponse();

            String uri = request.getURI().getPath();
            String method = request.getMethodValue();

            // 1.從AuthenticationFilter中獲取userName
            String key = "X-User-Name";
            if (!request.getHeaders().containsKey(key)) {
                response.setStatusCode(HttpStatus.FORBIDDEN);
                return response.setComplete();
            }

            String userName = Objects.requireNonNull(request.getHeaders().get(key)).get(0);

            // 2.驗證權限
            if (!session.checkPermissions(userName, uri, method)) {
                log.info("用戶:{}, 沒有權限", userName);
                response.setStatusCode(HttpStatus.FORBIDDEN);
                return response.setComplete();
            }

            return chain.filter(exchange);
        };
    }
}
  • 第一步從取出身份認證模塊傳遞的X-User-Name
  • 第二步去緩存中檢查是否有相應的權限
public boolean checkPermissions(String userName, String uri, String method) {
    String key = String.format("login:permission:%s", userName);
    String hashKey = String.format("%s:%s", method, uri);

    if (redisTemplate.opsForHash().hasKey(key, hashKey)){
        return  true;
    }

    String allKey = "login:permission:all";
    // 權限列表中沒有則通過
    return !redisTemplate.opsForHash().hasKey(allKey, hashKey);
}
  • 權限列表中沒有則通過 主要是放過一些沒有必要配置的公共資源,默認都可以訪問的資源
  • login:permission:all 所有配置過的權限列表需要在程序啟動時放入緩存,并需要保持數(shù)據(jù)的更新

3. 鑒權Filter配置

spring:
  cloud:
    gateway:
      routes:
        - id: cloud-user
          uri: lb://cloud-user  # 后端服務名
          predicates:
            - Path=/user/**   # 路由地址
          filters:
            - name: AuthenticationFilter  # 身份認證
            - name: AuthorizationFilter   # 用戶鑒權
            - StripPrefix=1 # 去掉前綴
  • 特別注意filter的順序,必須先做身份認證后再進行鑒權
  • 如果有較多的路由都需要配置,可使用default-filters默認Filter配置

三、其它問題

在做單元測試時,如遇到如下錯誤

nested exception is java.lang.NoClassDefFoundError: javax/validation/ValidationException

請升級依賴包版本:

<!--升級validation-api的版本-->
<dependency>
    <groupId>org.hibernate.validator</groupId>
    <artifactId>hibernate-validator</artifactId>
    <version>6.0.5.Final</version>
</dependency>
<dependency>
    <groupId>javax.validation</groupId>
    <artifactId>validation-api</artifactId>
    <version>2.0.1.Final</version>
</dependency>

四、完整代碼

代碼

以上就是Spring Cloud下實現(xiàn)用戶鑒權的方案的詳細內(nèi)容,更多關于Spring Cloud 用戶鑒權的資料請關注腳本之家其它相關文章!

相關文章

  • java使用poi讀取doc和docx文件的實現(xiàn)示例

    java使用poi讀取doc和docx文件的實現(xiàn)示例

    這篇文章主要介紹了java使用poi讀取doc和docx文件的實現(xiàn)示例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-03-03
  • 一文帶你搞懂Java類加載機制

    一文帶你搞懂Java類加載機制

    Java?類加載機制是?Java?運行時的核心組成部分,負責在程序運行過程中動態(tài)加載和連接類文件,并將其轉(zhuǎn)換為可執(zhí)行代碼,接下來小編就來帶大家搞懂面試官老問的?Java?類加載機制,需要的朋友可以參考下
    2023-08-08
  • DragChartPanel可拖拽曲線應用詳解

    DragChartPanel可拖拽曲線應用詳解

    這篇文章主要為大家詳細介紹了DragChartPanel可拖拽曲線的應用,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-12-12
  • springboot注入yml配置文件 list報錯的解決方案

    springboot注入yml配置文件 list報錯的解決方案

    這篇文章主要介紹了springboot注入yml配置文件 list報錯的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • 基于spring注入為null的原因及解決方案

    基于spring注入為null的原因及解決方案

    這篇文章主要介紹了spring注入為null的原因及解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • 高并發(fā)下如何避免重復數(shù)據(jù)產(chǎn)生技巧

    高并發(fā)下如何避免重復數(shù)據(jù)產(chǎn)生技巧

    這篇文章主要為大家介紹了高并發(fā)下如何避免重復數(shù)據(jù)的產(chǎn)生技巧詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-07-07
  • Java關于jar包的知識詳解

    Java關于jar包的知識詳解

    這篇文章主要介紹了Java關于jar包的知識,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-03-03
  • Java 兩種延時thread和timer詳解及實例代碼

    Java 兩種延時thread和timer詳解及實例代碼

    這篇文章主要介紹了Java 兩種延時thread和timer詳解及實例代碼的相關資料,需要的朋友可以參考下
    2017-02-02
  • Maven的pom.xml中resources標簽的用法

    Maven的pom.xml中resources標簽的用法

    本文主要介紹了Maven的pom.xml中resources標簽的用法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-07-07
  • Java 完美判斷中文字符的方法

    Java 完美判斷中文字符的方法

    Java判斷一個字符串是否有中文一般情況是利用Unicode編碼正則來做判斷,但是其實這個區(qū)間來判斷中文不是非常精確,以下是比較完善的判斷方法
    2013-02-02

最新評論