OAuth2 使用Zuul细粒度权限控制笔记

2023-11-09

先置条件(基于我的项目) 假设我现在 有gateway-service(网关)    auth-service(权限认证) game-service(游戏)  ad-service (广告)

使用相关版本如下:(版本搭配参考:https://github.com/alibaba/spring-cloud-alibaba/wiki/%E7%89%88%E6%9C%AC%E8%AF%B4%E6%98%8E)

<!--springboot 版本-->
<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.5.RELEASE</version>
</parent>

 <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <spring-cloud.version>Hoxton.SR3</spring-cloud.version>
        <spring-cloud-alibaba.version>2.2.0.RELEASE</spring-cloud-alibaba.version>
</properties>

<dependencyManagement>
        <dependencies>
            <!--整合spring cloud-->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!--整合spring cloud alibaba-->
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>${spring-cloud-alibaba.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
</dependencyManagement>


1.game-service 通过feign调用 ad-service服务 现在要细粒度控制权限 采用OAuth2 来实现 首先4个微服务 都添加如下依赖:

<dependency>
   <groupId>org.springframework.cloud</groupId>
   <artifactId>spring-cloud-starter-oauth2</artifactId>
</dependency>

2.gateway-service(网关)  game-service(游戏)  ad-service (广告) yml 配置文件添加配置

security:
  oauth2:
    client:
      #client-id  client-secret 请根据自己不同的服务 填写配置信息
      client-id: gateway_client
      client-secret: 123456
    resource:
      jwt:
        #这个是认证服务器地址 即auth-service
        key-uri: http://localhost:8032/oauth/token_key  #访问路径参考源码 org.springframework.security.oauth2.provider.endpoint

3.实现微服务之间权限控制

//在需要控制的方法上添加注解
@PreAuthorize("#oauth2.hasScope('delete')")


//启动类上添加注解 prePostEnabled即在请求方法之前执行校验
@EnableGlobalMethodSecurity(prePostEnabled = true)

4.针对具体用户

//@see org.springframework.security.core.userdetails
//添加访问方法的控制具体用户注解 hasRole权限有哪些 是通过UserDetailsService中的loadUserByUsername方法来加载
@PreAuthorize("hasRole('ROLE_ADMIN')")


//启动类上添加注解 prePostEnabled即在请求方法之前执行校验
@EnableGlobalMethodSecurity(prePostEnabled = true)

5.如果角色和权限 实时在变化 以上方式就不太合适 假设我现在有一个权限控制系统来获取用户拥有的角色或者权限 那么怎么在网关上来集成并实现呢

//修改网关配置 指定访问规则表达式 permissionService.hasPermission(request,authentication)
@Configuration
@EnableResourceServer
public class ZuulSecurityConfig extends ResourceServerConfigurerAdapter  {

    @Override
    public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
        resources.resourceId("gateway");

    }

    /**
     * @param http
     * @throws Exception
     */
    @Override
    public void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .antMatchers("/token/**").permitAll()
             .anyRequest().access("#permissionService.hasPermission(request,authentication)");    //指定访问规则 authentication当前用户
    }
}

这样写是不会生效的 我们需要自己来实现 PermissionService 

import org.springframework.security.core.Authentication;

import javax.servlet.http.HttpServletRequest;

/**
 * @author Jax
 * @Description 权限控制接口
 * @Date 2020/6/27 13:11
 */
public interface PermissionService {

    boolean hasPermission(HttpServletRequest request, Authentication auth);
}

实现这个方法

import cn.hutool.core.util.RandomUtil;
import org.apache.commons.lang.builder.ReflectionToStringBuilder;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;

/**
 * @author Jax
 * @Description 权限控制实现类
 * @Date 2020/6/27 13:13
 */
