我已经审查了类似的帖子,其解决方案对我不起作用 .
我有一个在IIS 7.x中托管的MVC 5站点,它提供web ui - https://www.example.com . 呼叫者还可以访问api(Webapi 2.2) endpoints 以执行某些功能 - https://www.example.com/api/x . 有些页面/ apis是安全的,而有些则不是 . mvc / web ui安全性由使用UseCookieAuthentication和UseWsFederationAuthentication配置的owin中间件管理 .
当用户尚未拥有有效的SAML令牌时,webui中的安全页面将自动重定向到ADFS登录屏幕 - 根据需要 .
安全的Web apis需要在Auth头中传递单独的JWT令牌 .
Webapi与MVC托管在同一个应用程序池中 . Webapi没有控制器,而webapiconfig具有利用DelegatingHandler路由/传递api调用的路由 . 委托处理程序是检查JWT是否包含在Auth标头中的处理程序,如果是,则允许它继续使用验证JWT的不同内部webapi . 如果JWT不存在,则DelegatingHandler返回401 .
401返回曾经工作,因为它短路了请求的延续,因此绕过任何owin管道的东西 . 但是,现在当短路开火时401没有返回 . 相反,请求继续并传递到Owin auth,然后重定向(302)到ADFS登录 . 我不知道为什么 . If I change the response status code to something other than 401 then Owin Auth ignores it.
请参阅以下代码:
Global.asax.cs
public class Global : HttpApplication
{
protected void Application_Start(object sender, EventArgs e)
{
// Code that runs on application startup
AreaRegistration.RegisterAllAreas();
GlobalConfiguration.Configure(WebApiConfig.Register);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
}
WebApiConfig.cs
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.Routes.MapHttpRoute(
name: "Apis",
routeTemplate: "api/{*path}",
handler: HttpClientFactory.CreatePipeline
(
innerHandler: new HttpClientHandler(),
handlers: new DelegatingHandler[] { new ApiHandler() }
),
defaults: new { path = RouteParameter.Optional },
constraints: null
);
}
}
ApiHandler.cs
internal class ApiHandler : DelegatingHandler
{
protected async override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.Unauthorized);
try
{
// get jwt from header
var jwt = GetJWTFromHeader(request.Headers);
if (jwt == null)
{
response.ReasonPhrase = "Token required";
return await Task.FromResult<HttpResponseMessage>(response);
}
else if (!IsValidJWT(jwt))
{
response.ReasonPhrase = "Invalid token";
return await Task.FromResult<HttpResponseMessage>(response);
}
response = await base.SendAsync(request, cancellationToken);
}
catch (Exception ex)
{
// log error
response = new HttpResponseMessage(HttpStatusCode.InternalServerError);
}
// return result
return response;
}
}
Startup.Auth.cs
public partial class Startup
{
public void ConfigureAuth(IAppBuilder app)
{
ServicePointManager.ServerCertificateValidationCallback += ValidateServerCertificate;
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
app.UseCookieAuthentication(
new CookieAuthenticationOptions()
{
SlidingExpiration = false
}
);
app.UseWsFederationAuthentication(
new WsFederationAuthenticationOptions
{
Wtrealm = ADFS_REALM,
MetadataAddress = ADFS_METADATA,
UseTokenLifetime = true,
TokenValidationParameters = new TokenValidationParameters
{
SaveSigninToken = true
},
Notifications = new WsFederationAuthenticationNotifications
{
RedirectToIdentityProvider = async r =>
{
// do stuff
},
SecurityTokenValidated = async s =>
{
// if we get here, then UI user has valid saml token
// do stuff
}
}
}
});
}
我感谢任何帮助 . 如果需要更多细节,请告诉我!
2 回答
看起来你可以使用:https://msdn.microsoft.com/en-us/library/system.web.http.owinhttpconfigurationextensions.suppressdefaulthostauthentication(v=vs.118).aspx config.SuppressDefaultHostAuthentication();
感谢Finallz我能够优化我的搜索并找到答案 - 找到here . 在我的情况下,我没有't need any special authentication config since I' m在apihandler中手动检查了JWT . 但是,通过简单地将 Map 包含到我的api路径中,它自然会覆盖Owin安全性: