mirror of
https://github.com/rustfs/rustfs.git
synced 2026-08-31 01:09:23 +00:00
fix sts download
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
use crate::admin::utils::has_space_be;
|
use crate::admin::utils::has_space_be;
|
||||||
|
use crate::auth::get_session_token;
|
||||||
use crate::{admin::router::Operation, auth::check_key_valid};
|
use crate::{admin::router::Operation, auth::check_key_valid};
|
||||||
use http::HeaderMap;
|
use http::HeaderMap;
|
||||||
use hyper::StatusCode;
|
use hyper::StatusCode;
|
||||||
@@ -29,7 +30,8 @@ impl Operation for AddServiceAccount {
|
|||||||
return Err(s3_error!(InvalidRequest, "get cred failed"));
|
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 mut input = req.input;
|
||||||
let body = match input.store_all_unlimited().await {
|
let body = match input.store_all_unlimited().await {
|
||||||
@@ -357,10 +359,13 @@ impl Operation for ListServiceAccount {
|
|||||||
return Err(s3_error!(InvalidRequest, "get cred failed"));
|
return Err(s3_error!(InvalidRequest, "get cred failed"));
|
||||||
};
|
};
|
||||||
|
|
||||||
let (cred, _owner) = check_key_valid(&req.headers, &input_cred.access_key).await.map_err(|e| {
|
let (cred, _owner) =
|
||||||
debug!("check key failed: {e:?}");
|
check_key_valid(get_session_token(&req.uri, &req.headers).unwrap_or_default(), &input_cred.access_key)
|
||||||
s3_error!(InternalError, "check key failed")
|
.await
|
||||||
})?;
|
.map_err(|e| {
|
||||||
|
debug!("check key failed: {e:?}");
|
||||||
|
s3_error!(InternalError, "check key failed")
|
||||||
|
})?;
|
||||||
|
|
||||||
let target_account = if let Some(user) = query.user {
|
let target_account = if let Some(user) = query.user {
|
||||||
if user != input_cred.access_key {
|
if user != input_cred.access_key {
|
||||||
@@ -415,10 +420,13 @@ impl Operation for DeleteServiceAccount {
|
|||||||
return Err(s3_error!(InvalidRequest, "get cred failed"));
|
return Err(s3_error!(InvalidRequest, "get cred failed"));
|
||||||
};
|
};
|
||||||
|
|
||||||
let (_cred, _owner) = check_key_valid(&req.headers, &input_cred.access_key).await.map_err(|e| {
|
let (_cred, _owner) =
|
||||||
debug!("check key failed: {e:?}");
|
check_key_valid(get_session_token(&req.uri, &req.headers).unwrap_or_default(), &input_cred.access_key)
|
||||||
s3_error!(InternalError, "check key failed")
|
.await
|
||||||
})?;
|
.map_err(|e| {
|
||||||
|
debug!("check key failed: {e:?}");
|
||||||
|
s3_error!(InternalError, "check key failed")
|
||||||
|
})?;
|
||||||
|
|
||||||
let query = {
|
let query = {
|
||||||
if let Some(query) = req.uri.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 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() {
|
if session_token.is_some() {
|
||||||
return Err(s3_error!(InvalidRequest, "AccessDenied1"));
|
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访问
|
// // TODO: 判断权限, 不允许sts访问
|
||||||
if cred.is_temp() || cred.is_service_account() {
|
if cred.is_temp() || cred.is_service_account() {
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ use tracing::warn;
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
admin::{router::Operation, utils::has_space_be},
|
admin::{router::Operation, utils::has_space_be},
|
||||||
auth::check_key_valid,
|
auth::{check_key_valid, get_session_token},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug, Deserialize, Default)]
|
#[derive(Debug, Deserialize, Default)]
|
||||||
@@ -39,7 +39,8 @@ impl Operation for AddUser {
|
|||||||
return Err(s3_error!(InvalidRequest, "get cred failed"));
|
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();
|
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"));
|
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()
|
let sys_cred = get_global_action_cred()
|
||||||
.ok_or_else(|| S3Error::with_message(S3ErrorCode::InternalError, "get_global_action_cred failed"))?;
|
.ok_or_else(|| S3Error::with_message(S3ErrorCode::InternalError, "get_global_action_cred failed"))?;
|
||||||
|
|||||||
+22
-7
@@ -1,6 +1,7 @@
|
|||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use http::HeaderMap;
|
use http::HeaderMap;
|
||||||
|
use http::Uri;
|
||||||
use iam::error::Error as IamError;
|
use iam::error::Error as IamError;
|
||||||
use iam::get_global_action_cred;
|
use iam::get_global_action_cred;
|
||||||
use iam::sys::SESSION_POLICY_NAME;
|
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.
|
// 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 {
|
let Some(mut cred) = get_global_action_cred() else {
|
||||||
return Err(S3Error::with_message(
|
return Err(S3Error::with_message(
|
||||||
S3ErrorCode::InternalError,
|
S3ErrorCode::InternalError,
|
||||||
@@ -88,7 +89,7 @@ pub async fn check_key_valid(header: &HeaderMap, access_key: &str) -> S3Result<(
|
|||||||
cred = u.credentials;
|
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)))?;
|
.map_err(|e| S3Error::with_message(S3ErrorCode::InternalError, format!("check claims failed {}", e)))?;
|
||||||
|
|
||||||
cred.claims = if !claims.is_empty() { Some(claims) } else { None };
|
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))
|
Ok((cred, owner))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn check_claims_from_token(header: &HeaderMap, cred: &auth::Credentials) -> S3Result<HashMap<String, Value>> {
|
pub fn check_claims_from_token(token: &str, cred: &auth::Credentials) -> S3Result<HashMap<String, Value>> {
|
||||||
let token = get_session_token(header).unwrap_or_default();
|
|
||||||
|
|
||||||
if !token.is_empty() && cred.access_key.is_empty() {
|
if !token.is_empty() && cred.access_key.is_empty() {
|
||||||
return Err(s3_error!(InvalidRequest, "no access key"));
|
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())
|
Ok(HashMap::new())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_session_token(hds: &HeaderMap) -> Option<&str> {
|
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())
|
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>> {
|
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
|
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 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 ecstore::bucket::policy_sys::PolicySys;
|
||||||
use iam::error::Error as IamError;
|
use iam::error::Error as IamError;
|
||||||
use policy::auth;
|
use policy::auth;
|
||||||
@@ -8,6 +8,7 @@ use policy::policy::{Args, BucketPolicyArgs};
|
|||||||
use s3s::access::{S3Access, S3AccessContext};
|
use s3s::access::{S3Access, S3AccessContext};
|
||||||
use s3s::{dto::*, s3_error, S3Error, S3ErrorCode, S3Request, S3Result};
|
use s3s::{dto::*, s3_error, S3Error, S3ErrorCode, S3Request, S3Result};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
use tracing::info;
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
#[derive(Default, Clone)]
|
#[derive(Default, Clone)]
|
||||||
@@ -143,19 +144,20 @@ impl S3Access for FS {
|
|||||||
// /// + [`cx.extensions_mut()`](S3AccessContext::extensions_mut)
|
// /// + [`cx.extensions_mut()`](S3AccessContext::extensions_mut)
|
||||||
async fn check(&self, cx: &mut S3AccessContext<'_>) -> S3Result<()> {
|
async fn check(&self, cx: &mut S3AccessContext<'_>) -> S3Result<()> {
|
||||||
// 上层验证了 ak/sk
|
// 上层验证了 ak/sk
|
||||||
// info!(
|
info!(
|
||||||
// "s3 check uri: {:?}, method: {:?} path: {:?}, s3_op: {:?}, cred: {:?}, headers:{:?}",
|
"s3 check uri: {:?}, method: {:?} path: {:?}, s3_op: {:?}, cred: {:?}, headers:{:?}",
|
||||||
// cx.uri(),
|
cx.uri(),
|
||||||
// cx.method(),
|
cx.method(),
|
||||||
// cx.s3_path(),
|
cx.s3_path(),
|
||||||
// cx.s3_op().name(),
|
cx.s3_op().name(),
|
||||||
// cx.credentials(),
|
cx.credentials(),
|
||||||
// cx.headers(),
|
cx.headers(),
|
||||||
// // cx.extensions_mut(),
|
// cx.extensions_mut(),
|
||||||
// );
|
);
|
||||||
|
|
||||||
let (cred, is_owner) = if let Some(input_cred) = cx.credentials() {
|
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)
|
(Some(cred), is_owner)
|
||||||
} else {
|
} else {
|
||||||
(None, false)
|
(None, false)
|
||||||
|
|||||||
Reference in New Issue
Block a user