C# Tips | ログ・例外・診断:権限チェック

C# C#
スポンサーリンク
スポンサーリンク

権限チェックは「このアプリが“何を許されているか”を事前に把握するための技術です」

業務システムでは、実行ユーザーが誰かだけでなく、 そのユーザーがどんな権限を持っているかが極めて重要になります。 権限が不足していると、次のような問題が簡単に発生します。

ファイルが読めない・書けない ネットワーク共有にアクセスできない レジストリ操作が失敗する サービスの起動・停止ができない 管理者権限が必要な API が例外を投げる

つまり、権限チェックは「動かしてみて失敗する前に、権限不足を検知するための安全装置」です。 ここでは、初心者でも理解しやすいように、権限チェックの基本、実務で使えるコード例、ユーティリティ化のテンプレート、そしてログへの活用方法までを連続した流れで解説します。

権限チェックの基本:WindowsPrincipal と WindowsBuiltInRole

最も重要な権限は「管理者権限」

C# で権限チェックを行うとき、まず押さえるべきなのは 「このプロセスは管理者権限で動いているか?」 という点です。

Windows では、管理者権限があるかどうかでできることが大きく変わります。 その判定は WindowsPrincipal を使うと簡単にできます。

using System.Security.Principal;

public static class PermissionCheck
{
    public static bool IsAdministrator()
    {
        var identity = WindowsIdentity.GetCurrent();
        if (identity == null) return false;

        var principal = new WindowsPrincipal(identity);
        return principal.IsInRole(WindowsBuiltInRole.Administrator);
    }
}
C#

使い方はとてもシンプルです。

Console.WriteLine($"IsAdmin: {PermissionCheck.IsAdministrator()}");
C#

ここでの重要ポイントは、 「管理者権限は“ユーザー名”ではなく“ロール”で判定する」 ということです。

DOMAIN\Administrator という名前だから管理者、というわけではありません。 「そのユーザーが管理者ロールに属しているかどうか」が本質です。

特定の権限をチェックする:ファイル・レジストリ・ネットワークなど

権限は「できるかどうか」で判定するのが実務的

管理者権限以外にも、業務システムでは次のような権限が問題になります。

ファイル書き込み権限 フォルダ作成権限 ネットワーク共有アクセス権限 レジストリ読み書き権限 サービス操作権限

これらは「権限があるかどうか」を API で直接判定するより、 “実際に軽い操作を試してみて成功するかどうか”で判定する方が実務的です。

例えば、フォルダ書き込み権限をチェックするなら次のようにします。

using System;
using System.IO;

public static class PermissionCheck
{
    public static bool CanWriteToFolder(string path)
    {
        try
        {
            var testFile = Path.Combine(path, "permission_test.tmp");
            File.WriteAllText(testFile, "test");
            File.Delete(testFile);
            return true;
        }
        catch
        {
            return false;
        }
    }
}
C#

使い方は次の通りです。

Console.WriteLine($"CanWriteTo C:\\data: {PermissionCheck.CanWriteToFolder("C:\\data")}");
C#

ここでの重要ポイントは、 「権限は“理論上の権限”ではなく“実際にできるかどうか”で判定する」 ということです。

Windows の権限は複雑で、ユーザー権限・フォルダ ACL・継承・グループ権限などが絡むため、 「試してみる」のが最も確実な方法です。

実務で使える「権限チェックユーティリティ」のテンプレート

権限チェックを一箇所にまとめておくと後から楽になる

権限チェックは、アプリの起動時や重要処理の前に行うことが多いため、 ユーティリティとしてまとめておくと便利です。

using System;
using System.IO;
using System.Security.Principal;

public static class PermissionUtility
{
    public static bool IsAdmin()
    {
        var identity = WindowsIdentity.GetCurrent();
        if (identity == null) return false;

        var principal = new WindowsPrincipal(identity);
        return principal.IsInRole(WindowsBuiltInRole.Administrator);
    }

    public static bool CanWriteFolder(string path)
    {
        try
        {
            var testFile = Path.Combine(path, "perm_test.tmp");
            File.WriteAllText(testFile, "test");
            File.Delete(testFile);
            return true;
        }
        catch
        {
            return false;
        }
    }

