by WebSurfer
2011年2月5日 16:48
ASP.NET の承認は、"ユーザー" に加えて "ロール" というレベルでの管理をサポートしています。ロール管理では、ユーザーをロールに割り当てることにより、ユーザーのグループを単位として扱うことができます。 詳しくは MSDN ライブラリの ASP.NET のロールによる承認の管理 が参考になると思います。
Forms 認証の場合は、サイト管理者がロールを定義し、ロール情報は SQL Server などのデータベースに格納します。
一方、Windows 認証の場合は Windows アカウントを利用しますので、ロールはそのユーザーが属するグループになります。従って、ロールを定義するのはサーバーの管理者で、ロール情報は Active Directory ドメインコントローラーに格納されるということになります。
当然、Windows 認証の場合もロールによるアクセス制限は可能です。例えば、あるフォルダにロールによるアクセス制限をしておくと、そのロールに属さないユーザーがフォルダ内のページを要求すると下の画像のようなダイアログが出てきます。
ロールによるアクセス制限は、Forms 認証と同様に web.config で定義します。フォルダ直下の web.config に以下のような定義をしておくと、Domain Users グループに属するユーザー以外のアクセスは拒否されます。
<configuration>
<system.web>
<authorization>
<allow roles="<ドメイン名>\Domain Users" />
<deny users="*" />
</authorization>
</system.web>
</configuration>
なお、Windows 認証の場合、web.config でロールを有効にする(web.config で <roleManager enabled="true" /> とする)のは意味がなさそうです。というより、そういう設定はしてはいけないようです。
web.config でロールを有効にすると、Page.User は System.Security.Principal.IPrincipal ではなく、それから派生した System.Web.Security.RolePrincipal になります。そこで WindowsPrincipal オブジェクトを取得するため (WindowsPrincipal)User とすると、"型 'System.Web.Security.RolePrincipal' のオブジェクトを型 'System.Security.Principal.WindowsPrincipal' にキャストできません。" というエラーになりますので。
ここからは先は余談です。
Windows アカウントでは、ユーザーもグループもセキュリティ識別子 (SID) を認識に用いています。よく知られた SID は MSDN ライブラリの Windows サーバー オペレーティング システムの既知のセキュリティ識別子 に一覧がありますので見てください。
SID は S-1-1-0 のように人間にとっては意味不明の文字列ですが、これを Everyone のように ACL エディタで使われている名前に変換する方法を忘れないように書いておきます。
Everyone のような名前は NTAccount オブジェクトから取得できます。NTAccount オブジェクトは IdentityReference.Translate メソッドで取得できます。その例を以下のコードに示します。これを実行すると、上の画像のように表示されます。
<%@ Page Language="C#" %>
<%@ Import Namespace="System.Security.Principal" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">
protected void Page_Load(object sender, EventArgs e)
{
WindowsPrincipal principal = (WindowsPrincipal)User;
// IsInRole("S-1-2-35-545") ではダメ。
if (principal.IsInRole("BUILTIN\\Users"))
{
Label1.Text = "BUILTIN\\Users";
}
WindowsIdentity identity =
(WindowsIdentity)principal.Identity;
SecurityIdentifier sid = identity.Owner;
StringBuilder sb = new StringBuilder();
NTAccount nt = (NTAccount)sid.Translate(typeof(NTAccount));
sb.Append("ユーザーの SID: " + nt.Value +
" (" + sid.ToString() + ")<br /><br />");
sb.Append("ユーザーが属するグループ<br />");
IdentityReferenceCollection irc = identity.Groups;
foreach (IdentityReference ir in irc)
{
NTAccount ntAccount =
(NTAccount)ir.Translate(typeof(NTAccount));
sb.Append(" " + ntAccount.Value +
" (" + ir.Value + ")<br />");
}
Label2.Text = sb.ToString();
}
</script>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
ユーザ: <asp:LoginName ID="LoginName1" runat="server" />
<br />
ロール: <asp:Label ID="Label1" runat="server" />
<hr />
<h1>Windows Users のページ</h1>
<asp:Label ID="Label2" runat="server" />
<hr />
<asp:HyperLink ID="HyperLink1"
runat="server"
NavigateUrl="~/Default.aspx">
入り口に戻る
</asp:HyperLink>
</div>
</form>
</body>
</html>