使用外部 Web API 提供的 OAuth Bearer Token 进行授权
Authorization with OAuth Bearer Token provided by External Web API
我发布这篇文章是希望收到一些 feedback/advice 和关于我最近几天一直在努力解决的问题的信息。首先,我将简要介绍一下该项目。
解决方案中有 2 个应用程序:
WebAPI 资源和授权服务器 - 使用 OWIN(托管在 IIS 中)和 ASP.NET 身份在正确登录时颁发身份验证令牌,并且然后允许对各种控制器的请求。
MVC 客户端应用程序 - 目前还没有授权(直到我弄清楚)但会调用 WebAPI 资源服务器以获取所有数据.这些调用只会从客户端应用程序中的控制器的操作中进行,没有客户端 AJAX 调用。
客户端应用程序没有自己的数据源。所有信息都存储在 WebAPI 服务可以访问的数据库中,因此基本上,如果它们提供了正确的凭据并且客户端应用程序收到了不记名令牌,我需要提供一种方法让应用程序将它们视为已授权。
- 处理此问题的最佳方法是什么?
- 是否可以在客户端配置 OWIN 以使用 OAuth
服务器的设置?我是不是找错树了,我需要只使用 HTTPClients 吗?
- 我可以反序列化不记名令牌并将其存储在会话中,并且
然后编写我自己的授权提供程序在客户端检查这些?
我最初担心的是我在滥用不记名令牌并试图将它们拼凑成一个不理想的解决方案。到目前为止,我发现的所有外部授权示例通常都涉及调用由 Google/Facebook/Twitter 托管的提供商来检查用户是他们所说的人,然后继续在他们的系统中创建用户记录。我的应用程序无法执行此操作。
关于安全性,我计划引入过滤器,通过提供标识符和密码以及 IP 验证来验证请求是否来自客户端应用程序。
我意识到这可能有点开放性,但我将不胜感激任何建议。该项目的范围是 Web 服务是 唯一 可以访问数据库的东西。 MVC 客户端应用程序将托管在不同的服务器上,该服务将只接受来自该客户端应用程序的请求。
您无需访问 MVC 应用程序中的数据源来验证不记名令牌。基本上,您可以通过以下方式完成,
MVC 应用程序从 webapi 请求 access_token
并将其传递给 UI 客户端(假设是浏览器)。
浏览器将 access_token 存储在 cookie/localstorage 中,并将它们发送到 MVC 应用程序以供所有后续请求使用。
在 MVC 应用程序中创建一个 ActionFilter
以验证来自浏览器的请求是否具有 header 中提供的令牌。如果不是,则拒绝该请求。
MVC 应用将 Authorization
header 中的 access_token
传递给 webapi。
对所有通信使用 HTTPS(在 MVC 应用 <-> 客户端和 MVC 应用 <-> WebAPI 之间)
您可以进一步混淆或加密您从 MVC 应用程序端的 WebAPI 获得的 access_token
以提高安全性,但随后您必须将解密版本发送回 WebAPI。
我意识到我的回答有点晚了,但也许对其他人有帮助:
您从 API 获得的不记名令牌有一个加密的声明列表,只有 API 可以解密。我假设您也需要在 MVC 应用程序上拥有这些声明,以便您可以限制客户端上的资源。
所以,我所做的就是首先获得令牌。获取后,您向 API 资源 api/me/claims 发出另一个请求,以获取客户端上的可读声明列表。基于此列表,您可以使用基于授权属性的自定义声明来允许访问 MVC 客户端应用程序中的资源。此外,您可以将声明存储在客户端会话中的 cookie 中。下面是 API 控制器获取声明的代码。
[RoutePrefix("api/me/claims")]
public class ClaimsController : BaseApiController
{
[Authorize]
[Route("")]
public IHttpActionResult GetClaims()
{
var identity = User.Identity as ClaimsIdentity;
var claims = from c in identity.Claims
select new
{
subject = c.Subject.Name,
type = c.Type,
value = c.Value
};
return Ok(claims);
}
}
想法是在客户端重建登录用户的 ClaimsIdentity 对象,并可能将其添加到会话中。
令牌不够。您可能会冒着从 API 对您已在 MVC 客户端应用程序中对用户可见的资源获取未授权响应的风险。不用说,建议对所有请求使用 HTTPS。
我发布这篇文章是希望收到一些 feedback/advice 和关于我最近几天一直在努力解决的问题的信息。首先,我将简要介绍一下该项目。
解决方案中有 2 个应用程序:
WebAPI 资源和授权服务器 - 使用 OWIN(托管在 IIS 中)和 ASP.NET 身份在正确登录时颁发身份验证令牌,并且然后允许对各种控制器的请求。
MVC 客户端应用程序 - 目前还没有授权(直到我弄清楚)但会调用 WebAPI 资源服务器以获取所有数据.这些调用只会从客户端应用程序中的控制器的操作中进行,没有客户端 AJAX 调用。
客户端应用程序没有自己的数据源。所有信息都存储在 WebAPI 服务可以访问的数据库中,因此基本上,如果它们提供了正确的凭据并且客户端应用程序收到了不记名令牌,我需要提供一种方法让应用程序将它们视为已授权。
- 处理此问题的最佳方法是什么?
- 是否可以在客户端配置 OWIN 以使用 OAuth 服务器的设置?我是不是找错树了,我需要只使用 HTTPClients 吗?
- 我可以反序列化不记名令牌并将其存储在会话中,并且 然后编写我自己的授权提供程序在客户端检查这些?
我最初担心的是我在滥用不记名令牌并试图将它们拼凑成一个不理想的解决方案。到目前为止,我发现的所有外部授权示例通常都涉及调用由 Google/Facebook/Twitter 托管的提供商来检查用户是他们所说的人,然后继续在他们的系统中创建用户记录。我的应用程序无法执行此操作。
关于安全性,我计划引入过滤器,通过提供标识符和密码以及 IP 验证来验证请求是否来自客户端应用程序。
我意识到这可能有点开放性,但我将不胜感激任何建议。该项目的范围是 Web 服务是 唯一 可以访问数据库的东西。 MVC 客户端应用程序将托管在不同的服务器上,该服务将只接受来自该客户端应用程序的请求。
您无需访问 MVC 应用程序中的数据源来验证不记名令牌。基本上,您可以通过以下方式完成,
MVC 应用程序从 webapi 请求
access_token
并将其传递给 UI 客户端(假设是浏览器)。浏览器将 access_token 存储在 cookie/localstorage 中,并将它们发送到 MVC 应用程序以供所有后续请求使用。
在 MVC 应用程序中创建一个
ActionFilter
以验证来自浏览器的请求是否具有 header 中提供的令牌。如果不是,则拒绝该请求。MVC 应用将
Authorization
header 中的access_token
传递给 webapi。对所有通信使用 HTTPS(在 MVC 应用 <-> 客户端和 MVC 应用 <-> WebAPI 之间)
您可以进一步混淆或加密您从 MVC 应用程序端的 WebAPI 获得的 access_token
以提高安全性,但随后您必须将解密版本发送回 WebAPI。
我意识到我的回答有点晚了,但也许对其他人有帮助:
您从 API 获得的不记名令牌有一个加密的声明列表,只有 API 可以解密。我假设您也需要在 MVC 应用程序上拥有这些声明,以便您可以限制客户端上的资源。
所以,我所做的就是首先获得令牌。获取后,您向 API 资源 api/me/claims 发出另一个请求,以获取客户端上的可读声明列表。基于此列表,您可以使用基于授权属性的自定义声明来允许访问 MVC 客户端应用程序中的资源。此外,您可以将声明存储在客户端会话中的 cookie 中。下面是 API 控制器获取声明的代码。
[RoutePrefix("api/me/claims")]
public class ClaimsController : BaseApiController
{
[Authorize]
[Route("")]
public IHttpActionResult GetClaims()
{
var identity = User.Identity as ClaimsIdentity;
var claims = from c in identity.Claims
select new
{
subject = c.Subject.Name,
type = c.Type,
value = c.Value
};
return Ok(claims);
}
}
想法是在客户端重建登录用户的 ClaimsIdentity 对象,并可能将其添加到会话中。
令牌不够。您可能会冒着从 API 对您已在 MVC 客户端应用程序中对用户可见的资源获取未授权响应的风险。不用说,建议对所有请求使用 HTTPS。