mirror of
https://github.com/rustfs/rustfs.git
synced 2026-07-28 09:08:58 +00:00
fix sts download
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
use crate::admin::utils::has_space_be;
|
||||
use crate::auth::get_session_token;
|
||||
use crate::{admin::router::Operation, auth::check_key_valid};
|
||||
use http::HeaderMap;
|
||||
use hyper::StatusCode;
|
||||
@@ -29,7 +30,8 @@ impl Operation for AddServiceAccount {
|
||||
return Err(s3_error!(InvalidRequest, "get cred failed"));
|
||||
};
|
||||
|
||||
let (cred, _owner) = check_key_valid(&req.headers, &req_cred.access_key).await?;
|
||||
let (cred, _owner) =
|
||||
check_key_valid(get_session_token(&req.uri, &req.headers).unwrap_or_default(), &req_cred.access_key).await?;
|
||||
|
||||
let mut input = req.input;
|
||||
let body = match input.store_all_unlimited().await {
|
||||
@@ -357,10 +359,13 @@ impl Operation for ListServiceAccount {
|
||||
return Err(s3_error!(InvalidRequest, "get cred failed"));
|
||||
};
|
||||
|
||||
let (cred, _owner) = check_key_valid(&req.headers, &input_cred.access_key).await.map_err(|e| {
|
||||
debug!("check key failed: {e:?}");
|
||||
s3_error!(InternalError, "check key failed")
|
||||
})?;
|
||||
let (cred, _owner) =
|
||||
check_key_valid(get_session_token(&req.uri, &req.headers).unwrap_or_default(), &input_cred.access_key)
|
||||
.await
|
||||
.map_err(|e| {
|
||||
debug!("check key failed: {e:?}");
|
||||
s3_error!(InternalError, "check key failed")
|
||||
})?;
|
||||
|
||||
let target_account = if let Some(user) = query.user {
|
||||
if user != input_cred.access_key {
|
||||
@@ -415,10 +420,13 @@ impl Operation for DeleteServiceAccount {
|
||||
return Err(s3_error!(InvalidRequest, "get cred failed"));
|
||||
};
|
||||
|
||||
let (_cred, _owner) = check_key_valid(&req.headers, &input_cred.access_key).await.map_err(|e| {
|
||||
debug!("check key failed: {e:?}");
|
||||
s3_error!(InternalError, "check key failed")
|
||||
})?;
|
||||
let (_cred, _owner) =
|
||||
check_key_valid(get_session_token(&req.uri, &req.headers).unwrap_or_default(), &input_cred.access_key)
|
||||
.await
|
||||
.map_err(|e| {
|
||||
debug!("check key failed: {e:?}");
|
||||
s3_error!(InternalError, "check key failed")
|
||||
})?;
|
||||
|
||||
let query = {
|
||||
if let Some(query) = req.uri.query() {
|
||||
|
||||
@@ -42,12 +42,13 @@ impl Operation for AssumeRoleHandle {
|
||||
|
||||
let Some(user) = req.credentials else { return Err(s3_error!(InvalidRequest, "get cred failed")) };
|
||||
|
||||
let session_token = get_session_token(&req.headers);
|
||||
let session_token = get_session_token(&req.uri, &req.headers);
|
||||
if session_token.is_some() {
|
||||
return Err(s3_error!(InvalidRequest, "AccessDenied1"));
|
||||
}
|
||||
|
||||
let (cred, _owner) = check_key_valid(&req.headers, &user.access_key).await?;
|
||||
let (cred, _owner) =
|
||||
check_key_valid(get_session_token(&req.uri, &req.headers).unwrap_or_default(), &user.access_key).await?;
|
||||
|
||||
// // TODO: 判断权限, 不允许sts访问
|
||||
if cred.is_temp() || cred.is_service_account() {
|
||||
|
||||
@@ -11,7 +11,7 @@ use tracing::warn;
|
||||
|
||||
use crate::{
|
||||
admin::{router::Operation, utils::has_space_be},
|
||||
auth::check_key_valid,
|
||||
auth::{check_key_valid, get_session_token},
|
||||
};
|
||||
|
||||
#[derive(Debug, Deserialize, Default)]
|
||||
@@ -39,7 +39,8 @@ impl Operation for AddUser {
|
||||
return Err(s3_error!(InvalidRequest, "get cred failed"));
|
||||
};
|
||||
|
||||
let (cred, _owner) = check_key_valid(&req.headers, &input_cred.access_key).await?;
|
||||
let (cred, _owner) =
|
||||
check_key_valid(get_session_token(&req.uri, &req.headers).unwrap_or_default(), &input_cred.access_key).await?;
|
||||
|
||||
let ak = query.access_key.as_deref().unwrap_or_default();
|
||||
|
||||
@@ -246,7 +247,8 @@ impl Operation for RemoveUser {
|
||||
return Err(s3_error!(InvalidRequest, "get cred failed"));
|
||||
};
|
||||
|
||||
let (cred, _owner) = check_key_valid(&req.headers, &input_cred.access_key).await?;
|
||||
let (cred, _owner) =
|
||||
check_key_valid(get_session_token(&req.uri, &req.headers).unwrap_or_default(), &input_cred.access_key).await?;
|
||||
|
||||
let sys_cred = get_global_action_cred()
|
||||
.ok_or_else(|| S3Error::with_message(S3ErrorCode::InternalError, "get_global_action_cred failed"))?;
|
||||
|
||||
+22
-7
@@ -1,6 +1,7 @@
|
||||
use std::collections::HashMap;
|
||||
|
||||
use http::HeaderMap;
|
||||
use http::Uri;
|
||||
use iam::error::Error as IamError;
|
||||
use iam::get_global_action_cred;
|
||||
use iam::sys::SESSION_POLICY_NAME;
|
||||
@@ -48,7 +49,7 @@ impl S3Auth for IAMAuth {
|
||||
}
|
||||
|
||||
// check_key_valid checks the key is valid or not. return the user's credentials and if the user is the owner.
|
||||
pub async fn check_key_valid(header: &HeaderMap, access_key: &str) -> S3Result<(auth::Credentials, bool)> {
|
||||
pub async fn check_key_valid(session_token: &str, access_key: &str) -> S3Result<(auth::Credentials, bool)> {
|
||||
let Some(mut cred) = get_global_action_cred() else {
|
||||
return Err(S3Error::with_message(
|
||||
S3ErrorCode::InternalError,
|
||||
@@ -88,7 +89,7 @@ pub async fn check_key_valid(header: &HeaderMap, access_key: &str) -> S3Result<(
|
||||
cred = u.credentials;
|
||||
}
|
||||
|
||||
let claims = check_claims_from_token(header, &cred)
|
||||
let claims = check_claims_from_token(session_token, &cred)
|
||||
.map_err(|e| S3Error::with_message(S3ErrorCode::InternalError, format!("check claims failed {}", e)))?;
|
||||
|
||||
cred.claims = if !claims.is_empty() { Some(claims) } else { None };
|
||||
@@ -105,9 +106,7 @@ pub async fn check_key_valid(header: &HeaderMap, access_key: &str) -> S3Result<(
|
||||
Ok((cred, owner))
|
||||
}
|
||||
|
||||
pub fn check_claims_from_token(header: &HeaderMap, cred: &auth::Credentials) -> S3Result<HashMap<String, Value>> {
|
||||
let token = get_session_token(header).unwrap_or_default();
|
||||
|
||||
pub fn check_claims_from_token(token: &str, cred: &auth::Credentials) -> S3Result<HashMap<String, Value>> {
|
||||
if !token.is_empty() && cred.access_key.is_empty() {
|
||||
return Err(s3_error!(InvalidRequest, "no access key"));
|
||||
}
|
||||
@@ -149,8 +148,10 @@ pub fn check_claims_from_token(header: &HeaderMap, cred: &auth::Credentials) ->
|
||||
Ok(HashMap::new())
|
||||
}
|
||||
|
||||
pub fn get_session_token(hds: &HeaderMap) -> Option<&str> {
|
||||
hds.get("x-amz-security-token").map(|v| v.to_str().unwrap_or_default())
|
||||
pub fn get_session_token<'a>(uri: &'a Uri, hds: &'a HeaderMap) -> Option<&'a str> {
|
||||
hds.get("x-amz-security-token")
|
||||
.map(|v| v.to_str().unwrap_or_default())
|
||||
.or_else(|| get_query_param(uri.query().unwrap_or_default(), "x-amz-security-token"))
|
||||
}
|
||||
|
||||
pub fn get_condition_values(header: &HeaderMap, cred: &auth::Credentials) -> HashMap<String, Vec<String>> {
|
||||
@@ -295,3 +296,17 @@ pub fn get_condition_values(header: &HeaderMap, cred: &auth::Credentials) -> Has
|
||||
|
||||
args
|
||||
}
|
||||
|
||||
pub fn get_query_param<'a>(url: &'a str, param_name: &str) -> Option<&'a str> {
|
||||
let query_start = url.find('?')?;
|
||||
let query = &url[query_start + 1..];
|
||||
for pair in query.split('&') {
|
||||
let mut parts = pair.splitn(2, '=');
|
||||
if let (Some(key), Some(value)) = (parts.next(), parts.next()) {
|
||||
if key.to_lowercase() == param_name {
|
||||
return Some(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use super::ecfs::FS;
|
||||
use crate::auth::{check_key_valid, get_condition_values};
|
||||
use crate::auth::{check_key_valid, get_condition_values, get_session_token};
|
||||
use ecstore::bucket::policy_sys::PolicySys;
|
||||
use iam::error::Error as IamError;
|
||||
use policy::auth;
|
||||
@@ -8,6 +8,7 @@ use policy::policy::{Args, BucketPolicyArgs};
|
||||
use s3s::access::{S3Access, S3AccessContext};
|
||||
use s3s::{dto::*, s3_error, S3Error, S3ErrorCode, S3Request, S3Result};
|
||||
use std::collections::HashMap;
|
||||
use tracing::info;
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[derive(Default, Clone)]
|
||||
@@ -143,19 +144,20 @@ impl S3Access for FS {
|
||||
// /// + [`cx.extensions_mut()`](S3AccessContext::extensions_mut)
|
||||
async fn check(&self, cx: &mut S3AccessContext<'_>) -> S3Result<()> {
|
||||
// 上层验证了 ak/sk
|
||||
// info!(
|
||||
// "s3 check uri: {:?}, method: {:?} path: {:?}, s3_op: {:?}, cred: {:?}, headers:{:?}",
|
||||
// cx.uri(),
|
||||
// cx.method(),
|
||||
// cx.s3_path(),
|
||||
// cx.s3_op().name(),
|
||||
// cx.credentials(),
|
||||
// cx.headers(),
|
||||
// // cx.extensions_mut(),
|
||||
// );
|
||||
info!(
|
||||
"s3 check uri: {:?}, method: {:?} path: {:?}, s3_op: {:?}, cred: {:?}, headers:{:?}",
|
||||
cx.uri(),
|
||||
cx.method(),
|
||||
cx.s3_path(),
|
||||
cx.s3_op().name(),
|
||||
cx.credentials(),
|
||||
cx.headers(),
|
||||
// cx.extensions_mut(),
|
||||
);
|
||||
|
||||
let (cred, is_owner) = if let Some(input_cred) = cx.credentials() {
|
||||
let (cred, is_owner) = check_key_valid(cx.headers(), &input_cred.access_key).await?;
|
||||
let (cred, is_owner) =
|
||||
check_key_valid(get_session_token(cx.uri(), cx.headers()).unwrap_or_default(), &input_cred.access_key).await?;
|
||||
(Some(cred), is_owner)
|
||||
} else {
|
||||
(None, false)
|
||||
|
||||
Reference in New Issue
Block a user