    public static bool CanReadFolder(string path)
    {
        try
        {
            Directory.GetFiles(path);
            return true;
        }
        catch
        {
            return false;
        }
    }
}
C#

使い方は次のようになります。

Console.WriteLine($"IsAdmin: {PermissionUtility.IsAdmin()}");
Console.WriteLine($"CanWrite C:\\logs: {PermissionUtility.CanWriteFolder("C:\\logs")}");
Console.WriteLine($"CanRead C:\\config: {PermissionUtility.CanReadFolder("C:\\config")}");
C#

ここでの重要ポイントは、 「権限チェックのロジックをアプリ全体に散らばらせない」 ということです。

ユーティリティにまとめておけば、 後から権限チェックの仕様を変えたいときも一箇所の修正で済みます。

権限チェックをログに残すことで「なぜ失敗したか」を後から追えるようにする

権限不足は“静かに失敗する”ことが多いのでログが必須

権限不足による失敗は、例外が分かりづらかったり、 「成功したように見えて実は何もできていない」というケースが多いため、 権限チェックの結果をログに残すことが非常に重要です。

ILogger と組み合わせたログユーティリティは次のように書けます。

using Microsoft.Extensions.Logging;

public static class PermissionLogger
{
    public static void LogPermissions(ILogger logger, string context)
    {
        logger.LogInformation(
            "PermissionInfo Context={Context} IsAdmin={IsAdmin} CanWriteLogs={CanWriteLogs} CanReadConfig={CanReadConfig}",
            context,
            PermissionUtility.IsAdmin(),
            PermissionUtility.CanWriteFolder("C:\\logs"),
            PermissionUtility.CanReadFolder("C:\\config"));
    }
}
C#

使い方は次の通りです。

PermissionLogger.LogPermissions(_logger, "AppStart");
PermissionLogger.LogPermissions(_logger, "BeforeCriticalOperation");
C#

ログには次のような行が残ります。

PermissionInfo Context=AppStart IsAdmin=False CanWriteLogs=False CanReadConfig=True

この情報があるだけで、 「ログフォルダに書けないからログが出ていなかった」 「設定フォルダが読めないから初期化に失敗していた」 といった原因にすぐ気づけます。

ここでの重要ポイントは、 「権限チェックは“診断情報”としてログに残すことで価値が最大化する」 ということです。

権限チェックが役立つ具体的な場面

本番だけで起きる謎の失敗の原因が“権限不足”だったケース

権限チェックは、次のような場面で特に役立ちます。

開発環境では動くのに、本番ではファイルが書けない → 本番はサービスアカウントで動いており、フォルダ権限がなかった。

IIS Web アプリでネットワーク共有にアクセスできない → アプリプールユーザーに共有フォルダの権限がなかった。

タスクスケジューラで動かすと失敗する → スケジュール実行ユーザーが別で、権限が不足していた。

Windows サービスが起動できない → サービスアカウントに「ログオン権限」がなかった。

こうした問題は、権限チェックをログに残していないと原因が分かりづらいですが、 PermissionLogger のようなユーティリティを仕込んでおけば、 「どの権限が不足していたか」を後から正確に確認できます。

まとめ:権限チェックは「できること・できないことを事前に把握する」ためのユーティリティです

権限チェックの本質は、

「このアプリが、 どのユーザー権限で、 どの操作を許されているかを、 コードから機械的に判定し、ログとして残すことで、 権限差による不具合を正しく理解できるようにする」

という点にあります。

押さえておきたいポイントは次の通りです。

管理者権限は WindowsPrincipal で正確に判定する。 フォルダやファイルの権限は“実際に試してみる”のが最も確実。 権限チェックはユーティリティ化してアプリ全体で統一する。 権限チェック結果をログに残すことで、後から原因を追いやすくなる。

多くの購読者のみなさんが業務コードを書くとき、 「権限を意識した設計と診断」を身につけておくと、 本番環境でのトラブル対応が格段に楽になります。

タイトルとURLをコピーしました