asp.net-mvc - 在 ASP.NET 4中,Windows 认证和表单认证的iis混合

  显示原文与译文双语对照的内容

我们有一个 ASP.NET 4内部网应用程序。 我们正在使用 Windows 认证,这个方面很好。 用户的凭据被使用,我们可以从web应用程序访问这些凭证。

我们真正想要的是某种混合模式。 我们希望从浏览器获取用户的凭据,但我们还希望验证用户是否在应用程序的数据库中。 如果在用户的数据库中,那么他们就可以继续。 如果不是,我们希望将它们重定向到请求备用凭据的页面。 我现在正在做的是,在 Global.asax.cs 中,我有一个 Application_AuthenticateRequest 方法,我检查用户是否已经经过身份验证。 如果他们是和他们的cookie信息没有反映他们登录到系统,然后我记录他们的信息。 如果未经过身份验证,我将它们重定向到登录页。 由于公司政策涉及的原因,我们不能使用广告角色,所以我们需要使用数据库进行额外的认证。

我猜 Application_AuthenticateRequest 不是这么做的但可能是。 但是我们基本上需要一个地方来过滤认证请求。 但是另外这个实现又引出了另一个问题:

我们的应用程序中有一些允许匿名访问的url 。 我已经在 Web.Config 中添加了 <location> 标记。 问题是,当对这些调用进行匿名调用时,它会到 Application_AuthenticateRequest 并尝试将用户记录到数据库中。 现在,我可以将代码添加到 Application_AuthenticateRequest 中来处理这些 url,但是当前我的计划是编写的,而 Application_AuthenticateRequest 不是现在。

时间:

你需要为此目的使用动作过滤器。 你可以像这样扩展 AuthorizeAttribute:


public class MyAuthorizeAttribute : AuthorizeAttribute


{


 private UnitOfWork _unitOfWork = new UnitOfWork();



 protected override bool AuthorizeCore(HttpContextBase httpContext)


 {


 var isAuthorized = false;


 var username = httpContext.User.Identity.Name;


//Some code to find the user in the database...


 var user = _unitOfWork.UserRepository.Find(username);


 if(user!= null)


 {


 isAuthorized = true;


 }



 return isAuthorized;


 }



 public override void OnAuthorization(AuthorizationContext filterContext)


 { 


 if (filterContext == null)


 {


 throw new ArgumentNullException("filterContext");


 }



 if (AuthorizeCore(filterContext.HttpContext))


 {


 SetCachePolicy(filterContext);


 }


 else


 {


//If not authorized, redirect to the Login action 


//of the Account controller... 


 filterContext.Result = new RedirectToRouteResult(


 new System.Web.Routing.RouteValueDictionary {


 {"controller","Account"}, {"action","Login"}


 }


 ); 


 }


 }



 protected void SetCachePolicy(AuthorizationContext filterContext)


 {


//** IMPORTANT **


//Since we're performing authorization at the action level, 


//the authorization code runs after the output caching module. 


//In the worst case this could allow an authorized user 


//to cause the page to be cached, then an unauthorized user would later 


//be served the cached page. We work around this by telling proxies not to 


//cache the sensitive page, then we hook our custom authorization code into 


//the caching mechanism so that we have the final say on whether a page 


//should be served from the cache.


 HttpCachePolicyBase cachePolicy = filterContext.HttpContext.Response.Cache;


 cachePolicy.SetProxyMaxAge(new TimeSpan(0));


 cachePolicy.AddValidationCallback(CacheValidationHandler, null/* data */);


 }



 public void CacheValidationHandler(HttpContext context,


 object data,


 ref HttpValidationStatus validationStatus)


 {


 validationStatus = OnCacheAuthorization(new HttpContextWrapper(context));


 }


}



然后,你可以在控制器级别或者操作级别使用这里属性,如下所示:


[MyAuthorize]


public ActionResult SomeAction()


{


//Code that is supposed to be accessed by authorized users only


}



...