2 Star 12 Fork 0

皇叔 / elegent-security-优雅权限框架

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
贡献代码
同步代码
取消
提示: 由于 Git 不支持空文件夾,创建文件夹后会生成空的 .keep 文件
Loading...
README
Apache-2.0

ElegentSecurity【优雅权限框架】

介绍

​ ElegentSecurity是一款的基于令牌的轻量级权限框架。 这个框架可以让你更优雅地在项目中实现权限控制。这个组件具有的特点:

  1. 基于令牌的轻量级的权限框架,适用于前后端分离的项目架构。
  2. 支持访问地址的拦截和注解方式的拦截。
  3. 既适用于基于微服务网关的分布式架构,也适用于单体的Springboot微服务架构。
  4. 所有设计均采用组件化,用户可以自己进行定制开发和扩展。

框架集成与配置

单体架构

(1)项目引入依赖:

<!--地址拦截模块 -->
<dependency>
    <groupId>cn.elegent.security</groupId>
    <artifactId>elegent-security-verifier-web</artifactId>
    <version>1.1.0</version>
</dependency>
<!--令牌签发模块-->
<dependency>
    <groupId>cn.elegent.security</groupId>
    <artifactId>elegent-security-token</artifactId>
    <version>1.1.0</version>
</dependency>
<!--注解支持-->
<dependency>
    <groupId>cn.elegent.security</groupId>
    <artifactId>elegent-security-annotation</artifactId>
</dependency>

(2)配置文件 参考以下格式

elegent:
  security:
    login-strategies:
      - type: admin
        strategy: username_password
        secret-key: elegent
        ttl: 2
    verifier:
      header:
        type: login-type
        token: user-token
      ignore-url:  # 忽略地址,不用登录也可以访问的地址
        - POST/login
        - POST/logout
      privilege-url: #特权地址,所有登录用户都可以访问的地址
        - GET/user/list
        - GET/goods/list
      privilege-user:
        - admin

配置说明:

login-strategies: 定义登录策略组,下面可以有多个登录策略。登录策略包括以下配置:

-- type: 登录策略类型名称,用户自定义。

-- strategy: 登录策略表达式。有如下几个值: username 、 password 、code 、mobile

例如一个系统有多种登录入口,管理员通过用户名密码登录,那么策略表达式就是username_password ,普通员工通过手机号验证码进行登录,那么策略表达式就是 mobile_code, 如果管理员的登录方式是用户名密码+图形验证码,那么策略表达式为 username_password_code

--secret-key: 密钥key

--ttl : 令牌过期时间

verifier: 验证相关配置

--header :头信息相关配置 ,用户需要将登录类型 和登录令牌以头的方式传给后端。

--ignore-url :忽略地址列表

--privilege-url :特权地址列表

--privilege-user :特权用户列表

微服务架构

认证微服务

(1)在需要提供登录功能的微服务上,添加依赖

<dependency>
    <groupId>cn.elegent.security</groupId>
    <artifactId>elegent-security-token</artifactId>
    <version>1.1.0</version>
</dependency>

(2)添加配置

elegent:
  security:
    login-strategies:
      - type: admin
        strategy: username_password
        secret-key: elegent
        ttl: 2

微服务网关

(1)引入依赖


<dependency>
    <groupId>cn.elegent.security</groupId>
    <artifactId>elegent-security-verifier-gateway</artifactId>
    <version>1.1.0</version>
</dependency>

(2)添加配置,例子如下:

elegent:
  security:
    login-strategies:
      - type: admin
        secret-key: elegent
    verifier:
      header:
        type: login-type
        token: user-token
      ignore-url:  # 忽略地址,不用登录也可以访问的地址
        - POST/login
        - POST/logout
      privilege-url: #特权地址,所有登录用户都可以访问的地址
        - GET/user/list
        - GET/goods/list
      privilege-user:
        - admin

其它微服务

其它的微服务,因为需要获取当前登录用户,需要引入上下文依赖

<dependency>
    <groupId>cn.elegent.security</groupId>
    <artifactId>elegent-security-context</artifactId>
    <version>1.1.0</version>
</dependency>

代码开发

定义用户服务类

用户服务类作用是根据用户名可以查询用户信息。框架中提供了用户服务类接口

/**
 * 用户认证
 */
public interface UserDetailsServices {


    /**
     * 根据用户名加载用户信息
     * param username
     * param type
     * return
     */
    UserDetails loadUserByUsername(String username, String type);

}

loadUserByUsername方法就是仅根据用户名以及类型,查询用户信息,封装到UserDetails类中。

框架提供了一个默认的实现类,其中定义了两个用户test 和admin ,密码均为123456 , 用于简单案例的测试。

所以项目在做了框架集成后,就自动会有admin 和 test 两个用户。

