SpringCloud下如何实现用户鉴权呢?

重生 Spring Cloud 发布时间:2024-01-04 22:35:05 阅读数:14402 1
下文笔者讲述SpringCloud实现用户鉴权的方法及示例分享,如下所示

SpringCloud用户鉴权的实现思路

    重写网关的AbstractGatewayFilterFactory类的
      apply方法
    达到鉴权的效果
例:

用户登陆

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);
    }
}

拦截请求

@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 所有配置过的权限列表需要在程序启动时放入缓存,并需要保持数据的更新

鉴权Filter配置

spring:
  cloud:
    gateway:
      routes:
        - id: cloud-user
          uri: lb://cloud-user  # 后端服务名
          predicates:
            - Path=/user/**   # 路由地址
          filters:
            - name: AuthenticationFilter  # 身份认证
            - name: AuthorizationFilter   # 用户鉴权
            - StripPrefix=1 # 去掉前缀
版权声明

本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。

本文链接: https://www.Java265.com/JavaFramework/SpringCloud/202401/7625.html

最近发表

热门文章

好文推荐

Java265.com

https://www.java265.com

站长统计|粤ICP备14097017号-3

Powered By Java265.com信息维护小组

使用手机扫描二维码

关注我们看更多资讯

java爱好者