asp.net-mvc – 在.Net MVC WS-Federation站点中阻止XmlHttpRequ
我在MVC 3站点上使用WS Federated(Claims Aware)身份验证,但在身份验证失败时,保留一些发送
JSON的API控制器无法返回重定向.我有一个名为API的区域,它有几个只返回JSON的控制器,这些控制器都从相同的基类继承.我想发送合法的401错误响应,而不是默认情况下发生的302重定向.
我按照我发现的一些指示创建了一个自定义的WSFederationAuthenticationModule,并与我在API控制器操作中放置的过滤器一起使用: public class WSFederationServiceAuthenticationModule : WSFederationAuthenticationModule { private static Log4NetLoggingService logger = new Log4NetLoggingService(); public const string IsServiceIndicator = "ROIP.IsService"; protected override void OnAuthorizationFailed(AuthorizationFailedEventArgs e) { base.OnAuthorizationFailed(e); var isService = HttpContext.Current.Items[IsServiceIndicator]; if (isService != null) { logger.Info("WSFedService: Found IsService"); e.RedirectToIdentityProvider = false; } else { logger.Info("WSFedService: Did not find IsService"); } } } public class WSFederationServiceAuthAttribute : ActionFilterAttribute { private static Log4NetLoggingService logger = new Log4NetLoggingService(); public override void OnActionExecuting(ActionExecutingContext filterContext) { base.OnActionExecuting(filterContext); // Set an item that indicates this is a service request,do not redirect. logger.Info("WSFedService: Setting IsService"); HttpContext.Current.Items[WSFederationServiceAuthenticationModule.IsServiceIndicator] = 1; } } 但是我的日志记录显示我从未在Items中找到IsService项: {INFO}02/29 03:39:21 - WSFedService: Setting IsService {INFO}02/29 03:39:32 - WSFedService: Setting IsService {INFO}02/29 03:39:32 - WSFedService: Setting IsService {INFO}02/29 03:50:39 - WSFedService: Did not find IsService {INFO}02/29 03:53:16 - WSFedService: Did not find IsService {INFO}02/29 03:53:29 - WSFedService: Did not find IsService 我认为这可能是HttpContext.Current在过滤器和模块之间不一样的问题,但我不确定. 我尝试的另一个选项是在Global.asax.cs的Application_Start事件中订阅FederatedAuthentication.WSFederationAuthenticationModule.RedirectingToIdentityProvider事件,但此时WSFederationAuthenticationModule为null. private void ConfigureWSFederationAuthentication() { bool hasFederatedAuthentication = false; try { if (FederatedAuthentication.WSFederationAuthenticationModule != null) { hasFederatedAuthentication = true; } } catch { hasFederatedAuthentication = false; } if (hasFederatedAuthentication) { Logger.Info("WSFederation: Registering for Event Handler"); FederatedAuthentication.WSFederationAuthenticationModule.RedirectingToIdentityProvider += (s,e) => { var msg = string.Empty; try { if (HttpContext.Current.Request.Headers["X-Requested-With"] == "XMLHttpRequest") { e.Cancel = true; msg = "Found XMLHttpRequest header"; } else { msg = "Did not find XMLHttpRequest header"; } } catch (Exception ex) { msg = "WSFederation: Event Handler Error: " + ex.Message; } Logger.Info("WSFederation: Redirecting from Event Handler: " + msg); }; } else { Logger.Info("WSFederation: Null WSFederationAuthenticationModule"); } } 我想知道如何使第一个选项工作,或者我应该订阅RedirectingToIdentityProvider事件. 解决方法
我想我已经找到了这个问题的答案,想要回过头来为世界上任何可能遇到这个问题的人留下答案.
我的问题是HttpContext.Current.Items在我的ActionFilterAttribute和WSFederationAuthenticationModule之间没有匹配,所以我最终检查了上下文并添加了一些类似于Phil Haacks Forms Redirect Suppress Example的检查 这是我更新的自定义WSFederationAuthenticationModule的样子: public class WSFederationServiceAuthenticationModule : WSFederationAuthenticationModule { private static Log4NetLoggingService logger = new Log4NetLoggingService(); protected override void OnAuthorizationFailed(AuthorizationFailedEventArgs e) { base.OnAuthorizationFailed(e); var context = HttpContext.Current; var req = context.Request; var resp = context.Response; if (req == null || resp == null) { logger.Info("WSFedService: Did not find Request or Response"); return; } if ((resp.StatusCode == 302 || resp.StatusCode == 401) && req.Headers["X-Requested-With"] == "XMLHttpRequest") { logger.Info("WSFedService: Found Redirect and Header"); e.RedirectToIdentityProvider = false; } else { logger.Info(string.Format("WSFedService: Did not find redirect status code or XMLHttpRequest Header: {0}",resp.StatusCode)); } } } 当然,您需要将其添加到web.config中以代替默认的身份验证模块: <system.web> <httpModules> <!-- Old and Busted... <add name="WSFederationAuthenticationModule" type="Microsoft.IdentityModel.Web.WSFederationAuthenticationModule,Microsoft.IdentityModel,Version=3.5.0.0,Culture=neutral,PublicKeyToken=31bf3856ad364e35" /> --> <!-- New Hotness... --> <add name="WSFederationAuthenticationModule" type="MyApp.Web.Authentication.WSFederationServiceAuthenticationModule,MyApp.Web" /> </httpModules> </system.web> <system.webServer> <modules> <!-- Old and Busted... <add name="WSFederationAuthenticationModule" type="Microsoft.IdentityModel.Web.WSFederationAuthenticationModule,PublicKeyToken=31bf3856ad364e35" preCondition="managedHandler"/> --> <!-- New Hotness... --> <add name="WSFederationAuthenticationModule" type="MyApp.Web.Authentication.WSFederationServiceAuthenticationModule,MyApp.Web" preCondition="managedHandler"/> </modules> </system.webServer> (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- asp.net – 304未修改静态文件
- asp.net – ServiceReference是一个自托管的WCF服务
- asp.net-mvc – 在ASP.NET MVC应用程序中记录用户活动
- asp.net-mvc – 使用HtmlHelper类时,MVC单选按钮列表未分组
- asp.net-mvc-3 – ASP.NET MVC 3 Razor查看onclick编码
- ASP.Net MVC与Ruby on Rails
- asp-classic – 为ServerXMLHTTP请求设置超时
- asp.net-mvc – 将动态JSON对象传递给Web API – Newtonsof
- ASP.NET Core&EntityFramework核心:左(外)加入Linq
- asp.net-mvc – 如何成功配置Common.Logging?