【问题标题】:Web api authorization by capturing client's service account name通过捕获客户端的服务帐户名称进行 Web api 授权
【发布时间】:2018-07-07 10:29:13
【问题描述】:

所有,我在我的 Web api 控制器操作之一上实施授权时遇到问题。这是一个 .net 框架 4.6.1 应用程序和一个 MVC 5 应用程序调用此 Web api。 我们在客户端(MVC5)和 Web api 上都实现了 Windows 身份验证。客户端和服务器都使用相同的服务帐户(运行应用程序池的帐户名称),并且它们位于不同的服务器上。

客户端应用程序的用户在访问调用 Web api 的 MVC 应用程序部分之前使用 AD 帐户进行身份验证。

我在 api 控制器操作中添加了 [Authorize] 属性,但请求返回 401 未授权状态。

所以我添加了一个自定义授权逻辑,它将来自客户端应用程序的传入用户名(服务帐户)与 api 配置文件中配置的内容(在每个环境中)进行比较并接受/拒绝请求。但是用户(请请参阅下面的代码)在 actionContext.RequestContext.Principal.Identity.Name 行上是一个空字符串。

我尝试在 IIS 上的 MVC5 应用配置上启用 asp.net 模拟,但仍然没有成功

有没有人做过类似的事情?

自定义授权逻辑

public class CustomAuthorize : AuthorizeAttribute
{

    protected override bool IsAuthorized(HttpActionContext actionContext)
    {
        var isAuthorized = false;
        var environment = ConfigurationManager.AppSettings["Env"];
        var configuredAccountName = ConfigurationManager.AppSettings["appserviceaccountname"];
        string incomingServiceAccountName = null;

        try
        {

            if(actionContext.RequestContext.Principal != null && actionContext.RequestContext.Principal.Identity != null)
            {

                incomingServiceAccountName = actionContext.RequestContext.Principal.Identity.Name;
                if(!string.IsNullOrWhiteSpace(incomingServiceAccountName))
                {
                    logger.Error(string.Format("Service account name passed in is : {0}", incomingServiceAccountName));
                    switch (environment)
                    {
                        case "Dev":
                            if(incomingServiceAccountName.ToLower().Equals(configuredAccountName.ToLower()))
                            {
                                isAuthorized = true;
                            }
                            break;

                        default:
                            break;
                    }
                }

            }
            else if(actionContext.RequestContext.Principal == null)
            {
                logger.Error("Principal is null");
            }
            else
            {
                logger.Error("Identity is null");
            }

        }
        catch (Exception ex)
        {
            logger.Error(string.Format("Error occurred while authorizing the user inside the class CustomAuthorize and method IsAuthorized with {0}", ex.Message));
            isAuthorized = false;
        }

        return isAuthorized;

    }
}

进行 api 调用的 MVC5 客户端代码

using (var client = new HttpClient())
            {
                client.BaseAddress = new Uri("http://webapiurl");
                var jsonString = new StringContent(JsonConvert.SerializeObject(search), Encoding.UTF8, "application/json");
                client.DefaultRequestHeaders.Accept.Clear();
                client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
                HttpResponseMessage response = client.PostAsync(client.BaseAddress, jsonString).Result;
                if (response.IsSuccessStatusCode)
                {
                    var result = response.Content.ReadAsStringAsync().Result;
                    mydate = JsonConvert.DeserializeObject<List<mydate>>(result);
                }
            }
    }

【问题讨论】:

    标签: asp.net-mvc authentication asp.net-web-api


    【解决方案1】:

    您是否在服务器上的 IIS 中设置了 Windows 身份验证? IIS Windows 身份验证提供程序也必须存在(协商、NTLM),以允许 IIS 尝试使用 AD 进行身份验证。

    【讨论】:

    • IIS 上的 Windows 身份验证已打开
    • 我刚刚意识到您使用创建单独线程的 HttpClient 并且 Windows Auth 不允许新线程继承安全上下文。如果你坚持使用 HttpClient,你应该确保你设置了 HttpClientHandler.Credentials。否则,您可以使用不创建单独线程并传递 Windows 凭据的 WebClient。
    • 你在 Ivicz。我将客户端实现更改为使用 WebClient 和 UseDefaultCredentials = true。这会传递服务帐户,而不是来自客户端应用程序的登录用户帐户
    • 我认为此时您应该在客户端打开模拟。另一个想法,也许您允许在客户端上进行匿名身份验证,这会破坏协商提供程序的 Windows 用户登录。如果没有帮助,我想我一无所知。
    猜你喜欢
    • 2016-06-21
    • 2017-02-22
    • 2019-08-17
    • 1970-01-01
    • 1970-01-01
    • 2020-02-22
    • 2016-10-22
    • 2013-08-21
    • 2014-04-11
    相关资源
    最近更新 更多