Auth_basic_kv Permission Verification and Auth Kv Http API Interfaces

NGINX is evolving towards cloud native, All in OpenNJet

1. Requirements

Currently only auth_basic_user_file is supported, which requires manually modifying the file content to add new users and change passwords. A new type auth_basic_kv needs to be added, which uses KV storage to store usernames and passwords.

• The key follows the format auth_basic:{prefix}:{user_name}, and the value is the password. prefix supports variables, allowing the use of server_name and other variables for easier configuration.

• An HTTP interface is provided to dynamically add entries, change passwords, and also supports deletion.

2. auth_basic_kv Directive Design

This directive can be configured in the main, server, location, and limit_conf blocks. We will use api_limit_except as an example for explanation. The auth_basic_kv directive is placed in the njt_http_auth_basic_module module. You must choose either auth_basic_kv or auth_basic_user_file for configuration, and they cannot be used at the same time.

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

prefix can be either a variable or an ordinary string. The actual format of passwords stored in KV is: Key: auth_basic:{prefix}:{user_name}, Value: password (hashed using the SHA algorithm)

Eg:

• If the username is njet and you use the variable $server_name format (if the actual server_name is www.baidu.com), the actual key stored in KV is: Key: auth_basic:www.baidu.com:njet

• If the username is njet and you use the fixed string test_prefix format, the actual key stored in KV is: Key: auth_basic:test_prefix:njet

# Variable format
api_limit_except GET {
   auth_basic "OpenNJet AUTH API";
   auth_basic_kv  $server_name;
}

String format

api_limit_except GET {
auth_basic “OpenNJet AUTH API”;
auth_basic_kv test_prefix;
}

NOTE:

When an HTTP request arrives, if prefix is a variable, it will be converted to its actual value before looking it up in the KV database. Therefore, all data stored in the KV database are actual variable values, not variable names.

3. Password HTTP API Interface Design

A new module njt_http_auth_api_module has been added. Like other imperative API modules (the control plane is configured through the /api entry), it provides HTTP API interfaces for adding, deleting, and modifying passwords. The unified prefix is: /api/v1/auth_kv/{type}, where type supports [password|role|login] (these are reserved for future use). Currently only the password type is implemented for password operations, and role and login operations will be supported in the future.

3.1 Set Password Interface

PUT: /api/v1/auth_kv/password, the request body is in the following format:

{
    "prefix": "www.baidu.com",    # Corresponds to the $server_name variable above, this is the actual variable value
    "user_name": "njet",
    "password": "123456"
}

OR

{
“prefix”: “test_prefix”, # This is an explicit string prefix
“user_name”: “njet”,
“password”: “123456”
}

Error Code Error Message
Add succeeded 0 success
User already exists 4 user existed
Add failed 4 add password error
Empty parameter 3 prefix,user_name and password should not be empty
Invalid parameter 3 Specific JSON error will be returned
Password encryption failed 4 password encrypt error

3.2 Change Password Interface

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

# Actual variable value
/api/v1/auth_kv/password/www.baidu.com/njet

OR

Explicit string prefix

/api/v1/auth_kv/password/test_prefix/njet

The request body is in the following format:

{
    "password": "123456"
}
Error Code Error Message
Modify succeeded 0 success
User does not exist 4 user is not existed
Modify failed 4 modify password error
Empty parameter 3 prefix,user_name and password should not be empty
Invalid parameter 3 Specific JSON error will be returned
Password encryption failed 4 password encrypt error

3.3 Delete Password Interface

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

# Actual variable value
/api/v1/auth_kv/password/www.baidu.com/njet

OR

Explicit string prefix

/api/v1/auth_kv/password/test_prefix/njet

Return value

Error Code Error Message
User deleted successfully 0 success
User does not exist 4 user is not exist
Delete failed 4 delete error

4. Testing

4.1 Test Configuration (Testing with the api_limit_except block in control plane configuration as an example):

We will test adding authentication for the range API interface (with fixed string prefix), and test adding authentication for the SSL API interface (with variable prefix).

ctrl.conf

...
load_module modules/njt_http_range_api_module.so;  # Test authentication for the range API with a fixed string prefix as an example
load_module modules/njt_http_ssl_api_module.so;  # Test authentication for the API with a variable prefix as an example
load_module modules/njt_http_auth_api_module.so;   # Load the auth KV module
...

http {
server {
listen 8081;
server_name www.test.com; # We will use the $server_name variable for testing below

    location /api {
        dyn_module_api;

        api_limit_except  /v1/range PUT {
           auth_basic "OpenNJet range API";
           auth_basic_kv test_kv;       # range uses a fixed prefix string for testing
        }

        api_limit_except  /v1/ssl PUT {
           auth_basic "OpenNJet ssl API";
           auth_basic_kv $server_name;  # ssl uses a variable prefix for testing
        }
    }
    
    location /doc {
        doc_api;
    }
}

}

4.2 range Fixed String Prefix Test (Username: njet, Password: 123456)

PUT add username and password test: Initially, the user njet with password 123456 does not exist. When accessing the range API GET interface, you will be prompted to enter a password. After entering njet/123456, authentication fails.

Add the username and password njet/123456 via the auth configuration.

Access the range GET interface again, enter njet/123456, and authentication succeeds.

PATCH change password test

Access the range GET interface again, using njet/12345, authentication fails.

Using njet/654321, authentication succeeds.

DELETE delete password test: delete the password.

Access range again, authentication fails.

4.3 SSL Variable Prefix Test (Username: ssl, Password: 123456)

PUT add username and password test: Initially, the user ssl with password 123456 does not exist. When accessing the SSL GET interface, you will be prompted to enter a password. After entering ssl/123456, authentication fails.

Add the username and password ssl/123456 via the auth configuration, using www.test.com as the prefix.

Access the SSL GET interface again, enter ssl/123456, and authentication succeeds.

PATCH change password test

Access the SSL GET interface again, using ssl/12345, authentication fails.

Using ssl/654321, authentication succeeds.

DELETE delete password test: delete the password.

Access SSL again, authentication fails.

NJet application engine implements a unique dynamic configuration loading capability at runtime through kernel refactoring, and is a new generation of high-performance Web application engine. NJet has high-performance data plane processing capability, and schedules various auxiliary functions such as clustering, high availability, active health check, and declarative API through NJet's unique CoPilot service framework, which facilitates function expansion and isolates the impact of management/control functions on the data plane. The performance of the NJet application engine is three times higher than that of the Envoy application engine recommended by CNCF. Official Website Mailing List


This is a discussion topic separated from the original topic at https://juejin.cn/post/7368712423795097609