日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

前言

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

一、整體架構

跟常用框架SpringSecurity比 微服務到底勝在哪?

 


整體結構

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

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

二、實現步驟

跟常用框架SpringSecurity比 微服務到底勝在哪?

 


登陸鑒權流程

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);    }}
  • 用戶驗證通過后,下發userToken,保存當前登陸信息,緩存用戶授權列表
  • 緩存授權列表時,為了方便讀取使用hash方式保存為list,切勿直接將數組對象保存為一個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 所有配置過的權限列表需要在程序啟動時放入緩存,并需要保持數據的更新

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>

四、完整代碼

gitee.com/hypier/barr…

 

最后

大家看完有什么不懂的可以在下方留言討論.

謝謝你的觀看。

覺得文章對你有幫助的話記得關注我點個贊支持一下!

鏈接:https://juejin.im/post/6865580470151675918

分享到:
標簽:微服
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定