@Service
public class PermissionServiceImpl implements PermissionService {
    @Override
    public boolean hasPermission(HttpServletRequest request, Authentication auth) {
        //TODO 需要查询业务逻辑 来获取用户的权限信息 这里采用 反射方法 打印
        System.err.println(request.getRequestURI());
        System.err.println(ReflectionToStringBuilder.toString(auth));
        return RandomUtil.randomInt() % 2 == 0;
    }
}

然后重写权限表达式解析方法

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.security.core.Authentication;
import org.springframework.security.oauth2.provider.expression.OAuth2WebSecurityExpressionHandler;
import org.springframework.security.web.FilterInvocation;
import org.springframework.stereotype.Component;

/**
 * @author Jax
 * @Description 权限表达式解析处理器
 * @Date 2020/6/27 13:23
 */
@Component
public class ZuulWebSecurityExpressionHandler extends OAuth2WebSecurityExpressionHandler {
    //注入我们自己的permissionService
    @Autowired
    private PermissionService permissionService;

    /**
     * 创建一个评估的上下文
     * @param authentication
     * @param invocation
     * @return
     */
    @Override
    protected StandardEvaluationContext createEvaluationContextInternal(Authentication authentication, FilterInvocation invocation) {
        StandardEvaluationContext standardEvaluationContext = super.createEvaluationContextInternal(authentication, invocation);
        standardEvaluationContext.setVariable("permissionService",permissionService);
        return standardEvaluationContext;
    }
}

最后一步 在第5步开始的 ZuulSecurityConfig添加配置

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;

/**
 * @Description 网关资源认证配置
 * @Date 2020/6/24 16:43
 * @Author Jax
 */
@Configuration
@EnableResourceServer
public class ZuulSecurityConfig extends ResourceServerConfigurerAdapter  {

    //注入我们自己的权限表达式解析处理器
    @Autowired
    private ZuulWebSecurityExpressionHandler securityExpressionHandler;

    @Override
    public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
        resources.resourceId("gateway");
        resources.expressionHandler(securityExpressionHandler);
    }

    /**
     * @param http
     * @throws Exception
     */
    @Override
    public void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
              .anyRequest().access("#permissionService.hasPermission(request,authentication)");    //指定访问规则 authentication当前用户
    }
}

现在所有的权限 都是在网关来控制 可能会出现越权的情况 可以在每一个微服务都去做权限的校验(即上述方法 不推荐这样去做),一般细粒度的权限90%以上都是在网关上来控制 微服务之间互相调的时候 可以使用ip的黑白名单来控制访问的权限 !

此博客纪录为自己项目中需要使用的技术栈而学习的笔记~~~

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

OAuth2 使用Zuul细粒度权限控制笔记 的相关文章

