WPF客户端WebAPI - 如何处理密码验证

WPF客户端WebAPI - 如何处理密码验证

问题描述:

我正在开发与ASP.Net WebAPI和WPF客户端/服务器应用程序。 现在我正考虑通过https对基本身份验证进行身份验证。您可以提出更好的解决方案,但Windows身份验证和服务器端会话不适用于我。WPF客户端WebAPI - 如何处理密码验证

对于基本身份验证,我需要用纯文本(base64)在客户端上的密码通过电话发送每个请求,对不对?

但我不希望用户在每次请求时重新输入密码,所以我在应用程序启动时有一个登录窗口。

WPF PasswordBox使用SecureString并且未绑定到视图模型。但至少在请求之前,我必须将密码作为普通字符串来将其编码为base64。 因此无论我做什么,迟早密码都以纯文本格式存储在RAM中。

以后的请求保存密码的最佳做法是什么?

  • 缓存PasswordBox
  • 缓存SecureString的
  • 高速缓存中的纯文本字符串,因为它会在RAM任一方式
  • 高速缓存中的base64编码字符串,因为它至少是不明显;)
  • ...?

那么我该如何处理这种合理安全的方式呢? 大型玩家(MS,Google,Apple,...)的其他应用程序不会为每次通话请求我的密码,所以必须有一种方法。

+0

为什么在地球上你想发送密码为Base64?这是一个简单的,非加密的编码,所有使用它的用户都会使用更多的内存。 Base64通常用于将二进制数据编码为字符串,而不是字符串作为更长的字符串。 – ProfK

+0

首先,我要感谢您强调这一点,因为谈论安全主题时应该了解这一点。在这种情况下,你对base64绝对没有帮助。我知道这一点,并且在问这个问题之前我知道这一点。 这就是为什么我写道:_至少它是晦涩难懂的)_ 但为什么base64?因为这是WebAPI的基本身份验证工作原理:[请参阅asp.net站点](https://www.asp.net/web-api/overview/security/basic-authentication) – alex

您应该读取身份验证令牌,这是一种常用的方法,而asp.net-web-api框架提供了OWin提供的许多功能。

基本上流程如下:

  • 身份验证在你的网络API。
  • 返回一个标记
  • 使用此令牌中的每一个标题下面的网络API/HTTP请求

好处:

  • 不存储在内存中的用户名和密码(只需一个电话)
  • 令牌可以在服务器端无效
  • 带有web-api2的开箱即用功能

你可以阅读一下: http://bitoftech.net/2014/06/01/token-based-authentication-asp-net-web-api-2-owin-asp-net-identity/

至于你的WPF客户端:

您可以创建一个。通过网络客户端的HTTP/Web的API请求:

HttpClienthttps://msdn.microsoft.com/en-us/library/system.net.http.httpclient%28v=vs.118%29.aspx

一些伪代码如下所示:

public async Task<IEnumerable<DataContainer>> GetDataForTarget(string id) 
{ 
    var requestMessage = new HttpRequestMessage(HttpMethod.Post, new Uri(new Uri(Host), 
     string.Format("api/Data?id={0}", id))); 

     var response = await Client.SendAsync(requestMessage); 

     //etc... 
} 

注: 对于基于令牌的安全性你需要https,否则令牌可能被拦截。每个知道令牌的人都可以代表相应的用户拨打web-api。因此,问题基本上从保护密码转移到保护令牌。令牌的好处是它的寿命应该比密码短得多,这就是为什么它更安全。尽管如此,将标记存储在SecureString中仍是有争议的。

在服务器端

这是

同时是个好习惯(或者即使你不这样做不道德),其前提是用户可以选择自己的密码,您在使用单向加密机制的服务器来存储密码。

这可以通过使用(加密强)随机salt和使用该非对称hash加密使用该salt来完成。

要验证用户,只需使用存储的salt加密传入的密码,并检查它是否为您提供存储的散列值。在这种情况下,没有真正的密码将被存储在您的服务器上,并且无法检索用户密码(....以及ehh排除一些技术细节)。

+0

谢谢,链接到bitoftech.net已经启发了我一点。到现在为止,我认为令牌意味着服务器状态,并需要多个服务器的共享会话。但根据该网站令牌是自足的。所以我会读到。 您提到第一个请求在内存中仍然有明文密码。我应该做些什么来尽快摆脱它,还是我不得不离开GC的东西? – alex

+0

那么,例如'securestring'的问题是,当你想使用它时,你需要将它转换成一个普通的字符串,这是不安全的。因此,在这种情况下,如果您确保托管字符串或文本框在您继续之前已被清除,那么您可以做的最好。 – Stefan

+0

另一件事:为了使基于令牌的安全性起作用,您需要使用“https”,否则可以拦截令牌。每个知道令牌的人都可以代表相应的用户拨打web-api。因此,问题基本上从保护密码转移到保护令牌。令牌的好处是它的寿命应该比密码短得多,这就是为什么它更安全。尽管如此,将标记存储在“SecureString”中是有争议的。我会在我的回答中加上这个。 – Stefan