是否可以使用本地 AD 系统帐户通过身份验证过滤器保护 Web api?
Posted
技术标签:
【中文标题】是否可以使用本地 AD 系统帐户通过身份验证过滤器保护 Web api?【英文标题】:Is it possible to secure a web api with Authentication Filters using the local AD system acounts? 【发布时间】:2016-03-08 21:02:56 【问题描述】:我已经研究了一种方法来模拟您的 AD 用户,以使用我的本地域 AD 保护我的 Web API。 我发现的所有示例都使用基本身份验证或令牌身份验证。或使用 Azure AD 保护它。
我想使用我的本地域 AD/Impersonation 来实现我的自定义授权业务逻辑。我所能实现的就是使用 BASIC 身份验证,并且挑战总是弹出一个表单来输入用户名/密码。我想绕过它并使用我的本地域 + 自定义逻辑来验证/授权用户。
有没有一种方法可以模拟 windows 用户在我的 web api 中对资源进行身份验证和授权?
这是我的挑战功能的样子:
void Challenge(HttpRequestMessage request, HttpResponseMessage response)
var host = request.RequestUri.DnsSafeHost;
response.Headers.Add(WWWAuthenticateHeader, string.Format("Basic realm=\"0\"", host));
非常感谢!
【问题讨论】:
【参考方案1】:首先,您应该阅读以下内容:
How to get HttpClient to pass credentials along with the request?
第二(如果你正在做“单跳”)。
如果启用“Windows 身份验证”并禁用“匿名身份验证”(在 IIS 中的“身份验证”下)......您可以获取 Windows 身份。
您需要编写一个自定义 AuthorizeAttribute。
这是一个基本的尝试:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Security.Principal;
using System.Web;
using System.Web.Http;
using System.Web.Http.Controllers;
namespace MyLibrary.CustomAttributes.WebApi
public class IdentityWhiteListAuthorizationAttribute : System.Web.Http.AuthorizeAttribute
public const string ErrorMessageBadIdentityContent = "IIdentity.Name was empty or IIdentity was not a WindowsIdentity. CurrentAction='0'";
public const string ErrorMessageBadIdentityReasonPhrase = "IIdentity.Name was empty or IIdentity was not a WindowsIdentity. The most likely reason is that the web service is not setup for WindowsAuthentication and/or Anonymous Authentication is enabled.";
public const string ErrorMessageNotAuthenticated = "IIdentity.IsAuthenticated was false. '0'";
public IdentityWhiteListAuthorizationAttribute()
private string CurrentActionName get; set;
public override void OnAuthorization(HttpActionContext actionContext)
this.CurrentActionName = actionContext.ActionDescriptor.ActionName;
base.OnAuthorization(actionContext);
protected override bool IsAuthorized(HttpActionContext actionContext)
/* this will authenticate if the authorization-header contained a "Negotiate" windows Identity. Note, WebApi must be running in Windows-Authentication mode (and the WebApi-web.config must be set for "<authentication mode="Windows" />") for this to work. (the client will send the windows identity via the DefaultRequestHeaders.Authorization header */
string currentActionName = this.CurrentActionName;
IPrincipal httpContextCurrentUserPrinc = HttpContext.Current.User; /* */
IIdentity ident = httpContextCurrentUserPrinc.Identity;
bool badIdentity = false;
string errorMessageContent = string.Empty;
string errorMessageReasonPhrase = string.Empty;
if (null == ident)
badIdentity = true;
errorMessageContent = string.Format(ErrorMessageBadIdentityContent, currentActionName);
errorMessageReasonPhrase = ErrorMessageBadIdentityReasonPhrase;
if (!badIdentity)
/* Ensure that we have an actual userName which means windows-authentication was setup properly */
if (string.IsNullOrEmpty(ident.Name))
badIdentity = true;
errorMessageContent = string.Format(ErrorMessageBadIdentityContent, currentActionName);
errorMessageReasonPhrase = ErrorMessageBadIdentityReasonPhrase;
if (!badIdentity)
if (!ident.IsAuthenticated)
badIdentity = true;
errorMessageContent = string.Format(ErrorMessageNotAuthenticated, ident.Name);
errorMessageReasonPhrase = string.Format(ErrorMessageNotAuthenticated, ident.Name);
if (!badIdentity)
if (ident.GetType() != typeof(WindowsIdentity))
badIdentity = true;
errorMessageContent = string.Format(ErrorMessageBadIdentityContent, currentActionName);
errorMessageReasonPhrase = ErrorMessageBadIdentityReasonPhrase;
if (badIdentity)
HttpResponseMessage resp = new HttpResponseMessage(HttpStatusCode.BadRequest)
Content = new StringContent(errorMessageContent),
ReasonPhrase = errorMessageReasonPhrase
;
throw new HttpResponseException(resp);
return true;
将该属性应用于 webapi 控制器和/或方法。
您也可以编写一个 DelegatingHandler...并使用上面相同的代码......
【讨论】:
非常感谢伙计...这非常有用。在这种情况下使用委托处理程序有什么好处?我想在某处编写我的自定义授权例程。您是否建议在“IsAuthorized”事件中这样做?再次感谢您的帮助!干杯! 委托处理程序(一旦添加)..将影响每个控制器/动作。属性方式(在我的帖子上方)让您选择。委托处理程序在管道中较早运行。如果每个控制器/操作都需要安全检查.....那么请使用委托处理程序。以上是关于是否可以使用本地 AD 系统帐户通过身份验证过滤器保护 Web api?的主要内容,如果未能解决你的问题,请参考以下文章