随机推荐

  • 如何使用 Parallels Desktop 虚拟机在 Mac 上安装 Windows 系统!

    一 下载安装 Parallels Desktop for Mac 如果您刚开始接触 Parallels Desktop for Mac 请点击下载最新版本 访问 如果已是 Parallels Desktop 用户 请继续执行后续步骤 二 自
  • STM32使用bool型变量

    环境Keil5 编译器 include
  • facebook 获取好友列表

    直接上函数 public void getfriends if Session getActiveSession null Session getActiveSession isOpened new Request Session getA
  • javamail发送邮件

    废话不多说 直接上代码 以下三段代码是我的全部代码 朋友们如果想用 直接复制即可 jar包因为我不知道怎么传到javaeye上 所以朋友们回去自己打吧 我的代码有三个类 第一个类 MailSenderInfo java package co
  • Win10 AMD显卡不兼容造成的开机黑屏问题解决

    1 将以下文本粘贴到文本文件中 保存为ULPS Disable reg Windows Registry Editor Version 5 00 HKEY LOCAL MACHINE SYSTEM ControlSet001 Control
  • 根据点云高度赋色(附open3d python代码)

    绘制点云图时用颜色来表征其高度 我们先计算了点云的高度范围 然后把每个点的颜色根据高度来进行映射 稍微修改代码 我们也可以让高度颜色渐变转换为 X 轴距离颜色渐变 稍微修改代码 我们也可以让高度颜色渐变转换为 X 轴距离颜色渐变 codin
  • Promise 实现原理

    文章目录 一 Promise 介绍 二 promise 源码实现 一 Promise 介绍 定义 Promise 是异步编程的一种解决方法 比传统的回调函数和事件更合理 它是由社区提出和实现经由 ES6 将其写进语言标准 并在原生提供了 P
  • Linux安装python3和pip3

    安装python3 yum y install zlib devel bzip2 devel openssl devel ncurses devel sqlite devel readline devel tk devel gdbm dev
  • python serial打开M5串口重启问题

    使用比较常用的方法打开串口 import serial ser serial Serial COM3 115200 使用上述代码 第一次打开会导致m5重启 重启的原因可能跟烧录类似 在烧录程序完毕以后都会重启 解决方法 import ser
  • 问题/lib64/libc.so.6: version `GLIBC_2.18‘ not found

    1 首先下载GLIBC 2 18到本地 2 解压压缩包 3 cd进入到解压好的文件夹内 mkdir build 4 cd build 执行该命令 configure prefix usr disable profile enable add
  • python 绘制正弦余弦函数 matplotlib的基本使用

    matplotlib的基本使用 import matplotlib pyplot as mp import numpy as np x np linspace 0 2 np pi 1000 y sin np sin x y cos np c
  • [初学python]新类(new-style class)

    类 class 也是对象在python之中 万物皆对象 类也是对象 类的类 就被称为元类 即类是元类的实例 正如类的实例的行为取决于类 元类的实例 类 的行为也取决于元类 new style classes的由来new style clas
  • 华为OD机试真题Java_2022-2023-题目0189-最多等和不相交连续子序列

    最多等和不相交连续子序列 题目描述 给定一个数组 我们称其中连续的元素为连续子序列 称这些元素的和为连续子序列的和 数组中可能存在几组连续子序列 组内的连续子序列互不相交且有相同的和 求一组连续子序列 组内子序列的数目最多 输出这个数目 输
  • 笔记24-2(C语言进阶 程序环境和预处理)

    目录 注 预定义详解 预处理符号 举例 使用例 define define 定义标识符 define定义宏 括号很重要 define 替换规则 和 带副作用的宏参数 宏和函数的对比 命名约定 undef 命名行定义 条件编译 常见的条件编译
  • 宏定义 类模板 及类模板的全特化

    如下所示 定义一个宏函数 只要传入类型名 即可生成一个类模板 include
  • 图灵1月书讯:阅新书辞旧岁,览经典迎新年

    原文链接 本期小编为您特别推荐的是 说服人要懂心理学 著名行为心理学家 演讲大师最新力作 七大动力 丰富实例 教你做个说服高手 Susan M Weinschenk拥有行为心理学博士学位 在35年的职业生涯中 她一直致力于把心理学领域对人类
  • c语言把一个数组里面的部分值直接复制到另外一个数组

    头文件是 include
  • MATLAB实现费诺编码的计算与分析

    一 实验目的 1 理解霍费诺编码的原理 2 掌握费诺编码的方法和步骤 3 熟悉费诺编码的效率 4 本实验用Matlab语言编程实现费诺 Fano 编码 二 实验环境 windows XP MATLAB 7 三 实验原理 费诺编码算法如下 在
  • 【实战 01】心脏病二分类数据集

    目录 1 获取数据集 2 数据集介绍 3 数据预处理 4 构建随机森林分类模型 5 预测测试集数据 6 构建混淆矩阵 7 计算查全率 召回率 调和平均值 8 ROC曲线 AUC曲线 注 每一章节可以为一个py文件 4 5 6 7写在同一个文
  • OAuth2 使用Zuul细粒度权限控制笔记

    先置条件 基于我的项目 假设我现在 有gateway service 网关 auth service 权限认证 game service 游戏 ad service 广告 使用相关版本如下 版本搭配参考 https github com a