前言

  • 若只有API放行,那么对于一些复杂的场景,肯定是不够的,我们需要更强大的认证功能
  • 经过较长的实践,BladeX实现了一套属于自己的安全配置,支持注解与配置两种方式
  • 话不多说,我们来看一下具体的使用方法

注解申明

@RestController
@AllArgsConstructor
@PreAuth("hasAuth()")
@RequestMapping("/blade-chat/weixin")
public class ApiScopeController extends BladeController {

   private final IWeixinService weixinService;

   @GetMapping("/user-info")
   public UserInfo userInfo() {
      return weixinService.userInfo();
   }

   @PostMapping("/send-message")
   public R<Message> sendMessage() {
      return weixinService.sendMessage();
   }

}
@RestController
@AllArgsConstructor
@RequestMapping("/blade-desk/dashboard")
public class DashboardController extends BladeController {

   private final IDashboardService dashboardService;

   @PreAuth("hasTimeAuth(9, 17)")
   @PostMapping("/upload")
   public UserInfo upload() {
      return dashboardService.upload();
   }

   @PreAuth("hasAnyRole('administrator', 'admin', 'user')")
   @PostMapping("/submit")
   public R submit() {
      return dashboardService.submit();
   }

}

配置文件申明

#blade配置
blade:
  #安全框架配置
  secure:
    #放行路径配置
    skip-url:
      - /blade-test
    #授权认证配置
    auth:
      - method: ALL
        pattern: /blade-chat/weixin
        #需要Token通过校验
        expression: "hasAuth()"
      - method: POST
        pattern: /blade-desk/dashboard/upload
        #需要在 [9:00-17:00] 之间调用
        expression: "hasTimeAuth(9, 17)"
      - method: POST
        pattern: /blade-desk/dashboard/submit
        #需要拥有 administrator或 admin 或 user 角色
        expression: "hasAnyRole('administrator', 'admin', 'user')"
    #基础认证配置
    basic:
      - method: ALL
        pattern: /blade-desk/dashboard/activities
        username: "blade"
        password: "blade"

代码配置申明

@Configuration
public class BladeConfiguration {

   @Bean
   public SecureRegistry secureRegistry() {
      // 创建认证类
      SecureRegistry secureRegistry = new SecureRegistry();
      // 认证放行配置
      secureRegistry.setEnabled(true);
      secureRegistry.excludePathPatterns("/blade-test/**");
      // 认证鉴权配置
      secureRegistry
         .addAuthPattern(HttpMethod.ALL, "/blade-chat/weixin/**", "hasAuth()")
         .addAuthPattern(HttpMethod.POST, "/blade-desk/dashboard/upload", "hasTimeAuth(9, 17)")
         .addAuthPattern(HttpMethod.POST, "/blade-desk/dashboard/submit", "hasAnyRole('administrator', 'admin', 'user')");
      // 基础认证配置
         secureRegistry.addBasicPattern(HttpMethod.POST, "/blade-desk/dashboard/upload", "blade", "blade");
      // 返回认证类
      return secureRegistry;
   }

}

认证实战

  1. 鉴权配置注解名称为 @PreAuth ,在需要进行鉴权配置的方法加上 @PreAuth 注解,并在注解内写入相关的鉴权方法,具体逻辑可以看(org.springblade.core.secure.auth.AuthFun)
  2. 为了可以起到对比的作用,对 count 进行权限放行(只要通过Token认证就可调用API)。
@GetMapping("count")
@PreAuth("permitAll()")
public Integer count(Integer cnt) {
   return cnt * 10;
}
  1. info进行权限判断,调用方需要拥有test的角色权限才可以调用
@GetMapping("info")
@PreAuth("hasRole('test')")
public String info(String name) {
   return "Hello, My Name Is: " + name;
}
  1. 调用 /api/count 发现请求成功。
  2. 调用 /api/info 发现返回了 请求未授权,因为我们的admin账号没有分配test角色
  3. 尝试改回admin权限
@GetMapping("info")
@PreAuth("hasRole('administrator')")
public String info(String name) {
   return "Hello, My Name Is: " + name;
}
  1. 调用 /api/info 发现请求成功。

后记

  • Secure 框架进行了两层 API 鉴权。
  • 第一层校验请求携带的Token是否合法,不需要Token校验的可通过配置放行。
  • 第二层校验PreAuth配置的逻辑是否符合,若不符合也返回请求未授权
  • 注解 @PreAuth支持类层级和方法层级,放到类层级则对该类的所有方法进行鉴权。
  • 注解 @PreAuth还支持 Spring el 表达式,可拓展性非常高,更多功能等您挖掘~
  • Spring el 文档地址:https://docs.spring.io/spring/docs/5.1.6.RELEASE/spring-framework-reference/core.html#expressions
  • PreAuth的逻辑封装:org.springblade.core.secure.auth.AuthFun