最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

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

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

一、整體架構(gòu)

用戶鑒權(quán)模塊位于API GateWay服務(wù)中,所有的API資源請(qǐng)求都需要從此通過(guò)。

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

二、實(shí)現(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);

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

    return loginUser;
}

// ...
// 緩存用戶權(quán)限到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);
    }
}
  • 用戶驗(yàn)證通過(guò)后,下發(fā)userToken,保存當(dāng)前登陸信息,緩存用戶授權(quán)列表
  • 緩存授權(quán)列表時(shí),為了方便讀取使用hash方式保存為list,切勿直接將數(shù)組對(duì)象保存為一個(gè)object

2. 攔截請(qǐng)求

@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.驗(yàn)證權(quán)限
            if (!session.checkPermissions(userName, uri, method)) {
                log.info("用戶:{}, 沒(méi)有權(quán)限", userName);
                response.setStatusCode(HttpStatus.FORBIDDEN);
                return response.setComplete();
            }

            return chain.filter(exchange);
        };
    }
}
  • 第一步從取出身份認(rèn)證模塊傳遞的X-User-Name
  • 第二步去緩存中檢查是否有相應(yīng)的權(quán)限
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";
    // 權(quán)限列表中沒(méi)有則通過(guò)
    return !redisTemplate.opsForHash().hasKey(allKey, hashKey);
}
  • 權(quán)限列表中沒(méi)有則通過(guò) 主要是放過(guò)一些沒(méi)有必要配置的公共資源,默認(rèn)都可以訪問(wèn)的資源
  • login:permission:all 所有配置過(guò)的權(quán)限列表需要在程序啟動(dòng)時(shí)放入緩存,并需要保持?jǐn)?shù)據(jù)的更新

3. 鑒權(quán)Filter配置

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

三、其它問(wèn)題

在做單元測(cè)試時(shí),如遇到如下錯(cuò)誤

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

請(qǐng)升級(jí)依賴包版本:

<!--升級(jí)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下實(shí)現(xiàn)用戶鑒權(quán)的方案的詳細(xì)內(nèi)容,更多關(guān)于Spring Cloud 用戶鑒權(quán)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • JAVA字符串拼接常見(jiàn)方法匯總

    JAVA字符串拼接常見(jiàn)方法匯總

    這篇文章主要介紹了JAVA字符串拼接常見(jiàn)方法,文中講解非常細(xì)致,代碼幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下
    2020-06-06
  • spring boot + mybatis如何實(shí)現(xiàn)數(shù)據(jù)庫(kù)的讀寫分離

    spring boot + mybatis如何實(shí)現(xiàn)數(shù)據(jù)庫(kù)的讀寫分離

    這篇文章主要給大家介紹了關(guān)于spring boot + mybatis如何實(shí)現(xiàn)數(shù)據(jù)庫(kù)的讀寫分離的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用spring boot具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-09-09
  • 基于restTemplate遇到的編碼問(wèn)題及解決

    基于restTemplate遇到的編碼問(wèn)題及解決

    這篇文章主要介紹了restTemplate遇到的編碼問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • Spring核心容器之ApplicationContext上下文啟動(dòng)準(zhǔn)備詳解

    Spring核心容器之ApplicationContext上下文啟動(dòng)準(zhǔn)備詳解

    這篇文章主要介紹了Spring核心容器之ApplicationContext上下文啟動(dòng)準(zhǔn)備詳解,ApplicationContext 繼承自 BeanFactory ,其不僅包含 BeanFactory 所有功能,還擴(kuò)展了容器功能,需要的朋友可以參考下
    2023-11-11
  • spring boot實(shí)現(xiàn)過(guò)濾器和攔截器demo

    spring boot實(shí)現(xiàn)過(guò)濾器和攔截器demo

    本篇文章主要介紹了spring boot實(shí)現(xiàn)過(guò)濾器和攔截器demo ,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-02-02
  • IDEA實(shí)現(xiàn)添加 前進(jìn)后退 到工具欄的操作

    IDEA實(shí)現(xiàn)添加 前進(jìn)后退 到工具欄的操作

    這篇文章主要介紹了IDEA 前進(jìn) 后退 添加到工具欄的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2021-02-02
  • shiro與spring集成基礎(chǔ)Hello案例詳解

    shiro與spring集成基礎(chǔ)Hello案例詳解

    這篇文章主要介紹了shiro與spring集成基礎(chǔ)Hello案例詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-11-11
  • 詳解spring mvc對(duì)異步請(qǐng)求的處理

    詳解spring mvc對(duì)異步請(qǐng)求的處理

    spring mvc3.2及以上版本增加了對(duì)請(qǐng)求的異步處理,是在servlet3的基礎(chǔ)上進(jìn)行封裝的,有興趣的可以了解一下。
    2017-01-01
  • JDK安裝配置教程

    JDK安裝配置教程

    這篇文章主要為大家詳細(xì)介紹了JDK安裝配置教程,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-01-01
  • SpringBoot整合Shiro兩種方式(總結(jié))

    SpringBoot整合Shiro兩種方式(總結(jié))

    這篇文章主要介紹了SpringBoot整合Shiro兩種方式,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-06-06

最新評(píng)論

武定县| 墨竹工卡县| 西丰县| 嘉鱼县| 上思县| 子长县| 屏东县| 湘阴县| 双鸭山市| 梁平县| 银川市| 兴山县| 建德市| 安溪县| 浦城县| 麟游县| 玉林市| 上饶县| 马龙县| 阿勒泰市| 乌拉特中旗| 松阳县| 科尔| 江阴市| 深泽县| 扶风县| 巴东县| 蓬莱市| 金昌市| 文山县| 开江县| 黎城县| 怀化市| 南雄市| 工布江达县| 玉门市| 遂宁市| 台东市| 安图县| 黄石市| 马公市|