十二.SpringCloud+Security+Oauth2实现微服务授权 - 资源服务器配置

简介: SpringCloud+Security+Oauth2实现微服务授权 - 资源服务器配置

1.概述Oauth2资源服务配置

资源服务器也需要导入oauth2的依赖

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

当客户端(web端,mobile移动端)带着Token向资源服务器发起请求获取资源,资源服务器需要对请求中的Token进行校验以及对资源进行授权,如果Token校验和授权都通过即可返回相应的数据给客户端,那么,资源服务器配什么?

Oauth2提供的资源服务配置类为ResourceServerConfigurerAdapter ,它实现与ResourceServerConfigurer 接口,提供了两个configure方法,源码如下:

**
 * @author Dave Syer
 *
 */
public class ResourceServerConfigurerAdapter implements ResourceServerConfigurer {
   
   
   @Override
   public void configure(ResourceServerSecurityConfigurer resources)
 throws Exception {
   
    }

   @Override
   public void configure(HttpSecurity http) throws Exception {
   
   
      http.authorizeRequests().anyRequest().authenticated();
   }
}

注意上面是源码,别乱拷贝,解释一下:

  • ResourceServerSecurityConfigurer : 第一个configure方法的参数,它是资源服务安全配置,比如Token该如何校验就是通过它来配置的
  • HttpSecurity :第二个configure方法的参数,用作WEB安全配置,在学习Security基础的时候我们就接触过他

    2.资源服务器配置实战

    改造 “security-resource-server” ,增加资源服务器器配置类

    //资源服务配置
    @Configuration
    @EnableResourceServer   //开启资源服务配置
    public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
         
         
    
      //配置资源id ,对应oauth_client_details表中配置的resourceIds
      //一个资源ID可以对应一个资源服务器,如果Token中不包含该资源ID就无法访问该资源服务器
      public static final String RESOURCE_ID = "res1";
    
      @Bean
      public TokenStore tokenStore(){
         
         
          //return new InMemoryTokenStore();
          return new JwtTokenStore(jwtAccessTokenConverter());
      }
      //JWT令牌校验工具
      @Bean
      public JwtAccessTokenConverter jwtAccessTokenConverter(){
         
         
          JwtAccessTokenConverter jwtAccessTokenConverter = new JwtAccessTokenConverter();
          //设置JWT签名密钥。它可以是简单的MAC密钥,也可以是RSA密钥
          jwtAccessTokenConverter.setSigningKey("123");
          return jwtAccessTokenConverter;
      }
      //资源服务器安全性配置
      @Override
      public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
         
         
          //资源ID,请求中的Token必须有用该资源ID的访问权限才可以访问该资源服务器
          resources.resourceId(RESOURCE_ID);
          //指定TokenStore,使用JWT校验
          resources.tokenStore(tokenStore());
          //无状态
          resources.stateless(true);
          //验证令牌的服务,令牌验证通过才允许获取资源,使用远程校验
          //resources.tokenServices(resourceServerTokenServices());
      }
    
      //资源服务令牌验证服务,通过远程校验令牌
      /**
      @Bean
      public ResourceServerTokenServices resourceServerTokenServices(){
          //使用远程服务请求授权服务器校验token , 即:资源服务和授权服务器不在一个主机
          RemoteTokenServices services = new RemoteTokenServices();
          //授权服务地址 , 当浏览器访问某个资源时就会调用该远程授权服务地址去校验token
          //要求请求中必须携带token
          services.setCheckTokenEndpointUrl("http://localhost:3000/oauth/check_token");
          //客户端id,对应认证服务的客户端详情配置oauth_client_details表中的clientId
          services.setClientId("webapp");
          //密钥,对应认证服务的客户端详情配置的秘钥
          services.setClientSecret("secret");
          return services;
      }
      */
      //SpringSecurity的相关配置
      @Override
      public void configure(HttpSecurity http) throws Exception {
         
         
          http.authorizeRequests()
                  //校验scope必须为all , 对应认证服务的客户端详情配置的clientId
                  .antMatchers("/**").access("#oauth2.hasScope('all')")
                  //关闭跨域伪造检查
                  .and().csrf().disable()
                  //把session设置为无状态,意思是使用了token,那么session不再做数据的记录
                  .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
      }
    }
    
  • resources.tokenStore(tokenStore()) :这是在配置Token的校验方式,使用的是JwtTokenStore,JWT自校验的方式,当然这里也可以使用resources.tokenServices指定一个RemoteTokenServices 远程校验方案,这种方案的流程是当请求到达资源服务器,资源服务会带着请求中的token,向认证服务器发起远程校验(/oauth/check_token) ,可想而知性能不怎么好。

  • resources.resourceId(RESOURCE_ID):这个是配置资源服务器ID,意思是访问这个资源服务器的请求中的Token必须包含这个资源ID的访问权限

  • .antMatchers("/**").access("#oauth2.hasScope('all')"):意思是Token必须拥有all的授权访问才可以访问到资源服务器

