【发布时间】:2017-03-18 20:37:49
【问题描述】:
我正在使用 JavaFX 和 Java Spark 开发桌面软件,这基本上是用于开发 Web 应用程序的准系统框架,但我正在尝试严格使用它来放置/获取敏感的方法和变量在服务器上,以便用户无法访问它们。 REST 似乎是正确的方法,但我很难理解 2 个相互关联的 REST 概念。 Spark 文档很简单,但我已将几个好的教程集成到下面的工作演示中,但我碰壁了。我简单解释一下:
在Postman 的帮助下,我已经能够使用http://localhost:4567/secrets 的路径和以下的正文将put 一些记录放到服务器上:
{
"title" : "demofield1",
"content" : "12345"
}
每条记录都包含一个标题作为标识符 (demofield1) 和内容作为敏感数据,应始终对用户隐藏 (12345)。将put 这些字符串放到服务器上然后get 使用title 作为参数,这非常简单,如下所示。演示代码只有一个用于创建和返回记录(秘密)的 Model 类、一个 JSON 转换方法以及一个 get 和 put Spark 方法。秘密暂时存储在本地的 HashMap 中,我假设真正的应用程序会简单地交换服务器数据库。
get 方法按预期工作,返回正确的 JSON 记录并将内容存储为具有以下行的字符串:String secretString = model.getCertainSecret(title).getContent();
话虽如此......
问题(部分答案也非常感谢):
secretString上面现在包含一个机密值 (12345),它是使用所谓的安全 REST 方法获得的。但是用户不能简单地对我的源代码进行逆向工程并编写System.out.println(secretString)并显示那个 12345 吗?尽管没有明确显示,但我不明白从服务器检索简单字符串后如何保护它。代码似乎正确,但值很容易获得。我错过了什么?你如何在服务器上
put整个 java 方法?我需要保护的很多代码不仅仅是字符串,而是包含Tasks、Platform.runLater()->的方法,并且需要与其他桌面软件交互。例如,我的一种方法使用 JACOB 来识别第三方软件的某个区域何时被点击。我什至无法理解在这种情况下 get/put 会是什么样子。
我的假设是服务器端数据库会存储来自我的put 请求的所有内容,但我不明白它是如何存储和返回方法的?我应该阅读有关 servlet 或 SaaS 的内容吗?我专注于桌面用户。
代码:
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import lombok.Data;
import org.apache.log4j.BasicConfigurator;
import java.io.IOException;
import java.io.StringWriter;
import java.util.HashMap;
import java.util.Map;
import static spark.Spark.get;
import static spark.Spark.put;
public class ServerDemo
{
private static final int HTTP_BAD_REQUEST = 400;
@Data
static class NewSecretPayload {
private String title;
private String content;
public boolean isValid() {
return title != null && !title.isEmpty();
}
}
public static class Model {
private int nextId = 1;
private Map<String, Secret> secrets = new HashMap<>();
@Data
class Secret {
private int id;
private String title;
private String content;
}
public int createSecret(String title, String content){
int id = nextId++;
Secret secret = new Secret();
secret.setId(id);
secret.setTitle(title);
secret.setContent(content);
secrets.put(title, secret);
return id;
}
public Secret getCertainSecret(String titleToUse){
if(null != secrets.get(titleToUse)){
return secrets.get(titleToUse);
}else{
return null;
}
}
}
public static String dataToJson(Object data) {
try {
ObjectMapper mapper = new ObjectMapper();
mapper.enable(SerializationFeature.INDENT_OUTPUT);
StringWriter sw = new StringWriter();
mapper.writeValue(sw, data);
return sw.toString();
} catch (IOException e) {
throw new RuntimeException("IOException from a StringWriter?");
}
}
public static void main(String[] args) {
Model model = new Model();
BasicConfigurator.configure();
put("/secrets", (request, response) -> {
try {
ObjectMapper mapper = new ObjectMapper();
NewSecretPayload creation = mapper.readValue(request.body(), NewSecretPayload.class);
if (!creation.isValid()) {
response.status(HTTP_BAD_REQUEST);
return "";
}
int id = model.createSecret(creation.getTitle(), creation.getContent());
response.status(200);
response.type("application/json");
return id;
} catch (JsonParseException jpe) {
response.status(HTTP_BAD_REQUEST);
return "";
}
});
get("/secrets/:title", (req, res) -> {
String title = req.params(":title");
if (model.getCertainSecret(title) != null) {
res.status(200);
res.type("application/json");
String secretString = model.getCertainSecret(title).getContent();
return dataToJson(model.getCertainSecret(title));
}
res.status(400);
return new ResponseError("No user with title "+title+" was found", title);
});
}
}
【问题讨论】:
-
我对这个问题中的大多数假设感到困惑:是什么让您相信 JSON 响应中的任何内容对用户隐藏?或者你如何通过 JSON 发送方法? JSON 是一种数据格式,我不确定您打算如何将 Java 方法嵌入其中。
-
我也不确定,很清楚:) 为了回答你的问题,我假设我最初会将我的所有敏感代码(方法、变量)
put到服务器上,然后分发我的应用程序。然后,用户将拥有软件的“外壳”,该软件在需要时通过get方法从服务器请求某些代码。我错误地认为 JSON 隐藏了这个……如果 JSON 没有在请求时隐藏值,你如何正确地从服务器检索数据,使其永远不会暴露?整个方法都需要保护,并且只在需要时调用。这可能吗?谢谢。 -
这根本不是网络通信的工作方式。可以读取通过发送的任何数据(在某些情况下可能会有点困难)。如果您不希望用户访问某些内容,那么您将无法发送它。你的整个方法对我来说似乎很奇怪。为什么要发送方法和变量?与将它们放在用户正在执行的二进制程序中相比,它应该提供什么优势?
-
在我发布的另一个问题here 中,有 2 个值得注意的引语来自其他 SO 答案。“将服务的最关键部分移出应用程序,进入 Web 服务,隐藏在像 PHP 这样的服务器端语言。移动算法并让它在远程服务器上处理数据,然后使用应用程序简单地为其提供数据。”以及“设置一个服务器来响应来自您的应用程序的请求,“使用”资产,然后将结果发送回应用程序。”
-
这些是我对我的方法的影响,我如何完成他们的建议?我想隐藏某些方法/变量的代码,因为它们可能对反编译它们的人非常有用。 ProGuard 还不够,所以我想将它们移到服务器端。我该如何做到这一点,以便它们的功能仍然可以像集成在源代码中一样使用?我很迷茫
标签: java json rest javafx server