我想確保我在正確的軌道與這一項上。MVC3多用戶/連接字符串
我有一個網站有兩個後端區域,一個用於學校,另一個用於管理員。我想驗證使學校面積少DB的權限比管理的區域。要做到這一點我的想法是在SQL Server Management Studio中學校和管理,這是我可以映射到某些角色兩次登錄。也許學校的部分將具有隻讀訪問和管理讀寫等。
請可有人告訴我,以着手實施這個的最佳方式。我是否需要多個連接字符串(一個用於管理,一個用於學校)?這可以使用表單身份驗證完成嗎?
我目前正在連接到一個現有的數據庫,我已經使用Sql Server Management Studio創建了這個數據庫,並且已經有一個登錄的方法來設置FormsAuthentication,並且這種方式很好用,因爲我可以將authorize屬性添加到我的學校後臺控制器,用於停止要求登錄學校的網頁,除非學校已經登錄。問題是我怎樣才能使這個更具體,以便只有學校登錄才能看到這個區域,而不是管理員成員誰擁有,因爲他們本來還設置FormsAuthentication登錄。
我已經做了很多谷歌搜索,但沒有找到任何具體的問題,因此這篇文章。
如果需要,我可以生成代碼,並且不要求有人爲我寫代碼,而是如何解決這種安全模型的理論解釋。
在此先感謝您的幫助。
public role GetRoleForUser(string sUserName)
{
// Should only ever have one role...
role Role = (from roles in DBModel.roles
join userrole in DBModel.user_role on roles.role_id equals userrole.role_id
join users in DBModel.users on userrole.user_id equals users.user_id
where users.username == sUserName
select roles).FirstOrDefault();
return Role;
}
:
使用自定義角色提供
賬戶控制器代碼(現在一個兩個管理員和學校)
[HttpPost]
public ActionResult LogOn(LogOn model, string returnUrl)
{
if (ModelState.IsValid)
{
if (Membership.ValidateUser(model.UserName, model.Password))
{
FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe);
if (Url.IsLocalUrl(returnUrl) && returnUrl.Length > 1 && returnUrl.StartsWith("/")
&& !returnUrl.StartsWith("//") && !returnUrl.StartsWith("/\\"))
{
return Redirect(returnUrl);
}
else
{
// Now it's our job to route the user to the correct place. Ask our DB Helper to tell
// us what kind of user they are and route accordingly.
string sPage = "Index";
string sController = "Home";
var Role = DBHelperFunctions.Instance().GetRoleForUser(model.UserName);
switch (Role.role_name)
{
case LanguageSchoolsConstants.m_RoleAdministrator:
{
sController = "AuthorisedAdmin";
}
break;
case LanguageSchoolsConstants.m_RoleSchool:
{
sController = "AuthorisedSchool";
}
break;
}
return RedirectToAction(sPage, sController);
}
}
else
{
ModelState.AddModelError("", "The user name or password provided is incorrect.");
}
}
在上述方法中使用的
DB輔助函數工作方案
Web.config更改以允許調用角色提供程序:
使用授權<roleManager defaultProvider="RoleProvider" enabled="true" cacheRolesInCookie="true">
<providers>
<clear />
<add name="RoleProvider" type="namespace.Models.Security.CustomRoleProvider" />
<add name="AspNetSqlRoleProvider" type="System.Web.Security.SqlRoleProvider" connectionStringName="Entities" applicationName="/" />
<add name="AspNetWindowsTokenRoleProvider" type="System.Web.Security.WindowsTokenRoleProvider" applicationName="/" />
</providers>
</roleManager>
我的角色提供
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Security;
namespace neamsepace.Models.Security
{
public class CustomRoleProvider : RoleProvider
{
public override void AddUsersToRoles(string[] usernames, string[] roleNames)
{
throw new NotImplementedException();
}
public override string ApplicationName
{
get
{
throw new NotImplementedException();
}
set
{
throw new NotImplementedException();
}
}
public override void CreateRole(string roleName)
{
throw new NotImplementedException();
}
public override bool DeleteRole(string roleName, bool throwOnPopulatedRole)
{
throw new NotImplementedException();
}
public override string[] FindUsersInRole(string roleName, string usernameToMatch)
{
throw new NotImplementedException();
}
public override string[] GetAllRoles()
{
throw new NotImplementedException();
}
public override string[] GetRolesForUser(string username)
{
using (DB db = new DB())
{
string[] RolesForUser = null;
user User = db.users.FirstOrDefault(u => u.username.Equals(username, StringComparison.CurrentCultureIgnoreCase) ||
u.email.Equals(username, StringComparison.CurrentCultureIgnoreCase));
var roles = from dbroles in db.roles
join userroles in db.user_role on dbroles.role_id equals userroles.role_id
join users in db.users on userroles.user_id equals users.user_id
where users.user_id == User.user_id
select dbroles.role_name;
if (roles != null)
{
RolesForUser = roles.ToArray();
}
else
{
RolesForUser = new string[] { };
}
return RolesForUser;
}
}
public override string[] GetUsersInRole(string roleName)
{
throw new NotImplementedException();
}
public override bool IsUserInRole(string username, string roleName)
{
using (DB db = new DB())
{
bool bUserInRole = false;
user User = db.users.FirstOrDefault(u => u.username.Equals(username, StringComparison.CurrentCultureIgnoreCase) ||
u.email.Equals(username, StringComparison.CurrentCultureIgnoreCase));
var roles = from dbroles in db.roles
join userroles in db.user_role on dbroles.role_id equals userroles.role_id
join users in db.users on userroles.user_id equals users.user_id
where users.user_id == User.user_id
select dbroles.role_name;
if (User != null)
{
bUserInRole = roles.Any(r => r.Equals(roleName, StringComparison.CurrentCultureIgnoreCase));
}
return bUserInRole;
}
}
public override void RemoveUsersFromRoles(string[] usernames, string[] roleNames)
{
throw new NotImplementedException();
}
public override bool RoleExists(string roleName)
{
throw new NotImplementedException();
}
}
}
控制器。
[Authorize(Roles = LanguageSchoolsConstants.m_RoleAdministrator)]
public class AuthorisedAdminController : Controller
{
//
// GET: /AuthorisedAdmin/
public ActionResult Index()
{
return View();
}
}
我真的希望這可以幫助任何人,請隨時發表評論!
感謝您的幫助。
我看到'Membership.ValidateUser'這意味着你正在使用會員供應商。你在使用什麼提供商?更重要的是,您目前如何管理您的用戶(即學生,教授)? – 2013-02-25 11:50:44
我已經創建了自己的MembershipProvidor繼承。我稱它爲SchoolMembershipProvider,我將發佈它包含的代碼。我還有一個從MembershipUser繼承的SchoolMembershipUser。我還會發布上面的代碼。我希望這有助於說明我目前正在做的事情。謝謝。 – Yos 2013-02-25 12:04:31
如果您覺得自定義成員資格提供者編碼感覺舒適,那麼我會建議您實施自定義角色提供者。這個想法基本上是一樣的;你編碼它,把它掛在你的'web.config'中,就是這樣。所有角色檢查將針對您的自定義提供者返回的角色執行。 – 2013-02-25 12:12:27