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
的提供者并覆盖 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
并在配置中添加为过滤器 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 或请求的其他一些参数来决定使用哪种方法)但它有效。
我有一个 WebApi
使用 OWIN
自托管的项目。
我想对某些控制器的操作启用 Windows 身份验证,但允许匿名调用其他操作。
因此,根据我在网上找到的一些示例,我在 Statrup
class:
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
的提供者并覆盖 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
并在配置中添加为过滤器 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 或请求的其他一些参数来决定使用哪种方法)但它有效。