Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the difference between retrieving WindowsPrincipal from WindowsIdentity and Thread.CurrentPrincipal?

I am trying to work out why attribute based security isn't working as I'd expect in WCF and I suspect it might have something to do with the following:

AppDomain.CurrentDomain.SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal);

var identity = new WindowsIdentity("ksarfo");
var principal = new WindowsPrincipal(identity);
Console.WriteLine("\nChecking whether current user [" + identity.Name + "] is member of [" + groupName + "]");
Console.WriteLine(principal.IsInRole(groupName)); // returns true

principal = (WindowsPrincipal)Thread.CurrentPrincipal;
identity = (WindowsIdentity) principal.Identity;
Console.WriteLine("\nChecking whether current user [" + identity.Name + "] is member of [" + groupName + "]");
Console.WriteLine(principal.IsInRole(groupName)); // returns false

I don't understand why the results differ for the function call:

principal.IsInRole(groupName)

For the sake of completeness the point at which the code actually fails is here:

PrincipalPermission(SecurityAction.Demand, Role = "PortfolioManager")]

Help appreciated.

like image 731
Kofi Sarfo Avatar asked Dec 30 '10 14:12

Kofi Sarfo


People also ask

What is thread CurrentPrincipal in C#?

Thread. CurrentPrincipal is the way . NET applications represent the identity of the user or service account running the process. It can hold one or more identities and allows the application to check if the principal is in a role through the IsInRole method. Most authentication libraries in .

What is WindowsPrincipal?

The WindowsPrincipal class is primarily used to check the role of a Windows user. The WindowsPrincipal. IsInRole method overloads let you check the user role by using different role contexts.


1 Answers

Maybe it's because this is not the same classes.

Look at MSDN :

  • Thread.CurrentPrincipal
    • IPrincipal
      • IsInRole
  • WindowsPrincipal
    • IsInRole

So, if there are differents classes, maybe there are differents implementations.

EDIT :

I have try this code :

public class InGroup
{
    public string Name { get; set; }
    public bool Current { get; set; }
    public bool Fixe { get; set; }
    public bool Thread { get; set; }
}

WindowsIdentity current = System.Security.Principal.WindowsIdentity.GetCurrent();
WindowsPrincipal principalcurrent = new WindowsPrincipal(current);

WindowsIdentity fixe = new WindowsIdentity("JW2031");
WindowsPrincipal principalFixe = new WindowsPrincipal(fixe);

IPrincipal principalThread = System.Threading.Thread.CurrentPrincipal;

List<InGroup> ingroups = new List<InGroup>();
foreach (IdentityReference item in current.Groups)
{
    IdentityReference reference = item.Translate(typeof(NTAccount));
    Console.WriteLine("{0}\t{1}\t{2}\t{3}",
        reference.Value,
        principalcurrent.IsInRole(reference.Value),
        principalFixe.IsInRole(reference.Value),
        principalThread.IsInRole(reference.Value));

    ingroups.Add(new InGroup()
    {
        Name = reference.Value,
        Current = principalcurrent.IsInRole(reference.Value),
        Fixe = principalFixe.IsInRole(reference.Value),
        Thread = principalThread.IsInRole(reference.Value)
    });
}
foreach (IdentityReference item in fixe.Groups)
{
    IdentityReference reference = item.Translate(typeof(NTAccount));
    if (ingroups.FindIndex(g => g.Name == reference.Value) == -1)
    {
        ingroups.Add(new InGroup()
        {
            Name = reference.Value,
            Current = principalcurrent.IsInRole(reference.Value),
            Fixe = principalFixe.IsInRole(reference.Value),
            Thread = principalThread.IsInRole(reference.Value)
        });
        Console.WriteLine("{0}\t{1}\t{2}\t{3}",
            reference.Value,
            principalcurrent.IsInRole(reference.Value),
            principalFixe.IsInRole(reference.Value),
            principalThread.IsInRole(reference.Value));
    }
}

And here is the result

As you can see, I did not have the same groups with differents ways. So (because I'm administrator of my local machine) I think that WindowsIdentity.GetCurrent will get the user from AD and WindowsPrincipal(WindowsIdentity("")) will get the user from local machine.

In my webapp, I have got the lowest authorisation possible (I think). But, I have no explanations for the consoleapp...

It's only suppositions, but this is coherent.

like image 170
kerrubin Avatar answered Sep 20 '22 05:09

kerrubin