【问题标题】:How to implement authorization checks in ASP.NET MVC based on Session data?如何在 ASP.NET MVC 中基于 Session 数据实现授权检查?
【发布时间】:2010-11-12 04:40:03
【问题描述】:

这将是我的第一个带有表单身份验证的 ASP.NET MVC 应用程序,因此我正在努力确保不会遗漏任何内容。场景是这样的:公共/安全区域。

在私人区域内,它甚至进一步仅限于特定区域/用户。这些“区域”由对每个用户组自定义的基本区域的自定义定义。

例如,用户可以访问 url /Area/Controller/Action。他们需要获得安全区域的权限,否则他们将被重定向到登录视图。

我一直在阅读有关 AuthorizeAttribute 的信息,但我不确定应该如何/在哪里进行这些基本检查。我最初的预感是在成功登录后使用用户的 IP 和有关他们有权访问的内容等的详细信息在会话中存储一个用户对象。

每个安全控制器调用的授权检查将验证会话中是否存在有效的用户对象、IP 仍然匹配以及用户有权访问特定区域。这个设置有什么明显的漏洞吗?

编辑:我在哪里/如何实施这些检查,以便当控制器被标记为 [Authorize] 时,它将执行这些会话对象检查?

任何指针或建议将不胜感激。谢谢。

【问题讨论】:

    标签: c# asp.net asp.net-mvc security forms-authentication


    【解决方案1】:

    看来我使用了自定义 AuthorizeAttribute。其实很简单。代码如下:

    namespace MyApp.Custom.Security
    {
        public class Secure : AuthorizeAttribute
        {
            /// <summary>
            /// Checks to see if the user is authenticated and has a valid session object
            /// </summary>        
            /// <param name="httpContext"></param>
            /// <returns></returns>
            protected override bool AuthorizeCore(HttpContextBase httpContext)
            {
                if (httpContext == null) throw new ArgumentNullException("httpContext");
    
                // Make sure the user is authenticated.
                if (httpContext.User.Identity.IsAuthenticated == false) return false;
    
                // This will check my session variable and a few other things.
                return Helpers.SecurityHelper.IsSignedIn();
            }
        }
    }
    

    然后在我的控制器上,我只需放置一个[Secure] 属性,它就会在任何时候访问该控制器时使用我上面的函数。很简单。我还创建了一个[SecureByRole] 属性,它执行所有相同的操作,但也会检查我的自定义角色信息。不需要从罐头会员资格中获得所有内置的巫术:)

    【讨论】:

      【解决方案2】:

      尝试查看RoleProvider class。这是 ASP.net 如何对用户使用基于角色的授权的基本框架。我认为你应该使用[Authorize(Roles='...')] 属性来利用它。

      【讨论】:

      • 如果可能,我会尽量远离角色解决方案。不确定它的可定制性。
      • nope.. roleprovider 是您应该/可以实现您自己的自定义的基类。要开始自定义角色授权,您只需扩展 roleprovider 类并修改 web.config 文件以通知它。
      【解决方案3】:

      在我之前的应用程序中,我使用了一个简单的 HttpModule 来为经过身份验证的用户增加额外的角色等(我这样做是因为我的要求非常有限)。

      public class AuthorisationModule : IHttpModule
      {
          public void Init( HttpApplication context )
          {
              context.AuthorizeRequest += AuthorizeRequest;
          }
      
          private void AuthorizeRequest(object sender, EventArgs e)
          {
              var currentUser = HttpContext.Current.User;
              if( !currentUser.IsAuthenticated() )
              {
                  return;
              }
      
              var roles = new List<string>();
              // Add roles here using whatever logic is required
      
              var principal = new GenericPrincipal( currentUser.Identity, roles.ToArray() );
              HttpContext.Current.User = principal;
          }
      
          public void Dispose()
          {
              if(HttpContext.Current == null )
              {
                  return;
              }
      
              if(HttpContext.Current.ApplicationInstance == null)
              {
                  return;
              }
      
              HttpContext.Current.ApplicationInstance.AuthorizeRequest -= AuthorizeRequest;
          }
      }
      

      【讨论】:

        【解决方案4】:
        [Authorize]
        public class BaseController : Controller
        {
            protected override void OnAuthorization(AuthorizationContext authContext)
            {
                if
                    (
                    !User.Identity.IsAuthenticated &&
                    Request.LogonUserIdentity != null &&
                    Request.LogonUserIdentity.IsAuthenticated
                    )
                {
                    var logonUserIdentity = Request.LogonUserIdentity.Name;
                    if (!string.IsNullOrEmpty(logonUserIdentity))
                    {
                        if (logonUserIdentity.Contains("\\"))
                            logonUserIdentity = logonUserIdentity.Substring(logonUserIdentity.IndexOf("\\") + 1);
        
                        var db = new UsersContext();
                        var loginUser =
                            db.UserProfiles.FirstOrDefault(x => x.UserName == logonUserIdentity);
        
                        //Auto-Login Windows Identity
                        if (loginUser == null)
                            loginUser = CreateUser(db, logonUserIdentity);
        
                        if (loginUser != null)
                        {
                            FormsAuthentication.SetAuthCookie(loginUser.UserName, true);
        
                            string returnUrl = Request.RawUrl;
                            if (!string.IsNullOrEmpty(returnUrl))
                                Response.Redirect(returnUrl);
                            Response.Redirect("~/");
        
                        }
                    }
                }
            }
        
            private static UserProfile CreateUser(UsersContext db, string logonUserIdentity)
            {
                var user = new UserProfile {UserName = logonUserIdentity};
                db.UserProfiles.Add(user);
                db.SaveChanges();
                return user;
            }
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-04-06
          • 2018-03-01
          相关资源
          最近更新 更多