C# 使用外部Web API提供的OAuth承载令牌进行授权

C# 使用外部Web API提供的OAuth承载令牌进行授权,c#,model-view-controller,asp.net-web-api,owin,bearer-token,C#,Model View Controller,Asp.net Web Api,Owin,Bearer Token,我发布这篇文章的目的是希望收到一些反馈/建议,以及关于过去几天我一直在努力解决的问题的信息。首先,我将简要介绍一下这个项目 解决方案中有两个应用程序: WebAPI资源和授权服务器-使用OWIN(托管在IIS中)和ASP.NET标识在正确登录时发出身份验证令牌,然后允许向各个控制器发出请求 MVC客户端应用程序-目前还没有授权(直到我弄清楚),但将调用WebAPI资源服务器以获取所有数据。这些调用将只通过客户端应用程序中控制器的操作进行,而不会进行客户端AJAX调用 客户端应用程序没有自己的数据

我发布这篇文章的目的是希望收到一些反馈/建议,以及关于过去几天我一直在努力解决的问题的信息。首先,我将简要介绍一下这个项目

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

  • WebAPI资源和授权服务器-使用OWIN(托管在IIS中)和ASP.NET标识在正确登录时发出身份验证令牌,然后允许向各个控制器发出请求

  • MVC客户端应用程序-目前还没有授权(直到我弄清楚),但将调用WebAPI资源服务器以获取所有数据。这些调用将只通过客户端应用程序中控制器的操作进行,而不会进行客户端AJAX调用

  • 客户端应用程序没有自己的数据源。所有信息都存储在WebAPI服务可以访问的数据库中,因此基本上,如果它们提供了正确的凭据,并且客户端应用程序收到了承载令牌,那么我需要为应用程序提供一种方式,使其视为已授权

    • 最好的处理方法是什么
    • 是否可以在客户端配置OWIN以使用OAuth 服务器的设置?我是不是找错人了,我是否只需要使用HTTPClients
    • 我可以反序列化承载令牌并将其存储在会话中吗 然后写我自己的授权提供者在客户端检查这些
    我最初担心的是我滥用不记名代币,并试图将它们拼凑成一个不理想的解决方案。到目前为止,我发现的所有外部授权的例子通常都涉及到打电话给Google/Facebook/Twitter托管的提供商,检查用户是谁,然后在他们的系统中创建用户记录。我的应用程序无法执行此操作

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


    我意识到这可能有点无限制,但我希望得到任何建议。该项目的范围是,web服务是唯一可以访问数据库的东西。MVC客户端应用程序将托管在不同的服务器上,服务将只接受来自上述客户端应用程序的请求。

    您不需要访问MVC应用程序中的数据源来验证承载令牌。基本上,你可以用下面的方法

    • MVC应用程序从webapi请求
      访问\u令牌
      ,并将其传递给UI客户端(比如浏览器)

    • 浏览器将access_令牌存储在cookie/localstorage中,并将其发送到MVC应用程序以供所有后续请求使用

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

    • MVC应用程序将
      授权
      标题中的
      访问令牌
      传递给webapi

    • 使用HTTPS进行所有通信(MVC应用程序客户端和MVC应用程序WebAPI之间)


    您可以进一步混淆或加密从MVC应用程序端的WebAPI获得的
    access\u令牌
    ,以获得额外的安全性,但随后您必须将解密版本发送回WebAPI

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

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

    所以,我所做的是首先得到代币。获取后,向API资源API/me/claims发出另一个请求,以获取客户端上可读声明的列表。基于此列表,您可以允许使用自定义的基于声明的Authorize属性访问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);
        }
    }
    
    其思想是在客户端重建登录用户的ClaimSideEntity对象,并可能将其添加到会话中


    代币不够。您可能会在MVC客户端应用程序中使用户可见的资源上从API获得未授权的响应。我想说的是,建议对所有请求使用HTTPS。

    感谢您的评论。HTTPS将在生产版本中使用。我正在努力理解如何在客户端应用程序中实现基本的安全性。我想(如果可能的话)利用一些现有的功能,比如Authorize属性、AllowAnonymous等。我的WebAPI可以做到这一点,因为它有自己的用户存储和管理器,但是什么是向客户端应用程序添加授权的最佳解决方案呢?MVC客户端应用程序不必验证承载令牌。它只需检查请求中是否存在令牌(这是您可以在MVC应用程序端实现的基本安全性)。你可以通过创建一个ActionFilter并像Authorize属性一样使用它来实现这一点。我认为这是有意义的。我不打算验证持票人代币。计划是抓取它,将它存储在会话中,检查它是否存在,然后从那里处理请求。如果它过期了,我会要求他们重新验证或查看刷新令牌。这对我来说有点新鲜,所以我主要担心的是我可能忽略了一些缺陷。我想你已经回答了我的问题。为什么要将访问令牌存储在客户端的浏览器中,而不是存储在MVC服务器上的会话中?无论如何,令牌都会从MVC传递到Web Api。问得好。。。。