Coder Social home page Coder Social logo

azuread / azure-activedirectory-library-for-js Goto Github PK

View Code? Open in Web Editor NEW
625.0 127.0 375.0 2.08 MB

The code for ADAL.js and ADAL Angular has been moved to the MSAL.js repo. Please open any issues or PRs at the link below.

Home Page: https://github.com/AzureAD/microsoft-authentication-library-for-js/tree/dev/maintenance/adal-angular

License: Apache License 2.0

JavaScript 99.01% HTML 0.99%

azure-activedirectory-library-for-js's Introduction


This library, ADAL for JavaScript, will no longer receive new feature improvements, and this repository has been archived. Instead, use the new library MSAL.js (the code for ADAL.js and ADAL Angular has also been moved to the MSAL.js repository).

  • If you are starting a new project, you can get started with the MSAL.js docs for details about the scenarios, usage, and relevant concepts.
  • If your application is using the previous ADAL JavaScript library, you can follow this migration guide to update to MSAL.js.
  • Existing applications relying on ADAL JavaScript will continue to work.

Active Directory Authentication Library (ADAL) for JavaScript

Getting Started Docs Samples Support Feedback

Active Directory Authentication Library for JavaScript (ADAL JS) helps you to use Azure AD for handling authentication in your single page applications. This library works with both plain JS as well as AngularJS applications.

Build Statusnpmnpm

Installation

You have multiple ways of getting ADAL JS:

Via NPM:

npm install adal-angular

Note: Currently there is one NPM package providing both the plain JS library (adal.js) and the AngularJS wrapper (adal-angular.js).

Via CDN:

<!-- Latest compiled and minified JavaScript -->
<script src="https://secure.aadcdn.microsoftonline-p.com/lib/1.0.18/js/adal.min.js"></script>
<script src="https://secure.aadcdn.microsoftonline-p.com/lib/1.0.18/js/adal-angular.min.js"></script>

CDN will be updated to latest version 1.0.18.

Via Bower:

$ bower install adal-angular

The adal.js source is here. The adal-angular.js source is here.

Usage

In JavaScript

You can use ADAL JS as follows in a plain JavaScript application without any frameworks.

1- Include a reference to adal.js in your main app page before your application scripts.

<script src="App/Scripts/adal.js"></script>
<script src="App/Scripts/app.js"></script>

2- Initialize ADAL with the AAD app coordinates at app config time. The minimum required config to initialize ADAL is:

window.config = {
   clientId: 'g075edef-0efa-453b-997b-de1337c29185'
};
var authContext = new AuthenticationContext(config);

3- You can trigger the login and logout using the authContext

$signInButton.click(function () {
    authContext.login();
});

$signOutButton.click(function () {
    authContext.logOut();
});

Refer this sample for a full implementation example.

In AngularJS

ADAL also provides an AngularJS wrapper as adal-angular.js. Below you can find a quick reference for the most common operations you need to perform in AngularJS applications to use ADAL JS.

1- Include references to angular.js libraries, adal.js, adal-angular.js in your main app page. The ADAL should be included after Angular, but before your application scripts as shown below.

<script src="/Scripts/angular.min.js"></script>
<script src="/Scripts/angular-route.min.js"></script>
<script src="/Scripts/adal.js"></script>
<script src="/Scripts/adal-angular.js"></script>
<script src="App/Scripts/app.js"></script>

2- Include a reference to the ADAL module in your app module.

var app = angular.module('demoApp', ['ngRoute', 'AdalAngular']);

3- When HTML5 mode is configured, ensure the $locationProvider hashPrefix is set

// using '!' as the hashPrefix but can be a character of your choosing
app.config(['$locationProvider', function($locationProvider) {
	$locationProvider.html5Mode(true).hashPrefix('!');
}]);

