zhaohai666 opened a new pull request, #10704: URL: https://github.com/apache/rocketmq/pull/10704
## [Studio] feat: Proxy Admin Authentication and Security Interceptor **Issue:** #10634 **Branch:** `feature/rip-2-pr3-security-interceptor` --- ### Overview This PR adds the authentication and authorization layer for the RIP-2 Proxy Admin Interface, implementing a gRPC `ServerInterceptor` that enforces ACL 2.0 security policies on all admin endpoints. It also extends the proxy's context propagation to carry SSL and authentication metadata. ### Key Changes **ProxyAdminAuthInterceptor** -- Core gRPC `ServerInterceptor` (239 lines) implementing ACL 2.0 authentication and authorization for admin endpoints. - **`interceptCall()`**: Entry point. If both auth and authz are disabled, passes through. Otherwise calls `authenticate()` then `authorize()`. Catches `AuthenticationException` (returns `Status.UNAUTHENTICATED`), `AuthorizationException` (returns `Status.PERMISSION_DENIED`), and generic exceptions (returns `Status.INTERNAL`). - **`authenticate(Metadata, String)`**: Builds a `DefaultAuthenticationContext` from gRPC headers. Parses the `Authorization` header to extract `Credential=<username>/...` and `Signature=...` fields. Uses `DateTime` header as the signed content. Delegates to `AuthenticationEvaluator.evaluate()`. - **`authorize(Metadata, String)`**: Extracts username from `AUTHORIZATION_AK` header. Builds a `Resource` of type `ResourceType.ANY` with name `"proxy.admin.client"` and pattern `LITERAL`. Calls `resolveAction()` to determine the required `Action`. Builds `DefaultAuthorizationContext` with subject, resource, action, and source IP (from `x-forwarded-for`). Delegates to `AuthorizationEvaluator.evaluate()`. - **`resolveAction(String)`**: Maps RPC method names to ACL actions per RIP-2 section 7.2: `UpdateConfig` -> `Action.UPDATE` (write); `DescribeClient`/`GetConfig` -> `Action.GET` (single resource read); all others -> `Action.LIST` (collection read). **Context Propagation Extensions** - `ContextVariable`: Added `SSL_ENABLED` and `AUTH_USERNAME` constants; removed unused `CLIENT_TYPE`. - `ProxyContext`: Added `setSslEnabled()`/`isSslEnabled()`, `setAuthUsername()`/`getAuthUsername()` for carrying security metadata through the request pipeline. - `HeaderInterceptor`: Added `isSslEnabled(Attributes)` method that checks `Grpc.TRANSPORT_ATTR_SSL_SESSION` from the gRPC call's transport attributes and writes the result as `SSL_ENABLED` header. - `AuthenticationPipeline`: After successful authentication, stores the resolved username into `ProxyContext.setAuthUsername()`. - `ContextInitPipeline`: Extracts `SSL_ENABLED` and `AUTHORIZATION_AK` from gRPC metadata into `ProxyContext`. ### Test Coverage | Test File | Lines | Coverage | |-----------|-------|----------| | `ProxyAdminAuthInterceptorTest.java` | 443 | `resolveAction` for all 10 RPCs, full gRPC method name paths, null/empty inputs, `extractUsername`/`extractSourceIp`, `authenticate`/`authorize` via reflection, `AuthConfig` flag combinations | | `ProxyAdminSecurityTest.java` | 681 | Four security categories per RIP-2 section 11.4: auth bypass (both disabled passes through; auth enabled with no credentials rejected with UNAUTHENTICATED), unauthorized access (resource constants, action resolution), parameter injection (SQL injection, XSS, path traversal, null bytes, JNDI injection in clientId/group/topic/clientIdPrefix), oversized query (pageSize truncation to max 100, default to 20) | | `HeaderInterceptorTest.java` | 149 | SSL detection, remote/local address extraction, next handler invocation | | `ContextInitPipelineTest.java` | 140 | SSL enabled true/false/missing, auth username extraction/missing, namespace/action extraction | ### Files Changed | File | Description | |------|-------------| | `proxy/src/main/java/.../grpc/admin/ProxyAdminAuthInterceptor.java` | ACL 2.0 auth interceptor (new, 239 lines) | | `proxy/src/main/java/.../common/ContextVariable.java` | Added SSL_ENABLED, AUTH_USERNAME | | `proxy/src/main/java/.../common/ProxyContext.java` | Added SSL and auth username fields | | `proxy/src/main/java/.../grpc/interceptor/HeaderInterceptor.java` | SSL detection from transport attributes | | `proxy/src/main/java/.../grpc/pipeline/AuthenticationPipeline.java` | Store username after auth | | `proxy/src/main/java/.../grpc/pipeline/ContextInitPipeline.java` | Extract SSL and auth metadata | | `proxy/src/test/java/.../grpc/admin/ProxyAdminAuthInterceptorTest.java` | Auth interceptor tests (new, 443 lines) | | `proxy/src/test/java/.../grpc/admin/ProxyAdminSecurityTest.java` | Security-focused tests (new, 681 lines) | | `proxy/src/test/java/.../grpc/interceptor/HeaderInterceptorTest.java` | Header interceptor tests (new, 149 lines) | | `proxy/src/test/java/.../grpc/pipeline/ContextInitPipelineTest.java` | Context init tests (new, 140 lines) | ### Security Design - **Defense in depth**: Authentication and authorization are independently configurable; either can be enabled without the other. - **Input sanitization**: All user-supplied parameters (clientId, group, topic, clientIdPrefix) are validated against injection attacks (SQL, XSS, path traversal, null bytes, JNDI). - **Query size enforcement**: Page size is capped at 100 (default 20) to prevent resource exhaustion from oversized queries. - **Source IP tracking**: The `x-forwarded-for` header is captured for audit logging and authorization decisions, supporting deployment behind load balancers. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
