0

I configured the state which contains url with url parameters like this: url:route/:id1/:id2:id3 with ADAL js. When I hit url with route/1/2/3, after login, I am redirected to route/:id1/:id2/:id3?id1=1&id2=2&id3=3 instead of route/1/2/3.

I investigated further and in adal-angular.js file, we are setting browser url with $location.url().search(jsonParameters) where jsonParameters is json object with value {id1:1, id2:2, id3:3} which is causing the url malformation.

Can you guys point me in correct direction on how to solve this issue and redirect to proper url?

Edit: Adding code sample

I have configured the AAD route as specified below:

$stateProvider
        .state('State1', {
            templateUrl: getViewUrl('viewUrl'),
            controller: 'homeController',
            controllerAs: 'home',
            url: '/route/:id1/:id2/:id3',
            requireADLogin: true
        })

I am initializing the adal sevice provider in following way:

     $locationProvider.html5Mode(false);
    var endpoints = {}
    endpoints[EnvironmentConfig.url1] = EnvironmentConfig.url1;
    endpoints[EnvironmentConfig.url2] = EnvironmentConfig.url2;

    adalAuthenticationServiceProvider.init(
              {
                  instance: EnvironmentConfig.aadUrl,                           // 'https://login.microsoftonline.com/',
                  tenant: EnvironmentConfig.tenant,                             // 'microsoft.onmicrosoft.com',
                  clientId: EnvironmentConfig.clientId,                         
                  endpoints: endpoints,
                  loginResource: EnvironmentConfig.breServiceADUrl              
                  //cacheLocation: 'localStorage', // enable this for IE, as sessionStorage does not work for localhost.
              }, $httpProvider);

Thanks.

10
  • I am failed to reproduce this issue. How did you set the browser URL in the adal-angular.js?
    – Fei Xue
    Commented Jan 4, 2017 at 9:31
  • @FeiXue-MSFT, have configured my web application to use Azure AD login through adal-angular.js. So I have defined this url with state provider along with requireADLogin:true.
    – Kiran
    Commented Jan 4, 2017 at 10:20
  • I also add the requireADLogin: true via the $routeProvider but still not able to reproduce this issue. Did you mix the ui-router and ngRoute? It is helpful if you can provide a code sample to reproduce this issue.
    – Fei Xue
    Commented Jan 5, 2017 at 9:44
  • Hi @FeiXue-MSFT, I have added the sample state declaration and initialization of adal service provider for reference. I am using 1.0.10 version of ADAL.js.
    – Kiran
    Commented Jan 5, 2017 at 10:31
  • Did the code in the post work for you?
    – Fei Xue
    Commented Jan 11, 2017 at 8:53

2 Answers 2

0

I read the source code for adal-angular.js and found out that there is an issue when redirecting to the link with url parameters. I have modified code by @Fei Xue little bit to reproduce the scenario.

<!-- inject:css -->
<!-- endinject -->

<!-- bower:js -->
 <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.25/angular.min.js"></script>
    <script src="https://secure.aadcdn.microsoftonline-p.com/lib/1.0.10/js/adal.min.js"></script>
    <script src="https://secure.aadcdn.microsoftonline-p.com/lib/1.0.10/js/adal-angular.min.js"></script>
    <script src="//unpkg.com/angular-ui-router/release/angular-ui-router.min.js"></script>
    <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.25/angular-route.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore.js"></script>


<!-- endinject -->



<!DOCTYPE html>
<html ng-app="myApp">
<head>
       <base href="/">


</head>
<body>

    <div >
        <div ng-controller="homeCtrl">
            <ul class="nav navbar-nav navbar-right">
                <li><a ui-sref="hello({id1:1,id2:2,id3:1})" ui-sref-active="active">Hello</a></li>
                <li><a href="#hello/1/2/3" ui-sref-active="active">Hello2</a></li>
                <li><a ui-sref="about" ui-sref-active="active">About</a></li>
                <li ng-show="userInfo.isAuthenticated"><a href="" ng-click="logout()">Logout</a></li>
                <li><a href="" ng-hide="userInfo.isAuthenticated" ng-click="login()">Login</a></li>
            </ul>
            <ui-view></ui-view>

        </div>
    </div>

</body>

</html>

    
<script>
        var myApp = angular.module('myApp', ['AdalAngular', 'ui.router'])
