Skip to content

पोस्ट

Claims के साथ AngularJS को सुरक्षित करना

14 फ़रवरी 2015 • 6 मिनट पढ़ना

Claims के साथ AngularJS को सुरक्षित करना

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

गैर-सिंगल पेज एप्लिकेशन (SPA) में, एक claim या role डेटा या एप्लिकेशन के एक क्षेत्र के साथ जुड़ा होता है, या तो उपयोगकर्ता के पास यह role या claim है या नहीं है। SPA में यह वही है, लेकिन एक बड़े अस्वीकरण के साथ। एक SPA ब्राउज़र में डाउनलोड होता है। इस बिंदु पर ब्राउज़र का कोड पर पूरा नियंत्रण होता है। एक दुर्भावनापूर्ण व्यक्ति कोड को अपनी इच्छा के अनुसार बदल सकता है।

क्योंकि SPAs को सुरक्षित नहीं किया जा सकता, SPA में प्रमाणीकरण और प्राधिकरण केवल उपयोगकर्ता अनुभव है। सभी सार्थक सुरक्षा वेब सर्वर पर की जानी चाहिए। यह लेख आपके API को हमलों से सुरक्षित करने को कवर नहीं करता। मैं Pluralsight से एक वीडियो देखने या आपकी सर्वर तकनीक के लिए सुरक्षा को संबोधित करने वाला एक पेपर पढ़ने की सिफारिश करता हूं।

इस लेख का उद्देश्य आपको दिखाना है कि मैंने अपने Angular 1.x SPA में एक प्राधिकरण उपयोगकर्ता अनुभव कैसे जोड़ा।

सुरक्षा स्कोप

मैंने UI के 3 क्षेत्रों की पहचान की है जिन्हें प्राधिकरण की आवश्यकता है: Elements (HTML), Routes, और Data

बस एक अनुस्मारक, SPA को सुरक्षित करना सर्वर को सुरक्षित करने का विकल्प नहीं है। क्लाइंट पर अनुमतियां केवल ईमानदार लोगों को ईमानदार रखने और उपयोगकर्ता को एक अच्छा अनुभव प्रदान करने के लिए हैं।

विस्तार से 3 क्षेत्र:

Elements

आपको विशिष्ट HTML elements को छुपाना होगा। यह एक label, डेटा के साथ एक table, एक button, या पेज पर कोई भी element हो सकता है।

Routes

आप पूरे routes को छुपाना चाहेंगे। कुछ मामलों में आप नहीं चाहते कि उपयोगकर्ता एक view तक पहुंच सके। route को सुरक्षित करके एक उपयोगकर्ता view पर navigate नहीं कर सकता। इसके बजाय उन्हें “आप इस view पर navigate करने के लिए अधिकृत नहीं हैं” संदेश दिखाया जाएगा।

Data

कभी-कभी view में elements को छुपाना पर्याप्त नहीं होता। एक चतुर उपयोगकर्ता बस source देख सकता है और HTML source में छुपे हुए डेटा को देख सकता है या इसे ब्राउज़र में stream होते देख सकता है। हम चाहते हैं कि डेटा पहली जगह में retrieve न हो।

सुरक्षा जोड़ना मुश्किल है। पहले मैंने HTTP API (क्लाइंट पर) पर पहुंच को सीमित करने की कोशिश की। मैंने जल्दी महसूस किया कि यह काम नहीं करेगा। एक उपयोगकर्ता के पास डेटा तक प्रत्यक्ष पहुंच नहीं हो सकती, लेकिन इसका मतलब यह नहीं है कि उनके पास डेटा तक अप्रत्यक्ष पहुंच नहीं है। HTTP API layer पर (आमतौर पर एप्लिकेशन में सबसे निचली में से एक) हम कॉल के संदर्भ को नहीं बता सकते और इसलिए इसमें सुरक्षा चिंताओं को लागू नहीं कर सकते।

नीचे मैंने कोडिंग नमूने प्रदान किए हैं:

Code

मैंने प्राधिकरण जांच कोड के लिए एक service बनाई। यह प्राधिकरण का दिल है। सभी प्राधिकरण अनुरोध इस service का उपयोग करके जांचते हैं कि उपयोगकर्ता विशेष कार्य के लिए अधिकृत है या नहीं।

angular.module('services')
    .service('AuthorizationContext',function(_, Session){

        this.authorizedExecution = function(key, action){

            //Looking for the claim key that was passed in. If it exists in the claim set, then execute the action.
            Session.claims(function(claims){
                var claim = findKey(key, claims);

                //If Claim was found then execute the call.
                //If it was not found, do nothing
                if(claim !== undefined){
                    action();
                }
            });
        };

        this.authorized = function(key, callback){
            //Looking for the claim key that was passed in. If it exists in the claim set, then execute the action.
            Session.claims(function(claims){
                var claim = findKey(key, claims);

                //If they don't have any security key, then move forward and authorization.
                var valid = claim !== undefined;
                callback(valid);
            });
        };

        //this.agencyViewKey = '401D91E7-6EA0-46B4-9A10-530E3483CE15';

        function findKey(key, claims){
            var claim = _.find(claims, function(item){
                return item.value === key;
            });

            return claim;
        }
    });

