23

मेरे पास AngularJS क्लाइंट एप्लिकेशन है जो नवीनतम Identity 2 का उपयोग कर WebAPI 2 एप्लिकेशन के विरुद्ध प्रमाणीकृत करने के लिए javascript (कॉफ़ीस्क्रिप्ट या टाइपस्क्रिप्ट नहीं) Oauth2 का उपयोग करता है। मेरे आवेदन में सभी सॉफ्टवेयर बहुत ताजा है और this example पर आधारित है। मेरे क्लाइंट ब्राउज़र लक्ष्य IE9 और ऊपर हैं।AngularJS, WebAPI 2 और Oauth 2 का उपयोग करते समय मैं अपने क्लाइंट ऐप पर प्राधिकरण जानकारी वापस कैसे भेज सकता हूं?

ध्यान दें कि मैंने ऊपर दिए गए उदाहरण से कुछ मामूली परिवर्तन किए हैं, जिसमें मैं ट्रांसफॉर्म का उपयोग कर सर्वर पर भेजे गए सभी डेटा urlencode नहीं करता हूं। इसके बजाय मैं सिर्फ नीचे प्रमाणित विधि में urlencode:

user.authenticate = function (userName, password, rememberMe, successCallback, errorCallback) { 
    var config = { 
     method: 'POST', 
     url: '/Token', 
     headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, 
     data: 'grant_type=password&username=' + encodeURIComponent(userName) + '&password=' + encodeURIComponent(password), 
    }; 

मैं VS2013 अद्यतन 2 के साथ और सर्वर पर विकासशील हूँ, मैं, नवीनतम इकाई की रूपरेखा और एसक्यूएल सर्वर का उपयोग सी # 2012

मेरे मुवक्किल के लिए लॉग इन करने के लिए WebAPI को एक/टोकन विधि कॉल करता है और उपयोगकर्ता आईडी और पासवर्ड पास करता है। वेबएपीआई तब क्लाइंट को टोकन के साथ प्रतिक्रिया देता है जिसे मैं स्टोर करता हूं। वेबएपीआई लिए प्रत्येक अनुरोध के साथ टोकन वापस भेज दिया जाता है और प्रमाणीकृत:

$http.defaults.headers.common.Authorization = 'Bearer ' + user.data.bearerToken; 

यह अब तक बहुत अच्छी तरह से काम करता है लेकिन के रूप में यह खड़ा आवेदन उपयोगकर्ताओं उन्हें सौंपे गए विभिन्न भूमिकाओं है कि दोनों के बीच अंतर बताने में असमर्थ है।

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

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

जब इस सवाल कृपया ध्यान दें है कि मैं एक जवाब है कि समुदाय बता सकता है कि सर्वर या एक जवाब है कि कैसे महत्वपूर्ण यह सर्वर पर भूमिका की जाँच करता प्रदान करना है के बारे में बताते हैं पर भूमिकाओं स्थापित करने के लिए के लिए नहीं देख रहा हूँ का जवाब दे । मुझे लगता है कि लगभग हर किसी को इसके बारे में पता है। मैं वास्तव में क्या सोचता हूं इसका उपयोग नमूना कोड और स्पष्टीकरण के साथ कुछ बहुत ही विस्तृत तकनीकी सुझाव है। उत्तर केंद्रित रखने के लिए यह संभवतः सभी के लिए मदद की जाएगी यदि उत्तर जो इस आवश्यकता को पूरा नहीं करते हैं, उन्हें सुझाए गए उत्तरों के रूप में पोस्ट नहीं किया जाता है।

अग्रिम धन्यवाद।

+0

क्या आप इस "भूमिकाओं को दावों से नियंत्रित कर सकते हैं" पर विस्तार कर सकते हैं? दावे भूमिकाओं का एक विकल्प है, लेकिन यदि आप अभी भी भूमिकाओं का उपयोग करना चाहते हैं, तो प्रकार [दावे टाइप्स.रोल] (http://msdn.microsoft.com/en-us/library/system.security.claims.claimtypes) के साथ दावा जोड़ें .role (v = vs.110) .aspx) – LostInComputer

+0

मुझे लगता है कि इससे मदद मिल सकती है: http://msdn.microsoft.com/en-us/library/hh545448.aspx –

उत्तर

21

पर जा सकते हैं अपने प्रश्न का संक्षिप्त उत्तर ApplicationOAuthProvider.CreateProperties तरीका है। डिफ़ॉल्ट रूप से आप के लिए इसका बनाया है और WebApi2/प्रदाता/ApplicationOAuthProvider.cs अंतर्गत पाया जाता है, डिफ़ॉल्ट रूप से यह केवल भेजता userName

//WepApi2/Providers/ApplicationOAuthProvider.cs 
public static AuthenticationProperties CreateProperties(string userName) 
{ 
    IDictionary<string, string> data = new Dictionary<string, string> 
    { 
     { "userName", userName } 
    }; 
    return new AuthenticationProperties(data); 
} 

मैं निम्नलिखित अद्यतन बनाना होगा (मामले में मैं और अधिक उपयोगकर्ता डेटा भेजने की जरूरत है पर बाद में):

public static AuthenticationProperties CreateProperties(string userName, ClaimsIdentity oAuthIdentity) 
{ 
    IDictionary<string, string> data = new Dictionary<string, string> 
    { 
     { "userName", userName}, 
     { "roles",string.Join(",",oAuthIdentity.Claims.Where(c=> c.Type == ClaimTypes.Role).Select(c => c.Value).ToArray())} 

    }; 
    return new AuthenticationProperties(data); 
} 

यदि आप WebAPI परियोजना में बड़े बदलाव नहीं किया है, ApplicationOAuthProvider.CreateProperties केवल दो स्थानों में संदर्भित है, बस user.UserName के साथ oAuthIdentity पारित करने के लिए बुला कोड को अद्यतन करने और आप मिल जाएगा बुद्धिमानी के साथ भेजी गई उपयोगकर्ता भूमिकाएं ज पहुँच टोकन प्रतिक्रिया:

{ 
"access_token": "ZpxAZyYuvCaWgShUz0c_XDLFqpbC0-DIeXl_tuFbr11G-5hzBzSUxFNwNPahsasBD9t6mDDJGHcuEqdvtBT4kDNQXFcjWYvFP7U2Y0EvLS3yejdSvUrh2v1N7Ntz80WKe5G_wy2t11eT0l48dgdyak8lYcl3Nx8D0cgwlQm-pePIanYZatdPFP9q5jzhD-_k9SF-ARTHgf0ePnbvhLBi1MCYQjvfgPKlbBHt0M5qjwGAeFg1IhSVj0gb4g9QTXoiPhRmxGBmjOpGgzxXixavmrpM7cCBFLoR3DCGnIJo6pwT-6VArxlB8-ZyyOZqh_6gGtptd0lIu8iJRUIGwO9HFNkROdoE9T4buwLnhPpWpy9geBjPVwsB1K3xnbch26YbklhxIHVybBxeIVXd17QTw_LjlQ5TJdqpAYfiZ5B9Nx2AFYYYe3--aemh4y1XOIvN", 
"token_type": "bearer", 
"expires_in": 1209599, 
"userName": "MK", 
"roles": "Admin,Public", 
".issued": "Fri, 23 May 2014 17:36:54 GMT", 
".expires": "Fri, 06 Jun 2014 17:36:54 GMT" 
} 

अब आप भूमिकाओं के उपलब्ध है तुम्हें दिखाता हूँ/उपयोगकर्ता भूमिकाओं के अनुसार कार्यों को छिपाने के लिए कोणीय सशर्त निर्देशों का उपयोग कर सकते हैं।

यदि आपको अधिक स्पष्टीकरण की आवश्यकता है, तो कृपया मुझे बताएं।

संपादित करें:

अपने नियंत्रक तरीकों सजा के साथ Authorize विशेषता, वैध है के बाद से HttpContext.Current.User.Identity वास्तव में एक ClaimsIdentity है। लेकिन के रूप में नहीं अनुप्रयोग के भीतर कठिन कोड सुरक्षा तर्क है, मैं का उपयोग करना पसंद ClaimsAuthorizationManager

public ActionResult Secure() 
{ 
    if(!ClaimsPrincipalPermission.CheckAccess("resource", "action")) 
    return new HttpUnauthorizedResult(); 

    ViewBag.Message = "You are allowed to perform action on resource."; 
    return View(); 
} 

भूमिकाओं निर्माण RoleManager का उपयोग कर:

RoleManager roleManger = new RoleManager<IdentityRole>(new RoleStore<IdentityRole>()); 
roleManager.Create(new IdentityRole() { Name = "Admin" }); 

भूमिकाओं काम UserManager का उपयोग कर:

userManager.AddToRole(user.Id, "Admin"); 
+0

धन्यवाद। मैं आपका जवाब देखूंगा और टिप्पणियां अपडेट करूंगा। –

+0

एमके। - आपके सुझाव के लिए धन्यवाद। मैंने उपरोक्त अपना कोड नमूना चेक किया है और यह ठीक काम करता है। हालांकि मुझे इसमें कोई समस्या है हालांकि मेरे उपयोगकर्ताओं को भूमिका निभाई गई थी और वे पहचान तालिकाओं में फिट थे, ये भूमिका दावों के रूप में मौजूद नहीं हैं। इसलिए जब मैं उन उपयोगकर्ताओं को चेक करता हूं जिनके पास भूमिका निभाई गई है तो मैं देखता हूं कि उनके से कोई दावा नहीं है। आपके मामले में जहां आपके उपयोगकर्ता को व्यवस्थापक और लोक की भूमिका नियुक्त की गई थी, आपने भूमिका को व्यवस्थापक कैसे निर्दिष्ट किया? यह भी सुनिश्चित करने के लिए कि उपयोगकर्ता व्यवस्थापक भूमिका में है, आप अपने नियंत्रक विधियों को चेक के साथ सजाते हैं? –

+0

@ सैमांथाजे भूमिकाएं 'दावों की पहचान' के अंदर मौजूद हैं, मैं एक संशोधित 'उपयोगकर्ता प्रबंधक' का उपयोग कर रहा हूं, मैंने डिफ़ॉल्ट एएसपीनेट पहचान 2 के साथ काम करने का उत्तर अपडेट किया है। आप सीधे 'user.Roles' का उपयोग करके भूमिकाएं भी पूछ सकते हैं। भूमिकाओं की जांच के लिए मैं 'दावा प्राधिकरण प्रबंधक' का उपयोग करना पसंद करता हूं http://msdn.microsoft.com/en-us/library/system.security.claims.claimsauthorizationmanager.checkaccess(v=vs.110).aspx –

0

मेरे पास आपके जैसा ही परिदृश्य है, लेकिन प्रमाणीकरण के लिए टोकन का उपयोग करने के बजाय, मैं अपने प्रमाणीकरण को संभालने के लिए एक पहचान सर्वर (Thinktecture) का उपयोग करता हूं। मेरा ऐप प्रमाणीकरण के लिए पहचान सर्वर पर रीडायरेक्ट करता है और यह कुछ बहुत ही मूल दावों (उपयोगकर्ता नाम और ईमेल) के साथ आता है। ऐसा होता है जैसे कोई व्यक्ति पृष्ठ पर ब्राउज़ करने की कोशिश करता है। एक बार जब उपयोगकर्ता प्रमाणीकृत हो और मेरे ऐप पर रीडायरेक्ट हो जाए तो मैं उपयोगकर्ता की अनुमति प्राप्त करने के लिए सर्वर पर एक और कॉल करता हूं। ये अनुमतियां सुरक्षा सेवा (AngularJS) के अंदर संग्रहीत की जाती हैं जो "हैप्रमिशन" विधि का भी खुलासा करती है। मैं फिर एनजी का उपयोग करता हूं - यह तय करने के लिए कि क्या मैं पृष्ठ के कुछ हिस्सों को प्रदर्शित करने जा रहा हूं - मेनू आइटम समेत।इस आशय का कुछ:

var service = { 
    currentUser: ..., 
    isAuthenticated: function() { 
     return ...; 
    }, 
    checkAccess: function(permission) { 
     return service.isAuthenticated() ? 
      !!(service.currentUser.permissions.indexOf(permission) > -1) : false; 
    } 
} 

याद रखें कि सभी सभी अनुमतियों और html तत्व जो कोई देव उपकरण बटन हिट और एक झलक लेने का फैसला करने के लिए दिखाई दे रहे हैं। कोई कार्रवाई करने से पहले आपको सर्वर पक्ष पर एक ही चेक करना होगा। हमारे पास this के आधार पर एक कस्टम प्राधिकरण विशेषता है जो जांचता है कि उपयोगकर्ता को सामान्य मामलों के लिए निष्पादित होने से पहले एमवीसी/वेबएपीआई क्रिया निष्पादित करने के लिए आवश्यक अनुमतियां हैं या वास्तव में इसे किसी भी चीज को करने से पहले कार्रवाई या HTTP संसाधन में जांचें विशेषाधिकार।

यदि आप चाहते हैं कि ग्राहक आपकी साइट के किसी भी HTML तत्व या कुछ अनुभागों को न देखे, तो आप या तो अपने टेम्पलेट्स को एक एमवीसी क्रिया में इंगित कर सकते हैं जो प्रमाणीकृत करेगा और फिर HTML टेम्पलेट को वापस लाएगा या किसी अन्य पृष्ठ पर रीडायरेक्ट करेगा (एसपीए दायरे नहीं) और प्रतिक्रिया वापस लौटने से पहले उन्हें सर्वर पर प्रमाणित किया है।

+0

आपकी सलाह के लिए धन्यवाद लेकिन मैं दावों की तलाश में हूं आधारित समाधान जो भूमिकाओं और दावों को अधिक निकटता से एकीकृत करता है। –

+0

भूमिकाएं दावा हैं। क्या mithun_daa कह रहा है कि आपको –

+2

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

2

मुझे लगता है कि आप अपनी समस्या से संपर्क कर सकते हैं 2 तरीके हैं।

  1. संलग्न के रूप में आप एक टोकन बनाने हैं, तो आप कोणीय पर यह समझ सकती है एक हैश या एक सरल स्ट्रिंग द्वारा टोकन के लिए "भूमिका" सूचना शामिल हैं।

  2. ऐसा लगता है कि आप एएसपी.नेट पहचान प्रणाली का उपयोग करना चाहते हैं और वहां स्टोर की जानकारी पुनर्प्राप्त करना चाहते हैं। यदि ऐसा है तो आप this post के माध्यम से जा सकते हैं "व्यवस्थापक भूमिका और व्यवस्थापक उपयोगकर्ता बनाने के लिए डेटाबेस आरंभ करें" अनुभाग पर ध्यान दें।

IMO, # 1 आप आप कैसे की दुकान के बारे में अधिक लचीलापन और, # 2 आप माइक्रोसॉफ्ट के IdentityUser अनुसरण कर रहे हैं के रूप में अपने उपयोगकर्ता डेटा का उपयोग हालांकि यह कभी कभी जादू देखने के लिए और यह सीमा पोस्ट करने के लिए जाते हैं और आप खर्च करने की जरूरत है यह समझने का समय है कि यह दृश्य के पीछे कैसे काम करता है और इसे आपके प्रोजेक्ट के लिए काम करता है।

"व्यक्तिगत उपयोगकर्ता खातों" आप वेबएपीआई परियोजना आपके द्वारा बनाए दौरान लेने के बारे में अधिक जानने के लिए आप http://www.asp.net/visual-studio/overview/2013/creating-web-projects-in-visual-studio#indauth

0

यहाँ एक और सवाल का जवाब :

I n ApplicationOAuthProvider.cs

public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context) 
     { 
      var userManager = context.OwinContext.GetUserManager<ApplicationUserManager>(); 

      ApplicationUser user = await userManager.FindAsync(context.UserName, context.Password); 


      if (user == null) 
      { 
       context.SetError("invalid_grant", "The user name or password is incorrect."); 
       return; 
      } 

बस एक कस्टम हेडर जोड़ें!

context.OwinContext.Response.Headers.Add("Roles", userManager.GetRoles(user.Id).ToArray()); 
संबंधित मुद्दे