关于我的 Web 应用程序的身份验证和角色的说明和同行评审

Posted

技术标签:

【中文标题】关于我的 Web 应用程序的身份验证和角色的说明和同行评审【英文标题】:Clarifications and peer review regarding authentication and roles of my web application 【发布时间】:2015-12-02 08:55:30 【问题描述】:

我正在尝试了解 ASP MVC 的基本安全性和访问限制。

到目前为止,我已经阅读/观看了教程,但它们似乎都彼此不同。如果我要搜索一些东西,它会引导我找到另一个与我所拥有的完全不同的实现。

我实现了Authenticationcustom role provider,我对事情的运作方式有一些疑问。我从互联网上找到的大多数解释似乎过于复杂或过时。

这就是我实现 authentication 的方式。

登录控制器

 [HttpGet]
    [ActionName("login")]
    public ActionResult login_load()
    
        return View();
    

    [HttpPost]
    [ActionName("login")]
    public ActionResult login_post(string uname,string pword)
    
        using (EmployeeContext emp = new EmployeeContext())
        
            int success = emp.login.Where(x => x.username == uname && x.password == pword).Count();
            if (success == 1)
            
                FormsAuthentication.SetAuthCookie(uname, false);

                return RedirectToAction("Details", "Enrollment");
            
            return View();
        
    

然后我用[Authorize]保护了我的大部分控制器

问题 #1 FormsAuthentication.SetAuthCookie(uname, false); 的目的是什么?我通常应该用它做什么?存储username 可以吗?我以后需要它进行比较吗?(进一步的安全性?)。它在这里说Authentication ticket 将被赋予用户名。那些是随机字母的吗?

--

在那之后,我决定深入研究并实现custom role provider

来自roleprovider.cs(目前我只实现了2个方法)

public override string[] GetRolesForUser(string username)
            
                if (!HttpContext.Current.User.Identity.IsAuthenticated)
                
                    return null;
                

                var cacheKey = username;
                if (HttpRuntime.Cache[cacheKey] != null)
                
                    return (string[])HttpRuntime.Cache[cacheKey];
                
                string[] roles = new string[]  ;
                using (MvcApplication6.Models.EmployeeContext emp = new MvcApplication6.Models.EmployeeContext())
                
                    roles = (from a in emp.login
                             join b in emp.roles on a.role equals b.id
                             where a.username.Equals(username)
                             select b.role).ToArray<string>();
                    if (roles.Count() > 0)
                    
                        HttpRuntime.Cache.Insert(cacheKey, roles, null, DateTime.Now.AddMinutes(_cacheTimeoutInMinute), Cache.NoSlidingExpiration);
                    
                
                return roles;
            

问题 #2 我在这里有点困惑,我需要深入澄清:所以cacheKey 的基本目的是什么,从我的例子中,我只是让它等于uname,因为我不知道发生了什么。

问题 #3 如果值为空,为什么返回(string[])HttpRuntime.Cache[cacheKey];?什么时候退回,谁收到?

问题 #4 从数据库中获取角色列表的值后,该函数将被称为HttpRuntime.Cache.Insert(cacheKey, roles, null, DateTime.Now.AddMinutes(_cacheTimeoutInMinute), Cache.NoSlidingExpiration);。所以从我所看到的,角色被插入到缓存中?是为了稍后检查登录类型吗?

问题 #5

从这行代码:

  public override bool IsUserInRole(string uname, string roleName)
            
                var userRoles = GetRolesForUser(uname);
                return userRoles.Contains(roleName);
            

它们是在什么时候准确触发的?谁提供了参数? roleName 是缓存中的吗?

我很难想象幕后发生的事情。解释/推荐将非常有帮助。

【问题讨论】:

我也想补充一下,我需要在Role Providers之前实现Authentication吗?我感觉RP在用户成功登录后被触发了。 【参考方案1】:

FormsAuthentication.SetAuthCookie() 的目的是什么?

这是 ASP.NET FormsAuthentication 处理身份验证 cookie 的内置方法。

How does cookie based authentication work? Explained: Forms Authentication in ASP.NET 2.0

