当社のネットワークでは、Active Directory(AD)の役割がアプリケーションに適切に割り当てられていません。そこで、AD内のすべてのユーザーとその役割をマッピングする簡単なテーブルをデータベースに作成しました。このテーブルには、文字通り、ユーザーとロールの2つの列しかありません。
Asp.netの強力な役割管理を利用したいと思っています。[Authorize(Roles = "Managers")]
のような機能を使用したいと思います。複雑なロールとメンバーシッププロバイダーを設定せずに、これらのカスタムロールを使用する簡単な方法はありますか?
アプリケーションの背景:SQLサーバー、linq、asp.net mvc
カスタムロールプロバイダーを実装するのは本当に簡単です。基本的に、2つの関数を実装する必要があります。
記事を見てください: MVCのカスタムロールプロバイダー
MVCのカスタムロールプロバイダー
前回の記事では、カスタムメンバーシッププロバイダーを作成してユーザーを承認し、コントロールとページを保護する方法について説明しました。しかし、特定のユーザーグループの領域、コントローラー、またはページを表示または保護したい場合はどうでしょうか。たとえば、管理者のみに管理パネルへのアクセスを許可します。
この目的のための.NetFrameworkには、ロールプロバイダーがあります。ただし、ここでも、ストアユーザーロールに独自のDBを使用します。それでは、DBまたはその他のストレージを使用するカスタムロールプロバイダーを作成して構成しましょう。前と同じように、.NETからクラスを上書きする必要があります。
最小限の機能を得るには、2つの関数GetRolesForUserとIsUserInRoleを実装して上書きする必要があります。まず、1つを使用して、すべてのユーザーロール(またはグループ)のリストを取得します。
public override string[] GetRolesForUser(string username)
{
using (DatabaseEntities db = new DatabaseEntities())
{
User user = db.Users.FirstOrDefault(u => u.UserName.Equals(username, StringComparison.CurrentCultureIgnoreCase) || u.Email.Equals(username, StringComparison.CurrentCultureIgnoreCase));
var roles = from ur in user.UserRoles
from r in db.Roles
where ur.RoleId == r.Id
select r.Name;
if (roles != null)
return roles.ToArray();
else
return new string[] {}; ;
}
}
ご覧のとおり、関数のユーザー名パラメーター(私の場合はユーザー名またはメールアドレス)でDB内のユーザーを検索し、ユーザーロールの文字列リストを作成します。
2番目の機能は、ユーザーがロール(またはグループ)にいるかどうかを確認することです。
public override bool IsUserInRole(string username, string roleName)
{
using (DatabaseEntities db = new DatabaseEntities())
{
User user = db.Users.FirstOrDefault(u => u.UserName.Equals(username, StringComparison.CurrentCultureIgnoreCase) || u.Email.Equals(username, StringComparison.CurrentCultureIgnoreCase));
var roles = from ur in user.UserRoles
from r in db.Roles
where ur.RoleId == r.Id
select r.Name;
if (user != null)
return roles.Any(r => r.Equals(roleName, StringComparison.CurrentCultureIgnoreCase));
else
return false;
}
}
次に、作成したロールプロバイダーを使用するようにweb.configファイルソリューションで構成する必要があります。デバッグの目的でcacheRolesInCookie
をfalseに設定する必要がある場合があります。そうしないと、動作が予測できなくなります。
<system.web>
<compilation debug="true" targetFramework="4.5.2" />
<httpRuntime targetFramework="4.5.2" />
<authentication mode="Windows" />
<authorization>
<deny users="?" />
</authorization>
<roleManager cacheRolesInCookie="true" defaultProvider="KitsulaRoleProvider" enabled="true">
<providers>
<clear />
<add name="KitsulaRoleProvider" type="Kitsula.Security.KitsulaRoleProvider" />
</providers>
</roleManager>
</system.web>
これで、Authorize属性を設定することにより、指定されたロールにある特定のユーザーグループのコントローラー、アクション、ページを保護できます。
using System;
using System.Web.Mvc;
namespace Kitsula.Areas.Admin.Controllers
{
[Authorize(Roles = "Administrators")]
public class HomeController : Controller
{
//
// GET: /Admin/Home/
public ActionResult Index()
{
return View();
}
}
}