Without the hashPrefix set, the AAD login will loop indefinitely as the callback URL from AAD (in the form of, {yourBaseUrl}/#{AADTokenAndState}) will be rewritten to remove the '#' causing the token parsing to fail and login sequence to occur again.

4- Initialize ADAL with the AAD app coordinates at app config time. The minimum required config to initialize ADAL is:

adalAuthenticationServiceProvider.init({
        // clientId is the identifier assigned to your app by Azure Active Directory.
        clientId: "e9a5a8b6-8af7-4719-9821-0deef255f68e"
    },
    $httpProvider   // pass http provider to inject request interceptor to attach tokens
);

5- Define which routes you want to secure via ADAL - by adding requireADLogin: true to their definition

$routeProvider.
    when("/todoList", {
        controller: "todoListController",
        templateUrl: "/App/Views/todoList.html",
        requireADLogin: true
    });

Any service invocation code you might have will remain unchanged. ADAL's interceptor will automatically add tokens for every outgoing call.

Anonymous endpoints, introduced in version 1.0.10, is an array of values that will be ignored by the ADAL route/state change handlers. ADAL will not attach a token to outgoing requests that have these keywords or URI. Routes that do not specify the requireADLogin=true property are added to the anonymousEndpoints array automatically.

Optional

If you so choose, in addition (or substitution) to route level protection you can add explicit login/logout UX elements. Furthermore, you can access properties of the currently signed in user directly form JavaScript (via userInfo and userInfo.profile). The userInfo.profile property provides access to the claims in the ID token received from AAD. The claims can be used by the application for validation, to identify the subject's directory tenant, and so on. The complete list of claims with a brief description of each value is here, Claims in Azure AD Security Tokens:

<!DOCTYPE html>
<html>
<head>
    <title>Angular Adal Sample</title>
</head>
<body ng-app="adalDemo" ng-controller="homeController" ng-init="hmCtl.init()">
    <a href="#">Home</a>
    <a href="#/todoList">ToDo List</a>


    <!--These links are added to manage login/logout-->
    <div data-ng-model="userInfo">
        <span data-ng-hide="!userInfo.isAuthenticated">Welcome {{userInfo.userName}} </span>
        <button data-ng-hide="!userInfo.isAuthenticated" data-ng-click="logout()">Logout</button>
        <button data-ng-hide="userInfo.isAuthenticated" data-ng-click="login()">Login</button>

        <div>
            {{userInfo.loginError}}
        </div>
        <div>
            {{testMessage}}
        </div>
    </div>
    <div ng-view>
        Your view will appear here.
    </div>

    <script src="/Scripts/angular.min.js"></script>
    <script src="/Scripts/angular-route.min.js"></script>
    <script src="/Scripts/adal.js"></script>
    <script src="/Scripts/adal-angular.js"></script>
    <script src="App/Scripts/app.js"></script>
    <script src="App/Scripts/homeController.js"></script>
    <script src="App/Scripts/todoDetailController.js"></script>
    <script src="App/Scripts/todoListController.js"></script>
    <script src="App/Scripts/todoService.js"></script>
</body>
</html>

6- You have full control on how to trigger sign in, sign out and how to deal with errors:

'use strict';
app.controller('homeController', ['$scope', '$location', 'adalAuthenticationService', function ($scope, $location, adalAuthenticationService) {
    // this is referencing adal module to do login

    //userInfo is defined at the $rootscope with adalAngular module
    $scope.testMessage = "";
    $scope.init = function () {
        $scope.testMessage = "";
    };

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

    $scope.login = function () {
        adalAuthenticationService.login();
    };

    // optional
    $scope.$on("adal:loginSuccess", function () {
        $scope.testMessage = "loginSuccess";
    });

    // optional
    $scope.$on("adal:loginFailure", function () {
        $scope.testMessage = "loginFailure";
        $location.path("/login");
    });

    // optional
    $scope.$on("adal:notAuthorized", function (event, rejection, forResource) {
        $scope.testMessage = "It is not Authorized for resource:" + forResource;
    });

}]);

Multi-Tenant

By default, you have multi-tenant support. ADAL will set tenant to 'common', if it is not specified in the config. This allows any Microsoft account to authenticate to your application. If you are not interested in multi-tenant behavior, you will need to set the tenant property as shown below.

window.config = {
    tenant: "52d4b072-9470-49fb-8721-bc3a1c9912a1", // Optional by default, it sends common
    clientId: 'g075edef-0efa-453b-997b-de1337c29185'
};

If you allow multi-tenant authentication, and you do not wish to allow all Microsoft account users to use your application, you must provide your own method of filtering the token issuers to only those tenants who are allowed to login.

Cache Location

Default storage location is sessionStorage. You can specify localStorage in the config as well.

window.config = {
    clientId: 'g075edef-0efa-453b-997b-de1337c29185',
    cacheLocation: 'localStorage' // optional cache location. Default is sessionStorage
};

Logging

Log levels are mapped as:

0: Error
1: Warning
2: Info
3: Verbose

You can add the code below to app.js to turn on logging. Implement the log method depending on how you want to redirect logs.

Logging = {
    level: 3,
    log: function (message) {
        console.log(message);
    }
};

Security

Tokens are accessible from JavaScript since ADAL.JS is using HTML5 storage. Default storage option is sessionStorage, which keeps the tokens per session. You should prompt users to login again for important operations on your app. You should protect your site for XSS. Please check the article here: https://www.owasp.org/index.php/XSS_(Cross_Site_Scripting)_Prevention_Cheat_Sheet

CORS API usage and IE

ADAL will get access token using Iframe for the given CORS API endpoints in the config. The Iframe needs to access cookies for the same domain that you did the initial sign in. Since IE does not allow to access cookies in an IFrame for localhost, your URL needs to be a fully qualified domain i.e http://yoursite.azurewebsites.com. Chrome does not have this restriction.

To make CORS API call, you need to specify endpoints in the config for your CORS API as shown here.

// endpoint to resource mapping(optional)
var endpoints = {
    "https://yourhost/api": "b6a68585-5287-45b2-ba82-383ba1f60932",
};
adalAuthenticationServiceProvider.init(
    {
        tenant: "52d4b072-9470-49fb-8721-bc3a1c9912a1", // Optional by default, it sends common
        clientId: "e9a5a8b6-8af7-4719-9821-0deef255f68e", // Required
        endpoints: endpoints  // If you need to send CORS API requests.
    },
    $httpProvider   // pass http provider to inject request interceptor to attach tokens
);

Your service will be as shown below to make the call from JS. In your API project, you need to enable CORS API requests to receive pre-flight requests. You can check this sample for CORS API.

'use strict';
app.factory('contactService', ['$http', function ($http) {
    var serviceFactory = {};

    var _getItems = function () {
        $http.defaults.useXDomain = true;
        delete $http.defaults.headers.common['X-Requested-With'];
        return $http.get('http://adaljscors.azurewebsites.net/api/contacts');
    };

    serviceFactory.getItems = _getItems;

    return serviceFactory;
}]);

You can read extended blogs about CORS API below.

Andrew's blog related to CORS and Office365 usage

http://www.andrewconnell.com/blog/adal-js-cors-with-o365-apis-files-sharepoint

Vittorio's blog

http://www.cloudidentity.com/blog/2015/02/19/introducing-adal-js-v1/ http://www.cloudidentity.com/blog/2014/10/28/adal-javascript-and-angularjs-deep-dive/

Trusted Site settings in IE

If you put your site in the trusted site list, cookies are not accessible for iFrame requests. You need to remove protected mode for Internet zone or add the authority URL for the login to the trusted sites as well.

Known issues on Edge

Certain issues have been reported when using ADAL.js with the Microsoft Edge version 40.15063.0.0. Please take a look at this page for details and workarounds before filing a new issue experienced with Edge.

Build and run tests

Run tests

npm install
bower install
npm test

// angular tests
karma start

To use Karma as test runner, you need to install the karma command line.

npm install -g karma
npm install -g karma-cli

Reference doc generation

Install grunt and run the command

grunt doc

Contribution

We encourage and welcome contributions to the library. Please read the contributing guide before starting.

Versions

This is a GA released version. Current version - 1.0.18
Minimum recommended version - 1.0.18
You can find the changes for each version in the change log.

Samples and Documentation

We provide a full suite of sample applications and documentation on GitHub to help you get started with learning the Azure Identity system. This includes tutorials for native clients such as Windows, Windows Phone, iOS, OSX, Android, and Linux; and a detailed guide to registering your app with Azure Active Directory. We also provide full walkthroughs for authentication flows such as OAuth2, OpenID Connect, Graph API, and other awesome features.

Community Help and Support

We leverage Stack Overflow to work with the community on supporting Azure Active Directory and its SDKs, including this one! We highly recommend you ask your questions on Stack Overflow (we're all on there!) Also browser existing issues to see if someone has had your question before.

We recommend you use the "adal" tag so we can see it! Here is the latest Q&A on Stack Overflow for ADAL: http://stackoverflow.com/questions/tagged/adal

Submit Feedback

We'd like your thoughts on this library. Please complete this short survey.

Security Reporting

If you find a security issue with our libraries or services please report it to the Microsoft Security Response Center (MSRC) with as much detail as possible. Your submission may be eligible for a bounty through the Microsoft Bounty program. Please do not post security issues to GitHub Issues or any other public site. We will contact you shortly upon receiving the information. We encourage you to get notifications of when security incidents occur by visiting this page and subscribing to Security Advisory Alerts.

License

Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");

We value and adhere to the Microsoft Open Source Code of Conduct

This project has adopted the Microsoft Open Source Code of Conduct. For more information see the Code of Conduct FAQ or contact [email protected] with any additional questions or comments.

azure-activedirectory-library-for-js's People

Contributors

aiwangmicrosoft avatar brandwe avatar brianyingling avatar dhodgin avatar dstrockis avatar ela-valorem avatar jasonnutter avatar lovemaths avatar manospasj avatar mockorp avatar mottykohn avatar navyasric avatar omercs avatar rcasto avatar rdmchenry avatar richardp-au avatar rohitnarula7176 avatar rohitpagariya avatar salvoravida avatar sarmut avatar shannoncantech avatar snobu avatar somkape avatar tugupta avatar tushargupta51 avatar vadimm avatar valera-rozuvan avatar vibronet avatar weijjia avatar zanawar avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

azure-activedirectory-library-for-js's Issues

Better Cordova inappbrowser support

Hi there,
When developing with the adaljs and angular library on a cordova project the login and logout functions could use some better support.
For the login function there is a displaycall available where I use the inappbrowser plugin so I can close the login page after login is successful. The logout function doesn't have this config option yet. I've worked around that by using the following code:

/**
* Logout user will redirect page to logout endpoint. 
* After logout, it will redirect to post_logout page if provided.
*/
AuthenticationContext.prototype.logOut = function () {
    this.clearCache();
    var tenant = 'common';
    var logout = '';
    this._user = null;
    if (this.config.tenant) {
        tenant = this.config.tenant;
    }

    if (this.config.instance) {
        this.instance = this.config.instance;
    }

    if (this.config.postLogoutRedirectUri) {
        logout = 'post_logout_redirect_uri=' + encodeURIComponent(this.config.postLogoutRedirectUri);
    }

    var urlNavigate = this.instance + tenant + '/oauth2/logout?' + logout;

    this._logstatus('Logout navigate to: ' + urlNavigate);
    //this.promptUser(urlNavigate);

    // Use a hidden inappbrowser view to navigate to the logout url
    var ref = window.open(urlNavigate, '_blank', 'hidden=yes');
    ref.addEventListener('loadstop', ref.Close());

};

I've hidden the frame because it isn't possible to navigate back to the app after the logout redirect has taken place.

Could you build a config option to be able to handle this better or more flexible?

The returned id_token is not parseable

I have followed your instructions but authentication fails and prints the following to the console:

The returned id_token is not parseable.
Route change event for:/
Start login at:https://localhost:44308/#
Navigate url:https://login.windows.net/myapp.onmicrosoft.com/oauth2/authorize
Navigate to:https://login.windows.net/myapp.onmicrosoft.com/oauth2/authorize
TypeError: Cannot read property 'data' of undefined

Then my web app redirects to its home page, authenication fails again and redirects again to homepage... infinitely...

$routeParams lost during authentication

In angular, if a route contains a $routeParam (example route: '/orders/:orderId') then on redirection, both on initial rerouting to azure login, as well as when a token expires, on returning to the route, the value of the $routeParam (in this example, orderId) is lost.

Instead of being routed back to '/orders/1' for example, user lands back on '/orders/:orderId'.

adal:loginSuccess event does'nt fire until trying to move away to another page.

I'm pretty inexperienced with AngularJS so if I've done something wromg please forgive me; given this code snippet:

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

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

// optional
$scope.$on("adal:loginSuccess", function () {
adalUserSvc.setUser();
});

// optional
$scope.$on("adal:loginFailure", function () {
adalUserSvc.loginFailure();
});

// optional
$scope.$on("adal:notAuthorized", function (event, rejection, forResource) {
adalUserSvc.notAuthorized(event, rejection, forResource);
});

$scope.$on("adalUserSvc:signedInChanged", function (event, args) {
$scope.signedIn = adalUserSvc.info.signedIn;
$scope.username = adalUserSvc.info.username;
});

I find that the loginSuccess event does fire until I try to move away from this controller / view. I fell like I should have 'then' command after the login function call to make it update or something. Have I missed something simple ?

ADAL.JS crashes when extracting ID token

I know about the issue with reusing Windows Account in WAAD, but I think a lot of people will stumble upon the same issue.

One of my azure subscriptions is related to my Windows Account (former LiveID) when trying to authenticate that user, ADAL.JS throws an error when it tries to extract the ID token within _extractIdToken

broadcast userInfo (_oauthInfo) instead of setting it on rootscope

setting userInfo on the rootscope is a kind of misguiding. Services should not make changes to scopes without explicitly being asked for.

It would be a better option to broadcast once the _oauthInfo has changed, devs who are interested in accessing user information can register to the event and populate this to the required scope.

Endpoint Only Requests Do Not Issue Refresh Token

Authentication works well when navigating around Angular routes (using requireADLogin) but when attempting to access an endpoint, I'm not issued a refresh token if it has already expired. The request is submitted without an idtoken in the header and I receive a 401 unauthorized response. I tried adding the endpoints flag in the provider, but still no authorization.

Any reason why refresh tokens are properly issued with Angular routes (requireADLogin) but not when sitting idle for awhile and then attempting to hit an endpoint that requires said token?

Thanks.

login redirect is not keeping the started page for non-angular usage

In our vanilla adal.js sample, after the login flow completes, adal does not redirect the user to the same view/page/place in the app that the login request originated. I’m not sure if this is a requirement for GA, but it seems like something that most developers will want.

Currently, adal stores the pre-request location of the window in browser storage:
this._saveItem(this.CONSTANTS.STORAGE.LOGIN_REQUEST, window.location);

But it doesn’t send the user back there in the handleWindowCallback function. Instead, it just replaces the hash with the empty string:
window.location.hash = '';

Since the handleWindowCallback function isn’t used in adal-angular.js, it seems like it would be a pretty quick fix to make this work. As it stands, our sample handles the redirect like this, which is a bit more difficult:
// Check For & Handle Redirect From AAD After Login
var isCallback = authContext.isCallback(window.location.hash);
authContext.handleWindowCallback();
$errorMessage.html(authContext.getLoginError());

if (isCallback && !authContext.getLoginError()) {
    window.location = authContext._getItem(authContext.CONSTANTS.STORAGE.LOGIN_REQUEST);
}

Interceptor needs to specify a reason when rejecting the request

Tokeninterceptor is redirecting user to login page, when user hits the protected route. All incoming requests are rejected. Hottowel template is expecting a reason in the reject call.
Update interceptor code to:

if (authService.loginInProgress()) {
     return $q.reject('login in progress');

Infinite loop while refreshing the token

Hello,

I'm implementing the adal js library for a mobile project project with cordova. Everething works fine but when the token expires and the application starts refreshing in the iframe it will end up in an infinite loop. Two iframes are added one with the names adalRenewFrame and undefined. My configuration looks like this.

var localUri = window.location.href;
var redirectUri = "http://redirect_uri";

var config = {
    tenant: "xxxx",
    clientId: 'xxxx',
    endpoints: {
        "/api": "xxxx",
    },
    displayCall: function(url){
        var ref = window.open(url, '_blank', 'location=no');
        ref.addEventListener('loadstart', function(event) {
            if((event.url).indexOf(redirectUri) === 0) {
                ref.close();
                window.location.href = event.url.replace(redirectUri + "/", localUri);
                window.location.reload();
            } 
        });
    },
    cacheLocation: "localStorage"
};

if(localUri.indexOf("http://") !== 0 && localUri.indexOf("https://") !== 0){
    config.redirectUri = redirectUri;
}

adalAuthenticationServiceProvider.init(config, $httpProvider);

adal-js Mobile Service

Don't know if this repo is the right place, but at least I ran in the issue when using the latest adal-js build. Long story short, is it possible to use adal-js in conjunction with Azure Mobile Services?

Digest iterations infinite loop in HTML5 mode

If I add the library to a project that uses html5mode and enter a URL with a # on the end (e.g. http://localhost:9000# or http://localhost:9000/# ) the developer console is battered with errors:

Uncaught Error: [$rootScope:infdig] 10 $digest() iterations reached. Aborting!
Watchers fired in the last 5 iterations: []

If I turn off html5mode or remove the adalAuthenticationServiceProvider.init call in app.js then everything is fine. I've had a quick look through but I cannot see what's causing it. I've added a sample at https://github.com/ruddles/ADALIssue which you can clone, npm install && bower install, grunt serve and then test the app by opening the developer console, and add a # to the end of the URL.

I've tested this in both chrome and firefox on a mac.

Frame request is adding a frame with undefined name

there are always two iframes loaded on the page. One with the correct id and one with id undefined.

<iframe id="adalIdTokenFrame"................. <iframe id="undefined"..............................

Fix: Loadframe method is not passing frame name

TypeScript declaration

It would be nice if you could provide TypeScript declaration files for adal.js and adal-angular.js

sample update

For the sample - in case of error on login, don’t redirect again to the STS - add view for showing login errors (and offer button for retrying the login)

Support for multi-tenancy

This is great stuff! When do you guys plan to add support for multi-tenant applications. Currently it only works when I login from the same tenant. For example, my app is registered in contoso.com, if I login with the user from contoso.com - all is good. But when I try to login from contoso-partner.com it does not work, even though I enabled application to be multi-tenant (in azure portal). Here is the error:

Additional technical information:
Correlation ID: 6fca5212-fb8f-4d08-8572-49fa4bcbf75d
Timestamp: 2014-11-06 20:56:16Z
AADSTS50008: SAML token is invalid.

Also, MFA (multi factor auth). I expect it will be handled by the login.windows.net itself (currently is).

Thanks,
Serg

Refused to display in a frame because it set 'X-Frame-Options' to 'deny'.

Hi,
I have implemented the adal library in Visual Studio Hybrid App (Cordova)
When I try to run in in the ripple emulator I got

"Refused to display 'https://login.microsoftonline.com/login.srf?wa=wsignin1.0&wtrealm=....'
in a frame because it set 'X-Frame-Options' to 'deny'."

It is working fine on a native device.

Is there a way to allow login.microsoftonline.com to accept rendering in an iFrame?
Also, the page normally redirect to an sts adfs server. Maybe there is a way to redirect directly to the sts uri?

Thanks

Separate Angular services/implementation from adal.js

I would understand that you want this library to be a single file that developers can easily use and be ready to go with Angular but having them coupled like this seems more confusing to me.

I expect adal.js library to only be concerned with managing authentication and each Spa framework to provide their own file which levelerages apis from adal.js. You could easily move the angular specific services to angular.adal.js and start a convention that each framework: Ember, React, Backbone, etc have [name].adal.js as the filename.

Also, this repo would be specifically for iterating on the ADAL library, and use a separate repo (such as: SinglePageApp-DotNet) which demonstrates ADAL used with Angular and only that repo would have the angular specific information. This would allow people to open issues only concerned with adal.js here, and other issues with the angular implementation somewhere else instead of having people unsure where to provide feedback.

Add support for authentication using pop-up method instead of full redirect.

I think adaljs should add support for authentication using a pop-up instead of a full redirect.

There are two major benefits to using this technique:

  • Much easier for developers!
  • Works with SPA frameworks.

Much easier for developers!

With the pop-up method more of the conceptual complexity can be abstracted into the adaljs library and the developer can have much easier time using the library. Adaljs currently does a full redirect and then in order to work with angularjs router there is a bunch of code like:

$rootScope.$on('$locationChangeStart', locationChangeHandler);
....
var locationChangeHandler = function () {
                var hash = $window.location.hash;

                if (_adal.isCallback(hash)) {
                    // callback can come from login or iframe request

                    var requestInfo = _adal.getRequestInfo(hash);
                    _adal.saveTokenFromHash(requestInfo);
....

This is watching the url and if it has a parameter of 'id_token' then it saves the tokens etc.. This logic is currently exposed to the framework such as AngularJS and would have to re-written for every framework which is the largest barrier to using adaljs. Now imagine you have to rewrite all of this for Ember, React, Knockout, etc... way too much overhead especially when people have to try to integrate into existing projects which may already have complex router configurations.

I hope in the future adaljs is modeled after other major JS OAuth SDK's such as Facebook or Google.
FB: http://connect.facebook.net/en_US/all.js
Google: https://apis.google.com/js/client.js?onload=googleApiLoaded

With pop-up style of authentication you can get rid of all url watching stuff in angular and have a simple call like:

FB.login(function(fbResponse) {
  if (fbResponse.authResponse) {
    Ember.run(function() {
      resolve({ accessToken: fbResponse.authResponse.accessToken });
    });
  } else {
    reject();
  }
});

This encapsulates the entire login process in one asynchronous call! Yes, with pop-ups there is a the possibility that pop-ups maybe disabled, but the benefits out weigh this greatly. Especially if this is an option the developer can choose. Just realize what that means for ease of use! FB/Google SDK's handle setting up the window and watching that frame's url for change and closing then it has redirected. I assume this is extremely similar to how the Windows 8 WebAuthenticationBroker works.

Works with SPA frameworks.

The first point was more about how the pop-up can greatly simply needed code and reduce learning for developers, this second point is more about just explaining why the full redirect breaks other SPA frameworks and the pop-up solves the issue. Most SPA frameworks have a router which watches for changes in the hash which correlate to a route as seen in AngularJS. With the full redirect happens the router will attempt to navigate to route 'id_token' which won't exist and thus cause an error. It seems that AAD is always putting the id_token in the hash portion of the url such as adal.html#id_token=eyJ0eXAiOiJKV1Qi... when I would expect it to be able to control this and put it in the search portion of the url such as adal.html?id_token=eyJ0eXAiOiJKV1Qi.... Even if I change the line:

str.push('redirect_uri=' + encodeURIComponent(obj.redirectUri) + '%3F');

I assumed it would append the id_token=asdfasdf to the ? but it still overrides and uses hash. I assume this is because the hash portion of the url can be changed without page refresh, but perhaps someone can clarify if this is infact customizable by the adaljs request to AAD.

expired idToken + navigation issues 2 renew commands

Description:
If a user is logged in, but the idToken is expired, then they navigate to a page with requireADLogin, 2 refresh operations are issued: one in an iFrame and another via a main page redirect.

in $locationChangeStart, if the location is not a callback, it updates the auth cache. If the idToken is expired, getCachedToken will return null. This causes the else clause in the event to trigger. when acquireToken is called, the idToken will start being refreshed via an iFrame.

Then the $routeChangeStart event triggers. At this point, authData.isAuthenticated is false due to the cache refresh in locationChangeStart. If the page they are navigating to has requireADLogin, it will call adal.login(), trying to log the user in on the main page as well.

I believe if an iFrame refresh is happening, the main page should not redirect.

Changing this:
if (!_oauthData.isAuthenticated) {

To:
if (!_oauthData.isAuthenticated && !_adal._renewActive) {

in the routeChangeHandler in adal-angular.js should resolve this issue.

IE10 error "redefining a constant"

IE10 has an issue when rewriting constant like window.
This happens in adal.js en adal-anguler.js for testing purpose:

//if (typeof module !== 'undefined' && module.exports) {
// var window, localStorage, angular, document, sessionStorage; => this line
// module.exports.inject = function (windowInj, storageInj, documentInj, MathInj, angularInj, conf) {
// window = windowInj;
// localStorage = storageInj;
// sessionStorage = storageInj;
// document = documentInj;
// Math = MathInj; // jshint ignore:line
// angular = angularInj;
// return new AuthenticationContext(conf);
// };
//}

For now I'm commenting the lines

Strict DI for adalAuthenticationService

I am using ng-strict-di in my angular app. Upon startup, I get the following error with the library:

adalAuthenticationService is not using explicit annotation and cannot be invoked in strict mode

I thought it may be just a case of wrapping the function block inside an array, but other errors were caused by doing this (as so):

AdalModule.provider('adalAuthenticationService', [function () {
    return new AdalService();
}]);

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.