2011-09-11 43 views
0

我有使用REST服务访问数据库登录用户的安全问题,我有它的工作,但我知道它不能这样,因为密码不是以任何方式编写和通过URL旅行。这是我的代码:如何隐藏基于REST的服务中的帐户信息?

首先,发送请求的代码:

private void validateUser(String user, String pass) 
{ 

    String URL = "http://myserviceserver/MyService.svc"; 

    AlertDialog popup; 

    try{ 
     HttpGet request = new HttpGet(URL + "/Validate" + "/" + user + "/" + pass); 

     request.setHeader("Accept", "application/json"); 
     request.setHeader("Content-type", "application/json"); 

     DefaultHttpClient httpClient = new DefaultHttpClient(); 
     HttpResponse response = httpClient.execute(request); 

     HttpEntity responseEntity = response.getEntity(); 

     // Read response data into buffer 
     char[] buffer = new char[(int)responseEntity.getContentLength()]; 
     InputStream stream = responseEntity.getContent(); 
     InputStreamReader reader = new InputStreamReader(stream); 
     reader.read(buffer); 
     stream.close(); 

     String resultado = new String(buffer); 

     if(resultado.contains("true")) 
     { 
      popup = createAlertDialog("Message", "User Validated", "OK"); 
      popup.show(); 
     } 
     else 
     { 
      popup = createAlertDialog("Message", "User NOT Validated", "OK"); 
      popup.show(); 
     }  


    } 
    catch(Exception e) 
    { 

    } 


} 

现在,从服务器端,这是我的服务接口:

[ServiceContract] 
public interface IMyService 
{ 
    [OperationContract] 
    [WebInvoke(Method = "GET", UriTemplate = "Create/{user}/{pass}/{email}")] 
    bool CreateNewAccount(string user, string pass, string email); 

    [OperationContract] 
    [WebInvoke(Method = "GET", UriTemplate = "Validate/{user}/{pass}")] 
    bool ValidateUser(string user, string pass); 
} 

现在,这就像一个魅力,但它是不安全的,但我不太明白我怎么能隐藏发送的信息,因为现在我只需在http://myserviceserver/MyService.svc/Validate/user/password提出请求登录。

任何帮助将apreciated :)

+0

为什么不使用内置到WCF中的函数进行身份验证?这样你就不必用头文件和东西重新实现整个HTTP客户端,只需使用WCF并将其配置为使用wsHttp即可。 – CodeCaster

回答

0

如果你是担心的是人在这方面的中间人攻击,我建议HTTPS:证书是相当便宜和如果您使用HTTPS,大部分问题都会消失。

如果您担心在服务器日志中泄漏东西,那么我会将参数作为请求参数而不是请求的一部分。它看起来像你实际上使用用户名/密码作为你的服务器方法的参数,所以HMAC并不会完全帮助你。对于未使用传递参数的请求,您可能需要切换到散列验证方案。

+0

将使用HMAC而不是密码,除此之外。 hmac签名可以公开,因为一旦请求已经被处理(或者在稍后的日期,当时间戳是散列明文的一部分时),它们就没有用了。 – SingleNegationElimination

+0

好吧,如果你看看上面他正在使用的实际方法签名创建帐户的用户名/密码('bool CreateNewAccount(字符串用户,字符串传递,字符串电子邮件);')。 HMAC不会给他的,因此我的套期保值。 – Femi

1

一个开明的解决方案是使用HMAC授权。在这个方案中,对REST API的每个请求都包含一个额外的头部,其中包含请求本身的校验和,并将密码或其他预共享密钥作为请求的一部分。服务器收到请求后,将请求主体与其在数据库中保存的密码连接起来,并验证校验和是否匹配。这意味着每个请求都是无状态的,并且即使请求以某种方式被嗅探到,但由于校验和仅对该特定请求有效,所以它对攻击者无用。

的一个很好的例子是这样的Amazon Web Services的工作原理:See here for a description