みなさんこんにちは!ヒロポンです!!
今回は ASP.NET 生存ガイド連載・第6回 の本論記事。業務イントラ ASP.NET で 認証どうする?? の話。
ASP.NET 案件のキックオフで「認証どうする??」と聞かれて、WinForms 時代の WindowsIdentity.GetCurrent() 感覚で答えようとして詰まったこと、ないっすか??ん? ASP.NET の認証って何種類あんねん?って手が止まる瞬間。
俺も流通系SIer 時代に同じ場面を経験しました。イントラ業務系 ASP.NET 案件で「AD 統合で SSO したい」「フォームでログイン入力する画面が欲しい」「MFA も将来入れたい」みたいな要件が並んだ時、認証方式を 3つから選ぶ判断軸が必要だと初めて気付いたんですよね。
結論から言うと、業務イントラ ASP.NET MVC 5 の認証方式は3択で、業務系の大半は Windows 認証で十分カタが付く:
- Windows 認証 (Active Directory 統合): イントラ専用・SSO・コード変更不要
- Forms 認証 (Cookie ベース): 外部公開・独自ユーザー管理・標準実装
- Cookie 認証 (OWIN / ASP.NET Identity): MFA・外部プロバイダ連携・モダン拡張
連載第1〜5回(View/Controller/Routing/ORM/DI)で View 〜 Action 〜 DB アクセスの流れを押さえたので、今回は 「リクエストの認証 / 認可」 を扱います。連載通奏低音の レイヤー分離思考 が、今回は 「認証レイヤー / 認可レイヤー / セッションレイヤー」の3層分離 に再拡張されます。
この記事では VS2019 / .NET Framework 4.7.2 / C# 7.3 / ASP.NET MVC 5 環境で、3方式の最小実装と、[Authorize] 属性での認可制御、User.Identity.Name でのユーザー名取得をコード5本でまとめます。後ろの「現場メモ」で、業務系チームでルール化した時の話も書いてる。
3行で結論:
- 業務イントラ + AD 統合あり → Windows 認証一択(実装最も簡単・コード変更不要)
- 外部公開 + 独自ユーザー管理 → Forms 認証 or Cookie 認証(パスワード自前管理)
- MFA / 外部プロバイダ連携 → Cookie 認証(ASP.NET Identity)
俺の体験 — 流通系SIer時代のイントラ認証案件
正直に書いておきます。俺が初めて ASP.NET MVC 5 で認証を扱ったのは 流通系SIer 時代 のイントラ業務システム。要件は「社内 PC から SSO で社員番号取れればいい」だけだったので、Windows 認証一択で実装完了。web.config を3行書くだけで終わって、コード変更ゼロ。
その後、別案件で社外パートナー向けの ASP.NET MVC 5 受発注画面を作った時は、Forms 認証(独自ユーザー管理)に切り替え。さらにその後、MFA 必須の経営層向け画面では Cookie 認証(OWIN + ASP.NET Identity)を導入。業務系イントラ = Windows 認証で大半カタが付く・例外で Forms / Cookie、という現場の判断軸が見えてきた経緯です。
連載通奏低音の レイヤー分離思考 が今回は 認証 / 認可 / セッションレイヤー の3層に進化します:
- 認証レイヤー: 「あなたは誰か」を確認する(AD・パスワード・MFA)
- 認可レイヤー: 「あなたは何ができるか」を制御する(
[Authorize]属性・Role) - セッションレイヤー: 認証結果を保持する(Cookie・Windows トークン)
業務系の認証選びは、この 3層の関心事を分離 して考えると迷わないんですよね。
対応マップ — 3つの認証方式の比較
3方式を業務SE 視点で6観点で比較すると、こんな感じになります:
| 観点 | Windows 認証 | Forms 認証 | Cookie 認証 (Identity) |
|---|---|---|---|
| 用途 | イントラ + AD 統合 | 外部公開 + 独自ユーザー | モダン拡張 + MFA |
| ID 管理 | Active Directory | 自前 DB | ASP.NET Identity DB |
| SSO | ✅(ドメイン参加 PC) | ❌ | ❌(外部プロバイダ経由なら可) |
| MFA | ❌ | ❌(自前実装) | ✅ |
| 外部公開 | ❌(VPN・モバイル不向き) | ✅ | ✅ |
| 学習コスト | 低(web.config + IIS のみ) | 中 | 高(OWIN 設定) |
| パスワード管理 | AD 任せ | 自前ハッシュ化必須 | Identity 標準実装 |
判断軸:
- イントラ + AD あり → Windows 認証(実装コスト最小)
- 外部公開 + 独自ユーザー → Forms 認証
- MFA / 複数プロバイダ → Cookie 認証(Identity)
- 既存 AD 環境で Cookie が要件 → Forms 認証で AD バインド
ここから順に、コード対比で見ていきます。
定石1: Windows 認証 — 最小設定でイントラ SSO
業務系イントラの最頻パターン。web.config 3行 + IIS 設定 で完結します:
<!-- ✅ 定石1: Windows 認証の web.config(最小設定) -->
<configuration>
<system.web>
<authentication mode="Windows" />
<authorization>
<deny users="?" /> <!-- 匿名ユーザーを拒否 -->
</authorization>
</system.web>
</configuration>
IIS 側の設定:
- サイトの認証で 「Windows 認証」を有効
- 「匿名認証」を無効
- アプリプールの ID がドメインユーザーで AD に問い合わせできること
これで Controller の Action 内で User.Identity.Name を呼ぶと、DOMAIN\username 形式のユーザー名が取れます:
// ✅ 定石1: Action 内でユーザー名取得
public class HomeController : Controller
{
public ActionResult Index()
{
// ドメイン参加 PC からアクセスすると自動的に取れる
string userId = User.Identity.Name; // 例: "MYDOMAIN\\suzuki"
bool isAuth = User.Identity.IsAuthenticated; // true
ViewBag.UserId = userId;
return View();
}
}
ポイント:
- コード変更ゼロ(
web.configと IIS 設定のみ) - SSO 自動(ドメイン参加 PC からアクセスすると自動でログイン状態)
User.Identity.Nameで社員番号取得(AD アカウント名)- 業務系イントラの大半はこれで完結
業務SE の判断軸: AD 統合できる環境ならまず Windows 認証。コード変更なしで実装が終わるので、学習コストが最も低い選択肢っす。
定石2: Forms 認証 — フォームログイン + Cookie
外部公開 or 独自ユーザー管理が要る場合の標準パターン:
<!-- ✅ 定石2: Forms 認証の web.config 設定 -->
<configuration>
<system.web>
<authentication mode="Forms">
<forms loginUrl="~/Account/Login"
timeout="60"
slidingExpiration="true"
requireSSL="true" />
</authentication>
<authorization>
<deny users="?" />
</authorization>
</system.web>
</configuration>
// ✅ 定石2: Login Action での Cookie 発行
using System.Web.Security;
public class AccountController : Controller
{
[AllowAnonymous] // 認証前でもアクセス可
public ActionResult Login() => View();
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult Login(LoginVm model, string returnUrl)
{
// 自前 DB でパスワード検証(ハッシュ化済み)
var user = _userService.Authenticate(model.UserId, model.Password);
if (user == null)
{
ModelState.AddModelError("", "ID またはパスワードが違います");
return View(model);
}
// Cookie 発行(Forms 認証)
FormsAuthentication.SetAuthCookie(user.UserId, model.RememberMe);
return Redirect(returnUrl ?? "/");
}
public ActionResult Logout()
{
FormsAuthentication.SignOut();
return RedirectToAction("Login");
}
}
ポイント:
FormsAuthentication.SetAuthCookie(userId, persistent)で Cookie 発行<forms timeout="60" slidingExpiration="true">で60分操作なしでログアウト、操作で延長requireSSL="true"で SSL 必須化(本番運用の鉄則)- パスワードハッシュ化は自前実装(PBKDF2 / Argon2 を NuGet で)
業務系で外部公開 ASP.NET MVC 5 を作る時の本命。.NET Framework 標準で追加 NuGet なしで実装できるので、学習コストが Cookie 認証より低いっす。
定石3: Cookie 認証 — OWIN + ASP.NET Identity
モダンな選択肢。MFA や外部プロバイダ連携が要る場合:
// ✅ 定石3: OWIN Startup.cs での Cookie 認証設定
using Owin;
using Microsoft.Owin;
using Microsoft.Owin.Security.Cookies;
using Microsoft.AspNet.Identity;
[assembly: OwinStartup(typeof(MyApp.Startup))]
public partial class Startup
{
public void ConfigureAuth(IAppBuilder app)
{
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString("/Account/Login"),
ExpireTimeSpan = TimeSpan.FromMinutes(60),
SlidingExpiration = true,
CookieSecure = CookieSecureOption.Always, // SSL 必須
Provider = new CookieAuthenticationProvider
{
OnValidateIdentity = SecurityStampValidator
.OnValidateIdentity<ApplicationUserManager, ApplicationUser>(
validateInterval: TimeSpan.FromMinutes(30),
regenerateIdentity: (manager, user) =>
user.GenerateUserIdentityAsync(manager))
}
});
// 外部プロバイダ追加(Microsoft, Google, etc.)
// app.UseMicrosoftAccountAuthentication(...);
// app.UseGoogleAuthentication(...);
}
}
ポイント:
Install-Package Microsoft.AspNet.Identity.Owinで導入UseCookieAuthenticationで Cookie 認証ミドルウェア登録SecurityStampValidatorでセキュリティスタンプ検証(パスワード変更時に既存セッション無効化)- 外部プロバイダ連携が ASP.NET Identity の最大の旨み
学習コストは Forms 認証より高めですが、MFA / Google ログイン / Microsoft アカウント連携が要件にあるなら Cookie 認証一択。連載第5回(DI)で扱った DI コンテナとの相性も良くて、UserManager を Unity で注入する流れになります。
定石4: [Authorize] 属性で認可制御
認証通過したユーザーに対する認可(何ができるか)は [Authorize] 属性で:
// ✅ 定石4: [Authorize] 属性で認可制御
public class OrderController : Controller
{
[Authorize] // ログイン必須(未ログインは LoginUrl にリダイレクト)
public ActionResult Index() => View();
[Authorize(Roles = "Admin")] // Admin Role のユーザーのみ
public ActionResult Delete(int id) { /* ... */ }
[Authorize(Roles = "MYDOMAIN\\SalesGroup,MYDOMAIN\\ManagerGroup")]
// Windows 認証で AD Group 制御(カンマ区切りで OR 条件)
public ActionResult Export() { /* ... */ }
[AllowAnonymous] // 認証不要([Authorize] のオーバーライド)
public ActionResult Public() => View();
}
// Controller 全体に適用する場合
[Authorize]
public class SecuredController : Controller
{
[AllowAnonymous]
public ActionResult Login() => View(); // ここだけ匿名 OK
public ActionResult Dashboard() => View(); // ログイン必須
}
ポイント:
[Authorize]で未ログイン排除(LoginUrl にリダイレクト)[Authorize(Roles = "...")]で Role 制御- AD Group も Role として使える(Windows 認証時)
[AllowAnonymous]でオーバーライド(Login Action 等)
業務系の認可制御は [Authorize] + Role の組み合わせで9割対応できる。データ単位の細かい認可(「自分の部署のデータだけ」等)は Action 内で User.Identity.Name を見て自前判定するパターンっす。
定石5: User.Identity.Name でユーザー情報取得
ログイン後のユーザー情報取得は3つのプロパティで:
// ✅ 定石5: User.Identity からの情報取得
public class HomeController : Controller
{
[Authorize]
public ActionResult Profile()
{
// 認証済みか
bool isAuth = User.Identity.IsAuthenticated;
// ユーザー名(認証方式で形式が違う)
string userName = User.Identity.Name;
// Windows 認証: "MYDOMAIN\\suzuki"
// Forms 認証: "suzuki"(SetAuthCookie で渡した値)
// Cookie 認証: "suzuki@example.com"(Identity の UserName)
// Role 判定
bool isAdmin = User.IsInRole("Admin");
bool isInAdGroup = User.IsInRole("MYDOMAIN\\SalesGroup");
// ClaimsIdentity から追加情報(Cookie 認証時)
if (User.Identity is System.Security.Claims.ClaimsIdentity claims)
{
string email = claims.FindFirst(System.Security.Claims.ClaimTypes.Email)?.Value;
}
return View();
}
}
ポイント:
User.Identity.Nameで認証方式ごとに違う形式の ID 取得User.IsInRole("Role名")で Role 判定(AD Group も使える)ClaimsIdentityで Cookie 認証時の追加情報(メール / 電話番号 等)
業務系で「ログインユーザーの社員番号で部署を引きたい」「Admin だけメニュー表示」みたいな要件は、これらの基本 API で大半対応できる。複雑な認可は AuthorizeAttribute を継承して自前実装するパターンっす。
ハマりポイント — 実体験ベースの本番事故3点
1. Windows 認証で AD 接続できずローカル ID で動いた(半日デバッガで追ってハマった)
開発機で動いていた Windows 認証が、本番デプロイ後にローカル ID で動く事件。User.Identity.Name が IIS APPPOOL\DefaultAppPool みたいな値になっていて、社員番号取得できず画面が空白になった。半日デバッガで追ってハマった末に、IIS 側の「匿名認証」が有効のままだったのが原因と判明。web.config の <authentication mode="Windows"> + IIS の「匿名認証 OFF」+「Windows 認証 ON」の3点セット確認をチェックリスト化。
2. Forms 認証の Cookie 有効期限切れで突然ログアウト(30分溶かした)
業務画面の入力中に突然ログイン画面に飛ばされて入力データがロストする事件。30分溶かした末に、<forms timeout="20"> の20分タイムアウトが原因と判明。timeout="60" + slidingExpiration="true" に変更して、業務系の入力体験を改善。業務画面の Cookie 設定は60分 + slidingExpiration セットを業務系チーム規約に揃えた。
3. Cookie 認証で SSL 強制忘れで Cookie 漏洩リスク(数日プロファイラで追った)
開発環境を HTTP で動かしていた延長で本番も SSL 強制を入れ忘れる事件。数日プロファイラで追ってようやく気付いた。<httpCookies requireSSL="true"> + <forms requireSSL="true"> の SSL 強制設定 + Cookie 認証 OWIN の CookieSecure = CookieSecureOption.Always で本番では SSL 必須化。本番デプロイ前に Cookie 系の SSL 設定をチェックリスト化を業務系チーム規約に。
俺の現場メモ — 業務系チームでの認証規約
流通系SIer 時代に過去 ASP.NET MVC 5 案件を grep -rnE "authentication mode|FormsAuthentication|UseCookieAuthentication" . で50箇所近くひっかけたら、Windows 認証なのに <authentication mode="Forms"> 残骸・Forms timeout=10 で短すぎ・Cookie 認証 HTTP のままが全部入りだった。後輩と一緒に 3行ルール にまとめた:
- イントラ + AD あり = Windows 認証寄せ、外部公開 = Forms 認証、MFA = Cookie 認証(判断軸を持つ)
- Forms 認証は timeout=60 + slidingExpiration=true + requireSSL=true(業務系の入力体験)
- 本番デプロイ前に SSL 設定 + 認証 mode + IIS 設定の3点セット確認(チェックリスト化)
このルール化で、認証周りの本番事故が消えた。判断軸を持つ + 書き方を揃えるだけで保守工数と事故率が両方下がるおすすめルールっす。
まとめ
| 状況 | 推奨認証方式 |
|---|---|
| イントラ + AD 統合 | Windows 認証(web.config 3行 + IIS 設定) |
| 外部公開 + 独自ユーザー | Forms 認証 + Cookie + 自前パスワード管理 |
| MFA / 外部プロバイダ | Cookie 認証(OWIN + ASP.NET Identity) |
| Cookie 有効期限 | timeout=60 + slidingExpiration=true |
| SSL 強制 | requireSSL=true + httpCookies requireSSL=true |
| 認可制御 | [Authorize] 属性 + Role |
| ユーザー情報取得 | User.Identity.Name / User.IsInRole() / ClaimsIdentity |
| Login Action | [AllowAnonymous] でオーバーライド |
業務イントラの認証は、「3層分離(認証/認可/セッション)」「判断軸3つ(イントラ/外部公開/MFA)」「SSL 強制」 の3点で9割困らなくなります。業務系イントラの大半は Windows 認証で十分カタが付くので、AD 統合できる環境なら Windows 認証寄せが現実解。次回(連載第7回)は「CSS が効かない時のチェックリスト10項目」を扱うので、認証通過後の UI 表示まわりのトラブルシューティングに進みます。
よくある質問
Q1. 業務イントラの ASP.NET MVC 5 で認証方式はどう選べばいい?
A. 判断軸は3点。イントラ専用 + AD 統合あり → Windows 認証(実装最も簡単・コード変更不要)/ 外部公開 + 独自ユーザー管理 → Forms 認証 or Cookie 認証(パスワード自前管理)/ MFA・外部プロバイダ連携必要 → Cookie 認証(ASP.NET Identity)。業務系イントラの大半は Windows 認証で十分カタが付くので、AD 統合できる環境なら Windows 認証寄せが現実解です。
Q2. Windows 認証で AD が繋がらない時、どこを見ればいい?
A. 3点をチェックします。(1)web.config の <authentication mode="Windows"> が設定されているか、(2)IIS のサイト設定で「Windows 認証」が有効・「匿名認証」が無効か、(3)アプリプールの ID がドメインユーザーで AD に問い合わせできるか。AD 接続できないと匿名アクセス扱いで User.Identity.Name が空文字になる「ローカル ID 誤動作」が起きるので、3点を順に確認するのが業務SE 鉄則です。
Q3. Forms 認証の Cookie 有効期限切れで突然ログアウトされる時は?
A. <forms timeout="分数"> の値を確認してください。web.config の <authentication><forms timeout="30"> が30分なら、30分操作なしでログアウト。業務系で「画面入力中に Cookie 切れて入力データロスト」事故を防ぐには、timeout="60" 程度に伸ばす + slidingExpiration="true" で操作のたびに有効期限延長する設定がおすすめ。SSL 必須(requireSSL="true")も合わせて確認です。
Q4. [Authorize] 属性の Role 名で大文字小文字の差で詰まる時は?
A. AD の Role 名は大文字小文字を厳密に区別します。[Authorize(Roles = "DOMAIN\\SalesGroup")] と書く時、AD 側の Group 名が SALESGROUP でも salesgroup でも一致しない。AD 側の正式表記をコピペするか、User.IsInRole("...") で一旦テスト出力して確認してから [Authorize] に書くのが業務SE 定番の予防策です。
Q5. Cookie 認証は SSL 必須って本当?
A. 本番運用では SSL 必須です。Cookie 認証は認証トークンを Cookie に乗せて送るので、HTTP(平文)で送信すると Wireshark などで Cookie が抜き取られてなりすましができてしまう。<httpCookies requireSSL="true"> で SSL 必須化、<forms requireSSL="true"> も合わせて設定。開発環境では HTTP も許可することがありますが、本番では SSL 強制が業務SE 鉄則です。
ここまでで認証3方式・認可制御・User.Identity 取得・SSL 強制は押さえた。次回は CSS のトラブルシューティングを扱うので、認証通過後の UI 表示まわりに進みます。連載・WinForms の隣接トピックも貼っておきます。
関連記事
- Controller は WinForms の Form_Load 拡張版だと理解する — ASP.NET MVC 5 業務SE 入門 — 連載第2回・Action 内部で
User.Identityを扱う基礎に効く - ASP.NET MVC 5 で使える ORM 3択 — EF6 / Dapper / ADO.NET の業務SE 視点比較 — 連載第4回・ASP.NET Identity の DB 管理を整理する時に効く
- ASP.NET MVC 5 で DI は業務系に要るのか — 入れない派の論点も書く — 連載第5回・認証サービスを DI コンテナで注入する時に効く
ASP.NET 生存ガイド・連載目次
今回は WinForms 業務SE のための ASP.NET 生存ガイド 全10回の 第6回 です。
- 第1回: WinForms の Form と Razor View の対応関係を業務SE が一日で腹落ちさせる
- 第2回: Controller は WinForms の Form_Load 拡張版だと理解する — ASP.NET MVC 5 業務SE 入門
- 第3回: ASP.NET MVC 5 のルーティングを WinForms の Form 切替で理解する
- 第4回: ASP.NET MVC 5 で使える ORM 3択 — EF6 / Dapper / ADO.NET の業務SE 視点比較
- 第5回: ASP.NET MVC 5 で DI は業務系に要るのか — 入れない派の論点も書く
- 第6回(今回): 業務イントラの認証 — Windows認証 / Forms認証 / Cookie の使い分け ← イマココ
- 第7回: CSS が効かない時のチェックリスト10項目(公開予定)
- 第8回: IIS デプロイ — オンプレ業務系の現実(公開予定)
- 第9回: ASP.NET MVC 5 トラブルシューティング・チェックリスト20項目(公開予定)
- 目次(最終回): WinForms 業務SE のための ASP.NET 生存ガイド・全体目次(公開予定)
以上!
同じ罠でハマってる業務SE仲間いたら、どんどんシェア待ってるぜ!!


コメント