我想确保我在这个轨道上正确。
我的网站有两个后端区域,一个用于学校,一个用于管理员。我想对这些区域进行身份验证,以便学校区域的数据库权限少于管理员。为此,我的想法是在Sql Server Management Studio School和Admin中有两个登录,我可以将某些角色映射到。也许学校部分只有读取权限和管理员读写等。
请有人可以告诉我实施此方法的最佳方法。我需要多个连接字符串(一个用于管理员,一个用于学校)?可以使用表单身份验证吗?
我目前正在连接到我使用Sql Server Management Studio创建的现有数据库,并且已经有一种登录方式,它将设置FormsAuthentication,这在我可以向我的学校添加authorize属性的意义上运行良好除非学校登录,否则后端控制器会停止显示需要登录学校的页面。问题是我如何使这更具体,以便只允许学校登录才能看到此区域而不是管理员谁登录了,因为他们也设置了FormsAuthentication。
我已经做了大量的谷歌搜索,但没有找到任何具体的问题,因此这篇文章。
如果需要我可以生成代码,并不是要求有人为我编写代码,而是要求如何解决这种安全模型的理论解释。
提前感谢您的帮助。
使用自定义角色提供程序的工作解决方案
帐户控制器代码(现在是管理员和学校的代码)
[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 Helper函数:
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;
}
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();
}
}
我真的希望这有助于任何人请随时发表评论!
感谢您的帮助。
答案 0 :(得分:1)
您可以在会话中存储登录访问权限 在您查看的“if”语句中的项目
&lt;%if(Convert.ToString(ViewData [“access”])==“School”)
{ %>
//your controls here
<% } %>
如果不满足条件,则不会显示其中的内容。
希望这有帮助! 问候。
答案 1 :(得分:1)
您不需要多个连接字符串(除非您有多个DB。)您可以通过使用[Authorize(Roles = "XYZ")]
属性修饰操作并定义角色来指定要保护的内容,从而轻松完成所需操作。除了在此上下文中, role 表示任务。例如:
public class ProfessorsController : Controller
{
[Authorize(Roles = "Professors.List")]
public ViewResult Index()
{
// TODO: List professors
}
[Authorize(Roles = "Professors.Create")]
public ViewResult Create()
{
// TODO: Create professor
}
[Authorize(Roles = "Professors.Update")]
public ViewResult Update(int id)
{
// TODO: Update professor
}
[Authorize(Roles = "Professors.Delete")]
public ViewResult Delete(int id)
{
// TODO: Delete professor
}
}
然后,例如,用户Van Driessen(教授)将被授予访问所有四个操作的权限,而用户Beavis(学生)将被授予访问 Professors.List。