开发者需要自己创建一个实现了UserDetailsServices接口的实现类,来定义用户的查询和封装逻辑。

@Component
public class UserDetailServiceImpl implements UserDetailsServices {

    @Override
    public UserDetails loadUserByUsername(String username, String type) {
        //todo: 根据username和type查询数据库,然后封装到UserDetails中
    }
}

这样系统就会根据你编写的逻辑,实现查询用户逻辑。

测试:

POST http://localhost:8080/login

{
"username":"user",
"password":"123456",
"type":"admin"
}

返回内容:

{
    "tokenDetails": {
        "type": "admin",
        "accessToken": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJqdGkiOiJ1c2VyIiwiaWF0IjoxNjk0ODU1NTEyLCJwYXNzd29yZCI6IiQyYSQxMCRFakRwTVp1bFhuVFFvb25hTUsvdWN1WWljR0hFWko0VkZEY1BSYUZmWGRBcC9EblVkcW51LiIsInJvbGVzIjpbIlRFU1QiXSwicmVzb3VyY2VzIjpbIkdFVC90ZXN0Il0sImVuYWJsZWQiOnRydWUsInN1cGVyVXNlciI6ZmFsc2UsInVzZXJuYW1lIjoidXNlciIsImV4cCI6MTY5NDg2MjcxMn0.tlopU9blXr-exGPOSNuC85NgMZ47rslOQbRQYR4KorY",
        "refreshToken": null
    },
    "userDetails": {
        "username": "user",
        "password": null,
        "roles": [
            "TEST"
        ],
        "resources": [
            "GET/test"
        ],
        "enabled": true,
        "superUser": false
    },
    "errorInfo": null,
    "authenticated": true
}

图形验证码

框架提供了图形验证码的访问接口

http://localhost:8080/user/imageCode/{clientToken}

clientToken 是前端传递的用于区分每个用户的图形验证码的字符串

如果你要使用图形验证码登录验证,策略表达式为 username_password_code

完整的配置:

elegent:
  security:
    login-strategies:
      - type: admin
        strategy: username_password_code
        secret-key: elegent
        ttl: 2
    verifier:
      header:
        type: login-type
        token: user-token
      ignore-url:  # 忽略地址,不用登录也可以访问的地址
        - POST/login
        - POST/logout
      privilege-url: #特权地址,所有登录用户都可以访问的地址
        - GET/user/list
        - GET/goods/list
      privilege-user:
        - admin

登录测试:

POST http://localhost:8080/login

{
"username":"user",
"password":"123456",
"type":"admin",
"clientToken":"12345",
"code":"n2fn"
}

短信验证码

框架提供了短信验证码的访问接口

http://localhost:8080/user/code/{mobile}

系统没有提供发送短信的功能,生成的短信验证码会在控制台输出

用户需要自行实现发送短信验证码的逻辑,编写类实现 SmsService 接口

如果你要使用手机号验证码方式登录,策略表达式 为 mobile_code

完整的配置:

elegent:
  security:
    login-strategies:
      - type: admin
        strategy: username_password_code
        secret-key: elegent
        ttl: 2
      - type: user
        strategy: mobile_code
        secret-key: elegent
        ttl: 2
    verifier:
      header:
        type: login-type
        token: user-token
      ignore-url:  # 忽略地址,不用登录也可以访问的地址
        - POST/login
        - POST/logout
      privilege-url: #特权地址,所有登录用户都可以访问的地址
        - GET/user/list
        - GET/goods/list
      privilege-user:
        - admin

双令牌刷新

我们可以通过配置,实现令牌刷新

elegent:
  security:
    login-strategies:
      - type: admin
        strategy: username_password_code
        secret-key: elegent
        ttl: 2
        refresh-key: refreshElegent  ## 刷新令牌key
        refresh-ttl: 200  ## 刷新令牌过期时间

测试登录结果如下格式:

