如何解决SPA 的 MSAL JS 目录选择器切换目录组件
Microsoft 是否有(或是否有任何人知道的自定义 JS 组件)目录选择器来为 AAD 安全 SPA 提供“切换目录”功能(当前使用 MSAL JS https://github.com/AzureAD/microsoft-authentication-library-for-js)?
解决方法
如果您想在 msal.js
之前切换 SPA 中的租户,似乎没有关于它的官方演示。根据我的理解,如果你想这样做,你应该解决两件事:
- 您的应用应该能够获取当前帐户所属的所有租户。
- 公共客户端 Azure AD 应用程序应为 multi-tenant one,以便用户能够无缝登录到不同的租户。
对于第 1 点,我们可以使用 this API 获取所有用户租户。该API属于Azure管理REST API,所以你的公共客户端Azure AD App应该被授予以下权限,以便登录的用户可以调用这个API来获取所有租户:
我用 msal.js 为你写了一个简单的演示,我认为可以满足你的要求,试试下面的 HTML 页面代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Azure AD test</title>
<script type="text/javascript" src="https://alcdn.msauth.net/lib/1.4.4/js/msal.min.js"></script>
</head>
<body>
<div >
<button id="SignIn" onclick="signIn()">Sign in</button><br/>
<div id="WelcomeMessage"/><br/>
</div>
</body>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script>
var clientAppID = "<multi tenant public client Azure ad app id>"
var tenantID = "<tenant ID for default login >"
var demoScops = {
scopes:["https://management.azure.com/user_impersonation"]
}
var msalConfig = {
auth: {
clientId: clientAppID,authority: "https://login.microsoftonline.com/" + tenantID
},cache: {
cacheLocation: "localStorage",storeAuthStateInCookie: true
}
};
var myMSALObj = new Msal.UserAgentApplication(msalConfig);
myMSALObj.handleRedirectCallback(authRedirectCallBack);
function signIn() {
myMSALObj.loginPopup(demoScops).then(function (loginResponse) {
console.log(loginResponse);
initPage();
}).catch(function (error) {
console.log(error);
});
}
function initPage(){
showWelcomeMessage();
getAllTenants();
}
function showWelcomeMessage() {
var divWelcome = document.getElementById('WelcomeMessage');
divWelcome.innerHTML = 'welcome! ' + myMSALObj.account.userName + '</br>';
var loginbutton = document.getElementById('SignIn');
loginbutton.innerHTML = 'sign out';
loginbutton.setAttribute('onclick','signOut();');
}
function getAllTenants(){
myMSALObj.acquireTokenSilent(demoScops).then(function (tokenResponse) {
var accessToken = tokenResponse.accessToken;
$.ajax({
url: "https://management.azure.com/tenants?api-version=2020-01-01",type: "GET",async: false,beforeSend: function(xhr){xhr.setRequestHeader('Authorization','Bearer '+ accessToken);},success: function(data) {
var divWelcome = document.getElementById('WelcomeMessage');
divWelcome.innerHTML += " your current tenant: "+ myMSALObj.account.idToken.tid +",all your tenants :</br>"
data.value.forEach(item=>{
var tentantItem = "<div id='"+item.tenantId+"' style='border: 2px solid grey; margin:5px; width:500px' onclick='switchTenant(this)' > name :"+item.displayName+ " Tenant ID:"+ item.tenantId +"</div>"
divWelcome.innerHTML += tentantItem;
})
}
});
}).catch(function (error) {
console.log(error);
})
}
function switchTenant(obj){
var msalConfig = {
auth: {
clientId: clientAppID,authority: "https://login.microsoftonline.com/" + $(obj).attr('id')
},cache: {
cacheLocation: "localStorage",storeAuthStateInCookie: true
}
};
var myMSALObj = new Msal.UserAgentApplication(msalConfig);
myMSALObj.handleRedirectCallback(authRedirectCallBack);
myMSALObj.loginPopup(demoScops).then(function (loginResponse) {
console.log(loginResponse);
location.reload();
}).catch(function (error) {
console.log(error);
});
}
function authRedirectCallBack(error,response) {
if (error) {
console.log(error);
}
}
function requiresInteraction(errorCode) {
if (!errorCode || !errorCode.length) {
return false;
}
return errorCode === "consent_required" ||
errorCode === "interaction_required" ||
errorCode === "login_required";
}
var ua = window.navigator.userAgent;
var msie = ua.indexOf('MSIE ');
var msie11 = ua.indexOf('Trident/');
var msedge = ua.indexOf('Edge/');
var isIE = msie > 0 || msie11 > 0;
var isEdge = msedge > 0;
var loginType = isIE ? "REDIRECT" : "POPUP";
if (loginType === 'POPUP') {
if (myMSALObj.getAccount()) {
initPage()
}
}
else if (loginType === 'REDIRECT') {
document.getElementById("SignIn").onclick = function () {
myMSALObj.loginRedirect(requestObj);
};
if (myMSALObj.getAccount() && !myMSALObj.isCallback(window.location.hash)) {
initPage()
}
} else {
console.error('Please set a valid login type');
}
function signOut() {
window.localStorage.clear();
myMSALObj.logout();
}
</script>
</html>
结果:
一旦我点击了一个租户项,一个登录窗口会弹出并在登录成功后重新显示页面:
最后:
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。