自定义角色提供程序的授权属性在MVC 5中不起作用

本文关键字:MVC 不起作用 属性 授权 角色 程序 自定义 | 更新日期: 2023-09-27 18:17:18

我正在开发一个带有自定义角色提供程序的MVC 5应用程序,但似乎授权属性从未调用我的客户角色提供程序。我的代码如下:

namespace SIMSPortal.Models
{
public class MyCustomRoleProvider:RoleProvider
{
public override string[] GetRolesForUser(string username)
    {
        //throw new NotImplementedException();
        using(var usersContext = new SchoolPortalEntities())
        {
            var user = usersContext.login_details.SingleOrDefault(u => u.user_id == username);
if(user == null)
                return new string[] { };
            return user.UserInRoles == null ? new string[] { } :
              user.UserInRoles.Select(u => u.Role).Select(u => u.RoleName).ToArray();
        }          
    }
  }
}    

我的配置文件:

<add key="PreserveLoginUrl" value="true" />
<add key="enableSimpleMembership" value="false" />
<add key="autoFormsAuthentication" value="false" />
</appSettings>
<system.web>
<authentication mode="Forms">
  <forms loginUrl="~/Login/UserLogin" timeout="2880" />
</authentication>
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5" />
<roleManager defaultProvider="CustomRoleProvider" enabled="true"  cacheRolesInCookie="false">
  <providers>
    <clear />
    <add name="CustomRoleProvider" type="SIMSPortal.Models.MyCustomRoleProvider" />
  </providers>
</roleManager>

然而,我的自定义角色提供程序在模型文件夹中,我使用EF DB第一方法。我能够调用我的自定义角色提供程序方法与以下代码在我的控制器:

String[] roles = Roles.GetRolesForUser(userId);

然而,任何使用[authorization]属性的控制器,用户总是被重定向到登录页面,即使用户登录和角色都是有效的。

如何使我的授权属性调用我的自定义角色提供者?

自定义角色提供程序的授权属性在MVC 5中不起作用

必须将当前主体设置为RolePrincipal。你可以在AuthenticationFilter上全局地做那个,并在global.asax上注册它。请参阅这两个链接获取一些示例:RolePrincipal/IAuthenticationFilter

我在Web中添加了以下代码。配置(在authentication标签下)来解决相同的问题:

<authorization>
  <deny users="?" />
</authorization>

以下是我使用的登录控制器(工作):

// POST: /ClientAccount/Login
[AllowAnonymous]
[HttpPost]
public ActionResult Login(LoginViewModel model, string returnUrl)
{
        if (ModelState.IsValid)
        {
            //try to pick the password from database
        ClientAccountDAO userManager = ClientAccountDAO.Instance;
            string password = userManager.GetUserPassword(model.Password);
            if (string.IsNullOrEmpty(password))
            {
             //the password wars not found in database
                ModelState.AddModelError("", "The user login or password provided is incorrect.");
            }
            if (model.Password == password)
            {
                //password is in database, do login FormsAuthentication.SetAuthCookie(model.Username, false);
                System.Web.HttpContext.Current.Session["name"] = model.Username;
                System.Web.HttpContext.Current.Session["nameSurname"] = clientDao.getName(model.Username, model.Password);
                if (Url.IsLocalUrl(returnUrl) && returnUrl.Length > 1 && returnUrl.StartsWith("/")
                    && !returnUrl.StartsWith("//") && !returnUrl.StartsWith("/''"))
                {
                    return Redirect(returnUrl);
                }
                else
                {
                    return RedirectToAction("Docs", "ClientAccount");
                }
            }
            else
            {
                ModelState.AddModelError("", "Username or password not correct");
            }
        }
        ViewBag.Successfull = false;
        // If we got this far, something failed, redisplay form
        return View("Login", model);
    }

在成瘾中,这个链接对我很有用:https://msdn.microsoft.com/en-us/library/ff647070.aspx

编辑

我添加了一些注释来澄清代码的某些部分。方法GetUserPassword尝试从db中获取给定的密码,而GetName获取具有给定凭据的用户的Name。

编辑

我添加了GetUserPassword的代码:

  public string GetUserPassword(string userLogIn)
       {
           var user = db.users.Where(m => m.pwd == userLogIn && m.attivo == true);
           if (user.ToList().Count > 0)
               return user.First().pwd;
           else
               return string.Empty;
       }
getName:

 public string getName(string username, string password)
         {
             var user = db.users.Where(m => m.username == username && m.pwd == password);
             if (user.ToList().Count <= 0)
                 return "";
             else {
                 var client= db.clients.Where(m => m.credenziali == user.First().id);
                 return (client.First().name + client.First().surname);
             }