{"id":15287546,"url":"https://github.com/eacdy/light-security","last_synced_at":"2025-08-21T02:32:18.575Z","repository":{"id":57725211,"uuid":"182076705","full_name":"eacdy/light-security","owner":"eacdy","description":"Light Security是一个基于jwt的权限控制框架，支持与Spring Boot配合使用，支持Spring MVC与WebFlux","archived":false,"fork":false,"pushed_at":"2022-03-28T16:31:42.000Z","size":88,"stargazers_count":125,"open_issues_count":2,"forks_count":36,"subscribers_count":6,"default_branch":"master","last_synced_at":"2024-12-10T05:42:47.418Z","etag":null,"topics":["role-based-access-control","security","spring-mvc","webflux"],"latest_commit_sha":null,"homepage":"http://www.itmuch.com","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/eacdy.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-04-18T11:39:21.000Z","updated_at":"2024-07-09T14:34:53.000Z","dependencies_parsed_at":"2022-09-08T16:51:57.943Z","dependency_job_id":null,"html_url":"https://github.com/eacdy/light-security","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eacdy%2Flight-security","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eacdy%2Flight-security/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eacdy%2Flight-security/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eacdy%2Flight-security/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/eacdy","download_url":"https://codeload.github.com/eacdy/light-security/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":230198045,"owners_count":18188752,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["role-based-access-control","security","spring-mvc","webflux"],"created_at":"2024-09-30T15:30:45.579Z","updated_at":"2024-12-19T18:18:21.522Z","avatar_url":"https://github.com/eacdy.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Light Security\n\nLight Security是一款基于 `jwt` 的、简洁而不简单的权限控制框架，可与 `Spring Boot` 配合使用，支持 `Spring MVC` 及 `WebFlux` 。\n\n\n\n## 地址\n\n* [GitHub](https://github.com/eacdy/light-security)\n* [Gitee](https://gitee.com/itmuch/light-security)\n\n\n\n## 特点\n\n### 优点\n\n- 上手快速\n- **开箱即用**\n- **轻量级，代码精简，不到500行代码**；\n- **功能实用，市面上安全框架常见能力与套路均已具备**：\n  - 支持 `RESTful` 权限控制\n  - 支持灵活的权限配置(**代码配置方式优先级更高**)\n    - 支持基于配置文件的权限配置\n    - 支持基于代码的权限控制\n  - 支持基于注解的权限控制\n- 设计简单，没有复杂概念；\n  - Spring Web编程模型\n    - 基于权限配置的方式：核心是1个拦截器\n    - 基于注解的权限控制：核心是1个切面\n  - WebFlux编程模型\n    - 基于权限配置的方式：核心是1个过滤器\n    - 基于注解的权限控制：核心是1个切面\n\n### 缺点\n\n* 功能\n  * 比 Spring Security 弱一点\n  * 和Shiro比功能差不多，但没有实现复杂的Authentication Strategy（想实现也很简单，详见扩展点）\n* **只考虑权限相关问题**\n  * 不考虑身份认证(登录)，意味着登录逻辑得自己玩；\n  * 不考虑防攻击，意味着网络攻击得自己防；\n\n\n\n## 依赖\n\n* Spring MVC：用到Spring MVC的拦截器，如只使用基于注解的权限控制，则无需该部分依赖；\n* Spring WebFlux：用到WebFlux的Filter，如只使用基于注解的权限控制，则无需该部分依赖；\n* Spring AOP：如果不用基于注解的权限控制，则无需该部分依赖；\n* jwt：你懂的\n\n\n\n## 快速上手\n\n### Spring Web编程模型\n\n\u003e **TIPS**\n\u003e\n\u003e 快速上手可详见项目 `light-security-example` 目录，内附详细测试步骤。\n\n#### 基于配置文件的权限配置\n\n* 加依赖：\n\n  ```xml\n  \u003cdependency\u003e\n      \u003cgroupId\u003ecom.itmuch.security\u003c/groupId\u003e\n      \u003cartifactId\u003elight-security-spring-boot-starter\u003c/artifactId\u003e\n      \u003cversion\u003e1.1.0-RELEASE\u003c/version\u003e\n  \u003c/dependency\u003e\n  \u003cdependency\u003e\n      \u003cgroupId\u003eorg.springframework.boot\u003c/groupId\u003e\n      \u003cartifactId\u003espring-boot-starter-aop\u003c/artifactId\u003e\n  \u003c/dependency\u003e\n  ```\n\n* 写配置\n\n  ```yaml\n  server:\n    port: 8009\n  light-security:\n    # 权限规则配置：表示用{http-method}方法请求的{path}路径必须具备什么{expression}\n    spec-list:\n      - http-method: ANY\n        path: /login\n        expression: \"anon()\"\n      - http-method: ANY\n        path: /user\n        expression: \"hasAnyRoles('user','admin')\"\n      - http-method: ANY\n        path: /user-no-access\n        expression: \"hasAllRoles('user','admin','xx')\"\n      - http-method: GET\n        path: /error\n        expression: \"anon()\"\n      - http-method: ANY\n        path: /**\n        expression: \"hasLogin()\"\n    jwt:\n      # jwt sign算法\n      algorithm: hs512\n      # jwt secret\n      secret: {secret}\n      # jwt 有效时间\n      expiration-in-second: 1209600\n  ```\n\n* 写代码：\n\n  ```java\n  @RequestMapping\n  @RestController\n  @RequiredArgsConstructor(onConstructor = @__(@Autowired))\n  public class TestController {\n      private final UserOperator userOperator;\n      private final JwtOperator operator;\n  \n      /**\n       * 演示如何获取当前登录用户信息\n       * - 该路径需要具备user或admin权限才可访问，详见application.yml\n       *\n       * @return 用户信息\n       */\n      @GetMapping(\"/user\")\n      public User user() {\n          return userOperator.getUser();\n      }\n  \n      @GetMapping(\"/user-no-access\")\n      public User userNoAccess() {\n          return userOperator.getUser();\n      }\n  \n      /**\n       * 演示基于注解的权限控制\n       *\n       * @return 如果有权限返回 亲，你同时有user、admin角色..\n       */\n      @GetMapping(\"/annotation-test\")\n      @PreAuthorize(\"hasAllRoles('user','admin')\")\n      public String annotationTest() {\n          return \"亲，你同时有user、admin角色..\";\n      }\n  \n      @GetMapping(\"/annotation-test-no-access\")\n      @PreAuthorize(\"hasAllRoles('user','admin','xx')\")\n      public String annotationTestNoAccess() {\n          return \"亲，你同时有user、admin、xx角色..\";\n      }\n  \n      /**\n       * 模拟登录，颁发token\n       *\n       * @return token字符串\n       */\n    @GetMapping(\"/login\")\n      public String loginReturnToken() {\n          User user = User.builder()\n                  .id(1)\n                  .username(\"张三\")\n                  .roles(Arrays.asList(\"user\", \"admin\"))\n                  .build();\n          return operator.generateToken(user);\n      }\n  }\n  ```\n  \n  \n\n#### 基于代码的权限配置\n\n```java\n@Configuration\npublic class LightSecurityConfigurtion {\n    @Bean\n    public SpecRegistry specRegistry() {\n        return new SpecRegistry()\n                .add(HttpMethod.GET, \"/user\", \"hasAnyRoles('user')\")\n                .add(HttpMethod.ANY, \"/**\", \"hasLogin()\");\n    }\n}\n```\n\n此时，`application.yml` 中的如下配置可删除，**因为代码配置方式优先级更高，配置文件方式将会失效**。\n\n```yaml\nlight-security:\n  # 权限规则配置：表示用{http-method}方法请求的{path}路径必须具备什么{expression}\n  spec-list:\n    - http-method: ANY\n      path: /login\n      expression: \"anon()\"\n    - http-method: ANY\n      path: /user\n      expression: \"hasAnyRoles('user','admin')\"\n    - http-method: ANY\n      path: /user-no-access\n      expression: \"hasAllRoles('user','admin','xx')\"\n    - http-method: GET\n      path: /error\n      expression: \"anon()\"\n    - http-method: ANY\n      path: /**\n      expression: \"hasLogin()\"\n```\n\n\n\n#### 扩展点\n\n| 类                                                           | 作用                                                         |\n| ------------------------------------------------------------ | ------------------------------------------------------------ |\n| com.itmuch.lightsecurity.jwt.UserOperator                    | 提供用户相关操作，例如解析token获得用户信息等。              |\n| com.itmuch.lightsecurity.el.PreAuthorizeExpressionRoot       | 提供表达式支持，例如`hasAnyRoles('user')` 等，如需新能力，只需编写新方法即可 |\n| com.itmuch.lightsecurity.annotation.support.PreAuthorizeAspect | 为注解 `@PreAuthorize(\"hasAllRoles('user','admin')\")`提供支持 |\n\n\n\n### WebFlux编程模型\n\n\u003e **TIPS**\n\u003e\n\u003e 快速上手可详见项目 `light-security-webflux-example` 目录，内附详细测试步骤。\n\n#### 基于配置文件的权限配置\n\n* 加依赖\n\n  ```xml\n  \u003cdependency\u003e\n    \u003cgroupId\u003eorg.springframework.boot\u003c/groupId\u003e\n    \u003cartifactId\u003espring-boot-starter-webflux\u003c/artifactId\u003e\n  \u003c/dependency\u003e\n  \u003cdependency\u003e\n    \u003cgroupId\u003ecom.itmuch.security\u003c/groupId\u003e\n    \u003cartifactId\u003elight-security-webflux-spring-boot-starter\u003c/artifactId\u003e\n    \u003cversion\u003e1.1.0-RELEASE\u003c/version\u003e\n  \u003c/dependency\u003e\n  ```\n\n* 写配置\n\n  ```yaml\n  server:\n    port: 8009\n  light-security:\n    # 权限规则配置：表示用{http-method}方法请求的{path}路径必须具备什么{expression}\n    spec-list:\n      - http-method: ANY\n        path: /login\n        expression: \"anon()\"\n      - http-method: ANY\n        path: /user\n        expression: \"hasAnyRoles('user','admin')\"\n      - http-method: ANY\n        path: /user-no-access\n        expression: \"hasAllRoles('user','admin','xx')\"\n      - http-method: GET\n        path: /error\n        expression: \"anon()\"\n      - http-method: ANY\n        path: /**\n        expression: \"hasLogin()\"\n    jwt:\n      # jwt sign算法\n      algorithm: hs512\n      # jwt secret\n      secret: {secret}\n      # jwt 有效时间\n      expiration-in-second: 1209600\n  ```\n\n* 写代码\n\n  ```java\n  @RequestMapping\n  @RestController\n  @RequiredArgsConstructor(onConstructor = @__(@Autowired))\n  public class TestController {\n      private final ReactiveUserOperator userOperator;\n      private final JwtOperator operator;\n  \n      /**\n       * 演示如何获取当前登录用户信息\n       * - 该路径需要具备user或admin权限才可访问，详见application.yml\n       *\n       * @return 用户信息\n       */\n      @GetMapping(\"/user\")\n      public Mono\u003cUser\u003e user() {\n          return userOperator.getUser();\n      }\n  \n      @GetMapping(\"/user-no-access\")\n      public Mono\u003cUser\u003e userNoAccess() {\n          return userOperator.getUser();\n      }\n  \n      /**\n       * 演示基于注解的权限控制\n       *\n       * @return 如果有权限返回 亲，你同时有user、admin角色..\n       */\n      @GetMapping(\"/annotation-test\")\n      @PreAuthorize(\"hasAllRoles('user','admin')\")\n      public Mono\u003cString\u003e annotationTest() {\n          return Mono.just(\"亲，你同时有user、admin角色..\");\n      }\n  \n      @GetMapping(\"/annotation-test-no-access\")\n      @PreAuthorize(\"hasAllRoles('user','admin','xx')\")\n      public Mono\u003cString\u003e annotationTestNoAccess() {\n          return Mono.just(\"亲，你同时有user、admin、xx角色..\");\n      }\n  \n      /**\n       * 模拟登录，颁发token\n       *\n       * @return token字符串\n       */\n      @GetMapping(\"/login\")\n      public String loginReturnToken() {\n          User user = User.builder()\n                  .id(1)\n                  .username(\"张三\")\n                  .roles(Arrays.asList(\"user\", \"admin\"))\n                  .build();\n          return operator.generateToken(user);\n      }\n  }\n  ```\n\n\n\n#### 基于代码的权限配置\n\n```java\n@Configuration\npublic class LightSecurityConfigurtion {\n    @Bean\n    public SpecRegistry specRegistry() {\n        return new SpecRegistry()\n                .add(HttpMethod.GET, \"/user\", \"hasAnyRoles('user')\")\n                .add(HttpMethod.ANY, \"/**\", \"hasLogin()\");\n    }\n}\n```\n\n此时，`application.yml` 中的如下配置可删除，**因为代码配置方式优先级更高，配置文件方式将会失效**。\n\n```yaml\nlight-security:\n  # 权限规则配置：表示用{http-method}方法请求的{path}路径必须具备什么{expression}\n  spec-list:\n    - http-method: ANY\n      path: /login\n      expression: \"anon()\"\n    - http-method: ANY\n      path: /user\n      expression: \"hasAnyRoles('user','admin')\"\n    - http-method: ANY\n      path: /user-no-access\n      expression: \"hasAllRoles('user','admin','xx')\"\n    - http-method: GET\n      path: /error\n      expression: \"anon()\"\n    - http-method: ANY\n      path: /**\n      expression: \"hasLogin()\"\n```\n\n#### 扩展点\n\n| 类                                                           | 作用                                                         |\n| ------------------------------------------------------------ | ------------------------------------------------------------ |\n| com.itmuch.lightsecurity.jwt.ReactiveUserOperator            | 提供用户相关操作，例如解析token获得用户信息等。              |\n| com.itmuch.lightsecurity.el.ReactivePreAuthorizeExpressionRoot | 提供表达式支持，例如`hasAnyRoles('user')` 等，如需新能力，只需编写新方法即可 |\n| com.itmuch.lightsecurity.annotation.support.ReactivePreAuthorizeAspect | 为注解 `@PreAuthorize(\"hasAllRoles('user','admin')\")`提供支持 |\n\n\n\n## 常见问题\n\n### 为什么要造这个轮子？\n\n老是有人问我诸如\"微服务安全怎么管理？\"、\"Spring Security xxxx问题你遇到过吗？\"、\"能写个Spring Cloud Security的系列教程吗？\"、\"Shiroxxxx问题你遇到过吗？\"\n\n烦不胜烦，初期积极回复；后来消极回复；再后来懒得回复。\n\n分析一下，发现主要原因还是Spring Security、Shiro学习曲线较高，特别是Spring Security。所以就想写个轻量的框架，能够快速解决主要矛盾——足够简单、能实现权限控制。\n\n\n\n### 为什么不考虑身份认证(登录)？\n\n目前市面上大多权限框架都考虑了\"身份认证(登录)\" + \"权限管理\" 。然而登录操作在现在这个时代，是一个\"五花八门\"的操作。例如：\n\n* 手机号 + 验证码登录\n* 扫二维码登录\n* 账号密码登录\n* 证书登录\n\n往往还需还同时支持多种登录方式。这挺难去抽象出通用模式，并为典型的登录方式提供支持。\n\n索性不考虑了——把登录问题留给使用者自己。用户可根据业务需求实现登录逻辑，并颁发Token，后面的事情就交给 `Light Security` ，让它给你搞定。这样相对更加灵活，更重要的是——你也不再需要去学习用框架应该怎么登录。\n\n\n\n## TODO\n\n* 支持对称加密/非对称加密配置化；\n* 支持 `JWE` \n* 补充单元测试\n* 将框架与starter分离，否则既是框架，又是Starter感觉有点怪。\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feacdy%2Flight-security","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Feacdy%2Flight-security","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feacdy%2Flight-security/lists"}