Authorize Directive

authorize directive को किसी भी HTML element पर लागू किया जा सकता है जिसे आप विशिष्ट स्तर की पहुंच के बिना उपयोगकर्ताओं से छुपाना चाहते हैं। यदि उपयोगकर्ता के पास उनके claims के हिस्से के रूप में access token है तो उन्हें element देखने की अनुमति है। यदि उनके पास नहीं है तो यह उनसे छुपा हुआ है।

angular.module('directives')
    .directive('authorize', ['$compile', 'AuthorizationContext', function($compile, AuthorizationContext) {
        return {
            restrict: 'A',
            replace: true,
            //can't have isolated the scope in a shared directive
            link:function ($scope, element, attributes) {

                var securityKey = attributes.authorize;
                AuthorizationContext.authorized(securityKey, function(authorized){
                    var el = angular.element(element);
                    el.attr('ng-show', authorized);

                    //remove the attribute, otherwise it creates an infinite loop.
                    el.removeAttr('authorize');
                    $compile(el)($scope);
                });
            }
        };
    }]);

Elements

मैं अपने एप्लिकेशन में tabs पर बहुत निर्भर करता हूं। मैं authorize directive को उस tab पर लागू करता हूं जिसे मैं उचित claims के बिना उपयोगकर्ताओं से छुपाना चाहता हूं।

<tabset>
<tab ng-cloak heading="Users" authorize="{{allowUserManagement}}">
...html content
</tab>
</tabset>

Routes

मैं ui-router का उपयोग कर रहा हूं। दुर्भाग्य से जो लोग नहीं हैं, उनके लिए मेरे पास out of the box AngularJS router के लिए कोड नहीं है।

$stateChangeStart में मैं route को authenticate करता हूं। यह उस event में कोड है।

$rootScope.$on("$stateChangeStart", function(event, toState, toParams, fromState, fromParams){
   AuthenticationManager.authenticate(event, toState, toParams);
});

वह function जो route को authorize करता है। यदि यह authorized है, तो route को जारी रखने की अनुमति है। यदि यह authorized नहीं है, तो उपयोगकर्ता को एक संदेश दिखाया जाता है और उन्हें home page पर भेज दिया जाता है।

function authorizedRoute(toState, location, toaster, breadCrumbs){
   if(toState.authorization !== undefined){
       AuthorizationContext.authorized(toState.authorization, function(authorized){
           if(!authorized){
               toaster.pop('error', 'Error', 'You are not authorized to view this page.');
               location.path("/search");
           } else {
               breadCrumbs();
           }
       });
   } else{
       breadCrumbs();
   }
}

इस router definition में आप ‘authorization’ नामक एक property देखेंगे। यदि उपयोगकर्ता के पास यह claim है तो उन्हें आगे बढ़ने की अनुमति है।

angular.module('agency',
    [
        'ui.router',
        'services'
    ])
    .config(function config($stateProvider){
    $stateProvider.state( 'agency', {
        url: '/agency',
        controller: 'agency.index',
        templateUrl: 'agency/agency.tpl.html',
        authenticate: true,
        authorization:'401d91e7-6ea0-46b4-9a10-530e3483ce15',
        data:{ pageTitle: 'Agency' }
    });
});

Data

कुछ मामलों में, आप डेटा के लिए सर्वर से request नहीं करना चाहते। यदि उपयोगकर्ता के पास claim है तो उन्हें request करने की अनुमति होगी।

लेख की शुरुआत में ऊपर दिया गया AuthorizationContext authoriedExecution के लिए कोड दिखाता है। यहां आप इसका उपयोग देखते हैं।

AuthorizationContext.authorizedExecution(Keys.authorization.allowUserManagement, function(){
    //execute code, if the loggedin user has rights.

                });

जैसा कि मैंने ऊपर उल्लेख किया है, यह सर्वर को सुरक्षित करने का विकल्प नहीं है। यह कोड एक अद्भुत उपयोगकर्ता अनुभव प्रदान करने के लिए काम करता है।

लेखक: चक कॉनवे सॉफ्टवेयर इंजीनियरिंग और जेनेरेटिव AI में विशेषज्ञता रखते हैं। उनसे सोशल मीडिया पर जुड़ें: X (@chuckconway) या उन्हें YouTube पर देखें।

↑ शीर्ष पर वापस

आपको यह भी पसंद आ सकता है