javascript - 将自定义服务插入 UI 路由

标签 javascript angularjs azure adal adal.js

我开发了一个应用程序,它成功地使用 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/

相关文章:

javascript - 有什么方法可以用 Promise.all 打破 promise 数组的并行执行

java - 为什么 Java 给我一个 IllegalArgumentException?

javascript - 单击登录后如何返回 Iron Router 路由和其他路由?

javascript - 将 jQuery 2 slider 范围值获取到 Angularjs

Azure AD B2C 自定义模板错误

我的 Azure WebApp for linux 上的 Linux 风格和版本

asp.net - 什么是 Azure ASP.NET 云服务的单实例或多实例?

javascript - 如何在仍在加载时更改原始 HTML

javascript - 有没有办法获取canvas的子元素?

Eclipse:新行上的未知标签