2017-03-10 15 views
0

角度なしのadal.jsライブラリを使用している問題があります。私のログインでAdal.jsがlocalstorageに小道具を設定していません

let config = { 
    tenant: '<tenant id>', 
    clientId: '<client id>', 
    redirectUri: 'http://myapplication.com/index.html', 
    // popUp: true, 
    cacheLocation: 'localStorage' 
} 

:私は、次のオプション(正確な値は無実を保護するために変更されている)で構成された認証コンテキストのインスタンスを、持っている

を(私はVue.js.を使用しています)最初にhttps://login.microsoftonline.com/にリダイレクトされるauthContext.login()を呼び出します。ここでAADにログインします。ログインに成功すると、別のリダイレクトがURLにあるid_tokenパラメータとともに、私が上で設定したURIでアプリケーションに戻ります。ただし、トークンやその他のプロパティはライブラリによってローカルストレージに格納されず、構成の結果であるいくつかのプロパティのみが格納されます。ログインに成功する上で

は、私がのlocalStorageに持っているすべては、限りAADに関しては、私は認証に成功してきたので、

{ 
    adal.access.token.key: "", 
    adal.error: "" 
    adal.error.description: "" 
    adal.expiration.key: "0" 
    adal.idtoken: "" 
    adal.login.error: "" 
    adal.login.request: "http://myapplication.com/#/login" 
    adal.nonce.idtoken: "<a non-empty string>" 
    adal.session.state: "" 
    adal.state.login: "<a non-empty string>" 
    adal.token.keys: "" 
    adal.username: "" 
} 

ですが、ライブラリ自体は、どのようなユーザーの概念を持っていないようですトークンが期限切れになったときにどのトークンが関連付けられているかなどを確認することができます。進める方法についてのアドバイスは、最も高く評価されます。読んでいただきありがとうございます。

答えて

0

JavaScript(ADAL JS)のActive Directory認証ライブラリは、単一ページのアプリケーションで認証を処理するためにAzure ADを使用するのに役立ちます。このライブラリは、AngularJSと連携するために最適化されています。

コード化しない限り、キャッシュにトークンを保存しません。相対コードはadal-angular.jsから確認できます。

saveTokenFromHashメソッドは、トークンをキャッシュに保存し、ページがAngularアプリにリダイレクトされた後に実行されます。

adal.js:

