Skip to content
This repository has been archived by the owner on Apr 12, 2024. It is now read-only.

AngularJS Routing Fails when running within a Juniper SSL VPN #8905

Closed
mikepugh opened this issue Sep 3, 2014 · 21 comments
Closed

AngularJS Routing Fails when running within a Juniper SSL VPN #8905

mikepugh opened this issue Sep 3, 2014 · 21 comments

Comments

@mikepugh
Copy link

mikepugh commented Sep 3, 2014

I write corporate web apps that need to be accessible via our SSL VPN. In particular we have a Juniper appliance, and it handles secure proxying of the app. The issue is that it adds a bunch of extra stuff to the URL and this causes Angular routes to fail since the extra stuff is random in nature (session ids, etc). I've found the easiest way to deal with this is to patch the parseAppUrl function in angular.js.

This doesn't make sense to include in the core Angular library since it's Juniper SSL VPN specific, but I wanted to post it for anyone struggling with similar URL re-write issues from external appliances. Though perhaps a better fix would be to provide a hook into the parseAppUrl method, to allow a user to configure some external processing of the locationObj prior to parseAppUrl returning.

function parseAppUrl(relativeUrl, locationObj, appBase) {
  var prefixed = (relativeUrl.charAt(0) !== '/');
  if (prefixed) {
    relativeUrl = '/' + relativeUrl;
  }
  var match = urlResolve(relativeUrl, appBase);
  locationObj.$$path = decodeURIComponent(prefixed && match.pathname.charAt(0) === '/' ?
      match.pathname.substring(1) : match.pathname);
  locationObj.$$search = parseKeyValue(match.search);
  locationObj.$$hash = decodeURIComponent(match.hash);

  //Detect Juniper re-write functions and handle the $$path issue
  if(locationObj.$$path === "[object Object]" && typeof(DanaOrigUrl) === 'function') {
    var __strH = 'href';
    var __tmpHack = match[__strH];
    var __nn = ("" + __tmpHack).match(/^(https?:\/\/[^\/]+)?([^?|#]*)/);
    locationObj.$$path = __nn[2];
  }
  // make sure path starts with '/';
  if (locationObj.$$path && locationObj.$$path.charAt(0) != '/') {
    locationObj.$$path = '/' + locationObj.$$path;
  }
}
@btford btford added this to the Purgatory milestone Sep 3, 2014
@btford
Copy link
Contributor

btford commented Sep 3, 2014

@mikepugh – thanks for taking the time to write this up for others.

We mostly use GH issues to plan tasks to work on, so I typically close these types of issues. It'd be nice to maybe write a blog post about it and link from here.

You could start a separate thread to discuss a potential new API for $location to better accommodate this use-case.

@Chris55
Copy link

Chris55 commented Sep 17, 2014

Thanks for sharing that, I have a similar issue.

@mortenvg
Copy link

Mike, Thanx for elaborate over this issue - I was in the same situation!

@AbuBkr
Copy link

AbuBkr commented Jun 5, 2015

After posting a question on stackoverflow.com, I got the brilliant idea to give my problem also a try on this topic. The solution in this topic helped me, but partially.

It seem that you guys get Angular routing working when running the app within a Juniper SSL VPN. What I do is simply loading a view ($location.path('/anotherView'); from a view controller. The routing table is also very simple:

app.config(function ($routeProvider, $httpProvider) {
        $routeProvider
            .when('/', {
                templateUrl: 'view1.html'
            })
            .when('/view2', {
                templateUrl: 'view2.html'
            });

Without the VPN the app works fine. Within the Juniper SSL VPN i get the following error message:

Error: [$rootScope:infdig] 10 $digest() iterations reached. Aborting!
    Watchers fired in the last 5 iterations: []
    http://errors.angularjs.org/1.3.15/$rootScope/infdig?p0=10&p1=%5B%5D
        at REGEX_STRING_REGEXP (,DanaInfo=server1.mydomain.nl,CT=js+angular.js:63)
        at Scope.$get.Scope.$digest (,DanaInfo=server1.mydomain.nl,CT=js+angular.js:14340)
        at Scope.$get.Scope.$apply (,DanaInfo=server1.mydomain.nl,CT=js+angular.js:14565)
        at done (,DanaInfo=server1.mydomain.nl,CT=js+angular.js:9685)
        at completeRequest (,DanaInfo=server1.mydomain.nl,CT=js+angular.js:9875)
        at XMLHttpRequest.requestLoaded (,DanaInfo=server1.mydomain.nl,CT=js+angular.js:9816)(anonymous function) @ ,DanaInfo=server1.mydomain.nl,CT=js+angular.js:11649$get @ ,DanaInfo=server1.mydomain.nl,CT=js+angular.js:8583$get.Scope.$apply @ ,DanaInfo=server1.mydomain.nl,CT=js+angular.js:14567done @ ,DanaInfo=server1.mydomain.nl,CT=js+angular.js:9685completeRequest @ ,DanaInfo=server1.mydomain.nl,CT=js+angular.js:9875requestLoaded @ ,DanaInfo=server1.mydomain.nl,CT=js+angular.js:9816

Any advice to get this working?

http://stackoverflow.com/questions/30658940/angular-web-app-routing-within-juniper-ssl-vpn

@mikepugh
Copy link
Author

mikepugh commented Jun 9, 2015

@AbuBkr I ran into something very similar, and it was related to ngRoute basically trying to load a few dozen instances of my controller based upon my route definition.

Let me state early on - I do not know the root cause.

The code where I saw this happening, was when I had a button with an ng-click="someFunc()" method, and that someFunc() method made a call to $location.path(..).

If I switched the button from

<button ng-click="someFunc()">Click Me</button>

to

<a class="btn" ng-href="{{some-val}}">Click Me</a>

then it worked fine. Luckily for me, switching from a function to an ng-href on some attribute was not a huge refactor for me. Your mileage will vary.

@AbuBkr
Copy link

AbuBkr commented Jul 8, 2015

@mikepugh Thanks for your comment, however your solution didn't work for me either.

Problem is now solved by configuring Juniper to act as a reversed proxy.

@theothermattm
Copy link

We have also hit this issue. I would agree that @mikepugh's original suggestion of having a hook into the parseAppUrl method would be great to have so we don't have to have our own fork to get angular to work in this (very, very non-ideal) environment.

@pieterwillaert
Copy link

+1 for the hook method

@mikepugh
Copy link
Author

mikepugh commented Sep 2, 2015

My editor did a bunch of formats to other areas of the code so I'm going to re-do my pull request a little bit later today, to make it a bit cleaner.

@demaryhuerto
Copy link

@AbuBkr have you get any new solution?
I think I have the same problem . I've tried the hook solution but I get similar errors when a route changes ("... $digest() iterations reached. Aborting! ..."). Then, hook solution is unsuccessfully for me and I have to configure Juniper to act as a reversed proxy, right?

@AbuBkr
Copy link

AbuBkr commented Nov 5, 2015

@demaryhuerto To configure Juniper to act as a reversed proxy was the solution for us. Unfortunately I can't help you with the details, because I'm not a system/network administrator.

@demaryhuerto
Copy link

@AbuBkr ok, thanks. I'll ask sysadmin to configure Juniper as a reversed proxy.

But someone knows what is exactly the problem and can explain it? I don't understand completely locationProvider functionality but watching @mikepugh solution I suppose he modifies locationObj.$$path to avoid Juniper URL stuff. Can you show an example of URL with stuff?

@AbuBkr
Copy link

AbuBkr commented Nov 6, 2015

If you experience the same problem as I did, simply open the dev tools in Chrome and look what Juniper did to your url's and routing addresses.

@petebacondarwin petebacondarwin modified the milestones: Backlog, Purgatory Jan 25, 2016
@ValentinBlokhin
Copy link

any updates?

@bbiesecker
Copy link

I'm not a sysadmin but I'm confused by the reverse proxy solution. Aren't reverse proxies installed on the server side and so not relevant here? I ask because I'd love a way to address this via a Juniper configuration change but the sysadmins I've asked (and Juniper support) don't know what to do with the suggestion to configure Juniper to reverse proxy.

@enzocalzone
Copy link

enzocalzone commented Sep 24, 2016

Hi, we have the same issue (URL Rewriting) here, and at least we have a support call open and running at juniper.
reording logs and everthing, and now we wait for a sulution.... i hope they solve it and bring up an patch&update....

@lehojogi
Copy link

Any news?

@demaryhuerto
Copy link

Hi, in my case I avoided the problem changing all href with states urls to angular ui-sref with states names.
I had something like this: <a href="/stateUrl">...</a> and I got the issue with Juniper url rewriting.
I've changed to <a ui-sref="stateName">...</a> and it works fine.

@murphy85
Copy link

murphy85 commented Apr 24, 2017

In my case, I had issues with the rewriting of URLs. The gateway did it pretty well with standard HTML href attributes, but not for the Angular AJAX calls. So I wrote an interceptor to do the trick:

app.config( function( $httpProvider ) {
  $httpProvider.interceptors.push( function( $q, $rootScope ) {
    return {
      'request': function( config ) {
        // Convert request URL for Juniper Secure Web Access
        if ( typeof DanaUrl === "function" && !config.url.includes( '.html' ) ) {
          config.url = DanaUrl( config.url );
        }
        return config;
      }
    };
  } );
} );

The URLs will be rewritten, if the Juniper's DanaURL function is available and the URL does not include with ".html". That is because Angular uses URLs to include views into the template, even they are included (e.g. in script tags). (I don't like this part, but for now it's working...)

I hope it's helpful for someone...

@rickbutton
Copy link

@murphy85 This is absolutely perfect for us. We are not using AngularJS, but Durandal/RequireJS, but this solution should just work for any sort of ajax request.

@Narretz
Copy link
Contributor

Narretz commented Sep 28, 2017

Since this is a very specific issue, which manifests in different ways, this will not be handled in core. I'll close this issue but leave it for reference, since it includes info on how to handle it.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests