【问题标题】:Angular Interceptor of Auth 0 and Azure AD are interfering in each other's authentication processAuth 0 的 Angular Interceptor 和 Azure AD 干扰彼此的身份验证过程
【发布时间】:2017-03-27 09:10:23
【问题描述】:

我正在开发一个包含 Auth 0 和 Azure AD 的应用程序,用于不同域的用户身份验证。例如。 gmail.com 和 outlook.com 的 Auth0 和其他域的 Azure AD。我想让他们分开。为此,我正在显示一个选项页面,用户可以在其中选择登录选项(Auth0 或 AzureAd)。

我正在使用 Angularjs 框架和 .Net

如果仅使用一个登录选项(即 Auth0 或 Azure Ad)专门实施,则 Auth0 和 Azure AD 的登录过程都可以顺利进行。但是一起使用时会乱码。问题始于状态路由和从 ClaimsPrincipal(.NET) 访问登录用户的电子邮件。一个(Auth0/AzureAd)似乎覆盖了 ClaimsPrincipal。例如。如果我在 Azure AD 中使用 a@b.com 登录并发布注销,我会尝试通过 Auth0 使用电子邮件 c@d.com 再次登录,ClaimsPrincipal仍然返回 Azure AD 用户的电子邮件,即 a@b 而不是 c@d。

我确信这是因为有两个拦截器拦截请求,每个拦截器一个。 ProtectedResourceInterceptor:Azure ADjwtInterceptor: Auth0

我尝试创建一个服务提供程序,该服务提供程序在选择登录选项 (Auth0/AzureAD) 时动态尝试从 $httpProvider 推送或弹出拦截器。

 app.config(['$provide', '$httpProvider', function ($provide, $httpProvider) {
    $provide.decorator('$interceptorManager', ['$delegate', '$injector', function ($delegate, $injector) {
        $delegate.addInterceptor = function (loginOptionValue) {                            
            if (loginOptionValue) {
                switch (loginOptionValue) {
                    case 'Auth 0':
                        var index = $httpProvider.interceptors.indexOf('ProtectedResourceInterceptor');
                        if (index != -1) $httpProvider.interceptors.splice(index, 1);
                        $httpProvider.interceptors.push('jwtInterceptor');
                        break;
                    case 'Azure Ad':
                        var index = $httpProvider.interceptors.indexOf('jwtInterceptor');
                        if (index != -1) $httpProvider.interceptors.splice(index, 1);
                        $httpProvider.interceptors.push('ProtectedResourceInterceptor');
                        break;
                }
            }
            console.log('Adding Interceptio: '+$httpProvider.interceptors.length);
        }
        $delegate.removeInterceptors = function (loginOptionValue) {
            var index = -1;
           //var index = $httpProvider.interceptors.indexOf('ProtectedResourceInterceptor');
           //if (index != -1) $httpProvider.interceptors.splice(index, 1);

           index = $httpProvider.interceptors.indexOf('jwtInterceptor');
           if (index != -1) $httpProvider.interceptors.splice(index, 1);
        }
        $delegate.printInterceptors = function () {
            for (var i = 0 ; i < $httpProvider.interceptors.length ; i++)
                console.log($httpProvider.interceptors[i]);
        }
        return $delegate;
    }]);
}]);

但这似乎对我不起作用。在同时部署 Auth 0 和 Azure AD 时,我应该如何实现不间断的登录过程

【问题讨论】:

  • 有没有我们可以同时实现的?
  • 好的,现在,在阅读了一篇文章后,我可以从 Auth 0 访问我的 Azure Active Directory。我可以成功登录到我的应用程序。但我有一个问题。截至目前,Auth 0 对我添加到其目录的每个用户收费。 Auth 0 是否会对我添加到 Azure Active Directory 的每个用户收费?我很困惑,因为我没有将用户添加到 Auth 0,我只是将它用于登录。在另一端,正在将用户添加到 Azure AD。

标签: asp.net angularjs auth0 azure-active-directory


【解决方案1】:

放弃了从 Auth0 访问 Azure Ad 的想法。我回滚到之前的步骤,在这两个步骤(Auth0 或 Azure AD)之间进行选择。

对于任何正在寻找答案的人,好吧,我尝试编辑拦截器。我不知道我是否应该编辑拦截器,但我做了很少,它对我有用。

就这样吧。我创建了一个angular value 并将其命名为loginOption,并在module creation 的开头使用属性valueloginOption 可以保存 Auth 0Azure AD 作为值。

app.value('loginOption', {value: null});

loginOption.value 在用户选择登录选项时填充。

对于Auth 0,我编辑了文件auth0-angular.js。我在authUtilsProviderthis.$get 中注入loginOption 并调节$stateChangeStart

$rootScope.$on('$stateChangeStart', function (e, to) {
  if (!config.initialized) {
    return;
  }
  //prevent state change only when the state change is in the favor of Auth0 or login option is yet to be selected
  //now, it won't prevent state change when done by Azure AD
  if (to.data && to.data.requiresLogin && (!loginOption.value || loginOption.value === 'Auth 0')) {
    if (!auth.isAuthenticated && !auth.refreshTokenPromise) {
      e.preventDefault();
      $injector.get('$state').go(config.loginState);
    }
  }
});

对于Azure AD,我编辑了文件adal-angular.js。我在ProtectedResourceInterceptor 中注入了loginOption 并调节了一些代码。

//to prevent adding token of Azure Ad into header of Auth 0 requests
if (tokenStored && (loginOption.value === loginOptions.AZURE_AD)) {
    authService.info('Token is available for this url ' + config.url);
    // check endpoint mapping if provided
    config.headers.Authorization = 'Bearer ' + tokenStored;
    return config;
}

if (loginOption.value === loginOptions.AZURE_AD) {
    // delayed request to return after iframe completes
    var delayedRequest = $q.defer();
    authService.acquireToken(resource).then(function (token) {
        authService.verbose('Token is available');
        config.headers.Authorization = 'Bearer ' + token;
        delayedRequest.resolve(config);
    }, function (err) {
        config.data = err;
        delayedRequest.reject(config);
    });

    return delayedRequest.promise;
}

无需在后端进行任何操作。请务必在Startup.cs 中为Auth0Azure Ad 添加令牌验证器

//for Azure Ad
UseWindowsAzureActiveDirectoryBearerAuthentication 

//for Auth0
UseJwtBearerAuthentication 

最后但并非最不重要的是索赔。对于Auth0,可以从ClaimTypes.Email 检索电子邮件,对于Azure Ad,可以从ClaimTypes.Name 检索电子邮件。

public static Claim GetClaim(string claimType)
{
    return ClaimsPrincipal.Current.FindFirst(claimType);
}

public static string GetLoggedInUserEmail()
{
    //Email comes up for Auth0
    var claimEmail = GetClaim(ClaimTypes.Email);

    //if claimEmail comes out to be null from ClaimTypes.Email then try it out for ClaimTypes.Name
    if (claimEmail == null)
        //Name comes up for Azure AD
        claimEmail = GetClaim(ClaimTypes.Name);

    var email = (claimEmail == null ? string.Empty : claimEmail.Value); //gets the email of the user
    return email;
}

我不确定这是否可以解决我的问题,但这对我有用。如果我在回答时有任何错误,请纠正我。谢谢

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-04-28
    • 2018-10-11
    • 1970-01-01
    • 2017-12-15
    • 2021-06-01
    • 2019-06-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多