2015-10-12 124 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> 

然而,我的自定義角色提供在模型文件夾,我使用EF DB第一種方法。我可以打電話給我的自定義角色提供方法與我的控制器中下面的代碼:

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

但是任何控制器,其中[授權]屬性正在被使用,用戶始終重定向到登錄頁面,甚至當用戶登錄和角色都是有效的。

如何使我的授權屬性,調用我的自定義角色提供者?

+0

爲什麼這會永遠是真實的'u.user_id ==用戶名'?它肯定應該是'u.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方法嘗試從數據庫中獲取給定的密碼,而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方法? – UwakPeter

+0

我會盡快發佈它們,這些方法只需從數據庫中選擇密碼和用戶名(我認爲它們不會有用)即可進行登錄。 – silviagreen

+0

我仍然無法得到這個工作,請問我需要做任何設置?在運行應用程序時出現此錯誤:在_ExternalLoginsListPartial.cshtml的上下文中找不到owin.Environment項,在以下代碼行中:var loginProviders = Context.GetOwinContext()。Authentication.GetExternalAuthenticationTypes(); – UwakPeter