允许mvc5 c#webapi以便只有我的应用才能访问它

时间:2016-08-22 09:22:33

标签: asp.net-mvc asp.net-web-api asp.net-mvc-5 episerver-7

我通过控制器操作方法进行api调用,如下所示。以下是它的工作代码。 但我想保护webapi,以便只有我的应用程序才能访问它。我见过有登录凭证的来源 但就我而言,它是一个面向公众的网站,没有登录用户。 只有来自我的应用程序的调用才能访问它。任何人都可以建议可以做些什么。或者我当前使用ValidateReferrer的代码是否足以处理?

[HttpGet]
[ValidateReferrer]
[ActionName("GetFind")]
[CacheOutput(ClientTimeSpan = 300, ServerTimeSpan = 300)]
public ApiQueryResponse GetFind(string query)
{
    return _Worker.GetFind(query);
}

控制器中的Validate Referrer具有以下实现:

public override void OnAuthorization(AuthorizationContext filterContext)
{
    if (filterContext.HttpContext == null)
    {
        throw new System.Web.HttpException("No Http context, request not allowed.");
    }
    else
    {
        if (filterContext.HttpContext.Request.UrlReferrer == null)
        {
            throw new System.Web.HttpException("Referrer information missing, request not allowed.");
        }
        else if (filterContext.HttpContext.Request.UrlReferrer.Host != filterContext.HttpContext.Request.Url.Host)
        {
            throw new System.Web.HttpException(string.Format("Possible cross site request forgery attack, request sent from another site: {0}", filterContext.HttpContext.Request.UrlReferrer.Host));
        }
    }
}

在工人阶级,

public ApiQueryResponse GetFind(string query)
{
    var results = GetResults(Settings.ApiKey, SetFindParameters(query), Resource);           
    return results;
}

private ApiQueryResponse GetResults(string apiKey, string parameterQuery, string Resource)
{
    var results = new ApiQueryResponse();
    if (apiKey != null && !String.IsNullOrWhiteSpace(apiKey))
    {
        using (var client = new HttpClient())
        {
            client.DefaultRequestHeaders.Accept.Clear();
            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
            var response = client.GetAsync(string.Format("{0}/{1}?{2}&key={3}", WebApiUrl, Resource, parameterQuery, apiKey)).Result;
            if (response.IsSuccessStatusCode)
            {
                var responseBodyAsText = response.Content.ReadAsStringAsync().Result;
                results = JsonConvert.DeserializeObject<ApiQueryResponse>(responseBodyAsText);
            }
        }
    }
    return results;
}

1 个答案:

答案 0 :(得分:2)

同样,您必须验证“应用程序”而不是用户。如果你检查facebook / twitter / gmail api,他们有一个客户端密码和客户端ID来验证应用程序。但仍然会有一个“授权”调用使用此id和秘密进行调用,api返回一个令牌,此后此令牌用于授权其他请求。此令牌也将有一个到期时间,并且有方法可以获得刷新令牌。

如上所述,您必须接听一个关于您为api实施多少安全性的电话。你可以有一个类似的方法,你的客户端首先通过提供客户端ID和秘密(这应该是一个秘密)来请求安全令牌。您可以针对您的商店(可能是数据库)检查此ID和密码,如果通过验证,您可以使用[Authroize]属性或自定义验证发送回可以进行身份​​验证的令牌。

如何创建令牌应该是IMO的另一个讨论。这里提到了简单的方法,例如 - how to generate a unique token which expires after 24 hours?。还有其他标准方法可以生成令牌JWT / OAuth令牌。

修改 作为一种简单的方法(不考虑安全性方面)将是:

  • 创建应用密钥(可能是Guid值)
  • 发送请求时,请获取当前时间戳并加密(拥有您的 自己的加密和解密逻辑)应用程序秘密的时间戳。让我们将加密值称为'token'
  • 在您的请求标头中传递令牌(可能是自定义标头,例如, 的x我-AUTH)
  • 在api中,有一个自定义授权过滤器
  • 在自定义过滤器中,重写OnAuthroizeCore方法,获取 来自请求标头的令牌
  • 使用相同的应用程序秘密解密令牌,您将获得 从客户端发送的时间戳
  • 如果解密很好,那么我们是通过第一步/或 令牌传递了第一步
  • 另外,检查当前时间是否有差异 从令牌解密的时间超过5(*你可以拥有你的 拥有到期价值)
  • 如果差异超过您的到期限制,则返回false 会将未经授权的异常抛回客户端(如果令牌无法解密则执行相同操作
  • 到期检查是为了处理有人攻击您的情况 来自请求的令牌,然后使用它。如果他 在到期后使用令牌,这将导致未经授权的

将上述逻辑和整个描述视为“思考的食物”,如果没有适当的研究和理解,请不要使用它。我的想法是提供一些关于应用程序身份验证的基本想法,直到有人真正擅长这篇文章在这篇文章中写了一篇非常好的文章