注意:这里在配置类上开启了@EnableGlobalMethodSecurity(prePostEnabled = true),因为我这里需要使用方法授权的方式指明我们的controller方法需要什么样的权限才能访问,当然也可以使用web授权的方式(回顾web授权和方法授权)

3.编写controller

controller就是具体的资源了,我们的方法使用了注解授权

@RestController
public class ResourceController {
   
   

    @RequestMapping("/employee/list")
    //这是一个测试方法,如果资源服务器对token校验通过就能够访问该资源
    @PreAuthorize("hasAnyAuthority('employee:list')")
    public String list(){
   
   
        return "您的token验证通过,已经访问到真正的资源 employee:list";
    }

    @RequestMapping("/employee/add")
    //这是一个测试方法,如果资源服务器对token校验通过就能够访问该资源
    @PreAuthorize("hasAnyAuthority('employee:add')")
    public String add(){
   
   
        return "您的token验证通过,已经访问到真正的资源 employee:add";
    }
}

该Controller作为测试返回数据,当客户端请求“oauth-resource”过来,如果Token校验成功,将会看到"您的token验证通过,已经访问到真正的资源"

注意:需要在资源服务配置类“ResourceServerConfig ”开启全局方法授权:@EnableGlobalMethodSecurity(prePostEnabled = true)

4.测试

再走一遍获取token的流程,然后带着Token访问资源服务器,请求头携带:Authorization=Bearer token值 ,如下:
image.png

这里我们已经成功的访问到真正的资源 , 请求资源之前,资源服务器会发送远程请求到授权服务器验证token的合法性,并且根据当前token获取权限列表,然后在进行授权,如果权限列表拥有资源(controller的方法)所需要的权限,即可访问成功 。

如果Token是无效的会出现如下信息:
image.png

如果Token中的权限不包含资源所需要的权限会出现如下信息:
image.png

5.总结资源服务器配置

资源服务器的配置不是很多,主要是配置如下内容:

  1. 通过HttpSecurity配置 #oauth2.hasScope('all') 资源服务器的授权范围
  2. 通过ResourceServerSecurityConfigurer 配置资源服务器的ResourceID
  3. 通过ResourceServerSecurityConfigurer 配置资源服务器如何校验Token,这里使用的是RemoteTokenServices 远程校验方式

那么资源服务器的执行流程是怎么样的呢?

  1. 我们请求头中带着Token向资源服务器发送请求
  2. 资源服务器收到请求,得到Token后通过jwtAccessTokenConverter转换器进行Token的转换得到Token中的认证授权信息
  3. 然后资源服务器会校验认证信息中是否拥有资源服务器配置的授权范围(Scope),资源ID(ResourceID),如果都验证通过资源服务器还会校验权限列表是否包含当前访问的资源(controller)说需要的权限
  4. 如果授权范围(Scope),资源ID(ResourceID),方法授权都校验通过就执行相关的方法返回资源

最后再配一张认证服务到资源服务器的完整流程图吧:

image.png