基本上,它正在为您完成艰苦的工作;为特定用户创建 cookie,将其提供给他们,然后在将来使用它来识别同一用户。您想使用此功能让用户登录(如果他们输入正确的凭据)。

string 参数用于用户名。是的,您可以使用username

bool 参数用于您希望 cookie 保持持久。也就是说,即使他们关闭浏览器(无论是否使用会话),也要让他们保持登录状态。

通过这种方式使用FormsAuthentication,当用户访问后续页面时,ASP.NET会自动再次检测到用户。

cacheKey 的基本目的是什么?

HttpRuntimeCache 组件用于管理您可能经常检索但不想一直访问数据库的对象“盒子”为。

缓存被实现为一种Key-Value Pair。您示例中的 cacheKey 是 Key-Value 集合中的一个键。您可以将其视为其他语言中使用的其他类似数据结构。


    "carlobrew": 
        "roles": 
            "Name": "Administrator"
        
    

因此,您基本上是将用户 carlobrew 的角色“保存”在一个容器中,以便以后可以再次获取它们。键值对中的键用于引用您放入其中的数据。您用来参考保存信息的键是uname;也就是用户名。

Key-Value Pairs 中的键是唯一的,因此您不能有两个名为 carlobrew 的键。

如果值为空,为什么返回(string[])HttpRuntime.Cache[cacheKey];

像这样使用典型的“缓存盒”有两个步骤。

    如果我们找到密钥(例如用户carlobrew),那么我们可以直接返回数据。如果值为空,则不是。如果值是 not null。这就是为什么代码是if (HttpRuntime.Cache[cacheKey] != null)。 如果找不到密钥(即我们没有carlobrew的密钥),那么我们必须自己添加它,然后然后返回它。

由于是缓存,ASP.NET MVC 会在定时器到期时自动从缓存中删除东西。这就是为什么您需要检查数据是否为空,如果是则重新创建它。

“接收者”是指首先负责调用GetRolesForUser() 方法的对象。

所以从我所见,角色被插入到缓存中?

是的。

基本上,如果数据不在缓存中,我们需要自己从数据库中抓取它并放入其中,这样如果我们很快调用相同的方法,我们就可以轻松取回它。

让我们分解一下。我们有:

Insert(cacheKey, roles, null, DateTime.Now.AddMinutes(_cacheTimeoutInMinute), Cache.NoSlidingExpiration);
Insert 是方法。我们称之为。 cacheKey 是 Key-Value Pair 的关键部分。用户名。 roles 是我们要存储在缓存中的对象。对象可以是我们想要的任何东西。 DateTime.Now.AddMinutes(_cacheTimeoutInMinute) 告诉 ASP.NET MVC 我们希望这些数据何时过期。它可以是我们想要的任何时间。我不确定变量 _cacheTimeoutInMinute 可能是 5 或 15 分钟。 Cache.NoSlidingExpiration 是一个特殊的标志。我们告诉 ASP.NET,当我们访问这些数据时,不要将过期计时器重置为满。例如,如果我们的计时器是 15 分钟,并且计时器即将到期,还有 1 分钟,如果我们使用滑动到期并尝试访问数据,计时器将重置回 15 分钟并且不会使数据到期.

不确定您所说的“是为了稍后检查登录类型”是什么意思。但是不,这里没有任何登录类型检查。

IsUserInRole

当用户尝试做某事时,您可能会调用它。例如,如果用户转到/Admin/Index 页面,那么您可以检查该用户是否具有Administrator 角色。如果不是,您将返回 401 Unauthorized 响应并告诉用户他们无权访问该页面。

public Controller Admin

    public ActionResult Index()
    
        if (!IsUserInRole("Administrator"))
        
            // redirect "not allowed"
        

        return View();
    

【讨论】:

以上是关于关于我的 Web 应用程序的身份验证和角色的说明和同行评审的主要内容,如果未能解决你的问题,请参考以下文章

身份验证和精细授权

ejb 关于角色和身份验证的安全问题

是否可以在没有 web.sitemap 的情况下进行基于 ASP.NET 角色的表单身份验证和授权?

Asp.net Web 应用程序基于角色的身份验证

关于 web.config 中的模拟、身份验证和授权的困惑

Azure AD 身份验证和为应用程序用户分配角色