Sergio Teijido
Sergio Teijido

Reputation: 89

Permission for IIS user to check local groups

In .NET 8, I have a function to check if the user belongs to a local group in order to authorize controllers and methods:

public static bool IsUserInLocalGroup(string userName, string groupName)
{
    using (PrincipalContext pc = new PrincipalContext(ContextType.Machine))
    {
        using (GroupPrincipal group = GroupPrincipal.FindByIdentity(pc, groupName))
        {
            if (group != null)
            {
                return group.GetMembers(true).Any(m => m.SamAccountName.Equals(userName, StringComparison.OrdinalIgnoreCase));
            }
        }
    }

    return false;
}

It works fine in debug mode, but once published to the production IIS, it fails with an error

The network path was not found

I think the user that runs the app in IIS does not have permission to check local groups, so I changed the identity from ApplicationPoolIdentity to LocalSystem, but it still doesn't work.

Is there anything else I need to do? Any help to solve this issue will be appreciated.

Edit: I call this function from program.cs like this:

builder.Services.AddAuthorization(options =>
{
    options.AddPolicy("Admin", policy =>
        policy.RequireAssertion(context =>
        {
            try
            {
                var userName = context.User.Identity?.Name?.Split('\\').Last();
                return LocalGroupHelper.IsUserInLocalGroup(userName, "rWork-Admin");
            }
            catch (Exception ex)
            {
                Console.WriteLine($"[ERROR]: {ex.Message} \n {ex.StackTrace}");
                File.AppendAllText("logs/error_log.txt", $"[{DateTime.Now}] {ex.Message} \n {ex.StackTrace}\n");
                return false;
            }

        }));
});

Then, I authorize my controllers and methods with [Authorize(Policy = "Admin")]

Upvotes: 0

Views: 30

Answers (1)

Sergio Teijido
Sergio Teijido

Reputation: 89

I will answer myself because I solved the issue by changing the approach. I still don't know why it fails using System.DirectoryServices.AccountManagement, but I realized that when using DirectoryEntry it works good in both server and development sides. So permissions and IIS configuration are good. Here is my finally method:

    public static bool IsUserInLocalGroup(string userName, string domain, string groupName)
    {
        string userPath = $"WinNT://{domain}/{userName}";

        try
        {
            using (var group = new DirectoryEntry($"WinNT://{Environment.MachineName}/{groupName},group"))
            {
                foreach (var member in (IEnumerable)group.Invoke("Members"))
                {
                    using (var memberEntry = new DirectoryEntry(member))
                    {
                        if (memberEntry.Path.Equals(userPath, StringComparison.OrdinalIgnoreCase))
                        {
                            return true;
                        }
                    }
                }
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine($"[ERROR]: {ex.Message} \n {ex.StackTrace}");
            File.AppendAllText("logs/error_log.txt", $"[{DateTime.Now}] {ex.Message} \n {ex.StackTrace}\n");
            return false;
        }
        return false;

    }

Upvotes: 0

Related Questions