2015-10-12 2 views
1

Я разрабатываю приложение MVC 5 с настраиваемым поставщиком роли, но кажется, что атрибут авторизации никогда не вызывает моего поставщика роли клиентов. Мой код, как показано ниже:Авторизовать атрибут пользовательского провайдера ролей, который не работает в 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> 

Однако мой пользовательский поставщик роль в папке Model, и я использую EF DB первый подход , Я могу назвать свой собственный метод поставщика роли с следующим кодом в моем контроллере:

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

Однако любой контроллер, где [Авторизоваться] атрибут используется, пользователи всегда перенаправляют на страницу входа в системе, даже если пользователь Войти и роль также действительна.

Как я могу присвоить авторизованный атрибут, позвоните в свой пользовательский поставщик роли?

+0

Почему это никогда не будет правдой 'u.user_id == username' ?? конечно, это должно быть 'u.username == username' или' u.user_id == userId' –

+0

Не могли бы вы опубликовать реализацию 'SchoolPortalEntities' и реализацию типа' login_details'? –

+0

@CallumLinington Коды длиннее требуемой длины, и я не знаю, как отредактировать мой вопрос – UwakPeter

ответ

0

Вы должны установить текущий принцип в RolePrincipal. Вы можете сделать это глобально на AuthenticationFilter и зарегистрировать его на global.asax. Смотрите эти две ссылки для некоторого образца: RolePrincipal/ IAuthenticationFilter

-1

Я добавил следующий код в Web.Config (под тегом аутентификации), чтобы решить ту же задачу:

<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 получает имя пользователя с указанными учетными данными.

Редактировать

Я добавил код 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); 

      } 

Я использовал этот метод только для целей тестирования.

+0

. Можете ли вы отправлять коды, которые вы используете для getName и GetUserPassword Methods? – UwakPeter

+0

Я отправлю их как можно скорее, эти методы просто выбирают пароль и имя пользователя из базы данных (я не думаю, что они могут быть полезны), чтобы сделать логин. – silviagreen

+0

Я все еще не мог получить эту работу, пожалуйста, мне нужно сделать какие-либо настройки? с этой ошибкой при запуске приложения: Нет owin.Environment элемент был найден в контексте на _ExternalLoginsListPartial.cshtml, в этой строке кода: var loginProviders = Context.GetOwinContext(). Authentication.GetExternalAuthenticationTypes(); – UwakPeter

Смежные вопросы