admin管理员组

文章数量:1122846

We already have a system in which backend uses Spring, and frontend is in Angular.We are grouping certain pages into features, allowing the admin to dynamically assign access to these features based on roles. Currently, we use the ResourceServerConfigurerAdapter with the .antMatchers("url").hasAnyAuthority(access1, access2) method to manage API access for entire controllers. However, this approach requires manually updating the ResourceServerConfigurerAdapter whenever a feature is completely removed. Since this file is primarily for security configurations, we often skip updating it when access to a feature is removed, as doing so would require redeployment. This practice is cumbersome, error-prone, and leaves APIs for removed features unnecessarily open to certain roles. To address this, we need a dynamic implementation where access to APIs is restricted to the features actively in use. Question-1: We have found a approach mentioned below but it is cumbersome, error-prone and time consuming so we need to know if there is any alternative to this approach. Current approach: We have feature table we are storing angular urls related to that feature in URLS column and controller apis in APIS column as mentioned below:

Database Setup:

  • Feature and API Mapping Table:
    FeatureID | FeatureName      | Code  | URLS                       | APIS
    ----------|------------------|-------|----------------------------|------------------------------
    1         | UserManagement   | UM    | /user/create,/user/update  | /api/user/create,/api/user/update
    2         | ProductCatalog   | PC    | /product/view,/product/edit| /api/product/view,/api/product/edit

Now we are retrieveing data of feature table in a map its json is mentioned below:

Cached Structure:

  • The cache stores the mapping as:
    {
       "Admin": [
           {
               "code": "UM",
               "urls": ["/user/create", "/user/update"],
               "apis": ["/api/user/create", "/api/user/update"]
           },
           {
               "code": "PC",
               "urls": ["/product/view", "/product/edit"],
               "apis": ["/api/product/view", "/api/product/edit"]
           }
       ],
       "User": [
           {
               "code": "PC",
               "urls": ["/product/view"],
               "apis": ["/api/product/view"]
           }
       ]
    }
  1. Frontend:

    • User logs in, and based on their role (e.g., "Admin"), the system fetches the relevant features and their URLs for dynamic route protection.
  2. Backend:

    • When a request is made to /api/user/create with /user/create in the header:
      • The backend extracts the role from the session (e.g., "Admin").
      • It retrieves the list of FeatureApisUrlsDto for "Admin" from the cache.
      • It iterates through the list to match the URL (/user/create) with a feature and checks if the API (/api/user/create) is authorized.

Problem Statement:

  • Querying the database for every API request is costly, so we cache the API map locally on each server.
  • We operate in a distributed server environment without centralized caching, so we update the cache every 5 minutes.
  • This approach works, but it has limitations:
    • Frequent cache updates may miss immediate changes in permissions.
    • Scalability concerns due to the large number of APIs.

Questions:

  1. Is there a better way to dynamically control APIs in such a system with minimal changes to the existing architecture?
  2. If we continue with this approach:
    • Is it better to store API endpoints in the database or a JSON file in the system (along with the feature codes)?
    • How can we ensure synchronization across distributed servers without implementing a centralized cache?

Constraints:

  • We have a significant number of APIs and features.
  • We want to minimize changes to the existing system.
  • We cannot implement centralized caching at the moment.

I appreciate any suggestions or best practices.

本文标签: