auth_basic_kv 权限校验以及auth kv http api 接口

🙈 By 陈潞波 2024-03-29

auth_basic_kv 权限校验以及auth kv http api 接口

1.需求

当前仅仅支持auth_basic_user_file,需要手工修改 file的内容增加新的用户,修改密码。 需添加一种类型: auth_basic_kv,利用kv存储用户名/密码

•key为 “auth_basic”:{prefix}:{user_name}, value 为 密码。 prefix支持变量,以便使用server_name等,方便配置。

•提供HTTP接口,实现动态增加条目,或修改密码,也支持删除

2.auth_basic_kv 指令设计

该指令可配置在main, server, location, limit_conf 块中以api_limit_except为例进行说明 auth_basic_kv指令放在 njt_http_auth_basic_module 模块中,与auth_basic_user_file 指令配置二选一,不可同时配置

Syntax auth_basic_kv {prefix}
Default -
Context main,server,location,limit_conf

prefix 即可为变量也可为普通字符串 kv存储的实际密码格式为: Key: auth_basic:{prefix}:{user_name} Value: 密码 (采用SHA算法)

Eg:

•假设用户名为njet, 使用变量 $server_name格式,(如果实际server_name 为www.baidu.com)则kv内存实际存储为: Key: auth_basic:www.baidu.com:njet

•假设用户名为njet, 使用固定字符串test_prefix格式,则kv内存实际存储为: Key: auth_basic:test_prefix:njet

#变量格式
api_limit_except GET {
   auth_basic "OpenNJet AUTH API";
   auth_basic_kv  $server_name;
}

#字符串格式
api_limit_except GET {
   auth_basic "OpenNJet AUTH API";
   auth_basic_kv  test_prefix;
}

NOTE:

Http 请求到来时,如果是变量,则会将变量转化为实际的值,然后再去kv db里查找,故kv db里存储的都是实际的变量取值而不是变量

3. 密码 http api接口设计

新增一个 njt_http_auth_api_module, 同其他命令式api 模块一样(控制面通过/api 入口配置),提供http api接口,提供密码增删改功能 统一前缀: /api/v1/auth_kv/{type} type:[password|role|login] 预留,目前时就password类型操作密码, 以后可以操作role角色以及login登陆

3.1 设置密码接口:

PUT:/api/v1/auth_kv/password body如下格式:

{
    "prefix": "www.baidu.com",    #对应上面$server_name变量,此处是实际的变量取值
    "user_name": "njet",
    "password": "123456"
}

或者

{
    "prefix": "test_prefix",    #此处是明确的字符串前缀
    "user_name": "njet",
    "password": "123456"
}
错误码 错误提示
增加成功 0 success
用户已存在 4 user existed
增加失败 4 add password error
参数有空值 3 prefix,user_name and password should not be empty
参数不合法 3 会有具体json错误
密码加密失败 4 password encrypt error

3.2 修改密码接口:

PATCH:/api/v1/auth_kv/password/{prefix}/{user_name}

#变量取值
/api/v1/auth_kv/password/www.baidu.com/njet

或者
#明确字符串前缀
/api/v1/auth_kv/password/test_prefix/njet

body如下格式:

{
    "password": "123456"
}
错误码 错误提示
修改成功 0 success
用户不存在 4 user is not existed
修改失败 4 modify password error
参数有空值 3 prefix,user_name and password should not be empty
参数不合法 3 会有具体json错误
密码加密失败 4 password encrypt error

3.3 删除密码接口:

DELETE:/api/v1/auth_kv/password/{prefix}/{user_name}

#变量取值
/api/v1/auth_kv/password/www.baidu.com/njet

或者
#明确字符串前缀
/api/v1/auth_kv/password/test_prefix/njet

返回值

错误码 错误提示
用户成功删除 0 success
用户不存在 4 user is not exist
用户删除失败 4 delete error

4. 测试

4.1 测试配置(以控制面配置 api_limit_except块测试为例):

为range api 接口添加权限验证为例进行测试(固定字符串前缀) 为ssl api 接口添加权限验证为例进行测试(使用变量前缀)

ctrl.conf

...
load_module modules/njt_http_range_api_module.so;  #以range api 设置权限验证普通字符串前缀为例测试
load_module modules/njt_http_ssl_api_module.so;  #以range api 设置权限验证变量前缀为例测试
load_module modules/njt_http_auth_api_module.so;   #auth kv 模块加载
...

http {
    server {
        listen       8081;
        server_name   www.test.com;           #下面使用$server_name变量测试
        
        location /api {
            dyn_module_api;

            api_limit_except  /v1/range PUT {
               auth_basic "OpenNJet range API";
               auth_basic_kv test_kv;       #range 使用固定前缀字符串测试
            }

            api_limit_except  /v1/ssl PUT {
               auth_basic "OpenNJet ssl API";
               auth_basic_kv $server_name;  #ssl 使用变量前缀测试
            }
        }
        
        location /doc {
            doc_api;
        }
    }
}

4.2 range 固定字符串前缀测试(用户名:njet 密码123456)

PUT 增加用户名密码测试 初始不存在njet用户以及密码123456 访问range api get接口,提示输入密码,输入njet/123456 , 校验不通过

img

img

通过auth 配置去配置用户名密码, njet/123456

img

再次访问range get 接口,输入 njet/123456, 成功验证通过

img

img

PATCH 修改密码测试

img

重新访问range get接口,使用 njet/12345 不通过

img

使用njet/654321, 验证通过

img

DELETE 删除密码测试 删除密码

img

再次访问range, 不通过

img

4.3 ssl 使用变量前缀测试(用户名:ssl 密码123456)

PUT 增加用户名密码测试 初始不存在ssl 用户以及密码123456 访问range ssl get接口,提示输入密码,输入ssl/123456 , 校验不通过

img

通过auth 配置去配置用户名密码, ssl/123456, 前缀使用www.test.com

img

再次访问ssl get 接口,输入 ssl/123456, 成功验证通过 img

img

PATCH 修改密码测试 img 重新访问ssl get接口,使用 ssl/12345 不通过

img

使用ssl/654321, 验证通过

img

DELETE 删除密码测试 删除密码

img

再次访问ssl, 不通过 img