MVC.NET Cookie认证系统如何通过令牌身份验证访问Web Api?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (16)

我有一个Mvc 5客户端,拥有一个拥有者Cookie认证。我还有一个Web API,它受Owin Bearer标记保护(我使用VS2013 Web Api模板创建Token端点)

好吧,现在我的Mvc 5客户端需要使用我的WebApi。我创建了一个获取不记名令牌的方法:

internal async Task<string> GetBearerToken(string siteUrl, string Username, string Password)
{
     HttpClient client = new HttpClient();

     client.BaseAddress = new Uri(siteUrl);
     client.DefaultRequestHeaders.Accept.Clear();

     HttpContent requestContent = new StringContent("grant_type=password&username=" + Username + "&password=" + Password, Encoding.UTF8, "application/x-www-form-urlencoded");

     HttpResponseMessage responseMessage = await client.PostAsync("Token", requestContent);

     if (responseMessage.IsSuccessStatusCode)
     {
         TokenResponseModel response = await responseMessage.Content.ReadAsAsync<TokenResponseModel>();
         return response.AccessToken;
     }

     return "";
}

在我的MVC操作中,我称之为:

public async Task<ActionResult> Index()
{
     var token = await GetBearerToken("http://localhost:6144/", "teste", "123456");

     using (var client = new HttpClient())
     {
         client.DefaultRequestHeaders.Add("Authorization", "Bearer "+ token);

         var response = await client.GetAsync("http://localhost:6144/api/values");

         if (response.IsSuccessStatusCode)
         {
             var data = response.Content.ReadAsAsync<IEnumerable<string>>();

             return Json(data.Result, JsonRequestBehavior.AllowGet);
         }
     }   
}

这一切工作正常......但我需要在我的所有行动中使用Web Api ...那么我怎么能保持该令牌(尽管每个请求得到一个新的令牌)以及如何验证它是否过期...是否有可能保持与认证cookie一起吗?处理这种情况的最佳实践是什么?

提问于
用户回答回答于

如果我理解正确,那么MVC 5客户端应用程序正在访问不同应用程序的WebAPI。MVC 5客户端使用cookie来验证用户。要访问WebAPI,需要从/ Token端点获取承载,然后将其发送到Authorization标头中。

不需要从客户端Javascript代码调用WebAPI,只需从MVC5应用程序的服务器上运行的MVC Actions中调用它即可。

在每次服务呼叫之前获取新的令牌听起来不对。这意味着每次往返2次。这不可能是高性能的。

如果我说得对,你可以:

  1. 将令牌存储在Session对象中。只要MVC App用户通过身份验证并且他的会话处于活动状态,就会始终拥有相同的令牌。如果它过期,将从WebAPI获得401未经授权的访问。为了保持MVC操作单元可测试性,可以将会话访问包装到注入到操作(依赖注入)中的服务中。
  2. 可以将令牌存储在类似于已有的验证cookie的cookie中。这样你就不需要服务器端的会话。在这里,我再次包装访问权限,以便在所有操作使用的服务中从Cookie中获取令牌。
用户回答回答于

不记名令牌不是授权Web应用程序的好方法。如果将服务的令牌存储在cookie中,则应用程序的客户端将可以使用该令牌,因此服务层将容易受到应用程序客户端的攻击。唯一的解决方案似乎是在会话中保留令牌,但将失去应用程序的无状态特性。

这里描述了什么/如何使用不记名令牌应该被使用: “不记名令牌只是一个客户端必须在每个API调用中出现的一个大的随机字符串,因为在两端都没有特殊的签名或验证码,所以签名令牌很简单。客户端负责将令牌存储在一个安全的地方并发送给每个请求,服务器负责在数据库中查找令牌并确保它是有效的令牌 - 就是这样。“

以下是在客户端直接与服务对话的单页应用程序中使用不记名令牌的好例子。

无论如何,我会建议你使用HMAC认证,BCrypt或ClientCertificates。

扫码关注云+社区