AuthenticationContext.prototype.saveTokenFromHash = function (requestInfo) { 
    this._logstatus('State status:' + requestInfo.stateMatch); 
    this._saveItem(this.CONSTANTS.STORAGE.ERROR, ''); 
    this._saveItem(this.CONSTANTS.STORAGE.ERROR_DESCRIPTION, ''); 

    // Record error 
    if (requestInfo.parameters.hasOwnProperty(this.CONSTANTS.ERROR_DESCRIPTION)) { 
     this._logstatus('Error :' + requestInfo.parameters.error); 
     this._logstatus('Error description:' + requestInfo.parameters[this.CONSTANTS.ERROR_DESCRIPTION]); 
     this._saveItem(this.CONSTANTS.STORAGE.FAILED_RENEW, requestInfo.parameters[this.CONSTANTS.ERROR_DESCRIPTION]); 
     this._saveItem(this.CONSTANTS.STORAGE.ERROR, requestInfo.parameters.error); 
     this._saveItem(this.CONSTANTS.STORAGE.ERROR_DESCRIPTION, requestInfo.parameters[this.CONSTANTS.ERROR_DESCRIPTION]); 

     if (requestInfo.requestType === this.REQUEST_TYPE.LOGIN) { 
      this._loginInProgress = false; 
      this._saveItem(this.CONSTANTS.STORAGE.LOGIN_ERROR, requestInfo.parameters.errorDescription); 
     } else { 
      this._renewActive = false; 
     } 
    } else { 

     // It must verify the state from redirect 
     if (requestInfo.stateMatch) { 
      // record tokens to storage if exists 
      this._logstatus('State is right'); 
      if (requestInfo.parameters.hasOwnProperty(this.CONSTANTS.SESSION_STATE)) { 
       this._saveItem(this.CONSTANTS.STORAGE.SESSION_STATE, requestInfo.parameters[this.CONSTANTS.SESSION_STATE]); 
      } 

      var keys, resource; 

      if (requestInfo.parameters.hasOwnProperty(this.CONSTANTS.ACCESS_TOKEN)) { 
       this._logstatus('Fragment has access token'); 
       // default resource 
       this._renewActive = false; 
       resource = this.config.loginResource; 
       if (!this._hasResource(resource)) { 
        keys = this._getItem(this.CONSTANTS.STORAGE.TOKEN_KEYS) || ''; 
        this._saveItem(this.CONSTANTS.STORAGE.TOKEN_KEYS, keys + resource + this.CONSTANTS.RESOURCE_DELIMETER); 
       } 

       if (requestInfo.requestType === this.REQUEST_TYPE.RENEW_TOKEN) { 
        resource = this._getResourceFromState(requestInfo.stateResponse); 
       } 

       // save token with related resource 
       this._saveItem(this.CONSTANTS.STORAGE.ACCESS_TOKEN_KEY + resource, requestInfo.parameters[this.CONSTANTS.ACCESS_TOKEN]); 
       this._saveItem(this.CONSTANTS.STORAGE.EXPIRATION_KEY + resource, this._expiresIn(requestInfo.parameters[this.CONSTANTS.EXPIRES_IN])); 
      } 

      if (requestInfo.parameters.hasOwnProperty(this.CONSTANTS.ID_TOKEN)) { 
       this._loginInProgress = false; 
       this._user = this._createUser(requestInfo.parameters[this.CONSTANTS.ID_TOKEN]); 
       if (this._user && this._user.profile) { 
        if (this._user.profile.nonce !== this._getItem(this.CONSTANTS.STORAGE.NONCE_IDTOKEN)) { 
         this._user = null; 
         this._saveItem(this.CONSTANTS.STORAGE.LOGIN_ERROR, 'Nonce is not same as ' + this._idTokenNonce); 
        } else { 
         this._saveItem(this.CONSTANTS.STORAGE.IDTOKEN, requestInfo.parameters[this.CONSTANTS.ID_TOKEN]); 

         // Save idtoken as access token for app itself 
         resource = this.config.clientId; 
         if (!this._hasResource(resource)) { 
          keys = this._getItem(this.CONSTANTS.STORAGE.TOKEN_KEYS) || ''; 
          this._saveItem(this.CONSTANTS.STORAGE.TOKEN_KEYS, keys + resource + this.CONSTANTS.RESOURCE_DELIMETER); 
         } 
         this._saveItem(this.CONSTANTS.STORAGE.ACCESS_TOKEN_KEY + resource, requestInfo.parameters[this.CONSTANTS.ID_TOKEN]); 
         this._saveItem(this.CONSTANTS.STORAGE.EXPIRATION_KEY + resource, this._user.profile.exp); 
        } 
       } 
      } 
     } else { 
      this._saveItem(this.CONSTANTS.STORAGE.ERROR, 'Invalid_state'); 
      this._saveItem(this.CONSTANTS.STORAGE.ERROR_DESCRIPTION, 'Invalid_state'); 
      if (requestInfo.requestType === this.REQUEST_TYPE.LOGIN) { 
       this._saveItem(this.CONSTANTS.STORAGE.LOGIN_ERROR, 'State is not same as ' + requestInfo.stateResponse); 
      } 
     } 
    } 
}; 

そして、この関数は以下のようにthis.$getに呼び出されます。

