保护从网络作业调用的控制器操作

Securing controller action called from a webjob

我在 Azure 中部署了一个 MVC 网站,我需要允许用户从 html 页面生成 pdf 文件。我通过在从控制器操作调用的 WebJob 中调用 wkhtmltopdf.exe 来做到这一点。呈现的 html 页面由另一个控制器动作生成,该动作 return 是一个 ActionResult。

当我用 [AllowAnonymous] 修饰动作(为 pdf 呈现 html)时一切正常,但我想以某种方式保护它。

是否可以对来自 Web 作业的请求进行身份验证,或者让 mysecureaction return 其数据仅用于那些来自 Web 作业的请求?

这是我的网络工作代码:

static void Main(string[] args)
{
  if (args.Length == 2)
  {
    var URL = args[0];
    var filename = args[1];

    try
    {
      using (var p = new System.Diagnostics.Process())
      {
        var startInfo = new System.Diagnostics.ProcessStartInfo
        {
          FileName = "wkhtmltopdf.exe",
          Arguments = URL + " " + filename,
          UseShellExecute = false,
        };
        p.StartInfo = startInfo;
        p.Start();
        p.WaitForExit();
        p.Close();
      }

      // here save the pdf file to azure blob storage
    } 
    catch (Exception ex) { /*error handling*/ }
    }
  }

下面是调用网络作业的代码:

string baseUrl = Request.Url.Scheme + "://" + Request.Url.Authority +         
Request.ApplicationPath.TrimEnd('/');
string Url = baseUrl + "/mycontroller/mysecureaction/" + id.ToString();
string filename = "filename.pdf";

try
{
  using (var client = new HttpClient())
  {
    client.BaseAddress = new Uri("https://myazurewebapp.scm.azurewebsites.net/");
    client.DefaultRequestHeaders.Accept.Clear();
    var userName = "$myazurewebappuser";
    var password = "myazurewebapppassword";
    var encoding = new ASCIIEncoding();
    var authHeader = new AuthenticationHeaderValue("Basic",
       Convert.ToBase64String(
   encoding.GetBytes(string.Format($"{userName}:{password}"))));
    client.DefaultRequestHeaders.Authorization = authHeader;
    var content = new System.Net.Http.StringContent("");

    HttpResponseMessage response =
  await client.PostAsync($"api/triggeredwebjobs/myWebJob/run?arguments={Url} {filename}", content);

    if (!response.IsSuccessStatusCode)
    {
       //error handling
    }
  }
}
catch (Exception ex)
{
  //error handling
}


byte[] file = null;
try
{
  using (var client = new WebClient())
  {
    // retrieve the file from blob storage
    file = client.DownloadData("https://myazureaccount.blob.core.windows.net/pdf/" + filename);
  }
}
catch (Exception ex) { /*error handling*/ }

// return the file to the user

很明显,这是 Web 作业为获取 html

而调用的操作
[AllowAnonymous]
public ActionResult mysecureaction(int? id)
{
  SomeData model = new SomeData();
  // get some data from db using id
  return View(model);
}

这似乎不是 WebJob 的好用法。 WebJobs 通常不由 Web 应用程序调用,它们本身也不向 Web 应用程序发送请求。相反,考虑几个备选方案:

您可以直接在您的应用程序中完成这项工作,而不是使用 WebJob,这在这里不会给您带来太多麻烦。

您可以通过队列而不是通过直接的 http 消息在应用程序和 WebJob 之间进行通信。例如Web 应用程序将工作项添加到队列中,然后 WebJob 拾取它们,例如使用 WebJobs SDK。