在这种情况下如何保护Jersey REST调用

时间:2016-06-22 16:25:52

标签: rest jersey

我面临的问题是点击Chrome浏览器上的F12,我可以看到所有用于获取数据的其余调用

例如,其中一个REST API调用是

(点击上面的链接,它会获取数据)

这是我的前端代码由Jquery

组成
function displaymarketupdates() {
var updatedon = "";
  var html = '';
  var t = "",

  $.ajax({
    type: "GET",
    url: e,
    crossDomain: !0,
    dataType: "json",
    timeout: 17e3,
    async: !0,
    cacheResults: !1,
    cache: !1,
    contentType: "application/json",
    charset: "utf-8",
    beforeSend: function() {
      $(".loadingWrapformarketupdates").show()
    },
    complete: function() {
      $(".loadingWrapformarketupdates").hide()
    },
    success: function(response) {
    },
    error: function(t, e, a) {
      $(".loadingWrapformarketupdates").hide()
    }
  }).done(function() {

  })

}

这是我的服务

@Path("/fetchallvalues")
public class FetchAllValues {
    public FetchAllValues() {}
    private final static Logger logger = Logger.getLogger(FetchAllValues.class);

    @GET@Produces("text/plain")
    public Response Fetch_all_values() {
        PreparedStatement fetch_all_pstmt = null;
        ResultSet fetch_all_Rset = null;

        Connection dbConnection = null;
        ResponseBuilder builder = Response.status(Status.NOT_FOUND);
        final JSONArray fetch_array = new JSONArray();
        final   String inputsql = "select * from all_values";
        try {
            dbConnection = DBConnection.getDBConnection();
            fetch_all_pstmt = dbConnection.prepareStatement(inputsql);
            fetch_all_Rset = fetch_all_pstmt.executeQuery();
            while (fetch_all_Rset.next()) {
                ====

            }
            Response.status(Status.OK);
            builder = Response.ok(fetch_array.toString());
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("Error description", e);
        } finally {
            try {
                DBConnection.close(fetch_all_pstmt, fetch_all_Rset);
            } catch (Exception e) {
                logger.error("Error description", e);
            }
            try {
                DBConnection.close(dbConnection);
            } catch (Exception e) {
                logger.error("Error description", e);
            }
        }
        return builder.build();
    }



}

在这种情况下,您能告诉我如何保护REST CALL

4 个答案:

答案 0 :(得分:2)

您无法隐藏浏览器网络监控中的URL。它应该被显示,以便可以推断当您点击按钮或点击某些内容时发生的事情。

保护REST Jersey调用是完全不同的事情。这意味着您不希望人们看到您要传递的数据。正如Martingreber正确提到的那样,如果您在HTTPS上调用此URL,可能会帮助您加密通过服务器发送的数据。或者确保REST调用实际上意味着您为其提供某种身份验证。与Basic类似,Hashing类似MD5,基于令牌的身份验证,如JWT

您可以做的唯一一件事就是隐藏运行JavaScript的浏览器中的显式详细信息,这样可以缩小您的脚本。但是,您的网址仍会暴露多次,因为有人在Chrome浏览器上使用F12键进行调用以查看正在进行的操作。还有一件事可能是你担心你的主要服务电话,并且不想公开它,然后只使用你正在做的一些服务来代理它。但绝不是,当有人打电话时,您可以避免显示您的网址。

在您的情况下,fetchAllValues服务正在获取数据并将其公开给网络上点击它的任何人,但是如果您对服务进行身份验证可以防止这种情况,例如我点击该网址时,它会问我输入密码!然后我无法访问它。验证此服务的一种非常简单的方法是在请求用户名和密码(如凭据)之前调用过滤器或拦截器。

我希望你明白这一点。希望这会有所帮助:)

答案 1 :(得分:0)

  1. 您将始终能够看到正在处理的网址。但是,您可以对服务端点进行模糊处理以隐藏服务本身的用途,例如: @Path("/XYZ")代替@Path("fetchallvalues")
  2. 如果要隐藏客户端和服务器之间传输的数据,那么没有人可以读取它,只需使用https即可。根据您的网络服务器(Jetty,Tomcat),您必须以不同的方式对其进行配置,您仍然需要为您的域提供ssl证书,例如:https://letsencrypt.org
  3. 如果您想保护您的网络服务,所以任何人都无法使用它,但只有特定用户才能使用,您可能需要尝试使用Spring Security:User authentication on a Jersey REST service

答案 2 :(得分:0)

不幸的是,您无法阻止客户端检查请求的URL。但是,您始终可以要求凭据来访问您的API端点。

REST API中的身份验证

在REST应用程序中,从客户端到服务器的每个请求都必须包含服务器要理解的所有必要信息。有了它,你不依赖于存储在服务器上的任何会话上下文,你也不会破坏REST stateless constraint,由Roy Thomas Fielding在dissertation中定义:

  

5.1.3 Stateless

     

[...]通信本质上必须是无状态的[...],这样每个从客户端到服务器的请求必须包含理解请求所需的所有信息,并且不能利用任何存储的上下文。服务器。因此,会话状态完全保留在客户端上。 [...]

访问受保护资源(需要身份验证的端点)时,每个请求都必须包含所有必要的数据才能进行正确的身份验证/授权。身份验证数据应属于标准HTTP Authorization标头。来自RFC 7235

  

