我有一个 ASP.NET Web API 2 应用程序,它对所有 Controller 使用 Windows 身份验证。我现在需要一些 Controller 使用基本身份验证。
我知道不可能同时启用匿名和 Windows 身份验证,但是是否可以为某些 Controller 启用 Windows 身份验证并为其他一些 Controller 启用基本身份验证?
更新: 实现了一个过滤器,如文章 EdSF shared 所示。
这是我到目前为止所拥有的:
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false)]
public class BasicAuthenticationFilter : AuthorizationFilterAttribute
{
private bool _active = true;
private const string ValidUsername = @"Test";
private const string ValidPassword = @"T3st";
public BasicAuthenticationFilter()
{
}
public BasicAuthenticationFilter(bool active)
{
_active = active;
}
public override void OnAuthorization(HttpActionContext actionContext)
{
if (_active)
{
var identity = ParseAuthorizationHeader(actionContext);
if (identity == null)
{
Challenge(actionContext);
return;
}
if (!OnAuthorizeUser(identity.Name, identity.Password, actionContext))
{
Challenge(actionContext);
return;
}
var principal = new GenericPrincipal(identity, null);
Thread.CurrentPrincipal = principal;
if (HttpContext.Current != null)
{
HttpContext.Current.User = principal;
}
base.OnAuthorization(actionContext);
}
}
protected virtual bool OnAuthorizeUser(string username, string password, HttpActionContext actionContext)
{
if (string.IsNullOrWhiteSpace(username) || string.IsNullOrWhiteSpace(password) ||
!username.Equals(ValidUsername) || !password.Equals(ValidPassword))
{
return false;
}
return true;
}
protected virtual BasicAuthenticationIdentity ParseAuthorizationHeader(HttpActionContext actionContext)
{
string authHeader = null;
var auth = actionContext.Request.Headers.Authorization;
if (auth != null && auth.Scheme == "Basic")
{
authHeader = auth.Parameter;
}
if (string.IsNullOrEmpty(authHeader)) return null;
authHeader = Encoding.Default.GetString(Convert.FromBase64String(authHeader));
var tokens = authHeader.Split(':');
if (tokens.Length < 2) return null;
return new BasicAuthenticationIdentity(tokens[0], tokens[1]);
}
private void Challenge(HttpActionContext actionContext)
{
var host = actionContext.Request.RequestUri.DnsSafeHost;
actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.Unauthorized);
actionContext.Response.Headers.Add("WWW-Authenticate", string.Format("Basic realm=\"{0}\"", host));
}
}
BasicAuthenticationIdentity 类:
public class BasicAuthenticationIdentity : GenericIdentity
{
public BasicAuthenticationIdentity(string name, string password)
: base(name, "Basic")
{
Password = password;
}
public string Password { get; set; }
}
此外,用基本身份验证过滤器装饰我的 Controller :
[BasicAuthenticationFilter]
[RoutePrefix("api/BasicAuth")]
public class BasicAuthController : ApiController
{
//[BasicAuthenticationFilter]
[HttpGet]
public IHttpActionResult TestBasicAuth()
{
return Ok("success");
}
}
当我从 Fiddler 调用 api/BasicAuth 时,我得到了 401,但它只返回以下挑战:
WWW-Authenticate: Negotiate
WWW-Authenticate: NTLM
此时,Fiddler 再次尝试,但这次它没有通过基本授权方案,而是通过了协商。这一次也失败了。
然后,当 Fiddler 最终第三次尝试时,我的过滤器实际上收到了请求,但由于授权方案是 Negotiate 而不是 Basic,所以我的过滤器也返回 Unauthorized。
有没有办法强制 Controller 只使用BasicAuthenticationFilter?
提前致谢
最佳答案
您可以 - 因为 BASIC AUTH
凭据是在 HTTP header
中发送的(仅限 Base64 编码)。您不必在应用程序级别“启用”任何内容并“手动”处理对 API 端点的 HTTP 请求(通过检查 header )。
例如基本身份验证 header :授权:基本 dXNlcm5hbWU6cGFzc3dvcmQ=
参见this example创建一个可以应用于Controller
或Action
的AuthorizationFilter
,如果需要的话甚至可以应用于全局......
第一个。
关于c# - 为 ASP.NET Web API 2 应用程序启用 Windows 和基本身份验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41728799/