alts: AuthorizationUtil.clientAuthorizationCheck compares the peer service account case-sensitively
Maintainer thường phản hồi trong vòng 1 ngày
Đánh giá
- Độ khó
- 2/5
- Thời gian dự kiến
- 1-3 giờ
- Mức phù hợp với người mới
- 85/100
- Loại issue
- Lỗi
- Độ rõ ràng
- Đặc tả rõ ràng
- Mức độ hoạt động
- Sôi nổi
- Công nghệ
- java
- Lĩnh vực
- authorization
Hướng nghiên cứu
Phép so sánh nằm trong clientAuthorizationCheck tại alts/src/main/java/io/grpc/alts/AuthorizationUtil.java, hiện đang dùng Collection.contains, một phép kiểm tra khớp chính xác. Hãy đọc phương thức đó và AuthorizationUtilTest hiện có, rồi thêm trường hợp kiểm thử hồi quy không phân biệt chữ hoa chữ thường trong issue. Hoàn thành khi kiểm thử mới vượt qua, các kiểm thử hiện có vẫn vượt qua với ./gradlew :grpc-alts:test, và Javadoc ghi chú việc so khớp không phân biệt chữ hoa chữ thường.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
alts: AuthorizationUtil.clientAuthorizationCheck compares the peer service account case-sensitively
**正文(Markdown 原文)**
`````markdown
### What version of gRPC-Java are you using?
`master` at [`15d64a4`](https://github.com/grpc/grpc-java/commit/15d64a4678450991aa5bf7af23066d36b3391351) (`1.86.0-SNAPSHOT`); `AuthorizationUtil` is unchanged on current `master`.
### What is your environment?
Linux x86_64, OpenJDK 21.0.2, Gradle 8.14.5 (wrapper).
### What did you expect to see?
`AuthorizationUtil.clientAuthorizationCheck(call, expectedServiceAccounts)` accepts a client whose ALTS peer service account differs from an allowed entry only in letter case (for example peer `alice`, allowed `ALICE`), as grpc-go's equivalent `alts.ClientAuthorizationCheck` does.
### What did you see instead?
It returns `PERMISSION_DENIED` ("Client alice is not authorized").
**Location** (`grpc/grpc-java` @ `15d64a4`):
- [`alts/src/main/java/io/grpc/alts/AuthorizationUtil.java:35-47`](https://github.com/grpc/grpc-java/blob/15d64a4678450991aa5bf7af23066d36b3391351/alts/src/main/java/io/grpc/alts/AuthorizationUtil.java#L35-L47)
```java
public static Status clientAuthorizationCheck(
ServerCall<?, ?> call, Collection<String> expectedServiceAccounts) {
...
if (expectedServiceAccounts.contains(altsContext.getPeerServiceAccount())) {
return Status.OK;
}
return Status.PERMISSION_DENIED.withDescription(
"Client " + altsContext.getPeerServiceAccount() + " is not authorized");
}
Problem
Collection.contains() uses String.equals(), so the check is exact-match. Service account identifiers are e-mail style names that people often write in mixed case in config. grpc-go changed its helper for exactly this reason ("expectedServiceAccounts are commonly mixed-case, while the PeerServiceAccount is lower-case"). With the Java helper, an allow-list entry that differs only in case rejects a legitimate client, and the two languages give different answers for the same allow-list. This only concerns letter case; any other difference in the name is still rejected.
Steps to reproduce the bug
Reproduction
Regression test added to AuthorizationUtilTest (reuses its FakeServerCall, which sets the ALTS peer service account):
diff --git a/alts/src/test/java/io/grpc/alts/AuthorizationUtilTest.java b/alts/src/test/java/io/grpc/alts/AuthorizationUtilTest.java
--- a/alts/src/test/java/io/grpc/alts/AuthorizationUtilTest.java
+++ b/alts/src/test/java/io/grpc/alts/AuthorizationUtilTest.java
@@ -55,6 +55,14 @@ public final class AuthorizationUtilTest {
assertThat(status.getDescription()).endsWith("not authorized");
}
+ @Test
+ public void altsAuthorizationCheck_ignoresCase() throws Exception {
+ Status status =
+ AuthorizationUtil.clientAuthorizationCheck(
+ new FakeServerCall("alice"), Lists.newArrayList("ALICE", "Bob"));
+ assertThat(status.getCode()).isEqualTo(Status.Code.OK);
+ }
+
private static class FakeServerCall extends ServerCall<String, String> {
final Attributes attrs;
./gradlew :grpc-alts:test --tests io.grpc.alts.AuthorizationUtilTest -PskipCodegen=true -PskipAndroid=true
AuthorizationUtilTest > altsAuthorizationCheck_ignoresCase FAILED
value of: getCode()
expected: OK
but was : PERMISSION_DENIED
at app//io.grpc.alts.AuthorizationUtilTest.altsAuthorizationCheck_ignoresCase(AuthorizationUtilTest.java:63)
152 tests completed, 1 failed
Environment:
- Commit:
15d64a4678450991aa5bf7af23066d36b3391351 - Toolchain: OpenJDK 21.0.2, Gradle 8.14.5
Already fixed in grpc/grpc-go
PR: https://github.com/grpc/grpc-go/pull/3792 ("credentials/alts: ClientAuthorizationCheck to case-fold compare of peer SA", merged 2020-09-01T23:23:56Z, merge commit 48bf772d0c2). It switched the peer service account comparison to strings.EqualFold.
How grpc-go fixed it (relevant hunks, verbatim):
--- a/credentials/alts/utils.go
+++ b/credentials/alts/utils.go
@@ -152,12 +152,13 @@ func AuthInfoFromPeer(p *peer.Peer) (AuthInfo, error) {
func ClientAuthorizationCheck(ctx context.Context, expectedServiceAccounts []string) error {
authInfo, err := AuthInfoFromContext(ctx)
if err != nil {
- return status.Newf(codes.PermissionDenied, "The context is not an ALTS-compatible context: %v", err).Err()
+ return status.Errorf(codes.PermissionDenied, "The context is not an ALTS-compatible context: %v", err)
}
+ peer := authInfo.PeerServiceAccount()
for _, sa := range expectedServiceAccounts {
- if authInfo.PeerServiceAccount() == sa {
+ if strings.EqualFold(peer, sa) {
return nil
}
}
- return status.Newf(codes.PermissionDenied, "Client %v is not authorized", authInfo.PeerServiceAccount()).Err()
+ return status.Errorf(codes.PermissionDenied, "Client %v is not authorized", peer)
}
Suggested fix
Compare the peer service account to each expected entry with equalsIgnoreCase, and document it:
diff --git a/alts/src/main/java/io/grpc/alts/AuthorizationUtil.java b/alts/src/main/java/io/grpc/alts/AuthorizationUtil.java
--- a/alts/src/main/java/io/grpc/alts/AuthorizationUtil.java
+++ b/alts/src/main/java/io/grpc/alts/AuthorizationUtil.java
@@ -29,8 +29,8 @@ public final class AuthorizationUtil {
/**
* Given a server call, performs client authorization check, i.e., checks if the client service
- * account matches one of the expected service accounts. It returns OK if client is authorized and
- * an error otherwise.
+ * account matches one of the expected service accounts, ignoring case. It returns OK if client
+ * is authorized and an error otherwise.
*/
public static Status clientAuthorizationCheck(
ServerCall<?, ?> call, Collection<String> expectedServiceAccounts) {
@@ -39,10 +39,13 @@ public final class AuthorizationUtil {
if (altsContext == null) {
return Status.PERMISSION_DENIED.withDescription("Peer ALTS AuthContext not found");
}
- if (expectedServiceAccounts.contains(altsContext.getPeerServiceAccount())) {
- return Status.OK;
+ String peerServiceAccount = altsContext.getPeerServiceAccount();
+ for (String serviceAccount : expectedServiceAccounts) {
+ if (peerServiceAccount.equalsIgnoreCase(serviceAccount)) {
+ return Status.OK;
+ }
}
return Status.PERMISSION_DENIED.withDescription(
- "Client " + altsContext.getPeerServiceAccount() + " is not authorized");
+ "Client " + peerServiceAccount + " is not authorized");
}
}
Verified on 15d64a4 (OpenJDK 21.0.2, Gradle 8.14.5): the test above fails without this patch and passes with it; no other test results change (:grpc-alts:test).
I can submit a PR for this.
Checked: searches for clientAuthorizationCheck case, ALTS service account case-insensitive and AuthorizationUtil found only #11042 and #7840 (ALTS context API changes), not this comparison.
- Ngôn ngữ chính
- Java
- Star
- 12.1k
- Fork
- 4k
- Merge trung bình
- 1 ngày 13 giờ
- Pull request đã merge (30 ngày)
- 42
Chuẩn bị môi trường
- Không có Dockerfile hay tệp Docker Compose
- Không có mẫu pull request
- Đọc hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của grpc/grpc-java
-
Binary log config: `-service/*` exclusion is accepted and silently turned into a per-service rule, so the service is still loggedCó thể đã có người làm Có pull request liên kết đang mở hoặc đã được merge. Đang mởbug
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 82/100
grpc/grpc-java#13155 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
SpiffeUtil.loadTrustBundleFromFile accepts invalid trust domain names (e.g. `UPPER.example.com`, `invalid#character`) as bundle map keysCó thể đã có người làm Có pull request liên kết đang mở hoặc đã được merge. Đang mởbug
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 82/100
grpc/grpc-java#13154 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
xds: EDS resource is not NACKed when locality weights at one priority sum to more than uint32 maxCó thể đã có người làm Có pull request liên kết đang mở hoặc đã được merge. Đang mởbug
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
grpc/grpc-java#13153 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
okhttp: OkHttpServerTransport logs a WARNING with EOFException for every TCP connection that closes before sending the HTTP/2 preface (e.g. load balancer health checks)Có thể đã có người làm @hidingmyname đã nhận 1 ngày trước. Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
grpc/grpc-java#13152 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
xds: RBAC `Authenticated` principal without `principal_name` is rejected ("Unknown StringMatcher match pattern: MATCHPATTERN_NOT_SET")Có thể đã có người làm @hidingmyname đã nhận 1 ngày trước. Đang mởbug
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
grpc/grpc-java#13150 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
Tất cả issue của grpc/grpc-java
Issue tương tự
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 70/100
Dans-Plugins/Medieval-Roleplay-Engine#396 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
bug
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 82/100
Maintainer thường phản hồi trong vòng 1 ngày
-
LtByXsl throws NoSuchElementException when defect element has no text contentCó thể đã có người làm Có pull request liên kết đang mở hoặc đã được merge. Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 84/100
objectionary/lints#1640 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 75/100
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
virtualcell/vcell#2193 ·
Maintainer thường phản hồi trong vòng 1 ngày