JAX-RS安全性和身份验证

时间:2015-09-22 02:26:41

标签: authentication jersey jax-rs jersey-2.0

我正在开发REST webService,我的一些客户端将使用我的web服务,因此为了识别真正的客户端,我决定给每个真正的客户端一个唯一的应用程序令牌。客户端将对此令牌进行编码,他们会将此令牌放入请求标头中,并且我已在REST Web服务中配置REST过滤器以验证令牌。我不想使用https。我的问题是,任何人都可以从我的客户端站点获取该令牌,并可以使用我的REST Web服务。我怎么能阻止这个?

3 个答案:

答案 0 :(得分:1)

由于您不想使用https,我认为机密性不是问题,您只想基于谁制作请求来授权请求​​。您应该要求您的客户签署他们的请求,而不是传递可能被盗的普通令牌。你在这里有一个很好的解释:

简而言之,取自Implementing HMAC authentication for REST API with Spring Security

  1. 客户端和服务器共享一个秘密访问密钥和一个公共访问密钥。
  2. 客户端创建一个包含三个基本元素的请求:公钥标题(纯文本),日期标题,计算的签名字符串使用秘密访问密钥散列请求的一些数据。此哈希通常包含http方法,uri路径,日期标头的值(用于回复攻击),请求的所有内容(用于POST和PUT方法)和内容类型。
  3. 客户端将请求发送给服务器。
  4. 服务器读取公钥标头并使用它来检索相应的私人访问密钥。
  5. 服务器使用私有访问密钥以与客户端相同的方式计算签名。
  6. 服务器检查刚刚计算的签名是否与客户端发送的签名匹配。
  7. (可选)为防止回复攻击,服务器会检查日期标题中的值是否在可接受的限制范围内(通常在帐号时钟差异的5到15分钟之间)。恶意攻击者无法操纵该值,因为它被用作签名的一部分。如果有人更改日期标题,服务器将计算客户端计算的不同签名,因此步骤6将失败。
  8. 该逻辑可以使用任何编程语言实现。以下是java中的伪代码签名示例:

    //clientId is the public client identifier
    //secretKey is the key shared between server and client
    //requestContent is a string representation of the HTTP request (HTTP verb, body, etc.
    
    //init signing key and mac
    SecretKeySpec signingKey = new SecretKeySpec(secretKey.getBytes(), "HmacSHA1");
    Mac mac = Mac.getInstance("HmacSHA1");
    mac.init(signingKey);
    
    //sign the request content
    byte[] rawHmac = mac.doFinal(requestContent.getBytes());
    
    //encode to base64
    String result = base64(rawHmac);
    
    //store in header
    request.setHeader("Authorization", "MyAPI " + clientId + ":" + result);
    

    在服务器端,当您收到该请求时,从头中提取clientId和签名,检索与收到的clientId对应的密钥,重新计算签名(完全如上)并比较结果。它匹配客户端是否被授权,如果不是你返回HTTP 403(或任何你想要的错误)。

    然后没有更多的“秘密”可以窃取中间的潜在人,但是仍然需要在客户端和服务器上安全地存储密钥。泄漏这些密钥会损害整个系统。

答案 1 :(得分:0)

由于令牌无法在HTTP层安全传输,因此可以轻松获取此令牌。您可以通过组合一些具有时间戳的逻辑来让真正的客户端加密此令牌,以便每次使用某种不同的算法加密令牌时,在服务器端,您应该遵循类似的算法来解密它。这种方式即使有人拿到了无法重复使用的令牌。一种方法是使用Google身份验证器加入此加密逻辑。 (http://www.techrepublic.com/blog/google-in-the-enterprise/use-google-authenticator-to-securely-login-to-non-google-sites/

答案 2 :(得分:0)

使用校验和来保护消息,如下所示

MD5或SHA1校验和应该用于验证密码而不传递实际密码。

The server sends a random string to the client.
The client appends his password to the random string, and returns an MD5/SHA1 sum of the result to the server.
On the server, do the same and compare the MD5/SHA1 sums.
If both MD5/SHA1 are identicals then the password is good and message is not changed.
相关问题