相关文章
|
缓存 Java API
微服务——SpringBoot使用归纳——Spring Boot集成 Swagger2 展现在线接口文档——Swagger2 的配置
本文介绍了在Spring Boot中配置Swagger2的方法。通过创建一个配置类,添加`@Configuration`和`@EnableSwagger2`注解,使用Docket对象定义API文档的详细信息,包括标题、描述、版本和包路径等。配置完成后,访问`localhost:8080/swagger-ui.html`即可查看接口文档。文中还提示了可能因浏览器缓存导致的问题及解决方法。
1408 0
微服务——SpringBoot使用归纳——Spring Boot集成 Swagger2 展现在线接口文档——Swagger2 的配置
|
Java 关系型数据库 数据库
微服务——SpringBoot使用归纳——Spring Boot事务配置管理——Spring Boot 事务配置
本文介绍了 Spring Boot 中的事务配置与使用方法。首先需要导入 MySQL 依赖,Spring Boot 会自动注入 `DataSourceTransactionManager`,无需额外配置即可通过 `@Transactional` 注解实现事务管理。接着通过创建一个用户插入功能的示例,展示了如何在 Service 层手动抛出异常以测试事务回滚机制。测试结果表明,数据库中未新增记录,证明事务已成功回滚。此过程简单高效,适合日常开发需求。
1942 0
|
Java 测试技术 微服务
微服务——SpringBoot使用归纳——Spring Boot中的项目属性配置——少量配置信息的情形
本课主要讲解Spring Boot项目中的属性配置方法。在实际开发中,测试与生产环境的配置往往不同,因此不应将配置信息硬编码在代码中,而应使用配置文件管理,如`application.yml`。例如,在微服务架构下,可通过配置文件设置调用其他服务的地址(如订单服务端口8002),并利用`@Value`注解在代码中读取这些配置值。这种方式使项目更灵活,便于后续修改和维护。
428 0
|
SQL Java 数据库连接
微服务——SpringBoot使用归纳——Spring Boot使用slf4j进行日志记录—— application.yml 中对日志的配置
在 Spring Boot 项目中,`application.yml` 文件用于配置日志。通过 `logging.config` 指定日志配置文件(如 `logback.xml`),实现日志详细设置。`logging.level` 可定义包的日志输出级别,例如将 `com.itcodai.course03.dao` 包设为 `trace` 级别,便于开发时查看 SQL 操作。日志级别从高到低为 ERROR、WARN、INFO、DEBUG,生产环境建议调整为较高级别以减少日志量。本课程采用 yml 格式,因其层次清晰,但需注意格式要求。
1581 0
|
Java 数据库连接 微服务
微服务——MyBatis配置——事务管理
本段内容主要介绍了事务管理的两种类型:JDBC 和 MANAGED。JDBC 类型直接利用数据源连接管理事务,依赖提交和回滚机制;而 MANAGED 类型则由容器全程管理事务生命周期,例如 JEE 应用服务器上下文,默认会关闭连接,但可根据需要设置 `closeConnection` 属性为 false 阻止关闭行为。此外,提到在使用 Spring + MyBatis 时,无需额外配置事务管理器,因为 Spring 模块自带的功能可覆盖上述配置,且这两种事务管理器类型均无需设置属性。
271 0
|
Java 数据库连接 数据库
微服务——MyBatis配置——多环境配置
在 MyBatis 中,多环境配置允许为不同数据库创建多个 SqlSessionFactory。通过传递环境参数给 SqlSessionFactoryBuilder,可指定使用哪种环境;若忽略,则加载默认环境。`environments` 元素定义环境配置,包括默认环境 ID、事务管理器和数据源类型等。每个环境需唯一标识,确保默认环境匹配其中之一。代码示例展示了如何构建工厂及配置 XML 结构。
264 0
|
Java 数据库连接 数据库
微服务——SpringBoot使用归纳——Spring Boot集成MyBatis——MyBatis 介绍和配置
本文介绍了Spring Boot集成MyBatis的方法,重点讲解基于注解的方式。首先简述MyBatis作为持久层框架的特点,接着说明集成时的依赖导入,包括`mybatis-spring-boot-starter`和MySQL连接器。随后详细展示了`properties.yml`配置文件的内容,涵盖数据库连接、驼峰命名规范及Mapper文件路径等关键设置,帮助开发者快速上手Spring Boot与MyBatis的整合开发。
1993 0
|
缓存 Java 应用服务中间件
微服务——SpringBoot使用归纳——Spring Boot集成Thymeleaf模板引擎——依赖导入和Thymeleaf相关配置
在Spring Boot中使用Thymeleaf模板,需引入依赖`spring-boot-starter-thymeleaf`,并在HTML页面标签中声明`xmlns:th=&quot;http://www.thymeleaf.org&quot;`。此外,Thymeleaf默认开启页面缓存,开发时建议关闭缓存以实时查看更新效果,配置方式为`spring.thymeleaf.cache: false`。这可避免因缓存导致页面未及时刷新的问题。
560 0
|
Java 数据库 微服务
微服务——SpringBoot使用归纳——Spring Boot中的项目属性配置——指定项目配置文件
在实际项目中,开发环境和生产环境的配置往往不同。为简化配置切换,可通过创建 `application-dev.yml` 和 `application-pro.yml` 分别管理开发与生产环境配置,如设置不同端口(8001/8002)。在 `application.yml` 中使用 `spring.profiles.active` 指定加载的配置文件,实现环境快速切换。本节还介绍了通过配置类读取参数的方法,适用于微服务场景,提升代码可维护性。课程源码可从 [Gitee](https://gitee.com/eson15/springboot_study) 下载。
803 0
|
Java 微服务 Spring
微服务——SpringBoot使用归纳——Spring Boot中的项目属性配置——少量配置信息的情形
在微服务架构中,随着业务复杂度增加,项目可能需要调用多个微服务。为避免使用`@Value`注解逐一引入配置的繁琐,可通过定义配置类(如`MicroServiceUrl`)并结合`@ConfigurationProperties`注解实现批量管理。此方法需在配置文件中设置微服务地址(如订单、用户、购物车服务),并通过`@Component`将配置类纳入Spring容器。最后,在Controller中通过`@Resource`注入配置类即可便捷使用,提升代码可维护性。
320 0