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

时间:2015-09-06 20:17:00

标签: c# asp.net asp.net-mvc asp.net-mvc-4 caching

我正在尝试学习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因为我不知道是什么&#39;继续

问题#3 如果值为null,为什么返回(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吗?

我很难想象幕后发生了什么。解释/推荐将非常有用。

1 个答案:

答案 0 :(得分:1)

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

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

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

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

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

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

cacheKey的基本目的是什么?

HttpRuntime 缓存组件用于管理您可能经常检索但不想一直访问数据库的对象“框”对

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

{
    "carlobrew": {
        "roles": {
            "Name": "Administrator"
        }
    }
}

因此,您基本上“保存”用户 carlobrew 在容器中的角色,以便您以后可以再次获取它们。键值对中的键用于返回您放在那里的数据。您用来引用已保存信息的关键是uname;也就是用户名。

键值对中的键是唯一的,因此您不能有两个名为 carlobrew 的键。

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

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

  1. 如果我们找到密钥(例如用户 carlobrew ),那么我们可以直接返回数据。如果值为null则不是。如果值不为空,则为。这就是代码为if (HttpRuntime.Cache[cacheKey] != null)
  2. 的原因
  3. 如果找不到密钥(也就是说,我们没有 carlobrew 的密钥),那么我们必须自己添加密钥,然后返回它。
  4. 由于它是一个缓存,因此当计时器到期时,ASP.NET MVC将自动从缓存中删除内容。这就是为什么你需要检查数据是否为空,并重新创建它的原因。

    “谁正在接收它”是负责首先调用GetRolesForUser()方法的对象。

    从我看到的,角色被插入到缓存中?

    基本上,如果数据不在缓存中,我们需要从数据库中获取数据并将其放在那里,所以如果我们很快调用相同的方法,我们就可以轻松取回它。

    让我们分解吧。我们有:

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

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

    的isUserInRole

    当用户尝试执行某些操作时,您可能会调用此方法。例如,如果用户转到/Admin/Index页面,则可以检查用户是否处于管理员角色。如果不是,您将返回 401 Unauthorized 响应,并告诉用户他们不允许访问该页面。

    public Controller Admin
    {
        public ActionResult Index()
        {
            if (!IsUserInRole("Administrator"))
            {
                // redirect "not allowed"
            }
    
            return View();
        }
    }