首页 > 解决方案 > OWIN 托管的 web api:使用 windows 身份验证并允许匿名访问

问题描述

我有一个WebApi使用OWIN.

我想对控制器的某些操作启用 Windows 身份验证,但允许匿名调用其他操作。

因此,按照我在网上找到的一些示例,我在Statrup课堂上设置了这样的 WebApi:

public void Configuration(IAppBuilder appBuilder)
{
    HttpListener listener = (HttpListener)appBuilder.Properties["System.Net.HttpListener"];
    listener.AuthenticationSchemes = AuthenticationSchemes.IntegratedWindowsAuthentication | AuthenticationSchemes.Anonymous; //Allow both WinAuth and anonymous auth

    //setup routes and other stuff
    //...

    //Confirm configuration
    appBuilder.UseWebApi(config);
}

然后,在我的控制器中,我创建了两个操作:

[HttpGet]
[Authorize]
public HttpResponseMessage ProtectedAction()
{
    //do stuff...
}

[HttpGet]
[AllowAnonymous]
public HttpResponseMessage PublicAction()
{
    //do stuff...
}

但是,这不起作用。调用标记的操作AllowAnonymous按预期工作,但调用标记的操作Authorize总是返回 401 错误和以下消息:

{
    "Message": "Authorization has been denied for this request."
}

即使调用者支持 Windows 身份验证,也在浏览器(Chrome 和 Edge)和 Postman 上进行了测试。

我在这里想念什么?

标签: c#asp.net-web-apiowin

解决方案


好吧,我在另一个问题中找到了解决方法。您可以在运行时为每个请求选择身份验证模式,而不是指定多个身份验证模式(这不起作用),方法是设置如下 AuthenticationSchemeSelector 方法:

public void Configuration(IAppBuilder app)
{
    HttpListener listener = (HttpListener)appBuilder.Properties["System.Net.HttpListener"];
            listener.AuthenticationSchemeSelectorDelegate = new 
    AuthenticationSchemeSelector(GetAuthenticationScheme);
}

private AuthenticationSchemes GetAuthenticationScheme(HttpListenerRequest httpRequest)
{
    if(/* some logic... */){
        return AuthenticationSchemes.Anonymous;                    
    }
    else{
        return AuthenticationSchemes.IntegratedWindowsAuthentication;
    }
}

虽然并不理想(您必须手动检查请求 URL 或请求的其他一些参数来决定使用哪种方法)它可以工作。


推荐阅读