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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1151450/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 09:27:16  来源:igfitidea点击:

How to implement authorization checks in ASP.NET MVC based on Session data?

c#asp.netasp.net-mvcsecurityforms-authentication

提问by Kelsey

This will be my first ASP.NET MVC application with forms authentication so I am trying to make sure I don't miss anything. The scenario is this: Public / Secured Areas.

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

Within the private area it is even further limited to specific areas / user. These 'Areas' are defined by customizations to the base area that is customized per user group.

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

So for example a user could get to url /Area/Controller/Action. They would need to have permission to the secured area or they would be redirected to the sign-in view.

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

I have been reading about the AuthorizeAttributebut I am not sure how/where I should be doing these basic checks. My initial hunch would be to store a user object in the session after a successful sign-in with the user's IP and details about what they have access to etc.

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

The authorization check for each secured controller call would verify that a valid user object exists in the session, the IPs still match up, and the user has access to the specific area. Is there any obvious holes to this setup?

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

Edit:Where/how do I implement these checks so that when a controller is tagged with [Authorize] it will perform those session object checks?

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

Any pointers or suggestions would be much appreciated. Thanks.

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

采纳答案by Kelsey

Well it looks like I went with a custom AuthorizeAttribute. It was actually very simple. Here is the code:

好吧,看起来我使用了自定义 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();
        }
    }
}

Then on my controllers I just have to put a [Secure]attribute and it uses my function above anytime that controller is accessed. Pretty simple. I also made a [SecureByRole]attribute as well that does all the same stuff but checks for my custom role information as well. No need to for all that built in voodoo from the canned Membership :)

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

回答by xandy

Try to look at the RoleProvider class. This is the basic framework of how ASP.net use rolebased authorization to users. And I think you should use [Authorize(Roles='...')]attribute to make use of that.

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

回答by Neal

In my previous application I used a simple HttpModule to augment the authenticated user with additional roles etc ( I did this because my requirements were very constrained ).

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

回答by Tawani

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