首页 文章

使用外部Web API提供的OAuth Bearer Token授权

提问于
浏览
7

我发布这篇文章是希望收到一些反馈意见/建议和有关我过去几天一直在努力的事情的信息 . 首先,我将对项目进行快速细分 .

解决方案中有2个应用程序:

  • WebAPI resource & authorization server - 使用OWIN(在IIS中托管)和ASP.NET Identity在正确的登录上发出身份验证令牌,然后允许对各种控制器的请求 .

  • MVC client application - 尚未授权(直到我弄清楚),但会调用WebAPI资源服务器来获取所有数据 . 这些调用只能来自客户端应用程序中控制器的操作,而不是客户端AJAX调用 .

客户端应用程序没有自己的数据源 . 所有信息都存储在WebAPI服务可以访问的数据库中,因此,如果它们提供了正确的凭据并且客户端应用程序收到了承载令牌,我需要为应用程序提供一种方式来查看它们是否已获得授权 .

  • 处理此问题的最佳方法是什么?

  • 是否可以在客户端配置OWIN以使用服务器的OAuth设置?我咆哮着错误的树,我是否需要使用HTTPClients?

  • 我可以对承载令牌进行反序列化并将其存储在会话中,然后编写我自己的授权提供程序以在客户端检查这些吗?

我最初担心的是我在滥用Bearer Tokens并试图将它们拼凑成一个不理想的解决方案 . 到目前为止,我发现的所有外部授权示例通常都涉及拨打由Google / Facebook / Twitter托管的提供商来检查用户是否是他们所说的人,然后继续在他们的系统中创建用户记录 . 我的申请不能这样做 .

关于安全性,我计划引入过滤器,通过提供标识符和秘密以及IP验证来验证来自客户端应用程序的请求 .

我意识到这可能有点开放,但我很感激任何建议 . 该项目的范围是Web服务是访问数据库的东西 . MVC客户端应用程序将托管在不同的服务器上,并且该服务仅接受来自所述客户端应用程序的请求 .

2 回答

  • 5

    您无需访问MVC应用程序中的数据源即可验证持有者令牌 . 基本上,你可以通过以下方式完成,

    • MVC应用程序从webapi请求 access_token 并将其传递给UI客户端(假设是一个浏览器) .

    • 浏览器将access_token存储在cookie / localstorage中,并将它们发送到MVC应用程序以获取所有后续请求 .

    • 在MVC应用程序中创建 ActionFilter 以验证来自浏览器的请求是否具有标头中提供的令牌 . 如果没有,请拒绝该请求 .

    • MVC应用程序将 Authorization 标头中的 access_token 传递给webapi .

    • 对所有通信使用HTTPS(在MVC app < - > Client和MVC app < - > WebAPI之间)

    您可以进一步模糊或加密从MVC应用程序端的WebAPI获得的 access_token 以获得额外的安全性,但是您必须将解密的版本发送回WebAPI .

  • 3

    我意识到我的答案有点晚了,但也许它有助于其他人:

    您从API获得的承载令牌具有加密的声明列表,只有API可以解密 . 我假设您需要在MVC应用程序上拥有这些声明,以便您可以限制客户端上的资源 .

    所以,我所做的是先获得令牌 . 获得它之后,您再向API资源api / me / claim发出请求,以获取客户端上的可读声明列表 . 根据此列表,您可以使用基于自定义声明的“授权”属性访问MVC CLient应用程序中的资源 . 此外,您可以将声明存储在客户端会话中的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对象,并可能将其添加到会话中 .

    令牌是不够的 . 您可能会冒险从您在MVC客户端应用程序中为用户显示的资源上获取API的Not Authorized响应 . 有人说,建议对所有请求使用HTTPS .

相关问题