.config(['$httpProvider', 'adalAuthenticationServiceProvider', '$stateProvider','$locationProvider','$urlRouterProvider', function ($httpProvider, adalProvider, $stateProvider,$locationProvider,$urlRouterProvider) {

        $locationProvider.html5Mode(false); 
        $locationProvider.hashPrefix('');
    adalProvider.init(
       {
           instance: 'https://login.microsoftonline.com/',
           tenant: 'xxx.onmicrosoft.com',
           clientId: '<clientId>',
       },
       $httpProvider
       );


        $httpProvider.defaults.useXDomain = true;
        $httpProvider.defaults.headers.post["Content-Type"] = "application/x-www-form-urlencoded; charset=utf-8";



    var helloState = {
        name: 'hello',
        url: '/hello/:id1/:id2/:id3',
        template: '<h3>hello world!</h3>',
        controller: function ($stateParams) {
            // alert('kiran');
        },
        requireADLogin: true
    }

    var aboutState = {
        name: 'about',
        url: '/about',
        template: '<h3>Its the UI-Router hello world app!</h3>'
    }

    var homeState={
        name:'home',
        url:'/',
        controller:function(){
            
        },
        requireADLogin:true
    }

    $stateProvider.state(homeState);
    $stateProvider.state(helloState);
    $stateProvider.state(aboutState);


    $urlRouterProvider.otherwise('/');

}])
    myApp.controller('homeCtrl', ['$scope', '$http', 'adalAuthenticationService', '$location','$stateParams','$rootScope','$timeout',  function ($scope, $http, adalService, $location, $stateParams,$rootScope,$timeout) {
        $scope.double = function (value) { return value * 2; };

        $scope.login = function () {
            adalService.login();
        };
        $scope.logout = function () {
            adalService.logOut();
        };

        /*Fix for adal issue*/
    //     $rootScope.$on("adal:loginSuccess", function (e) {
  //              console.log('loginSuccess');
//
      //          $timeout(function () {
    //                var startPageURL = sessionStorage['adal.start.page'];
  //                  var stateParamsString = sessionStorage['adal.start.page.params'];
//
  //                  var stateParamsJson = stateParamsString ? JSON.parse(stateParamsString) : {};
//
                    //var matchedState = _.find($state.get(),
                  //      function (state) {
                //            return state.url == startPageURL;
             ///           });
           //         if (matchedState) {
         //               $state.go(matchedState.name, stateParamsJson, { reload: true });
       //             }
     //           }, 2);

      //      });
    }]);



</script>

I have added fix also. Adal-angular uses location.search method to replace the redirected url after successful login. But search method converts stored json object to query parameters which is causing the issue.

You can run below code as is to repro the issue. In incognito browser if we try to go to http://localhost:8080/hello/1/2/3 and it will redirect us to http://localhost:8080/#/hello/:id1/:id2/:id3?id1=1&id2=2&id3=1 which is wrong.

I have commented the fix for this issue. After uncommenting the code and it will work as expected and it will correctly redirect us to http://localhost:8080/hello/1/2/3

0

The code I tested seems no different with yours, I post the code for your reference. Hope it is helpful:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title></title>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.25/angular.min.js"></script>
    <script src="https://secure.aadcdn.microsoftonline-p.com/lib/1.0.10/js/adal.min.js"></script>
    <script src="https://secure.aadcdn.microsoftonline-p.com/lib/1.0.10/js/adal-angular.min.js"></script>
    <script src="//unpkg.com/angular-ui-router/release/angular-ui-router.min.js"></script>
    <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.25/angular-route.js"></script>

</head>
<body>

    <div ng-app="myApp">
        <div ng-controller="homeCtrl">
            <ul class="nav navbar-nav navbar-right">
                <li><a ui-sref="hello({id1:1,id2:2,id3:1})" ui-sref-active="active">Hello</a></li>
                <li><a href="#hello/1/2/3" ui-sref-active="active">Hello2</a></li>
                <li><a ui-sref="about" ui-sref-active="active">About</a></li>
                <li ng-show="userInfo.isAuthenticated"><a href="" ng-click="logout()">Logout</a></li>
                <li><a href="" ng-hide="userInfo.isAuthenticated" ng-click="login()">Login</a></li>
            </ul>
            <ui-view></ui-view>

        </div>
    </div>

    <script>
    var myApp = angular.module('myApp', ['AdalAngular', 'ui.router', 'ngRoute'])
.config(['$httpProvider', 'adalAuthenticationServiceProvider', '$stateProvider', '$routeProvider', function ($httpProvider, adalProvider, $stateProvider, $routeProvider) {

    var endpoints = {
        "https://localhost:44327/": "https://adfei.onmicrosoft.com/ToGoAPI",
    };

    adalProvider.init(
       {
           instance: 'https://login.microsoftonline.com/',
           tenant: 'xxx.onmicrosoft.com',
           clientId: '{clientId}',
           extraQueryParameter: 'nux=1',
           endpoints: endpoints,
       },
       $httpProvider
       );

    var helloState = {
        name: 'hello',
        url: '/hello/:id1/:id2/:id3',
        template: '<h3>hello world!</h3>',
        controller: function ($stateParams) {

        },
        requireADLogin: true
    }

    var aboutState = {
        name: 'about',
        url: '/about',
        template: '<h3>Its the UI-Router hello world app!</h3>'
    }

    $stateProvider.state(helloState);
    $stateProvider.state(aboutState);

    $routeProvider.
     when("/hello/:id1/:id2/:id3", {
         controller: "homeCtrl",
         templateUrl:  '<h3>hello world!-ngRoute</h3>',
         requireADLogin: true
     });
}])
    myApp.controller('homeCtrl', ['$scope', '$http', 'adalAuthenticationService', '$location',  function ($scope, $http, adalService, $location, $stateParams) {
        $scope.double = function (value) { return value * 2; };

        $scope.login = function () {
            adalService.login();
        };
        $scope.logout = function () {
            adalService.logOut();
        };

       
    }]);



    </script>
</body>
</html>

To test the code, first click the login and than you can switch the view by click the Hello and About hyperlink.

Update

It seems this issue was fixed by the version 1.0.12 of ADAL from #345. I suggest that you upgrade the ADAL to the latest version 1.0.13 to fix this issue.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.