【问题标题】:Azure Web API call with token authorisation带有令牌授权的 Azure Web API 调用
【发布时间】:2018-07-18 17:46:28
【问题描述】:

我有一个 Web API(我的所有代码)方法,我想在 Azure 中按计划调用它。我有这一切工作。我可以指定 URL,设置一个时间表,它工作正常。我想要做的是将呼叫限制为某个“系统”用户。

所有其他 Web API 方法都是从网站调用的。该网站允许用户登录并接收“访问令牌”,然后该令牌与所有其他请求一起发送。所以一个两步的过程。这一切都很好。

如何从 Azure 调度程序将“系统”用户/密码传递给 Web API 方法?它看起来很简单,选择基本身份验证,然后输入用户/密码组合。它仍然调用 Web API 方法,但它没有经过身份验证?我不确定如何在调用 Web API 方法之前获得用户身份验证?

【问题讨论】:

    标签: azure access-token azure-web-app-service azure-scheduler


    【解决方案1】:

    您可能会使用像 Azure Active Directory 这样的身份提供程序。您应该使用 服务主体,它代表您的计划应用程序,允许调用您的 API,而不是用户主体(您的系统用户)。

    阅读更多: Application and service principal objects in Azure Active Directory (Azure AD)

    因此,在身份验证设置中,您应该选择 Active Directory OAuth 并提供必要的值:

    基本身份验证必须在您的 WebAPI 中配置,它与您使用的令牌身份验证无关。

    【讨论】:

      【解决方案2】:

      它仍然调用Web API方法,但它没有经过身份验证?

      我不确定在调用 Web API 方法之前如何让用户通过身份验证?

      根据您的描述,您似乎想在 Web API 中使用 Basic Authentication。就像您的猜测一样,我们可以使用Basic Authentication 直接输入用户名和密码。我创建了一个简单的演示,如果我想读取 Web API 中的数据,我需要先进行身份验证。你可以参考我的代码:

      Web API 项目中的代码

      创建 BasicAuthHttpModule.cs:(指定您的用户名和密码)

      public class BasicAuthHttpModule : IHttpModule
          {
              private const string Realm = "My Realm";
      
          public void Init(HttpApplication context)
          {
              // Register event handlers
              context.AuthenticateRequest += OnApplicationAuthenticateRequest;
              context.EndRequest += OnApplicationEndRequest;
          }
      
          private static void SetPrincipal(IPrincipal principal)
          {
              Thread.CurrentPrincipal = principal;
              if (HttpContext.Current != null)
              {
                  HttpContext.Current.User = principal;
              }
          }
      
          // TODO: Here is where you would validate the username and password.
          private static bool CheckPassword(string username, string password)
          {
              return username == "peter" && password == "Password123!"; // you also could read user name and password from your Azure SQL database
          }
      
          private static void AuthenticateUser(string credentials)
          {
              try
              {
                  var encoding = Encoding.GetEncoding("iso-8859-1");
                  credentials = encoding.GetString(Convert.FromBase64String(credentials));
      
                  int separator = credentials.IndexOf(':');
                  string name = credentials.Substring(0, separator);
                  string password = credentials.Substring(separator + 1);
      
                  if (CheckPassword(name, password))
                  {
                      var identity = new GenericIdentity(name);
                      SetPrincipal(new GenericPrincipal(identity, null));
                  }
                  else
                  {
                      // Invalid username or password.
                      HttpContext.Current.Response.StatusCode = 401;
                  }
              }
              catch (FormatException)
              {
                  // Credentials were not formatted correctly.
                  HttpContext.Current.Response.StatusCode = 401;
              }
          }
      
          private static void OnApplicationAuthenticateRequest(object sender, EventArgs e)
          {
              var request = HttpContext.Current.Request;
              var authHeader = request.Headers["Authorization"];
              if (authHeader != null)
              {
                  var authHeaderVal = AuthenticationHeaderValue.Parse(authHeader);
      
                  // RFC 2617 sec 1.2, "scheme" name is case-insensitive
                  if (authHeaderVal.Scheme.Equals("basic",
                          StringComparison.OrdinalIgnoreCase) &&
                      authHeaderVal.Parameter != null)
                  {
                      AuthenticateUser(authHeaderVal.Parameter);
                  }
              }
          }
      
          // If the request was unauthorized, add the WWW-Authenticate header 
          // to the response.
          private static void OnApplicationEndRequest(object sender, EventArgs e)
          {
              var response = HttpContext.Current.Response;
              if (response.StatusCode == 401)
              {
                  response.Headers.Add("WWW-Authenticate",
                      string.Format("Basic realm=\"{0}\"", Realm));
              }
          }
      
          public void Dispose()
          {
          }
      }
      

      web.config 中的代码:

      <modules>
      <add name="BasicAuthHttpModule"
               type=" [your project name].[folder name].BasicAuthHttpModule, [your project name]"/>
      <!--Just like this: WebApiAzure1.BasicAuthor.BasicAuthHttpModule,WebApiAzure1-->
      </modules>
      

      API 控制器中的代码:

             [Authorize] //add authorize attribute for specific method
              public IEnumerable<string> Get()
              {
                  return new string[] { "value1", "value2" };
              }
      

      你可以看到这样的结果:

      【讨论】:

      • 目前正在尝试此代码。回复慢——搬家了。代码运行并且似乎按预期工作。但是,当它击中控制器动作时,它仍然是未经授权的。我会再调查一下。
      • 检查您的用户名和密码。请确保它们是正确的。
      • 上面的代码肯定是用正确的用户 ID / 密码调用的。查看文档,似乎我需要使用 Azure 目录服务?
      • 没有。我只是提供了一个关于 Web API 中基本身份验证的文档。我建议你可以按照上面文章中的步骤(docs.microsoft.com/en-us/aspnet/web-api/overview/security/…)。
      • 如果回复帮助你解决了问题,你可以标记为答案关闭本帖。
      猜你喜欢
      • 2015-04-24
      • 1970-01-01
      • 1970-01-01
      • 2018-06-05
      • 2021-10-20
      • 1970-01-01
      • 2019-10-14
      • 2019-01-09
      • 1970-01-01
      相关资源
      最近更新 更多