我开发了一个应用程序,它成功地使用 ADAL JS 库通过 azure 进行身份验证。但是我还需要实现授权,我的意思是我需要将 View 限制为特定组。
我已经有一个 REST API,只要给定用户 ID 或电子邮件,就可以向我返回他所属的组。
但是我不确定如何插入 Angular 服务来使用 REST API 并将其插入路由配置中。
app.js
(function () {
angular.module('inspinia', [
'ui.router', // Routing
'oc.lazyLoad', // ocLazyLoad
'ui.bootstrap', // Ui Bootstrap
'pascalprecht.translate', // Angular Translate
'ngIdle', // Idle timer
'AdalAngular', // ADAL JS Angular
'ngRoute' // Routing
])
})();
config.js
function config($stateProvider, $urlRouterProvider, $ocLazyLoadProvider, IdleProvider, KeepaliveProvider,adalAuthenticationServiceProvider, $httpProvider) {
// Configure Idle settings
IdleProvider.idle(5); // in seconds
IdleProvider.timeout(120); // in seconds
$urlRouterProvider.otherwise("/dashboards/dashboard_1");
$ocLazyLoadProvider.config({
// Set to true if you want to see what and when is dynamically loaded
debug: false
});
$stateProvider
.state('dashboards', {
abstract: true,
url: "/dashboards",
templateUrl: "views/common/content.html",
})
.state('dashboards.dashboard_1', {
url: "/dashboard_1",
templateUrl: "views/dashboard_1.html",
requireADLogin: true,
resolve: {
loadPlugin: function ($ocLazyLoad) {
return $ocLazyLoad.load([
{
serie: true,
name: 'angular-flot',
files: [ 'js/plugins/flot/jquery.flot.js', 'js/plugins/flot/jquery.flot.time.js', 'js/plugins/flot/jquery.flot.tooltip.min.js', 'js/plugins/flot/jquery.flot.spline.js', 'js/plugins/flot/jquery.flot.resize.js', 'js/plugins/flot/jquery.flot.pie.js', 'js/plugins/flot/curvedLines.js', 'js/plugins/flot/angular-flot.js', ]
},
{
name: 'angles',
files: ['js/plugins/chartJs/angles.js', 'js/plugins/chartJs/Chart.min.js']
},
{
name: 'angular-peity',
files: ['js/plugins/peity/jquery.peity.min.js', 'js/plugins/peity/angular-peity.js']
}
]);
}
}
})
理想情况下,如果我可以向每个状态添加一个名为“具有值的组”的新属性,那就太棒了:
类似于:
url: "/dashboard_1",
templateUrl: "views/dashboard_1.html",
requireADLogin: true,
groups: "Admin, Accounting, Marketing"
然后后台的自定义服务将验证这一点。
最佳答案
我对 ADAL.js 不太熟悉,但假设您可以在 http 请求中对服务器说“此用户是否具有这些 Angular 色”,那么您可以拦截 $stateChangeStart
,通过调用 event.preventDefault()
阻止状态更改,询问服务器当前用户是否属于 toState
中指定的任何具有访问权限的 Angular 色,并且然后以任一方式采取行动 - 发送到访问被拒绝的页面,或继续到 toState
。
以下是一个有缺陷的实现。工作版本在工作中被锁定,我现在在家,但希望它能给你一些想法。
(function (app) {
"use strict";
app.run(run);
function run($rootScope, $log, $state, $q, authService) {
/**
* The canceller is passed to the authService.isTokenValid()
*
* The canceller is a promise, that, when resolved, cancels the current
* token validation request
*/
let _canceller;
/**
* When state is changed, ensure that the current user has access
* @param event
* @param toState
*/
function onStateChangeStart(event, toState, toParams) {
// When token is valid, continue with navigation to the state
function onValidToken() {
if (toState.name === 'login'){
$state.go('home');
} else {
$state.go(toState, toParams, {notify: false}).then((state) => {
$rootScope.$broadcast('$stateChangeSuccess', state, null);
});
}
}
// When the token is not valid, set state to login
function onInvalidToken() {
if (toState.name === 'login'){
$state.go(toState, toParams, {notify: false}).then((state) => {
$rootScope.$broadcast('$stateChangeSuccess', state, null);
});
} else {
$log.warn(`Access denied to state ${toState.name}`);
$state.go('login');
}
}
// On completion of token validation, resolve the canceller
function onFinally() {
if (_canceller) {
_canceller.resolve();
}
}
// If the state requiresLogin
if (toState.requiresLogin || toState.name === 'login') {
// stop navigation
event.preventDefault();
// Cancel any current requests
if (_canceller) {
_canceller.resolve();
}
// create a new promise
_canceller = $q.defer();
// validate
authService.isTokenValid(_canceller)
.then(onValidToken, onInvalidToken)
.finally(onFinally);
}
}
$rootScope.$on('$stateChangeStart', onStateChangeStart);
}
}(angular.module('app.features')));
关于javascript - 将自定义服务插入 UI 路由,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31010620/