2015-02-22 14 views
10

Bir ASP Web Api 2 arka ucunu çağıran bir web ön uç var. Kimlik doğrulama ASP Kimlik ile yönetilir. Oluşturduğum kontrolörlerin bazıları için, kullanıcıyı aramayı bilmem gerekiyor. Kullanıcının kimliğini dahil etmemek için garip bir model yaratmak istemiyorum (ki bu da müşteride saklamam bile).Web Api çağrısı sırasında kullanıcı içeriği nasıl alınır?

API'ye yapılan tüm çağrılar bir taşıyıcı jetonu kullanılarak yetkilendirilmiştir, benim düşünceme göre denetleyici, kullanıcı bağlamını buna göre belirleyebilmeli, ancak nasıl uygulanacağını bilmiyorum. Aradım ama tam olarak ne aradığımı bilmiyorum ve alakalı bir şey bulamadım. Ben

Ben aşağıda çok umut verici görünüyordu bulundu Güncelleme

public async Task<IHttpActionResult> Post(ApplicationIdentity identity, WalkthroughModel data) 

... şey gibi gidiyorum ... ama değer her zaman null! Denetleyicim ApiController'dan miras alır ve bir Authorize üstbilgisine sahiptir.

var userid = User.Identity.GetUserId(); 

Güncelleme 2

Ben de Get the current user, within an ApiController action, without passing the userID as a parameter ama hiçbiri çalışmalarında tüm çözümleri çalıştılar. Şimdi de değilim nerede olursa olsun geçerli ve auth'd olmakla boş Kimliği

Güncelleme Burada 3

olan bir Kimlik oluyor alıyorum neyi.

[Authorize] 
    [Route("Email")] 
    public async Task<IHttpActionResult> Get() 
    { 
     var testa = User.Identity.GetType(); 
     var testb = User.Identity.GetUserId(); 
     var testc = User.Identity.AuthenticationType; 
     var testd = User.Identity.IsAuthenticated; 


     return Ok(); 
    } 
testa = Name: ClaimsIdentity, 
testb = null, 
testc = Bearer, 
testd = true 

kullanıcı besbelli kimliği doğrulanır ama onların kullanıcı kimliği alamıyor değilim.

Güncelleme 4

Bir yanıt buldum ama ... Hiçbir db çağrıları olmadan bana adını alır

ClaimsIdentity identity = (ClaimsIdentity)User.Identity; 
string username = identity.Claims.First().Value; 

onunla gerçekten mutsuz olduğum ama çok janky görünüyor ve Gelecekte destekleyecek bir acı. Daha iyi bir cevabın olsaydı sevinirdi.

Yolda hangi iddiaların yayınlanacağını değiştirmem gerekirse? Ayrıca, kullanıcının kimliğine ihtiyaç duyduğum her an kullanıcı adıma dönüştürmek için bir db çağrısı yapmak zorundayım

+0

talebine kesilirken Yani neden olmasın kullanıcı adı için bir tane ekleyin? Ayrıca, ClaimsIdentity'de kendi uzantı yöntemlerinizi de yapabilirsiniz. – Casey

+0

@emodendroket İyi bir fikir gibi geliyor, ama bunu nasıl yapacağımı bilmiyorum. Üyelik işlerinde oldukça zayıfım, bu yüzden online olarak bulunan şablonlar/eğiticilerden çalışıyorum. Ben açıkça kullanıcı adıyla bir hak talebi yayınlamıyorum ama görünüşe göre bu benim kodumda bir yerde olur: - \ Öneri için teşekkürler Ben –

+0

@emodendroket kapalı çalışacağım Teşekkürler ... benim araştırma göre User.Identity.GetUserId(); * Çalışmalı ve değil! Bunun neden işe yaramadığını ve bu sorunu doğru şekilde çözdüğünü ya da en azından anlayamadığını ve bir çözüm bulmasını istiyorum. –

cevap

18

Ortak bir yaklaşım, ApiControllers'ınız için bir temel sınıf oluşturmak ve ihtiyacınız olan bilgileri almak için ApplicationUserManager'dan faydalanmaktır. Bu yaklaşımla, kullanıcının bilgilerine tek bir yerden erişmek ve kontrol cihazlarınızda yeniden kullanmak için mantığı koruyabilirsiniz.

public class BaseApiController : ApiController 
{ 
     private ApplicationUser _member; 

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

     public string UserIdentityId 
     { 
      get 
      { 
       var user = UserManager.FindByName(User.Identity.Name); 
       return user.Id; 
      } 
     } 

     public ApplicationUser UserRecord 
     { 
      get 
      { 
       if (_member != null) 
       { 
        return _member ; 
       } 
       _member = UserManager.FindByEmail(Thread.CurrentPrincipal.Identity.Name); 
       return _member ; 
      } 
      set { _member = value; } 
     } 
} 
+0

AspNet Identity'nin biraz eski bir sürümünü kullanıyorsanız, UserManager.FindByX'in performansına dikkat edin. Http://stackoverflow.com/questions/28346479/how-to-handle-5-million-users-users-asp-net-identity – Dunc

+1

Web API otomatik yönlendirmesinden korumak için, bu sınıfa "abstract" anahtar sözcüğünü eklemek ve doğrudan bu sınıfın bir örneği olmamalıdır. – emackey

1

Ben özel kullanıcı kimlik doğrulaması (Varolan kullanıcı tablo alanları IdentityUser özelliklerinden uzak farklıydı çünkü AspIdentity kullanmayın) kullanmak ve API çağrıları benim taşıyıcı belirteci doğrulamak için benim masa kimliği ve UserName geçen ClaimsIdentity oluşturun.

public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context) 
    { 
     User user; 
     try 
     { 
      var scope = Autofac.Integration.Owin.OwinContextExtensions.GetAutofacLifetimeScope(context.OwinContext); 
      _service = scope.Resolve<IUserService>(); 

      user = await _service.FindUserAsync(context.UserName); 

      if (user?.HashedPassword != Helpers.CustomPasswordHasher.GetHashedPassword(context.Password, user?.Salt)) 
      { 
       context.SetError("invalid_grant", "The user name or password is incorrect."); 
       return; 
      } 
     } 
     catch (Exception ex) 
     { 
      context.SetError("invalid_grant", ex.Message); 
      return; 
     } 

     var properties = new Dictionary<string, string>() 
     { 
      { ClaimTypes.NameIdentifier, user.UserID.ToString() }, 
      { ClaimTypes.Name, context.UserName } 
     }; 

     var identity = new ClaimsIdentity(context.Options.AuthenticationType); 
     properties.ToList().ForEach(c => identity.AddClaim(new Claim(c.Key, c.Value))); 

     var ticket = new AuthenticationTicket(identity, new AuthenticationProperties(properties)); 

     context.Validated(ticket); 
     context.Request.Context.Authentication.SignIn(identity); 
    } 

Ve ApiController Detayları diyoruz Kullanıcı benim Kullanıcı tablo ayrıntıları almak için ClaimsIdentity nasıl kullandıklarını.

[HostAuthentication(DefaultAuthenticationTypes.ExternalBearer)] 
    [Route("Details")] 
    public async Task<IHttpActionResult> Details() 
    { 
     var user = await _service.GetAsync(RequestContext.Principal.Identity.GetUserId<int>()); 
     var basicDetails = Mapper.Map<User, BasicUserModel>(user); 

     return Ok(basicDetails); 
    } 

Bildirimi ClaimTypes.NameIdentifier = GetUserId() ve ClaimTypes.Name = GetUserName()

İlgili konular