无提示的身份验证Silent authentication

备注

若要对移动客户端上的选项卡进行身份验证,您需要确保您至少使用的是1.4.1 版本的团队 JavaScript SDK。For authentication to work for your tab on mobile clients, you need to ensure you're using at least the 1.4.1 version of the Teams JavaScript SDK.

在 Azure Active Directory (Azure AD)中进行无提示身份验证,可通过无提示刷新身份验证令牌,最大限度地减少用户输入其登录凭据的次数。Silent authentication in Azure Active Directory (Azure AD) minimizes the number of times a user needs to enter their login credentials by silently refreshing the authentication token. (有关真正的单一登录支持,请查看我们的SSO 文档(For true single sign-on support, view our SSO Documentation)

如果要将代码完全保持在客户端,可以使用适用于 JavaScript 的Azure Active Directory 身份验证库尝试以无提示方式获取 azure AD 访问令牌。If you want to keep your code completely client-side, you can use the Azure Active Directory Authentication Library for JavaScript to attempt to acquire an Azure AD access token silently. 这意味着用户可能永远不会看到弹出对话框(如果他们最近已登录)。This means that the user may never see a popup dialog if they have signed in recently.

尽管 ADAL.js 库针对 AngularJS 应用程序进行了优化,但它也适用于纯 JavaScript 单页应用程序。Even though the ADAL.js library is optimized for AngularJS applications, it also works with pure JavaScript single-page applications.

备注

目前,无提示身份验证仅适用于选项卡。Currently, silent authentication only works for tabs. 它在从 bot 登录时仍不起作用。It does not yet work when signing in from a bot.

无提示身份验证的工作方式How silent authentication works

ADAL.js 库为 OAuth 2.0 隐式授予流创建了一个隐藏的 iframe,但它指定了 prompt=none AZURE AD 从不显示登录页。The ADAL.js library creates a hidden iframe for OAuth 2.0 implicit grant flow, but it specifies prompt=none so that Azure AD never shows the login page. 如果需要用户交互,因为用户需要登录或授予对应用程序的访问权限,则 Azure AD 将立即返回一个错误,ADAL.js 然后向您的应用程序报告。If user interaction is required because the user needs to log in or grant access to the application, Azure AD will immediately return an error that ADAL.js then reports to your app. 此时,您的应用程序可以根据需要显示 "登录" 按钮。At this point your app can show a login button if needed.

如何执行无提示身份验证How to do silent authentication

本文中的代码来自团队示例应用程序Microsoft 团队身份验证示例(节点)The code in this article comes from the Teams sample app Microsoft Teams Authentication Sample (Node).

包含和配置 ADALinclude and configure ADAL

在选项卡页中包含 ADAL.js 库,并使用客户端 ID 和重定向 URL 配置 ADAL:Include the ADAL.js library in your tab pages and configure ADAL with your client ID and redirect URL:

<script src="https://secure.aadcdn.microsoftonline-p.com/lib/1.0.15/js/adal.min.js" integrity="sha384-lIk8T3uMxKqXQVVfFbiw0K/Nq+kt1P3NtGt/pNexiDby2rKU6xnDY8p16gIwKqgI" crossorigin="anonymous"></script>
<script type="text/javascript">
    // ADAL.js configuration
    let config = {
        clientId: "YOUR_APP_ID_HERE",
        // redirectUri must be in the list of redirect URLs for the Azure AD app
        redirectUri: window.location.origin + "/tab-auth/silent-end",
        cacheLocation: "localStorage",
        navigateToLoginRequestUrl: false,
    };
</script>

获取用户上下文Get the user context

在该选项卡的内容页中,调用 microsoftTeams.getContext() 获取当前用户的登录提示。In the tab's content page, call microsoftTeams.getContext() to get a login hint for the current user. 这将用作对 Azure AD 的调用中的 login_hint。This will be used as a login_hint in the call to Azure AD.

// Set up extra query parameters for ADAL
// - openid and profile scope adds profile information to the id_token
// - login_hint provides the expected user name
if (loginHint) {
    config.extraQueryParameter = "scope=openid+profile&login_hint=" + encodeURIComponent(loginHint);
} else {
    config.extraQueryParameter = "scope=openid+profile";
}

身份验证Authenticate

如果 ADAL 为用户缓存了未到期的令牌,请使用该令牌。If ADAL has an unexpired token cached for the user, use that. 否则,尝试通过调用以无提示方式获取令牌 acquireToken(resource, callback)Otherwise, attempt to get a token silently by calling acquireToken(resource, callback). ADAL.js 将使用请求的令牌调用回调函数,如果身份验证失败,则调用错误。ADAL.js will call your callback function with the requested token, or an error if authentication fails.

如果在回调函数中遇到错误,则显示 "登录" 按钮并回退到显式登录。If you get an error in the callback function, show a login button and fall back to an explicit login.

let authContext = new AuthenticationContext(config); // from the ADAL.js library
// See if there's a cached user and it matches the expected user
let user = authContext.getCachedUser();
if (user) {
    if (user.profile.oid !== userObjectId) {
        // User doesn't match, clear the cache
        authContext.clearCache();
    }
}

// In this example we are getting an id token (which ADAL.js returns if we ask for resource = clientId)
authContext.acquireToken(config.clientId, function (errDesc, token, err, tokenType) {
    if (token) {
        // Make sure ADAL gave us an id token
        if (tokenType !== authContext.CONSTANTS.ID_TOKEN) {
            token = authContext.getCachedToken(config.clientId);
        }
        showProfileInformation(idToken);
    } else {
        console.log("Renewal failed: " + err);
        // Failed to get the token silently; show the login button
        showLoginButton();
        // You could attempt to launch the login popup here, but in browsers this could be blocked by
        // a popup blocker, in which case the login attempt will fail with the reason FailedToOpenWindow.
    }
});

处理返回值Process the return value

通过 AuthenticationContext.handleWindowCallback(hash) 在登录回调页中调用,让 ADAL.js 负责从 AZURE AD 中分析结果。Let ADAL.js take care of parsing the result from Azure AD by calling AuthenticationContext.handleWindowCallback(hash) in the login callback page.

检查我们是否有有效的用户和呼叫, microsoftTeams.authentication.notifySuccess()microsoftTeams.authentication.notifyFailure() 将状态报告回您的主选项卡内容页面。Check that we have a valid user and call microsoftTeams.authentication.notifySuccess() or microsoftTeams.authentication.notifyFailure() to report status back to your main tab content page.

if (authContext.isCallback(window.location.hash)) {
    authContext.handleWindowCallback(window.location.hash);
    if (window.parent === window) {
        if (authContext.getCachedUser()) {
            microsoftTeams.authentication.notifySuccess();
        } else {
            microsoftTeams.authentication.notifyFailure(authContext.getLoginError());
        }
    }
}