¿Cuál es la diferencia entre la recuperación de WindowsPrincipal WindowsIdentity y Thread.CurrentPrincipal?

StackOverflow https://stackoverflow.com/questions/4563446

Pregunta

Estoy tratando de averiguar por qué la seguridad basada atributo no está funcionando como yo esperaría en WCF y sospecho que podría tener algo que ver con lo siguiente:

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

No entiendo por qué los resultados difieren de la llamada de función:

principal.IsInRole(groupName)

En aras de la exhaustividad del punto en el que el código no es en realidad aquí:

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

Ayuda apreciada.

¿Fue útil?

Solución

Tal vez sea porque no se trata de las mismas clases.

Look at MSDN:

Por lo tanto, si hay clases diferentes, tal vez hay diferentes implementaciones.

EDIT:

Tengo probar este código:

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));
    }
}

Y aquí es el resultado

Como se puede ver, no tenía los mismos grupos con diferentes formas. Por lo tanto (porque soy el administrador de mi máquina local) Creo que WindowsIdentity.GetCurrent obtendrá al usuario de AD y WindowsPrincipal (WindowsIdentity ( "")) va a conseguir que el usuario de la máquina local.

En mi aplicación web, he conseguido la autorización bajo posible (creo). Sin embargo, no tengo explicaciones para la ConsoleApp ...

Es sólo suposiciones, pero esto es coherente.

Otros consejos

Creo que es la diferencia entre el usuario conectado y la cuenta que ejecuta la aplicación (rosca). Estos no siempre serán los mismos.

Admito que es una solución bastante feo, pero si todo lo demás falla que podría reemplazar a:

principal = (WindowsPrincipal)Thread.CurrentPrincipal;

con algo como

principal = new WindowsPrincipal(new WindowsIdentity(Thread.CurrentPrincipal.Identity.Name));

Si eso no funciona, es probable que al menos ser instructivo en mostrar que las cosas van mal.

Pero no puedo imaginar que no, ya que hace exactamente lo mismo (donde sea relevante) como la línea que trabajé:. Asumo Thread.CurrentPrincipal.Identity.Name es "ksarfo"

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top