私はこれで正しい軌道に乗っていることを確認したいと思います。
学校用と管理用の2つのバックエンド領域があるサイトがあります。学校のエリアが管理者よりも少ないDB権限を持つように、エリアを認証したいと思います。これを行うための私の考えは、SQL Server Management Studio SchoolとAdminに2つのログインを設定し、特定の役割をマップできるようにすることです。たぶん、学校のセクションには読み取りアクセスと管理者の読み取りと書き込みなどしかありません。
誰かがこれを実装するための最善の方法について私にアドバイスできますか?複数の接続文字列(管理者用と学校用)が必要ですか?これはフォーム認証を使用して実行できますか?
現在、SQL Server Management Studioを使用して作成した既存のデータベースに接続しており、FormsAuthenticationを設定するログイン手段がすでにあります。これは、学校のバックエンドコントローラーにauthorize属性を追加できるという意味でうまく機能します。学校がログインしていない限り、ログインしている学校が必要なページが表示されないようにします。問題は、学校のログインのみがこの領域を表示でき、ログインした管理者メンバーは表示できないように、これをより具体的にするにはどうすればよいかということです。また、FormsAuthenticationを設定するためです。
私はたくさんのグーグルをしましたが、私の問題に固有のものは何も見つかりませんでした。したがって、この投稿。
必要に応じてコードを作成できますが、誰かにコードを書いてもらうのではなく、この種のセキュリティモデルを解決する方法の理論的な説明を求めています。
よろしくお願いします。
カスタムロールプロバイダーを使用した実用的なソリューション
アカウントコントローラーコード(現在は管理者と学校の両方に1つ)
[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ヘルパー関数:
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を使用するコントローラー。
[Authorize(Roles = LanguageSchoolsConstants.m_RoleAdministrator)]
public class AuthorisedAdminController : Controller
{
//
// GET: /AuthorisedAdmin/
public ActionResult Index()
{
return View();
}
}
これが皆さんのお役に立てば幸いです。お気軽にコメントしてください。
ご協力ありがとうございます。