Windows身份验证和混合型窗体身份验证在ASP.NET MVC 4 [英] Hybrid of Windows Authentication and Forms Authentication in ASP.NET MVC 4

查看:620
本文介绍了Windows身份验证和混合型窗体身份验证在ASP.NET MVC 4的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们有一个ASP.NET MVC 4 Intranet应用程序。我们使用Windows身份验证和这方面工作正常。用户的凭据使用,我们可以从Web应用程序访问这些凭据。

We have an ASP.NET MVC 4 intranet application. We’re using Windows Authentication and that aspect works fine. The user’s credentials are used and we can access those credentials from the web app.

我们真正需要的是某种混合模式,但是。我们希望得到来自浏览器的用户的凭据,但我们也需要验证用户在我们的应用程序的数据库。如果用户的数据库中,那么他们可以继续。如果他们没有,我们要重定向到要求的备用凭据的页面。我现在正在做的是,在的Global.asax.cs ,我有一个 Application_AuthenticateRequest 方法和我'M检查,查看是否用户被认证。如果他们和他们的cookie信息并不反映他们登录到系统的事实,那么我登录他们,并设置一些饼干有关用户的信息。如果他们没有经过认证,我重定向到一个登录页面。我们不能用AD角色参与公司政策的原因,所以我们需要使用数据库附加认证。

What we really want is some sort of hybrid mode, however. We want to get the user’s credentials from the browser, but we also want to verify that the user is in our application’s database. If the user’s in the database, then they can just continue on. If they’re not, we want to redirect them to a page asking for alternate credentials. What I’m doing now is, in Global.asax.cs, I’ve got an Application_AuthenticateRequest method and I’m checking to see if the user is authenticated. If they are and their cookie information doesn’t reflect the fact that they’re logged into the system, then I log them in and set up some cookies with info about the user. If they’re not authenticated, I redirect them to a login page. We can’t use AD roles for reasons involved with company policy, so we need to use the database for additional authentication.

我猜 Application_AuthenticateRequest 不是这样做的地方,但也许它是。但是,我们基本上需要一个地方来筛选用于身份验证的请求。但另外这个实现使我另一个问题:

I’m guessing Application_AuthenticateRequest isn’t the place to do this, but maybe it is. But we basically need a place to filter the requests for authentication. But additionally this implementation leads me to another issue:

我们已经在我们的应用程序的某些网址,允许匿名访问的。我已经添加了<地点> 标记到Web.config这些。问题是,当匿名呼叫被做成这些,它得到 Application_AuthenticateRequest ,并试图使用户登录到数据库。现在,我可以添加code到 Application_AuthenticateRequest 来处理这些URL,这就是目前我的计划,但如果我写和 Application_AuthenticateRequest 不是地方在做这一点,那么我宁愿弄清楚现在比晚。

We have certain URLs in our app that allow anonymous access. I’ve added <location> tags to the web.config for these. The problem is, when anonymous calls are made into these, it gets to Application_AuthenticateRequest and tries to log the user into the DB. Now, I can add code into Application_AuthenticateRequest to handle these URLs and that’s currently my plan, but if I’m write and Application_AuthenticateRequest isn’t the place to be doing this, then I’d rather figure it out now than later.

推荐答案

您需要使用操作过滤器用于此目的。您可以扩展AuthorizeAttribute是这样的:

You need to use Action Filters for this purpose. You can extend the AuthorizeAttribute like this:

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));
    }
}

然后,您可以在控制器级别或级别的行动像这样使用这个属性:

Then, you can use this attribute at the Controller level or Action level like this:

[MyAuthorize]
public ActionResult SomeAction()
{
  // Code that is supposed to be accessed by authorized users only
}

这篇关于Windows身份验证和混合型窗体身份验证在ASP.NET MVC 4的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