每个用户私有文件夹
要为用户创建单独的目录,您需要创建一个简单的机制来将当前用户映射到相应的目录路径。
在构建目录路径时,您应该记住以下可能导致路径遍历攻击的内容:
- 不要泄露任何敏感信息。
- 不要使用任何不安全的 data。
要为当前用户设置私有目录,您需要在当前 HTTP 请求范围内动态更改配置。这可以通过一个自定义的 事件监听器组件 来完成,该组件监听 GetConfigForRequestEvent
事件。
在下面的示例中,假设用户已经通过身份验证,并且其用户名存储在 username
会话属性中。私有用户目录路径使用当前用户名构建,因此每个用户在 /tmp
文件夹中都有自己的目录(例如 /tmp/user1
、/tmp/user2
)。
package com.cksource.ckfinder.listener;
import com.cksource.ckfinder.config.Config;
import com.cksource.ckfinder.event.GetConfigForRequestEvent;
import com.cksource.ckfinder.exception.InvalidRequestException;
import com.cksource.ckfinder.listener.Listener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import jakarta.inject.Inject;
import jakarta.inject.Named;
import jakarta.servlet.http.HttpSession;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
@Named
public class PerRequestConfigListener implements Listener<GetConfigForRequestEvent> {
private static final Logger logger = LoggerFactory.getLogger(PerRequestConfigListener.class);
@Inject
private HttpSession session;
@Override
public void onApplicationEvent(GetConfigForRequestEvent event) {
String username = (String) session.getAttribute("username");
if (username == null) {
throw new InvalidRequestException("Username is not set");
}
// It is assumed that the username is safe to use as a part of the file system path.
// You might need to perform some validation to avoid path traversal security issues.
String userFolderPath = "/tmp/" + username;
Path dirPath = Paths.get(userFolderPath);
// If the directory does not exist, create one.
if (!Files.exists(dirPath)) {
logger.info(String.format("Private directory for user \"%s\" doesn't exist", username));
try {
Files.createDirectories(dirPath);
logger.info(String.format("Created private directory for user \"%s\" under %s", username, dirPath));
} catch (IOException e) {
logger.error(String.format("Could not create private directory for user \"%s\" under %s", username, dirPath));
}
}
// Update the configuration and use the path as the root of the backend named "default".
Config.Backend backendConfig = event.getConfig().getBackendConfig("default");
backendConfig.setRoot(userFolderPath);
}
}