如何基于Session数据在ASP.NET MVC中实现授权检查?

时间:2009-07-20 01:51:12

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

这将是我的第一个带有表单身份验证的ASP.NET MVC应用程序,所以我试图确保我不会错过任何内容。场景是这样的:公共/安全区域。

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

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

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

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

编辑:在哪里/如何实施这些检查,以便在使用[授权]标记控制器时,它会执行这些会话对象检查?

任何指针或建议都会非常感激。感谢。

4 个答案:

答案 0 :(得分:11)

看起来我选择了自定义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]属性,它可以执行所有相同的操作,但也会检查我的自定义角色信息。没有必要为罐头会员制造伏都教所有内容:)

答案 1 :(得分:2)

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

答案 2 :(得分:1)

在我之前的应用程序中,我使用了一个简单的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;
    }
}

答案 3 :(得分:1)

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