Pega o usuário atual, dentro de uma ação ApiController, sem passar o ID do usuário como parâmetro


97

Como obtemos o usuário atual, dentro de uma ação ApiController segura, sem passar o userName ou userId como um parâmetro?

Presumimos que esteja disponível, pois estamos em uma ação segura. Estar em uma ação segura significa que o usuário já se autenticou e a solicitação tem seu token de portador. Dado que o WebApi autorizou o usuário, pode haver uma maneira embutida de acessar o userId, sem ter que passá-lo como um parâmetro de ação.


Por favor, veja esta resposta: stackoverflow.com/a/26453782/3290276 Adicionar a reivindicação resolveu
Gabriela Macias

Respostas:


149

No WebApi 2, você pode usar RequestContext.Principalde dentro de um método no ApiController


1
Não temos essa propriedade, ao que parece. Hmm. Talvez estejamos usando uma versão antiga do WebApi.
Shaun Luttin

2
@ShaunLuttin Ok, então se você está usando a API Web 1, então acredito que haja uma propriedade Prinicpal no ApiController. Este é apenas um invólucro sofisticado sobre como acessar a coleção Request.Properties. O objeto principal é armazenado nesse dicionário.
Darrel Miller

6
Só não se esqueçausing Microsoft.AspNet.Identity;
Overlord

1
@DarrelMiller existe uma maneira de obter o mesmo (digamos, contexto de solicitação) de outras partes do código (não dentro do controlador).
Ajay Aradhya

2
@AjayAradhya Somente se você passar lá. Esforços anteriores em estruturas da web mostraram que o uso de propriedades estáticas para acessar o contexto de solicitação causa todos os tipos de problemas arquitetônicos. É conveniente no início, mas causa tãããão dor a longo prazo.
Darrel Miller

36

Você também pode acessar o principal usando a Userpropriedade em ApiController.

Portanto, as duas declarações a seguir são basicamente as mesmas:

string id;
id = User.Identity.GetUserId();
id = RequestContext.Principal.Identity.GetUserId();

15
Estou tentando usar o que você escreveu aqui, mas a função GetUserId () sempre retorna nulo. O usuário está autenticado, estou passando um token do portador e o ApiController tem o cabeçalho [Autorizar]
Joshua Ohana

A função GetUserId () retorna um ID apenas se o usuário tiver uma declaração NameIdentifier. Para obter um exemplo de como resolver isso, consulte a resposta de Oswaldo aqui: stackoverflow.com/questions/19505526
jramm

14

A dica está no controlador de conta gerado automaticamente Webapi2

Tenha esta propriedade com getter definido como

public string UserIdentity
        {
            get
            {
                var user = UserManager.FindByName(User.Identity.Name);
                return user;//user.Email
            }
        }

e para obter UserManager - Em WebApi2 -do como Romanos (leia como AccountController) faça

public ApplicationUserManager UserManager
        {
            get { return HttpContext.Current.GetOwinContext().GetUserManager<ApplicationUserManager>(); }
        }

Deve ser compatível com IIS e modo de auto-host


7

Nenhuma das sugestões acima funcionou para mim. O seguinte fez!

HttpContext.Current.Request.LogonUserIdentity.Name

Acho que há uma grande variedade de cenários e este funcionou para mim. Meu cenário envolveu um front-end AngularJS e um aplicativo back-end Web API 2, ambos em execução no IIS. Tive que definir os dois aplicativos para serem executados exclusivamente na autenticação do Windows.

Não há necessidade de passar nenhuma informação do usuário. O navegador e o IIS trocam as credenciais do usuário conectado e a API da Web tem acesso às credenciais do usuário sob demanda (presumo do IIS).


6

A resposta de Karan Bhandari é boa, mas o AccountController adicionado em um projeto é muito provavelmente a Mvc.Controller. Para converter sua resposta para uso em um ApiController, altere HttpContext.Current.GetOwinContext()para Request.GetOwinContext()e certifique-se de ter adicionado as 2 usingdeclarações a seguir :

using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.Owin;

5

Em .Net Core, use User.Identity.Namepara obter a declaração de Nome do usuário.


2
User.Identity.Nameobtém o valor da afirmação do nome . Não é específico do Active Directory.
Nate Barbettini

@Nate Obrigado pelo seu comentário, eu
corrigi-

3

Se você estiver usando Asp.Identity UseManager, ele define automaticamente o valor de

RequestContext.Principal.Identity.GetUserId ()

com base no IdentityUser que você usa na criação do IdentityDbContext .

Se alguma vez você estiver implementando uma tabela de usuário personalizada e autenticação de portador de token owin, por favor, verifique minha resposta.

Como obter o contexto do usuário durante chamadas de API da Web?

Espero que ainda ajude. :)


1
string userName;
string userId;
if (HttpContext.Current != null && HttpContext.Current.User != null 
        && HttpContext.Current.User.Identity.Name != null)
{
    userName = HttpContext.Current.User.Identity.Name;
    userId = HttpContext.Current.User.Identity.GetUserId();
}

Ou, com base no comentário de Darrel Miller, talvez use isso para recuperar o HttpContext primeiro.

// get httpContext
object httpContext;
actionContext.Request.Properties.TryGetValue("MS_HttpContext", out httpContext);    

Veja também:

Como acessar HTTPContext de dentro de sua ação de API da Web


5
Não use HttpContext, pois ele limita suas opções de hospedagem e torna seu código difícil de testar.
Darrel Miller

O objeto HttpContext não estará no dicionário se você for Auto-host ou OwinHttpListener hospedado
Darrel Miller
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.