Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/333.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# OWIN托管的web api:使用windows身份验证并允许匿名访问_C#_Asp.net Web Api_Owin - Fatal编程技术网

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

C# OWIN托管的web api:使用windows身份验证并允许匿名访问,c#,asp.net-web-api,owin,C#,Asp.net Web Api,Owin,我有一个WebApi项目,使用OWIN自行托管 我想对控制器的某些操作启用Windows身份验证,但允许匿名调用其他操作 因此,下面是我在网上找到的一些示例,我在我的Statrup类中这样设置我的WebApi: public void Configuration(IAppBuilder appBuilder) { HttpListener listener = (HttpListener)appBuilder.Properties["System.Net.HttpListener"];

我有一个
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."
}
即使调用方支持在浏览器(Chrome和Edge)和Postman上测试的windows身份验证


我在这里遗漏了什么?

因为你对这个问题的描述有点有限,我已经建立了一个演示应用程序,在那里我实现了
OAuthorizationServerProvider
作为
OAuthorizationServerOptions
的提供者,并覆盖
GrantResourceOwnerCredentials
ValidateClientAuthentication

  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);

    }
public void配置(IAppBuilder应用程序)
{
app.useAuthBeareAuthentication(新的OAuthBeareAuthenticationOptions
{
Provider=新的ApplicationAuthBeareAuthenticationProvider()
});
app.Use();
var options=新的OAuthAuthorizationServerOptions
{
AllowInsecureHttp=true,
TokenEndpointPath=新路径字符串(“/api/xxxx”),
AccessTokenExpireTimeSpan=TimeSpan.FromDays(1),
Provider=新的OWInAuthorizationProvider()
};
app.useAuthAuthorizationServer(选项);
}
还尝试使用自定义的
AuthorizeAttribute
,并将其作为筛选器添加到配置类
.filters.Add(new AuthorizeAttribute())中

AuthenticationResponseMiddleware
中,我继承了
OwinMiddleware
,在
公共覆盖异步任务调用(IOwinContext上下文)
方法中,请检查请求流

它首先在
RequestToken
方法中点击
OAuthBeareAuthenticationProvider
,然后点击
OwinMiddleware
类,然后再点击任何
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或请求的某些其他参数,以决定使用哪种方法),但它仍然有效。

您如何调用API?可能您的API客户端没有传递useDefaultCredentials=true。@ManojChoudhari:正如我在问题中所说的,我尝试了Postman(配置了NTLM身份验证)和浏览器(Chrome和Edge),它们与服务器在同一台机器上运行,因此默认情况下应该自动进行身份验证。两者都失败了。请注意,如果我在HttpListener中onyl启用
IntegratedWindowsAuthentication
,然后不使用Authorize/AllowAnonymous属性,则身份验证将按预期工作(对于Postman和浏览器)。但如果我这样做,我将失去将某些操作标记为已授权,而将某些操作标记为匿名的能力,这正是我正在尝试做的。您是否使用“appBuilder.Use(typeof(WinAuthMiddleware));”在configure方法中?@ManojChoudhari:WinAuthMiddleware类是什么?在哪里可以找到它?它是nuget软件包的一部分吗?还有一件事-您是否在IIS/IIS Express中托管此web API?您是否检查了IIS设置中是否同时启用了windows/匿名身份验证。谢谢您的回答,但看起来(如果我错了,请更正我)您建议使用OAuth。相反,我想使用的是Windows身份验证(NTLM/Kerberos)。两者兼容吗?我可以使用OAuth进行windows身份验证吗?浏览器将如何处理这个问题,它会像NTLM一样向用户显示用户名/密码提示吗?抱歉问了这么愚蠢的问题,但我对OAuth不熟悉。是的,你说得对,我在用OAuth演示。我给出的示例是使用Oauth,如果您愿意,我可以开发基于Oauth令牌的身份验证。请在这里参考OAuth和Windows身份验证,我对Windows OAuth身份验证的了解有限,因此可能需要一些时间。