Angular Auth 0 和 Azure AD 的拦截器正在干扰彼此的身份验证过程
Angular Interceptor of Auth 0 and Azure AD are interfering in each other's authentication process
我正在开发一个包含 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 登录并 post 注销,我会尝试通过 Auth0 使用电子邮件 c@[=50= 再次登录],ClaimsPrincipal 仍然是 returns Azure AD 用户的电子邮件,即 a@b 而不是 c@d。
我确信这是因为有两个拦截器拦截请求,每个拦截器一个。 ProtectedResourceInterceptor:Azure AD 和
jwt拦截器: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 的同时实现不间断的登录过程?
我放弃了 从 Auth0 访问 Azure Ad 的想法。我回滚到之前的步骤,在那里我可以选择两者(Auth0 或 Azure AD)。
对于任何正在寻找答案的人,好吧,我尝试编辑拦截器。我不知道我是否应该编辑拦截器,但我做了很少的事情并且对我来说很有效。
就这样吧。我创建了一个 angular value
并在 module creation
开始时将其命名为 loginOption
和 属性 value
。 loginOption
可以将 Auth 0
或 Azure AD
作为值。
app.value('loginOption', {value: null});
loginOption.value
在用户选择登录选项时填充。
对于 Auth 0
我编辑了文件 auth0-angular.js
。我在 authUtilsProvider
的 this.$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
中为 Auth0
和 Azure 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;
}
我不确定这是否能解决我的问题,但这对我有用。如果我在回答时有任何错误,请纠正我。谢谢
我正在开发一个包含 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 登录并 post 注销,我会尝试通过 Auth0 使用电子邮件 c@[=50= 再次登录],ClaimsPrincipal 仍然是 returns Azure AD 用户的电子邮件,即 a@b 而不是 c@d。
我确信这是因为有两个拦截器拦截请求,每个拦截器一个。 ProtectedResourceInterceptor:Azure AD 和 jwt拦截器: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 的同时实现不间断的登录过程?
我放弃了 从 Auth0 访问 Azure Ad 的想法。我回滚到之前的步骤,在那里我可以选择两者(Auth0 或 Azure AD)。
对于任何正在寻找答案的人,好吧,我尝试编辑拦截器。我不知道我是否应该编辑拦截器,但我做了很少的事情并且对我来说很有效。
就这样吧。我创建了一个 angular value
并在 module creation
开始时将其命名为 loginOption
和 属性 value
。 loginOption
可以将 Auth 0
或 Azure AD
作为值。
app.value('loginOption', {value: null});
loginOption.value
在用户选择登录选项时填充。
对于 Auth 0
我编辑了文件 auth0-angular.js
。我在 authUtilsProvider
的 this.$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
Auth0
和 Azure 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;
}
我不确定这是否能解决我的问题,但这对我有用。如果我在回答时有任何错误,请纠正我。谢谢