1

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

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

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

4

2 回答 2

1

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

阅读更多: Azure Active Directory (Azure AD) 中的应用程序和服务主体对象

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

在此处输入图像描述

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

于 2018-02-08T08:27:51.970 回答
0

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

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

根据您的描述,您似乎想在 Web API中使用基本身份验证。就像您的猜测一样,我们可以使用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" };
        }

你可以看到这样的结果:

在此处输入图像描述

于 2018-02-09T01:44:56.627 回答