4.2. Authorization

     

Authorization标头字段允许用户代理进行身份验证   本身与原始服务器 - 通常,但不一定,后   收到401(未经授权)回复。它的价值包括   包含用户身份验证信息的凭据   被请求资源领域的代理。 [...]

换句话说,将对每个请求执行身份验证。

基本身份验证

RFC 7617中定义的基本身份验证方案是保护REST API的良好开端:

  

2. The 'Basic' Authentication Scheme

     

基本身份验证方案基于客户端的模型   需要使用每个用户ID和密码进行身份验证   保护空间("领域")。 [...]服务器只有在可以验证时才会为请求提供服务   应用于保护空间的用户标识和密码   请求的资源。

     

[...]

     

要获得授权,客户

     
      
  1. 从用户

  2. 获取用户ID和密码   
  3. 通过连接user-id(单个)来构造用户传递   冒号(":")字符和密码

  4.   
  5. 将用户传递编码为八位字节序列,

  6.   
  7. 并通过编码此八位字节序列来获取基本凭证   将Base64用于US-ASCII characters

  8. 的序列         

    [...]

         

    如果用户代理希望发送用户ID" Aladdin"和密码   "打开芝麻",它将使用以下标题字段:

    Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
    
         

    [...]

基于令牌的身份验证

如果您不想通过网络发送每个请求的用户名和密码,您可以考虑使用基于令牌的身份验证。在此方法中,您将交换硬凭证(用户名和密码)以获取客户端必须在每个请求中发送到服务器的令牌:

  1. 客户端将其凭据(用户名和密码)发送到服务器。
  2. 服务器验证凭据并生成令牌。
  3. 服务器将先前生成的令牌与用户标识符和到期日期一起存储在某个存储中。
  4. 服务器将生成的令牌发送给客户端。
  5. 在每个请求中,客户端都会将令牌发送到服务器。
  6. 服务器在每个请求中从传入请求中提取令牌。使用令牌,服务器查找用户详细信息以执行身份验证和授权。
    1. 如果令牌有效,则服务器接受请求。
    2. 如果令牌无效,则服务器拒绝该请求。
  7. 服务器可以提供端点来刷新令牌。
  8. 同样,必须为每个请求执行身份验证

    令牌可以是 opaque (除了值本身之外没有显示任何细节,比如随机字符串)或者可以自包含(例如 JSON Web Token )。

    • 随机字符串:可以通过生成随机字符串并将其持久保存到具有过期日期且与其关联的用户标识符的数据库来发出令牌。

      < / LI>
    • JSON网络令牌(JWT):由RFC 7519定义,它是在双方之间安全地表示声明的标准方法。 JWT是一个独立的令牌,使您能够在有效负载中存储用户标识符,到期日期和任何您想要的内容(但不要存储密码),这是{{3编码为JSON。客户端可以读取有效负载,并且可以通过验证服务器上的签名来轻松检查令牌的完整性。如果您不需要跟踪JWT令牌,则不需要坚持使用JWT令牌。尽管如此,通过持久存在令牌,您将有可能使其无效并撤销其访问权限。要找到一些与JWT合作的优秀资源,请查看Base64

    在基于令牌的身份验证中,令牌是您的凭据。因此,如上所述,标记应该以标准HTTP http://jwt.io标头发送到服务器。

    使用Jersey之后,您可以查看Authorization,了解有关如何在Jersey中实施基于令牌的身份验证的更多详细信息。

    HTTPS

    通过网络发送敏感数据时,您最好的朋友是HTTPS,它可以保护您的应用免受this answer的攻击。<​​/ p>

    要使用HTTPS,您需要由man-in-the-middle attack等证书颁发机构颁发的证书,该证书声称是免费,自动且开放的证书颁发机构。

答案 3 :(得分:0)

这是一个需要一些智能黑客来修复它的问题。

在超链接stackoverflow页面中,您将获得如何从客户端JavaScript发出SOAP请求的示例。 SOAP request from JavaScript

现在这是计划:

  1. 在服务器端,我们有一个随机数生成器,它会在短时间间隔内生成一个随机数,比如5分钟。 随机数生成器将作为SOAP服务公开,它将生成生成的随机数。
  2. 从客户端,我们将调用SOAP随机生成器服务(参考上面提到的stackoverflow页面)并获取生成的随机数作为响应。我们将从JS函数调用该服务,该函数将在您的页面加载时触发(onLoad)。所以,现在我们在客户端有随机数。
  3. 然后,我们将随机数作为路径参数传递给REST调用的GET请求URL并触发GET请求。
  4. 在服务器端,一旦收到Rest GET请求,我们检查作为路径参数接收的号码是否与服务器端生成的号码相同。 如果数字匹配,那么我们给出所需的响应,否则不发送响应。
  5. 这里我们尝试引入一个唯一的密钥,即服务器端生成的随机数。当作为Rest GET请求URL的路径参数传递时,该唯一密钥用作Rest GET调用的原点的标识。对于想要通过引用Chrome开发者控制台的网络选项卡来调用Rest Api的人来说,长时间不会获得唯一密钥(因为它会在每5分钟后刷新/重新生成)。因此,黑客将无法长时间使用Rest Api。此外,由于我们使用SOAP将唯一密钥(随机数)从服务器传输到客户端,因此黑客无法从Chrome的开发者控制台获取它。

    希望这种方法有所帮助!