Il s'agit d'une sécurité côté client que vous pouvez mettre en œuvre dans les versions régulières d'Angular. J'ai essayé et testé ceci. (Veuillez trouver mon article ici :-) https://www.intellewings.com/post/authorizationonangularroutes ) En plus de la sécurité des routes côté client, vous devez également sécuriser l'accès côté serveur. La sécurité côté client permet d'éviter les allers-retours supplémentaires vers le serveur. Cependant, si quelqu'un trompe le navigateur, alors la sécurité côté serveur devrait être capable de rejeter l'accès non autorisé.
J'espère que cela vous aidera !
Étape 1 : Définir les variables globales dans le module d'application
-définir les rôles pour l'application
var roles = {
superUser: 0,
admin: 1,
user: 2
};
-Définir la route pour l'accès non autorisé pour l'application.
var routeForUnauthorizedAccess = '/SomeAngularRouteForUnauthorizedAccess';
Étape 2 : Définir le service pour l'autorisation
appModule.factory('authorizationService', function ($resource, $q, $rootScope, $location) {
return {
// We would cache the permission for the session, to avoid roundtrip to server for subsequent requests
permissionModel: { permission: {}, isPermissionLoaded: false },
permissionCheck: function (roleCollection) {
// we will return a promise .
var deferred = $q.defer();
//this is just to keep a pointer to parent scope from within promise scope.
var parentPointer = this;
//Checking if permisison object(list of roles for logged in user) is already filled from service
if (this.permissionModel.isPermissionLoaded) {
//Check if the current user has required role to access the route
this.getPermission(this.permissionModel, roleCollection, deferred);
} else {
//if permission is not obtained yet, we will get it from server.
// 'api/permissionService' is the path of server web service , used for this example.
$resource('/api/permissionService').get().$promise.then(function (response) {
//when server service responds then we will fill the permission object
parentPointer.permissionModel.permission = response;
//Indicator is set to true that permission object is filled and can be re-used for subsequent route request for the session of the user
parentPointer.permissionModel.isPermissionLoaded = true;
//Check if the current user has required role to access the route
parentPointer.getPermission(parentPointer.permissionModel, roleCollection, deferred);
}
);
}
return deferred.promise;
},
//Method to check if the current user has required role to access the route
//'permissionModel' has permission information obtained from server for current user
//'roleCollection' is the list of roles which are authorized to access route
//'deferred' is the object through which we shall resolve promise
getPermission: function (permissionModel, roleCollection, deferred) {
var ifPermissionPassed = false;
angular.forEach(roleCollection, function (role) {
switch (role) {
case roles.superUser:
if (permissionModel.permission.isSuperUser) {
ifPermissionPassed = true;
}
break;
case roles.admin:
if (permissionModel.permission.isAdministrator) {
ifPermissionPassed = true;
}
break;
case roles.user:
if (permissionModel.permission.isUser) {
ifPermissionPassed = true;
}
break;
default:
ifPermissionPassed = false;
}
});
if (!ifPermissionPassed) {
//If user does not have required access, we will route the user to unauthorized access page
$location.path(routeForUnauthorizedAccess);
//As there could be some delay when location change event happens, we will keep a watch on $locationChangeSuccess event
// and would resolve promise when this event occurs.
$rootScope.$on('$locationChangeSuccess', function (next, current) {
deferred.resolve();
});
} else {
deferred.resolve();
}
}
};
});
Étape 3 : Utiliser la sécurité dans le routage : Utilisons tout ce que nous avons fait jusqu'à présent pour sécuriser les routes.
var appModule = angular.module("appModule", ['ngRoute', 'ngResource'])
.config(function ($routeProvider, $locationProvider) {
$routeProvider
.when('/superUserSpecificRoute', {
templateUrl: '/templates/superUser.html',//path of the view/template of route
caseInsensitiveMatch: true,
controller: 'superUserController',//angular controller which would be used for the route
resolve: {//Here we would use all the hardwork we have done above and make call to the authorization Service
//resolve is a great feature in angular, which ensures that a route controller(in this case superUserController ) is invoked for a route only after the promises mentioned under it are resolved.
permission: function(authorizationService, $route) {
return authorizationService.permissionCheck([roles.superUser]);
},
}
})
.when('/userSpecificRoute', {
templateUrl: '/templates/user.html',
caseInsensitiveMatch: true,
controller: 'userController',
resolve: {
permission: function (authorizationService, $route) {
return authorizationService.permissionCheck([roles.user]);
},
}
})
.when('/adminSpecificRoute', {
templateUrl: '/templates/admin.html',
caseInsensitiveMatch: true,
controller: 'adminController',
resolve: {
permission: function(authorizationService, $route) {
return authorizationService.permissionCheck([roles.admin]);
},
}
})
.when('/adminSuperUserSpecificRoute', {
templateUrl: '/templates/adminSuperUser.html',
caseInsensitiveMatch: true,
controller: 'adminSuperUserController',
resolve: {
permission: function(authorizationService, $route) {
return authorizationService.permissionCheck([roles.admin,roles.superUser]);
},
}
})
});
2 votes
Vous semblez déjà l'être, mais pour que ce soit clair pour tous les autres - utilisez toujours https, sinon le nom d'utilisateur/mot de passe sera envoyé en texte clair.
1 votes
J'ai une question, peut-être simple. Lorsque vous dites que le client reçoit un statut HTTP de 401 du reste, vous nettoyez et redirigez vers la page de connexion. Donc quelque part dans votre code, vous aurez une sorte de condition if pour response.status comme 401. Maintenant, en mode débogage, nous pouvons le changer. Comment gérez-vous cela ? Ou est-il possible qu'un pirate utilise un plugin pour modifier le code d'état de la réponse http ?
1 votes
Vous pouvez tout faire du côté client. Vous pouvez changer le statut 401 http en un statut 200 http et puis ? Vous pouvez faire de l'ingénierie inverse sur le code angulaire et atteindre une page qui fera une demande à un service de repos qui répondra avec un autre 401 :) La chose la plus importante est de sécuriser le côté serveur et de rendre difficile ou impossible à un attaquant d'appeler le rest WS avec une fausse session ou sans session. Je gère donc cela en vérifiant la session sur chaque rest WS et en ne répondant avec la ressource que si la session est valide.