c# - 为 ASP.NET Web API 2 应用程序启用 Windows 和基本身份验证

标签 c# asp.net asp.net-mvc authentication asp.net-web-api

我有一个 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创建一个可以应用于ControllerActionAuthorizationFilter,如果需要的话甚至可以应用于全局......

第一个。

关于c# - 为 ASP.NET Web API 2 应用程序启用 Windows 和基本身份验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41728799/

相关文章:

c# - 在 CKFinder v3 中将网站成员验证为用户

c# - 从我的 Web 服务读取 Http POST 正文内容? (.net 3.5)

javascript - jQuery 弹出窗口与 Asp.Net MVC 不能很好地配合

asp.net - AutoMapper 问题

c# - ViewResult 不使用 ASP.NET MVC 在 ASP.NET WebForms 项目中呈现页面内容

c# - 盲目地使用 InvokeRequired 不是一种不好的做法吗?

c# - 将包含多个对象的json对象反序列化为列表

c# - 出现错误 : No value given for one or more required parameters

javascript - 为什么 jquery ajax 调用 Controller 没有发现我的异常?

C# 单元测试模拟方法不起作用(为什么?)