2015-02-22 9 views
10

मेरे पास एक वेब फ्रंट एंड है जो एएसपी वेब एपीआई 2 बैकएंड को कॉल करता है। प्रमाणीकरण एएसपी पहचान के साथ प्रबंधित किया जाता है। मेरे द्वारा बनाए जा रहे कुछ नियंत्रकों के लिए मुझे कॉल करने वाले उपयोगकर्ता को जानने की आवश्यकता है। मैं उपयोगकर्ता की पहचान (जिसे मैं क्लाइंट में भी स्टोर नहीं करता) सहित पास करने के लिए कुछ अजीब मॉडल बनाना नहीं चाहता हूं।वेब एपीआई कॉल के दौरान उपयोगकर्ता संदर्भ कैसे प्राप्त करें?

एपीआई को सभी कॉल एक भालू टोकन का उपयोग करके अधिकृत हैं, मेरा विचार है कि नियंत्रक इस पर आधारित उपयोगकर्ता संदर्भ को निर्धारित करने में सक्षम होना चाहिए लेकिन मुझे नहीं पता कि इसे कैसे कार्यान्वित किया जाए। मैंने खोज की है लेकिन मुझे नहीं पता कि मैं वास्तव में क्या खोज रहा हूं और कुछ भी प्रासंगिक नहीं मिला है। मैं कुछ तरह के लिए जा रहा हूँ ...

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

अद्यतन

मैंने पाया जो नीचे बहुत आशाजनक देखा ... लेकिन मान हमेशा शून्य है! मेरा नियंत्रक एपीकंट्रोलर से विरासत में आता है और इसमें एक अधिकृत शीर्षलेख है।

var userid = User.Identity.GetUserId(); 

अद्यतन 2

मैं भी Get the current user, within an ApiController action, without passing the userID as a parameter लेकिन कोई भी काम में समाधान के सभी की कोशिश की है। कोई फर्क नहीं पड़ता कि मैं कहाँ मैं अब पर हूँ है एक पहचान है कि वैध और auth'd है, लेकिन एक अशक्त UserID

अद्यतन 3

यहाँ है हो रही है।

[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 

उपयोगकर्ता स्पष्ट रूप से प्रमाणित है, लेकिन मैं उनके userID प्राप्त करने में असमर्थ हूँ।

अद्यतन 4

मैं एक जवाब मिल गया है, लेकिन मैं वास्तव में इसे से संतुष्ट नहीं हूं ...

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

मुझे किसी भी db कॉल के बिना उपयोगकर्ता नाम हो जाता है यही कारण है कि लेकिन यह बहुत janky लगता है और भविष्य में समर्थन करने के लिए एक दर्द। अगर किसी के पास कोई बेहतर जवाब था तो प्यार करेंगे।

क्या होगा यदि मुझे सड़क को कौन से दावे जारी किए जाएंगे तो क्या होगा? इसके अलावा किसी भी समय मुझे वास्तव में उपयोगकर्ता की आईडी की आवश्यकता होती है, मुझे उपयोगकर्ता नाम आईडी

+0

तो जब आप दावा जारी क्यों नहीं उपयोगकर्ता नाम एक जोड़ सकता हूँ? आप दावाों पर अपनी खुद की विस्तार विधियां भी कर सकते हैं। – Casey

+0

@emodendroket यह एक अच्छा विचार की तरह लगता है, लेकिन मुझे नहीं पता कि यह कैसे करें। मैं सदस्यता सामग्री में बहुत कमजोर हूं इसलिए मैं ऑनलाइन मिले टेम्पलेट्स/ट्यूटोरियल से काम कर रहा हूं। मैं स्पष्ट रूप से उपयोगकर्ता नाम के साथ दावा जारी नहीं करता लेकिन स्पष्ट रूप से यह मेरे कोड में कहीं होता है: - \ सुझाव के लिए धन्यवाद मैं उस –

+0

@emodendroket को बंद करने की कोशिश करूंगा ... मेरे सभी शोधों के अनुसार User.Identity.GetUserId(); * काम करना चाहिए और यह नहीं है! मैं समझना चाहता हूं कि यह क्यों काम नहीं कर रहा है और इसे उचित तरीके से हल नहीं कर रहा है, या यदि कम से कम इसे समझने और कामकाज को लागू नहीं किया जाता है। –

उत्तर

18

एक आम तरीका है अपने एपीकंट्रोलर के लिए बेस क्लास बनाना और आपको आवश्यक जानकारी पुनर्प्राप्त करने के लिए ApplicationUserManager का लाभ उठाना है। इस दृष्टिकोण के साथ, आप उपयोगकर्ता की जानकारी को एक स्थान पर एक्सेस करने के लिए तर्क रख सकते हैं और इसे अपने नियंत्रकों में पुन: उपयोग कर सकते हैं।

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

UserManager.FindByX का प्रदर्शन सावधान रहें यदि आप एस्पनेट पहचान के थोड़ा पुराने संस्करण का उपयोग कर रहे हैं http://stackoverflow.com/questions/28346479/how-to-handle-5-million-users-asp-net-identity – Dunc

+1

आप शायद वेब एपीआई स्वचालित रूटिंग से इसकी रक्षा के लिए, इस वर्ग में 'abstract' कीवर्ड जोड़ना चाहते हैं, और क्योंकि इस वर्ग का उदाहरण सीधे नहीं होना चाहिए। – emackey

1

मैं एक कस्टम उपयोगकर्ता प्रमाणीकरण (मैं AspIdentity का उपयोग न क्योंकि मेरे मौजूदा उपयोगकर्ता तालिका क्षेत्रों IdentityUser गुण से दूर अलग था) का उपयोग करें और मेरी मेज UserID और उपयोगकर्ता नाम गुजर API कॉल पर अपने वाहक टोकन मान्य करने के लिए ClaimsIdentity पैदा करते हैं।

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

और कैसे मैं ClaimsIdentity का उपयोग उपयोगकर्ता ApiController विवरण फोन पर मेरे उपयोगकर्ता तालिका विवरणों को प्राप्त करने।

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

सूचना ClaimTypes.NameIdentifier = GetUserId() और ClaimTypes.Name = GetUserName()

संबंधित मुद्दे