fix(oidc): support case-insensitive claim name matching (#2362)

Co-authored-by: loverustfs <hello@rustfs.com>
Co-authored-by: 安正超 <anzhengchao@gmail.com>
This commit is contained in:
Logan Ye
2026-04-03 21:45:56 +08:00
committed by GitHub
parent c244943313
commit 2d91e2f580
2 changed files with 105 additions and 6 deletions
+52 -1
View File
@@ -239,9 +239,20 @@ impl Validator for BucketPolicy {
}
}
fn get_claim_case_insensitive<'a>(claims: &'a HashMap<String, Value>, claim_name: &str) -> Option<&'a Value> {
if let Some(v) = claims.get(claim_name) {
return Some(v);
}
let claim_name_lower = claim_name.to_lowercase();
claims
.iter()
.find(|(k, _)| k.to_lowercase() == claim_name_lower)
.map(|(_, v)| v)
}
fn get_values_from_claims(claims: &HashMap<String, Value>, claim_name: &str) -> (HashSet<String>, bool) {
let mut s = HashSet::new();
if let Some(pname) = claims.get(claim_name) {
if let Some(pname) = get_claim_case_insensitive(claims, claim_name) {
if let Some(pnames) = pname.as_array() {
for pname in pnames {
if let Some(pname_str) = pname.as_str() {
@@ -1693,4 +1704,44 @@ mod test {
"principal and resource match should keep ExistingObjectTag fetch hint"
);
}
#[test]
fn test_get_values_from_claims_case_insensitive() {
let mut claims = HashMap::new();
claims.insert("policyminio".to_string(), Value::Array(vec![Value::String("consoleAdmin".to_string())]));
let (policies, found) = get_values_from_claims(&claims, "policyMinio");
assert!(found);
assert!(policies.contains("consoleAdmin"));
let (policies, found) = get_values_from_claims(&claims, "POLICYMINIO");
assert!(found);
assert!(policies.contains("consoleAdmin"));
let (policies, found) = get_values_from_claims(&claims, "policyminio");
assert!(found);
assert!(policies.contains("consoleAdmin"));
}
#[test]
fn test_get_values_from_claims_exact_match_preferred() {
let mut claims = HashMap::new();
claims.insert("Policy".to_string(), Value::Array(vec![Value::String("exact_match".to_string())]));
claims.insert("policy".to_string(), Value::Array(vec![Value::String("lowercase".to_string())]));
let (policies, _) = get_values_from_claims(&claims, "Policy");
assert!(policies.contains("exact_match"));
assert!(!policies.contains("lowercase"));
}
#[test]
fn test_get_policies_from_claims_case_insensitive_string() {
let mut claims = HashMap::new();
claims.insert("policyminio".to_string(), Value::String("consoleAdmin,readwrite".to_string()));
let (policies, found) = get_policies_from_claims(&claims, "policyMinio");
assert!(found);
assert!(policies.contains("consoleAdmin"));
assert!(policies.contains("readwrite"));
}
}