{
    "tokenDetails": {
        "type": "admin",
        "accessToken": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJqdGkiOiJ1c2VyIiwiaWF0IjoxNjk0ODY2NzE1LCJwYXNzd29yZCI6IiQyYSQxMCRGMC40dHUxUU9TZ1ZuOVpHYUNYTU1lRndOajhmT0RCeVc4Wk1lNjNJblNJcHlJNlRLbEt4cSIsInJvbGVzIjpbIlRFU1QiXSwicmVzb3VyY2VzIjpbIkdFVC90ZXN0Il0sImVuYWJsZWQiOnRydWUsInN1cGVyVXNlciI6ZmFsc2UsInVzZXJuYW1lIjoidXNlciIsImV4cCI6MTY5NDg3MzkxNX0.Louu97lVK4rrdPE4ttgsrDtayA2sbcwVAe12V1cEJpU",
        "refreshToken": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJqdGkiOiJ1c2VyIiwiaWF0IjoxNjk0ODY2NzE2LCJwYXNzd29yZCI6IiQyYSQxMCRGMC40dHUxUU9TZ1ZuOVpHYUNYTU1lRndOajhmT0RCeVc4Wk1lNjNJblNJcHlJNlRLbEt4cSIsInJvbGVzIjpbIlRFU1QiXSwicmVzb3VyY2VzIjpbIkdFVC90ZXN0Il0sImVuYWJsZWQiOnRydWUsInN1cGVyVXNlciI6ZmFsc2UsInVzZXJuYW1lIjoidXNlciIsImV4cCI6MTY5NTU4NjcxNn0.dI8COIi_dqyiu6mQ-8kydeOSkedIoWe9AjO6dXi2RDE"
    },
    "userDetails": {
        "username": "user",
        "password": null,
        "roles": [
            "TEST"
        ],
        "resources": [
            "GET/test"
        ],
        "enabled": true,
        "superUser": false
    },
    "errorInfo": null,
    "authenticated": true
}

refreshToken就是刷新令牌

当访问令牌过期后,我们可以通过刷新令牌再次获得最新的访问令牌和刷新令牌

POST http://localhost:8080/refresh/{type}

{
"refreshToken":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJqdGkiOiJ1c2VyIiwiaWF0IjoxNjk0ODY2NzE2LCJwYXNzd29yZCI6IiQyYSQxMCRGMC40dHUxUU9TZ1ZuOVpHYUNYTU1lRndOajhmT0RCeVc4Wk1lNjNJblNJcHlJNlRLbEt4cSIsInJvbGVzIjpbIlRFU1QiXSwicmVzb3VyY2VzIjpbIkdFVC90ZXN0Il0sImVuYWJsZWQiOnRydWUsInN1cGVyVXNlciI6ZmFsc2UsInVzZXJuYW1lIjoidXNlciIsImV4cCI6MTY5NTU4NjcxNn0.dI8COIi_dqyiu6mQ-8kydeOSkedIoWe9AjO6dXi2RDE"
}

得到最新的令牌

{
    "type": "admin",
    "accessToken": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJqdGkiOiJ1c2VyIiwiaWF0IjoxNjk0ODY3MTM2LCJwYXNzd29yZCI6IiQyYSQxMCRGMC40dHUxUU9TZ1ZuOVpHYUNYTU1lRndOajhmT0RCeVc4Wk1lNjNJblNJcHlJNlRLbEt4cSIsInJvbGVzIjpbIlRFU1QiXSwicmVzb3VyY2VzIjpbIkdFVC90ZXN0Il0sImVuYWJsZWQiOnRydWUsInN1cGVyVXNlciI6ZmFsc2UsInVzZXJuYW1lIjoidXNlciIsImV4cCI6MTY5NDg3NDMzNn0.-vYyGVBKSiWatYWRVPhcneKjNj8pNKIWs5INg4660yU",
    "refreshToken": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJqdGkiOiJ1c2VyIiwiaWF0IjoxNjk0ODY3MTM2LCJwYXNzd29yZCI6IiQyYSQxMCRGMC40dHUxUU9TZ1ZuOVpHYUNYTU1lRndOajhmT0RCeVc4Wk1lNjNJblNJcHlJNlRLbEt4cSIsInJvbGVzIjpbIlRFU1QiXSwicmVzb3VyY2VzIjpbIkdFVC90ZXN0Il0sImVuYWJsZWQiOnRydWUsInN1cGVyVXNlciI6ZmFsc2UsInVzZXJuYW1lIjoidXNlciIsImV4cCI6MTY5NTU4NzEzNn0.OgtgQ3mVQlhE4AFss2U83ZRFihxIk0HW_D7Eetez0Xk"
}

对方法的权限控制

如果你想要在项目中,使用注解对方法进行权限控制,按以下步骤即可:

(1)引入依赖

<dependency>
    <groupId>cn.elegent.security</groupId>
    <artifactId>elegent-security-annotation</artifactId>
    <version>1.1.0</version>
</dependency>

(2)在需要控制的方法上,添加注解RolesAllowed ,指定角色名称(可以配置多个)

@RolesAllowed("角色名称")

高级应用

ElegentSecurity系统架构图

组件架构图

这是整体的组件架构图,展现了用户获取令牌与访问资源两种操作都用到哪些组件。

用户在登录后,由登录入口调用认证管理器,默认的认证管理器会调用用户详情服务获得用户信息,再调用密码编码器对密码进行校验,校验通过后通过令牌构建器创建令牌。

