OWIN 托管的网站 api:使用 windows 身份验证并允许匿名访问

OWIN-hosted web api: using windows authentication and allow anonymous access

我有一个 WebApi 使用 OWIN 自托管的项目。

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

因此,根据我在网上找到的一些示例,我在 Statrup class:

中像这样设置了我的 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 的操作总是 returns 401 错误和以下消息:

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

即使调用方支持 windows 身份验证,已在浏览器(Chrome 和 Edge)和 Postman 上进行测试。

我在这里错过了什么?

由于您对问题的描述有限,我已经设置了一个演示应用程序,我在其中实现 OAuthAuthorizationServerProvider 作为 OAuthAuthorizationServerOptions 的提供者并覆盖 GrantResourceOwnerCredentialsValidateClientAuthentication

  public void Configuration(IAppBuilder app)
    {
        app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions
        {
            Provider = new ApplicationOAuthBearerAuthenticationProvider()
        });
        app.Use<AuthenticationResponseMiddleware>();
        var options = new OAuthAuthorizationServerOptions
        {
            AllowInsecureHttp = true,
            TokenEndpointPath = new PathString("/api/xxxx"),
            AccessTokenExpireTimeSpan = TimeSpan.FromDays(1), 
            Provider = new OwinAuthorisationProvider()

        };
        app.UseOAuthAuthorizationServer(options);

    }

还尝试了自定义 AuthorizeAttribute 并在配置中添加为过滤器 class .Filters.Add(new AuthorizeAttribute());

AuthenticationResponseMiddleware中我继承了OwinMiddleware并且在public override async Task Invoke(IOwinContext context)方法中请检查请求的流程。

它首先在 RequestToken 方法中命中 OAuthBearerAuthenticationProvider,然后到达 OwinMiddleware class,然后再进入任何 DelegatingHandler 管道, 大多数情况下,您的身份验证都是在此层中实现的。

检查后请评论你的发现,同时我也修改API并更新你,希望它可以帮助你。

好吧,我在另一个问题中找到了解决此问题的方法。 您可以在运行时通过设置 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 或请求的其他一些参数来决定使用哪种方法)但它有效。