This post outlines the implementation of a silent login flow for Microsoft Teams. At SimplyDo we had previously implemented a solution for this and it worked, after some changes from Microsoft there is now a slightly more elegant solution available.

Sidenote: in all fairnesss, most of our prior issues stemmed from the proactive messages required by Teams applications, but this is also much more straightforward nowadays. If you’re interested in (or struggling with) implementing proactive notifications feel free to send me a message on one of my socials.

You can find our process for the previous solution in our team blog post . You will find that the process is actually still extremely similar, especially in regards to Steps 1 & 2. However, since then Microsoft has made some changes to their recommended Teams packages, so this updated approach should be more in line with the setup you can expect when creating a new Teams app in 2025.

Either way, the following should guide you through an example of how to implement a silent login flow in Microsoft Teams using the Teams SDK and the Microsoft Graph API. The example will cover both the frontend and backend parts of the flow.

The MS Teams frontend

The flow begins in the Teams environment itself. What we are looking for is a way to utilise the users authentication context of Teams itself to silently authenticate the user in our app.

For this we use the following versions of the Teams SDK, as of writing these are the latest versions available.

  "@microsoft/teams-js": "^2.36.0",
  "@microsoft/teamsfx": "^4.0.0",
  "@microsoft/teamsfx-react": "^4.0.2",

Technically only @microsoft/teams-js is required for this, but I assume most people will look at this in context of a React app. However, as you can see in their code the teamsfx packages actually just a wrapper around an authentication request around to make the ssoToken available, so this should always be available as long as app.initialize() has been called. References: Wrapping the internal call and calling the underlying authentication

If you open a Teams app in the Desktop or web client you will have the useTeamsUserCredential hook available to you. This hook will allow you to access the Teams user credentials and initiate the login flow. Crucially, you have access to the ssoToken which is the auth token that validates the user in Teams. This token is what we will use to authenticate the user in our app.

The setup should look something like this:

import { useTeamsUserCredential } from "@microsoft/teamsfx-react"

const Component = () => {
  const teamsCredentials = useTeamsUserCredential({
    initiateLoginEndpoint: import.meta.env.VITE_START_LOGIN_PAGE_URL,
    clientId: import.meta.env.VITE_CLIENT_ID,
  })
  const [currentUser, setCurrentUser] = useState(null)
  const [userLoginStatus, setUserLoginStatus] = useState("loading")

  const { loading, teamsUserCredential } = teamsCredentials
  if (loading) {
    return <div>Loading...</div>
  }

  useEffect(() => {
    if (userLoginStatus !== "loading") {
      return
    }
    setUserLoginStatus("initialising")

    // If we already have a token, we can skip the login flow
    const apiToken = localStorage.getItem("token")
    if (apiToken) {
      api.registerToken(apiToken)
      const user = api.getUser()
      setCurrentUser(user)

      setUserLoginStatus("loggedIn")
      return
    }

    const initialiseLogin = async () => {
      // Ensure the ssoToken is available
      const userInfo = await teamsUserCredential?.getUserInfo()
      if (!userInfo) {
        setUserLoginStatus("loginFailed")
        return
      }

      // Read the silent id token from the TeamsFx context
      const ssoToken = teamsUserCredential?.ssoToken?.token
      const response = await api.loginWithTeams({ ssoToken })

      api.registerToken(response.token)
      localStorage.setItem("token", response.token)
      setCurrentUser(response.user)

      setUserLoginStatus("loggedIn")
    }
    initialiseLogin()
  }, [teamsUserCredential])
}

Here we first call the .getUserInfo() method to ensure that the user is logged in and we have access to the ssoToken. This token is then passed to our backend API to authenticate the user. Once the request succeeds we can use this information set a session token in our api which allows us to further communicate with our backend without having to re-authenticate through the ssoToken in the future.

The backend

In the backend we will verify the ssoToken and use it to authenticate the user. Before we do so we need to check what our audience for the token is. This can be done by checking the aud claim in the token. You should never parse this directly from the token, but it will be stable across requests. If you are not deployed yet you can also check your Azure AD app registration to see what the audience is set to.

The following image shows where you would find the App audience in the App registration. Let’s assume it’s set to api://<your-app-id> for now.

Example of App ID in Azure

Now that we know the audience, we can verify the token and extract the user information from it. The token is signed by Microsoft and we can verify it using the public keys provided by Microsoft.

Please be aware that in this example we will request user information from the Microsoft Graph API using the https://graph.microsoft.com/.default scope. This scope grants access to any delegated permissions configured for the application, but fails if there isn’t any. You will need to ensure that the app registration has the necessary permissions granted to resolve the fields of the following Graph API call. The configured permissions can be found in the app registration under “API permissions”.

In these examples I will use a few dummy functions to illustrate how you could use the data in this flow, but you will need to implement your own logic to handle the user data and authentication flow in your app.

Nothing here is terribly complicated, but it does require some understanding of how the Teams SDK works and how to verify the JWT tokens. The key takeaway is that you can use the Teams user credentials to silently authenticate the user in your app without requiring them to log in again.