用户在携带令牌访问后端资源的时候,会经过鉴权过滤器,鉴权过滤器会调用鉴权管理器来实现对令牌进行校验,它通过调用令牌获取器获取令牌,通过调用URL获取器获得当前访问资源地址,再通过令牌检查器检查令牌。

自定义组件

自定义密码编码器

框架提供的密码编码器接口如下:

/**
 * 密码编码器
 */
public interface PasswordEncoder {


    /**
     * 匹配密码
     * param rawPassword 原始密码
     * param encodedPassword 编码后密码
     * return
     */
    boolean matches(String rawPassword, String encodedPassword);


    /**
     * 转换密码
     * param rawPassword
     * return
     */
    String encode(CharSequence rawPassword);

}

框架提供了PasswordEncoder的实现类BcryptPasswordEncoder,用户可以通过实现PasswordEncoder接口来自定义密码的编码规则。

编写后,在配置类添加配置。

/**
* 密码编码器配置
* return
*/
@Bean
public PasswordEncoder passwordEncoder(){
    return new XXXXXXPasswordEncoder();
}

自定义令牌构建器

框架提供的令牌构建器接口如下:

/**
 * 令牌建造者接口
 */
public interface TokenBuilder {

    /**
     * 根据用户详情创建令牌详情
     * param userDetails
     * return
     */
    TokenDetails createToken(UserDetails userDetails);

}

框架提供了TokenBuilder的实现类JWTSymmetryTokenBuilder(JWT对称加密构建器),用户可以通过实现TokenBuilder接口来自定义令牌的构建逻辑。

编写后,在配置类添加Bean配置。

自定义令牌获取器

框架提供的令牌获取器接口如下:

/**
 * 令牌获取者
 */
public interface TokenAcquirer<T> {

    /**
     * 获取token
     * return
     */
    TokenDetails getToken(T requestObject);

}

框架提供了两个实现 HeaderTokenAcquirer 和 GatewayTokenAcquirer ,HeaderTokenAcquirer用于单体架构下的令牌获取,GatewayTokenAcquirer 用于在微服务架构下网关中令牌的获取。 这里使用泛型是因为两个实现类的方法所用的参数类型不同 ,HeaderTokenAcquirer 用的是HttpServletRequest,而GatewayTokenAcquirer 用的是ServerHttpRequest 。

如果用户想自己实现令牌的获取逻辑,只需要自己写一个实现TokenAcquirer接口的类,泛型类型可以是HttpServletRequest或ServerHttpRequest 。

编写后,在配置类添加Bean配置。

自定义令牌检查器

框架提供的令牌检查器接口如下:

/**
 * 令牌检查器
 */
public interface TokenChecker {

    /**
     * 检查令牌
     * param token
     * return
     */
    UserDetails checkToken(String token);

}

框架提供了JWTSymmetryTokenChecker(对称加密的令牌检查),如果想自定义令牌认证的逻辑,可以编写类实现TokenChecker接口,并进行Bean配置。

自定义认证管理器

认证管理器主要职责是签发令牌,框架提供的认证管理器接口如下:

/**
 * 认证管理器接口
 */
public interface AuthenticationManager {

    /**
     * 认证
     * param userAuth
     * return
     */
    AuthenticateResult authenticate(UserAuth userAuth);

}

系统提供默认实现DefaultAuthenticationManager,用户可以编写类实现AuthenticationManager接口,并进行bean配置。

自定义鉴权管理器

鉴权管理器的主要职责是检查令牌合法性,检验用户权限。框架提供的鉴权管理器接口如下:

/**
 * 授权管理器
 */
public interface AuthorizationManager<T,M> {

    /**
     * 检查
     * param requestObject
     * param responseObject
     * return
     */
    AuthorizationResult check(T requestObject,M responseObject);
}

接口定义的两个泛型,T是请求对象 M是响应对象。

系统提供了默认的鉴权管理器DefaultAuthorizationManager ,如果用户想自定义鉴权逻辑,可以编写类实现AuthorizationManager<T,M>接口,并进行BEAN配置。

参与贡献

  1. 从 master 分支 checkout 一个新分支(请务必保证 master 代码是最新的
  2. 新分支命名格式:docs/username_description,例如:docs/tom_新增分布式锁配置项
  3. 在新分支上编辑文档、代码,并提交代码
  4. 最后 PR 合并到 develop 分支,等待作者合并即可
Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

简介

ElegentSecurity是一款的基于令牌的轻量级权限框架。 这个框架可以让你更优雅地在项目中实现权限控制。 展开 收起
Java
Apache-2.0
取消

发行版

暂无发行版

贡献者

全部

近期动态

加载更多
不能加载更多了
Java
1
https://gitee.com/myelegent/elegent-security.git
git@gitee.com:myelegent/elegent-security.git
myelegent
elegent-security
elegent-security-优雅权限框架
master

搜索帮助