我有一个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上进行了测试。
我在这里想念什么?
答案 0 :(得分:0)
由于您对问题的描述受到限制,因此我设置了一个演示应用程序,在其中我将OAuthAuthorizationServerProvider
用作OAuthAuthorizationServerOptions
的提供者,并覆盖了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);
}
还尝试了一个自定义AuthorizeAttribute
并作为过滤器添加到配置类.Filters.Add(new AuthorizeAttribute());
在AuthenticationResponseMiddleware
中,我继承了OwinMiddleware
;在public override async Task Invoke(IOwinContext context)
方法中,请检查请求的流程。
在进入任何OAuthBearerAuthenticationProvider
管道之前,它首先以RequestToken
方法命中OwinMiddleware
,然后到达DelegatingHandler
类,
大多数情况下,您的身份验证是在此层中实现的。
请在检查后评论您的发现,与此同时,我也修改了API并进行了更新,希望对您有所帮助。
答案 1 :(得分:0)
好吧,我在另一个问题中找到了解决方法。 您可以通过设置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或请求的其他参数来确定使用哪种方法),