WebSurfer's Home

トップ > Blog 1   |   ログイン
APMLフィルター

IIS Express で Windows 認証

by WebSurfer 2018年8月19日 14:10

IIS Express でも Visual Studio でプロジェクトのプロパティを設定することで Windows 認証が使えるという話を書きます。

プロパティの設定

上の画像は Visual Studio Community 2015 のテンプレートで[空]の Web Forms アプリケーションプロジェクトを作り、「ソリューションエクスプローラー」ウィンドウでプロジェクトを選択し、その「プロパティ」ウィンドウで[Windows 認証]の設定をデフォルトから変えて[有効]にしたところです。

上の画像では[匿名認証]の設定もデフォルトから変えて[無効]に設定していますが、そうしておかないと、匿名のままアクセスできてしまう(Windows 認証はスルーされてしまう)ので注意してください。

上記のように設定してから、Visual Studio で[デバッグ(D)]⇒[デバッグなしで開始(H)」(または[デバッグの開始(S)])をクリックすると Web アプリは IIS Express 上で実行され、以下の画像のように認証情報を入力するダイアログが表示されます。(画像は Windows 10 Pro 64-bit の IE11 のもの)

認証ダイアログ

そのダイアログに有効な Windows アカウント名とパスワードを入力して[OK]をクリックすれば認証は通って画面が表示されます。User.Identity.Name でアカウント名も取得できます。(そのあたりの動作は IIS を使った時のものと同じ)

実は自分は IIS Express で Windows 認証が使えることを知らなくて、わざわざローカル IIS を使って Windows 認証のテストをしてました。(汗)

MSDN Forum のスレッド「Request.ServerVariables("REMOTE_USER")が空の文字列を返す」の Q&A の際に調べて初めて知った次第です。

なお、Windows 認証は Windows の機能に依存するもので、IE と IIS の組み合わせでなければ実現できないそうですので注意してください。(他の組み合わせでできたとしてもたまたまで、Microsoft が保証しているわけではなさそうです)

Tags: ,

DevelopmentTools

統合 Windows 認証での User.Identity.Name

by WebSurfer 2015年6月8日 15:47

先の記事 では、基本認証の場合、IIS で資格情報がキャッシュされるという話を書きました。

この記事では、統合 Windows 認証においてもそれと似た話があって、User.Identity.Name で取得されるログインユーザーの Windows アカウント名が Web サーバーのキャッシュから取得されるという話を書きます。

Windows 認証が有効になっていて、かつ、現在ページ要求を行っているユーザーがログイン済みの場合、User.Identity.Name で取得されるのは DOMAIN\USERNAME の形式で表されるドメインユーザー名になります。(詳しくは先の記事 ASP.NET の ID オブジェクト を見てください)

ところが、Active Directory ドメインコントローラーでユーザー名を変更しても、User.Identity.Name で取得されるログインユーザー名に変更が反映されません(古いままになります)。

その具体例は stackoverflow の記事 IIS Returning Old User Names to my application に出ていますので、興味がありましたらそれをみて下さい。(手抜きですみません)

その理由は、Microsoft サポートの記事 KB946358 に書かれていますように、Web サーバーにユーザー名がキャッシュされ、キャッシュに情報が存在する場合はドメインコントローラーに照会せず、キャッシュされたユーザー名の情報を返すからです。

対応策は、

  1. ドメインユーザー名には将来にわたって変更する必要がないもの(例:社員番号)を使用する、または、
  2. KB946358 に従って Web サーバーのレジストリを書き換えてキャッシュを無効にする。

といったところでしょうか。

ただ、キャッシュするのはドメインコントローラーの負荷とネットワークトラフィックの削減のためだそうですので、キャッシュを無効にするとパフォーマンスに影響がありそうというところが気がかりではありますが・・・

Tags:

Authentication

Windows 認証でのロール

by WebSurfer 2011年2月5日 16:48

ASP.NET の承認は、"ユーザー" に加えて "ロール" というレベルでの管理をサポートしています。ロール管理では、ユーザーをロールに割り当てることにより、ユーザーのグループを単位として扱うことができます。 詳しくは MSDN ライブラリの ASP.NET のロールによる承認の管理 が参考になると思います。

Forms 認証の場合は、サイト管理者がロールを定義し、ロール情報は SQL Server などのデータベースに格納します。

一方、Windows 認証の場合は Windows アカウントを利用しますので、ロールはそのユーザーが属するグループになります。従って、ロールを定義するのはサーバーの管理者で、ロール情報は Active Directory ドメインコントローラーに格納されるということになります。

当然、Windows 認証の場合もロールによるアクセス制限は可能です。例えば、あるフォルダにロールによるアクセス制限をしておくと、そのロールに属さないユーザーがフォルダ内のページを要求すると下の画像のようなダイアログが出てきます。

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' にキャストできません。" というエラーになりますので。

ここからは先は余談です。

SID の表示

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("&nbsp;&nbsp;" + 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>

Tags: ,

Authentication

About this blog

2010年5月にこのブログを立ち上げました。その後 ブログ2 を追加し、ここは ASP.NET 関係のトピックス、ブログ2はそれ以外のトピックスに分けました。

Calendar

<<  2018年11月  >>
28293031123
45678910
11121314151617
18192021222324
2526272829301
2345678

View posts in large calendar