Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-mvc/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Asp.net mvc 如何使用ASP.NET MVC5 Windows身份验证在首次登录时执行一次性操作_Asp.net Mvc_Asp.net Mvc 5_Windows Authentication - Fatal编程技术网

Asp.net mvc 如何使用ASP.NET MVC5 Windows身份验证在首次登录时执行一次性操作

Asp.net mvc 如何使用ASP.NET MVC5 Windows身份验证在首次登录时执行一次性操作,asp.net-mvc,asp.net-mvc-5,windows-authentication,Asp.net Mvc,Asp.net Mvc 5,Windows Authentication,我正在使用带有“windows身份验证”的ASP.NET MVC5框架创建web应用程序,即,我正在创建一个根据active directory对用户进行身份验证的intranet应用程序 当新用户在公司的active directory中定义时,我需要捕获他的第一次登录,并将其重定向到配置文件页面,在该页面上提示用户填写一些信息 如果用户在某个表中有自己的记录,我可以通过简单地查看数据库来捕获用户的第一次登录。如果没有,用户第一次在这里,我可以为他创建这样的记录 在对各种可能性进行广泛搜索之后

我正在使用带有“windows身份验证”的ASP.NET MVC5框架创建web应用程序,即,我正在创建一个根据active directory对用户进行身份验证的intranet应用程序

当新用户在公司的active directory中定义时,我需要捕获他的第一次登录,并将其重定向到配置文件页面,在该页面上提示用户填写一些信息

如果用户在某个表中有自己的记录,我可以通过简单地查看数据库来捕获用户的第一次登录。如果没有,用户第一次在这里,我可以为他创建这样的记录

在对各种可能性进行广泛搜索之后,似乎唯一“合理”的方法是通过自定义AuthenticationFilter,特别是将DB检查逻辑放入

OnAuthenticationChallenge(AuthenticationChallengeContext filterContext)
方法

我之所以在引文中加上“合理”一词,是因为一方面,这种方法符合MVC理念——我的意思是,它不是某种“黑客”方法

另一方面,由于我使用的是windows身份验证,因此任何控制器中实际上都没有登录操作。用户可以键入任何“www.mysite.com/controller/action”url,如果未登录,则不会重定向到登录页面,windows安全框只会出现提示输入凭据的提示。这意味着我必须全局注册我的自定义身份验证过滤器,以覆盖所有控制器/操作模式。这意味着每次请求都会执行DB检查——我不喜欢这样。我不确定这会对性能造成多大的影响,但从设计的角度来看,这似乎并不正确

我尝试过的最后一件事是使用我的身份验证筛选器捕获“未经身份验证”的用户并将他们重定向到某些“登录”操作-但在这里,我发现windows安全框甚至在启动身份验证筛选器之前就出现了,因此从技术上讲,我的自定义身份验证筛选器从未捕获未经身份验证的用户

因此,我的问题是——有没有更好的方法可以通过一次性操作逐步完成日志记录过程?或者我可以使用我所拥有的-即全局注册的身份验证过滤器执行每个请求的DB检查


谢谢

我相信这就是你要找的。此时,您的数据库检查只会发生一次。您可以像这样将此方法添加到您的
Global.asax
中,该方法在获得授权后可与Windows Auth一起使用

protected void Application_AuthorizeRequest(object sender, EventArgs e)
{
    // Do your check here
    // Do something
}

最后,我有了一些有效的解决方案

问题是:

使用windows身份验证的MVC5 APS.NET intranet应用程序。在成功登录active directory之后,我们想知道用户是否第一次在这里,如果是,在应用程序数据库中创建他的记录

解决方案:

由于我最终只对经过身份验证和授权的用户感兴趣,因此我创建了一个全球注册的操作过滤器,即在成功进行身份验证/授权后将应用于每个控制器/操作组合的过滤器

在这个过滤器中,我正在检查当前会话是否将flagIsNewSession设置为true。如果是这样,我将对应用程序数据库执行该检查。这样,即使在用户的第一个请求期间,每次请求都只调用一次操作过滤器,我也只能往返数据库一次

实施:

public class DbCheckFilter : ActionFilterAttribute
{
    private AppDbContext db = new AppDbContext();

    //we are overriding OnActionExecuting method since this one
    //is executed prior the controller action method itself
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        //is this a new session
        if (filterContext.HttpContext.Session.IsNewSession)
        {
            //we are storing users in db based on their active directory
            //Guid - therefore we need to get 'UserPrincipal' object
            //instead of 'WindowsPrincipal' provided by filterContext
            using (var principalContext = new PrincipalContext(ContextType.Domain))
            {
                var principal = UserPrincipal.FindByIdentity(principalContext, filterContext.HttpContext.User.Identity.Name);

                if (principal != null)
                {
                    //finally we perform the DB check itself
                    if (!CreateUserInDbIfNew(principal.Guid.Value, principal.DisplayName))
                    {
                        filterContext.Result = new HttpUnauthorizedResult();
                    }
                }
                else
                {
                    filterContext.Result = new HttpUnauthorizedResult();
                }
            }
        }

        base.OnActionExecuting(filterContext);
    }

我相信每次请求都会调用这个函数。我也会说,每次请求都会执行这个函数。但感谢您提到它-我至少有机会了解一些关于global.asax:)无论如何,最后我决定将逻辑放入应用程序过滤器,因为在这里,我知道100%的用户经过身份验证/授权,我可以毫无问题地使用会话-在global.asax中,在会话可用之前,您必须等待特定事件。可以吗使用会话状态跟踪是否已为用户执行此操作?这将是我的方法,但我们可以并经常使用会话状态,而且不是每个人都这样。@stephen.vakil:会话肯定是一种方法。我试图找到一些类似于用户成功登录后触发的事件,以避免对每个请求执行该检查,但显然不存在这样的事件。