// special function that exposes methods in Angular controller 
// $rootScope, $window, $q, $location, $timeout are injected by Angular 
this.$get = ['$rootScope', '$window', '$q', '$location', '$timeout', function ($rootScope, $window, $q, $location, $timeout) { 

    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); 
      $window.location.hash = ''; 

      if (requestInfo.requestType !== _adal.REQUEST_TYPE.LOGIN) { 
       _adal.callback = $window.parent.AuthenticationContext().callback; 
      } 

      // Return to callback if it is send from iframe 
      if (requestInfo.stateMatch) { 
       if (typeof _adal.callback === 'function') { 
        // Call within the same context without full page redirect keeps the callback 
        if (requestInfo.requestType === _adal.REQUEST_TYPE.RENEW_TOKEN) { 
         // Idtoken or Accestoken can be renewed 
         if (requestInfo.parameters['access_token']) { 
          _adal.callback(_adal._getItem(_adal.CONSTANTS.STORAGE.ERROR_DESCRIPTION), requestInfo.parameters['access_token']); 
          return; 
         } else if (requestInfo.parameters['id_token']) { 
          _adal.callback(_adal._getItem(_adal.CONSTANTS.STORAGE.ERROR_DESCRIPTION), requestInfo.parameters['id_token']); 
          return; 
         } 
        } 
       } else { 
        // normal full login redirect happened on the page 
        updateDataFromCache(_adal.config.loginResource); 
        if (_oauthData.userName) { 
         //IDtoken is added as token for the app 
         $timeout(function() { 
          updateDataFromCache(_adal.config.loginResource); 
          $rootScope.userInfo = _oauthData; 
          // redirect to login requested page 
          var loginStartPage = _adal._getItem(_adal.CONSTANTS.STORAGE.START_PAGE); 
          if (loginStartPage) { 
           $location.path(loginStartPage); 
          } 
         }, 1); 
         $rootScope.$broadcast('adal:loginSuccess'); 
        } else { 
         $rootScope.$broadcast('adal:loginFailure', _adal._getItem(_adal.CONSTANTS.STORAGE.ERROR_DESCRIPTION)); 
        } 
       } 
      } 
     } else { 
      // No callback. App resumes after closing or moving to new page. 
      // Check token and username    
      updateDataFromCache(_adal.config.loginResource); 
      if (!_adal._renewActive && !_oauthData.isAuthenticated && _oauthData.userName) { 
       if (!_adal._getItem(_adal.CONSTANTS.STORAGE.FAILED_RENEW)) { 
        // Idtoken is expired or not present 
        _adal.acquireToken(_adal.config.loginResource, function (error, tokenOut) { 
         if (error) { 
          $rootScope.$broadcast('adal:loginFailure', 'auto renew failure'); 
         } else { 
          if (tokenOut) { 
           _oauthData.isAuthenticated = true; 
          } 
         } 
        }); 
       } 
      } 
     } 

     $timeout(function() { 
      updateDataFromCache(_adal.config.loginResource); 
      $rootScope.userInfo = _oauthData; 
     }, 1); 
    } 
... 

そしてここでは、あなたの参考のためにキャッシュにトークンを救うことができるサンプルコードです:

<html> 
<head> 
<script src="https://unpkg.com/vue"></script> 
<script src="node_modules\adal-angular\lib\adal.js"> </script> 
<script src="config.js"> </script> 
</head> 

<body> 
<div> 
    <button onclick="login()" >Login</button> 
</div> 
    <script> 

var authContext=new AuthenticationContext(config); 
function login(){ 
authContext.login(); 

} 

function init(configOptions){ 
    if (configOptions) { 
        // redirect and logout_redirect are set to current location by default 
        var existingHash = window.location.hash; 
        var pathDefault = window.location.href; 
        if (existingHash) { 
         pathDefault = pathDefault.replace(existingHash, ''); 
        } 
        configOptions.redirectUri = configOptions.redirectUri || pathDefault; 
        configOptions.postLogoutRedirectUri = configOptions.postLogoutRedirectUri || pathDefault; 


        // create instance with given config     
       } else { 
        throw new Error('You must set configOptions, when calling init'); 
       } 

       // loginresource is used to set authenticated status 
       updateDataFromCache(authContext.config.loginResource); 

} 

var _oauthData = { isAuthenticated: false, userName: '', loginError: '', profile: '' }; 
    var updateDataFromCache = function (resource) { 
       // only cache lookup here to not interrupt with events 
       var token = authContext.getCachedToken(resource); 
       _oauthData.isAuthenticated = token !== null && token.length > 0; 
       var user = authContext.getCachedUser() || { userName: '' }; 
       _oauthData.userName = user.userName; 
       _oauthData.profile = user.profile; 
       _oauthData.loginError = authContext.getLoginError(); 
      }; 

init(config); 

function saveTokenFromHash(){ 
    var hash = window.location.hash; 
    var requestInfo = authContext.getRequestInfo(hash); 
     if (authContext.isCallback(hash)) { 
         // callback can come from login or iframe request 

         var requestInfo = authContext.getRequestInfo(hash); 
         authContext.saveTokenFromHash(requestInfo); 
         window.location.hash = ''; 

         if (requestInfo.requestType !== authContext.REQUEST_TYPE.LOGIN) { 
          authContext.callback = window.parent.AuthenticationContext().callback; 
         }     
        } 
} 

saveTokenFromHash(); 
    </script> 

</body> 
</html> 
+0

ご返信いただきありがとうございます。 'handleWindowCallback'がすでに私のために両方を呼び出すときに' getRequestInfo'と 'saveTokenFromHash'を手動で呼び出す必要があるのはなぜですか? –

+0

あなたは 'handleWindowCallBack'を自分で呼び出すことを意味しましたか?そうであれば。それはまた機能するはずです。あなたが開発していたコードを分かち合いましょうか? –

関連する問題