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身份验证的了解有限,因此可能需要一些时间。