I've setup the adal and adal-angular v.1.0.10 libraries with my SPA application with mostly great success. I am using webpack, but reference these in my html page in hopes of avoiding global scope issues (though I'd like it to be a dependency). Everything works until the browser attempts to open an iframe to acquire a refresh token, and each iframe opens another iframe inside itself. It logs no errors, and I can't find an explanation as to what I'm doing wrong. So I'm forced to only run the application in a fresh incognito browser. I would appreciate even an explanation as to why this is happening, as we are very married to Azure AD.
relevant sections of index.html
<md-button aria-label="Login" ng-if="!userInfo.isAuthenticated" ng-click="login()">
Login
</md-button>
<script src="build/app.bundle.js" charset="utf-8"></script>
<script src="Scripts/adal.min.js" charset="utf-8"></script>
<script src="Scripts/adal-angular.min.js" charset="utf-8"></script>
my app.js
angular.module('myApp', ['AdalAngular', require('angular-route'), require('angular-animate'), require('angular-sanitize'), 'ngCookies', etc..])
.config(['$routeProvider', '$locationProvider', '$mdThemingProvider', '$httpProvider', 'adalAuthenticationServiceProvider',
function ($routeProvider, $locationProvider, $mdThemingProvider, $httpProvider, adalProvider) {
// azure ad init
adalProvider.init({
instance: 'https://login.microsoftonline.com/',
tenant: TENANT,
clientId: CLIENTID,
cacheLocation: 'localStorage',
anonymousEndpoints: []
},
$httpProvider
);
$routeProvider
.when('/home', {
templateUrl: '/App/Layout/home.html'
})
.when('/admin', {
templateUrl: '/App/Admin/admin.html',
requireADLogin: true
})
etc...
$locationProvider.html5Mode(true).hashPrefix('!');
}]);
After a long series of discussions on GitHub, it was brought to my attention that this was an issue with the AuthenticationContext in adal.js. It keeps opening an iframe while trying to authenticate, causing an infinite loop. I got it to work by exposing the AuthenticationContext.
var AuthenticationContext = require('expose?AuthenticationContext!./../Scripts/adal.js');
require('./../Scripts/adal-angular.js');
This may only work with the versions 0.3.0 version of the library. But it's good enough for now. Hopefully they will alter the library in the future to make it more compatible with modern js applications.
In adal.js in 'getRequestInfo' method, the iframe will 'look' into the parent for the AuthenticationContext. This means that the AuthenticationContext has to be on window scope.
//ES6
import AuthenticationContext from "adal-angular/lib/adal";
window.AuthenticationContext = AuthenticationContext;
...
//ES5
window.AuthenticationContext = require("adal-angular/lib/adal");
...
Related
There is no a clear solution for my below question in stackoverflow, i have searched for many but its not suitable
note: am not using GRUNT
Actually am developing a application using Node and Angular,
while using angular-route to route a page from application its working fine, but reloading browser shows me Cannot GET /secure/home
app.js
var myApp = angular.module('Whizzrd', ['ngRoute']).
config(['$routeProvider', '$locationProvider', '$httpProvider', function($routeProvider, $locationProvider, $httpProvider) {
$routeProvider.
when('/secure/home', {
templateUrl: '/pages/static/home.html',
controller: 'homeController'
});
$locationProvider.html5Mode({enabled: true, requireBase: false});
}]);
moving through home.html through application is working fine, but while reloading the page using browser am getting error as
Cannot GET /secure/home
Am stuck with this for more than 2 days, Help will be appreciated really
I am creating a basic html site that is using Angular JS and Adal Js to connect to Office 365. Below are the issues faced -
The page is not redirecting for login purpose.
Getting "unexpected token" and "[$injector:modulerr]" error in the
browser console.
I have configured application in Azure AD with following details -
SIGN-ON URL : http://localhost: port number/
APP ID URI : https:// tenant name/ThomasO365
REPLY URL : http://localhost: port number/
Exchange and SharePoint permission has been provided to the application.
Application Code
var o365CorsApp = angular.module("o365CorsApp", ['ngRoute', 'AdalAngular']) // loading the ADAL JS Angular module
o365CorsApp.config(['$routeProvider', '$httpProvider', 'adalAuthenticationServiceProvider',
function($routeProvider, $httpProvider, adalProvider) {
$routeProvider
.when('/', {
controller: 'HomeController',
templateUrl: 'index.html',
requireADLogin: true
})
.otherwise({
redirectTo: '/'
});
var adalConfig = {
tenant: '<tentant name>',
clientId: '<client id>',
extraQueryParameter: 'nux=1',
endpoints: {
"https://outlook.office365.com/api/v1.0": "https://outlook.office365.com/"
}
};
adalProvider.init(adalConfig, $httpProvider);
}
]);
o365CorsApp.factory('o365CorsFactory', ['$http',
function($http) {
var factory = {};
factory.getContacts = function() {
return $http.get('https://outlook.office365.com/api/v1.0/me/contacts')
}
return factory;
}
]);
o365CorsApp.controller("HomeController", function($scope, $q, o365CorsFactory) {
o365CorsFactory.getContacts().then(function(response) {
$scope.contacts = response.data.value;
});
});
<html ng-app="o365CorsApp">
<head>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular-route.min.js"></script>
<script type="text/javascript" src="adal-angular.js"></script>
<script type="text/javascript" src="adal.js"></script>
<script type="text/javascript" src="app.js"></script>
</head>
<body ng-controller="HomeController">{{contacts.Email}}
<br/>
<p></p>
</body>
</html>
I am referencing this article. I am using Brackets instead of Visual Studio.
Note-
Tenant and Client ID are correct.
Oauth2AllowImplicitFlow is set to true in manifest file.
I'm going through that article and finding some omissions. Here's some issues I found (don't know if they're causing your error though):
Cut and paste of the code introduces extra spaces in the URL's in app.js. Make sure there are no trailing spaces or spaces between the ? and the rest of the URLs.
The code in app.js has values for tenant and clientId that are obviously for the author, and they never tell you how to replace those with valid values for your app. You can get the correct clientId from the Azure Management Portal. tenant is a bit trickier to get the GUID, but luckily you can just put your domain name there (like contoso.onmicrosoft.com).
Other things to check:
Make sure that you enabled the implicit OAuth2 flow by downloading the manifest, setting oauth2AllowImplicitFlow to true, and reuploading (per the article).
Make sure you are signing into the app using an account that is in the same domain as the one you specify in the tenant property.
Try changing your reply URL to remove index.html. That may be messing with the ADAL libraries token parser.
I have an Angular v1.3 application, which uses Angular ui-router v0.2.13 for all routing. The site works great on all browsers, including IE 10 and IE 11, but not IE 9 (we've decided not to pursue IE8, which I understand isn't supported by v1.3, anyway). Despite my best efforts, IE 9 continually resolves to my $stateProvider's otherwise route (which is set to /*path, a possible culprit, so I disabled that route for testing purposes).
In an attempt to get any other route to resolve, I've tried setting $locationProvider.html5Mode(false), modified the $locationProvider.hashPrefix, changed the <base href="/" /> to various URLs, including <base href="/#!"/>, and I've even included xmlns:ng="http://angularjs.org" in the <html> tag for good measure. No matter what I try, IE 9 continually tries to resolve to my otherwise route, or nothing if that route is disabled. BTW, my home page route URL is set to /.
I've been up to my eyeballs in code with a launch deadline looming, so I'll be the first to admit that I'm potentially overlooking something obvious. Can anyone offer any other tips or tricks to cause ui-router to resolve properly in IE 9?
We use something like the following:
<!DOCTYPE html>
<html lang="fr" xmlns="http://www.w3.org/1999/xhtml" ng-csp xml:lang="fr-CA">
//...
var app = angular.module('YourApp', [...]);
angular.bootstrap(document, ['YourApp'], {strictDi: true})
//...
angular.module('YourApp').config(['$stateProvider', '$urlRouterProvider', '$locationProvider',
function ($stateProvider, $urlRouterProvider, $locationProvider) {
$locationProvider.html5Mode(false);
$locationProvider.hashPrefix('!');
$urlRouterProvider.otherwise('/');
$stateProvider
.state('home', {
url: '/',
cache: false,
controller: 'HomeController as vm'
})
.state('anon', {
url: '/info',
controller: 'AnonController as vm'
})
//etc...
For me, IE9 routes correctly for hash urls, /#/example, but visiting / would resolve to the otherwise route. I worked around this by using a function for otherwise, and checking the url in it.
$urlRouterProvider.otherwise(function($injector){
var state = $injector.get('$state');
var location = $injector.get('$location');
if (!location.url()) {
// handle HTML5 fallback / IE9 when url has no hash
return state.go('home');
}
state.go('404');
});
I am trying to modify the url of my angularjs app . Initially my urls were http:localhost:8080/a/web/app/index.html#/ and http:localhost:8080/a/web/app/index.html#/next
when I inserted the following code to my app.js
var App =angular.module('App', [
'ngCookies',
'ngResource',
'ngRoute',
])
.config(function ($routeProvider,$locationProvider) {
$routeProvider
.when('/', {
templateUrl: '/a/web/app/views/main.html',
controller: 'ctrl_main'
})
.when('/next', {
templateUrl: '/a/web/app/views/next.html',
controller: 'ctrl_next'
});
$locationProvider.html5Mode(true);
});
My new urls became http:localhost:8080 and
http:localhost:8080/next .
My problem is when I tried to reload the page at http:localhost:8080/next , 404 Not Found error is coming
That's expected with html5 mode. The browser, if you ask it to reload, will send a request to the URL it has in its location bar.
So you need to configure the server to actually send back the index.html page for all the bookmarkable URLs you use in the angular application. The whole page will reload, the angular app will restart, the $route service will restart, and will invoke the controller and display the partial configured for the URL.
I know the answer is a bit outdated, but in my case adding <base> attribute to index.html helped, for example:
<base href="/a/web/app/">
Express.js routing of /question/ask
app.get('/question/ask', function (req, res){
console.log('index.js');
console.log('came to question/:id');
res.render('app');
});
The corresponding angularjs routing is:-
when('/ask', {
templateUrl: 'partials/askQuestion',
controller: 'xController'
}).
whereas it should be:-
when('/question/ask', {
templateUrl: 'partials/askQuestion',
controller: 'xController'
}).
I'm working in $locationProvider.html5Mode(true); mode.
Is there anyway i can get the later angularjs routing working. I'm using angularjs 1.1.5 version.
Edit:-
app.get('/*', function (req, res){
console.log('index.js');
console.log('came to question/:id');
res.render('app');
});
has the same problem, the angular route only routes the last /ask for /question/ask.
The issue for me is that I can only do 1 of the following :-
www.example.com/question/:qId
www.example.com/discussion/:aId
because the application will catch only 1 when('/:id', { as it does not include the previous /question/ or /discussion/
Well, if you have the same routes on Express and Angular, if the user types the url directly in the browser you will hit the Express route, but if the user is navigating within the application, then he will hit the Angular route.
Is this what you want ?
What some do is to have a different set of routes on the server for the REST API, and a catch all route to serve the application no matter what the user type as a URL, bringing the user to the home page when a server route is hit. Within the application of course navigation is handled by Angular routes. The problem is that you get no deep linking.
Some other apps have the same routes on both the server and the client, this way they can serve some contents no matter what.
Some will write involved route rewriting to make sure that you both get the application bootstrapping code AND the required URL, thus allowing deep linking.
Cheers
using angular version 1.2.0-rc.3 cures the problem.
change:
var myApp = angular.module('myApp', []);
to
var myApp = angular.module('myApp', ['ngRoute']);
And include:-
script(type='text/javascript', src='js/angular-route.js')