使 REST API 仅响应已知客户端

Make REST API respond only to known clients

我有一个 .Net Core REST API。和本机移动应用程序(也是 SPA)。

我的应用程序没有任何个人用户身份验证。这就像一项免费服务。

但我想确保仅当最终用户尝试从本机移动应用程序或 SPA 访问服务时才能访问该服务。如果在浏览器上粘贴 GET/POST link,应该无法访问。

可以吗?

(如果不是一个完全安全的解决方案?至少是一个简单的解决方案(系统不容易被破解)?顺便说一句,目前使用一个简单的 API-Key)

谁在请求中,什么在执行请求?

I don't have any individual user authentication for my application. It's like a free service.

用户身份验证仅识别在向API服务器发出的请求中,而不是什么在做什么.

这是我经常在任何资历的开发人员中发现的误解,因此我建议您阅读我写的文章 this section,标题为 为什么您的移动应用程序需要Api 键?。该部分详细解释了 whowhat 正在访问您的 API 服务器之间的区别,但我将在此处提取主要内容它:

The what is the thing making the request to the API server. Is it really a genuine instance of your mobile app, or is it a bot, an automated script or an attacker manually poking around your API server with a tool like Postman?

The who is the user of the mobile app that we can authenticate, authorize and identify in several ways, like using OpenID Connect or OAUTH2 flows.

在简历中,您需要考虑 who 作为用户,您的 API 服务器将能够验证和授权对数据的访问,并考虑what 作为代表用户提出请求的软件。

可能吗?

But I want to make sure that the service can be accessed only if the end-users are trying to access it from the native mobile app or the SPA. if the paste the GET/POST link on a browser, it should not be accessible.

Is it possible?

“是”和“否”...好吧,我不喜欢明确使用任何这些肯定,因为在软件中总是更像是 it depends!,因此我将它们括在引号中;)

移动应用程序是

对于移动应用程序,您可以使用移动应用程序证明概念来高度确信提出请求的确实是您手机的原始且未篡改的版本应用程序,要了解更多信息,我建议您阅读 this answer 我提出的问题 How to secure an API REST for mobile app?,特别是保护API服务器可能更好的解决方案

部分

网络应用程序否

对于网络应用程序,攻击者需要做的就是点击 F12 来检查网页并查看其上的所有源代码,因此这里没有直接的解决方案来解决知道的问题高度信任 what 正在执行请求,但是你可以让攻击者的日子更难过。我建议您阅读 my answer 问题 保护 api 来自应用程序调用的数据 ,特别是致力于保护 API 服务器的部分.

您想加倍努力吗?

在任何对安全问题的回答中,我总是喜欢引用 OWASP 基金会的出色工作。

对于APIS

OWASP API Security Top 10

The OWASP API Security Project seeks to provide value to software developers and security assessors by underscoring the potential risks in insecure APIs, and illustrating how these risks may be mitigated. In order to facilitate this goal, the OWASP API Security Project will create and maintain a Top 10 API Security Risks document, as well as a documentation portal for best practices when creating or assessing APIs.

对于移动应用程序

OWASP Mobile Security Project - Top 10 risks

The OWASP Mobile Security Project is a centralized resource intended to give developers and security teams the resources they need to build and maintain secure mobile applications. Through the project, our goal is to classify mobile security risks and provide developmental controls to reduce their impact or likelihood of exploitation.

OWASP - Mobile Security Testing Guide:

The Mobile Security Testing Guide (MSTG) is a comprehensive manual for mobile app security development, testing and reverse engineering.

对于网络应用程序

The Web Security Testing Guide:

The OWASP Web Security Testing Guide includes a "best practice" penetration testing framework which users can implement in their own organizations and a "low level" penetration testing guide that describes techniques for testing most common web application and web service security issues.

对于我的 API,我刚刚进行了一般身份验证检查。我将 pre-set username/password 附加到我的请求 header 中,然后根据我的 API 中的设置检查它。我只关心密码,但我使用用户名来识别来源。我创建了一个基本控制器,我的所有 API 控制器都继承自该控制器,因此我可以授权所有请求。 (日志记录是可选的)

 public abstract class BaseController : ApiController
    {
        protected static readonly Logger _logger = LogManager.GetCurrentClassLogger();

        protected bool IsAuthorized()
        {
            try
            {
                _logger.Debug("Checking credentials");
                var (Username, Password) = Security.ParseCredentials(HttpContext.Current.Request);
                if (Password != AppConfig.Instance.Settings["Password"])
                {
                    _logger.Error($"Calling application ({Username}) was not authorized.");
                    return false;
                }
                else
                {
                    _logger.Debug($"Calling application {Username} successfully authenticated.");
                    return true;
                }
            }
            catch (Exception ex)
            {
                _logger.Error(ex, "An error occured checking authentication");
                return false;
            }
           
        }
    }

然后在调用 API 的代码中,我将用户名密码编码到授权中 属性。

var client = new HttpClient
{
    BaseAddress = new Uri(ConfigurationManager.AppSettings["ReportApiUri"])
};
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Authorization =
       new AuthenticationHeaderValue("Basic",
       Convert.ToBase64String(Encoding.UTF8.GetBytes(
           $"SourceApplication:{ConfigurationManager.AppSettings["ApiPassword"]}"
           )
       ));

如果您从 SPA 调用,您可以 pre-encrypt 值并将它们传递进来。我可以使用 Postman 传递它,所以必须有一种方法可以使用我的任何客户端传递它会想。

PS - 我的基本控制器中的 AppConfig object 只是我写的一个 class 来检索设置,您可以使用配置管理器甚至 hard-code 它。 . 我的意思是,我不推荐 hard-coding 它 long-term 只是为了测试一下。

这是另一个堆栈溢出问题(问题已回答)的 link,其中有人试图获取客户端 IP。