You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

设置Microsoft Entra ID应用分配要求后仍允许未授权用户登录的问题咨询

问题原因分析

useIsAuthenticated() 仅验证用户完成了Microsoft身份认证、持有有效ID令牌,不会校验该用户是否被分配到你的Entra ID应用。Entra ID的「需要用户分配」设置并非自动拦截未分配用户获取令牌,而是要求应用端自行完成用户权限校验——这是微软的设计逻辑,将权限管控的主动权交给应用开发者。

你遇到的「未分配用户仍能登录」情况,本质是前端只做了身份认证,没做权限校验;之前修改「允许用户登录」为否仍能登录,大概率是缓存的有效令牌未过期,只有删除应用才彻底切断了令牌签发渠道。

实现仅指定用户访问的方案

以下基于你使用的@azure/msal-browser@4.x和@azure/msal-react@3.x版本实现,无需维护独立用户表,所有权限配置可在Entra ID管理中心完成:

1. 完成Entra ID基础配置

  • 确保应用的「需要用户分配」设为「是」,并将允许的10个用户(或对应用户组)添加到应用的「用户和组」列表中
  • 将「允许用户登录」设为「是」,后续权限校验由前端完成

2. 前端权限校验(两种可选方案)

方案一:利用ID令牌声明校验(推荐,无需额外API调用)

通过Entra ID配置,让ID令牌携带用户所属组的信息,前端直接解析令牌判断权限:

  1. 在Entra ID「应用注册」→「令牌配置」中,添加ID令牌的可选声明:
    • 选择「ID令牌」,添加groups声明(若用用户组管理权限)
  2. 封装自定义权限校验钩子:
    import { useIsAuthenticated, useMsal } from "@azure/msal-react";
    
    export const useIsAuthorized = () => {
      const isAuthenticated = useIsAuthenticated();
      const { instance } = useMsal();
      const activeAccount = instance.getActiveAccount();
    
      if (!isAuthenticated || !activeAccount) return false;
    
      // 替换为你在Entra ID中创建的允许访问的用户组ID
      const ALLOWED_GROUP_ID = "xxxx-xxxx-xxxx-xxxx";
      // 检查用户令牌中的groups声明是否包含允许的组ID
      return activeAccount.idTokenClaims?.groups?.includes(ALLOWED_GROUP_ID);
    };
    
  3. 在私有路由中替换原判断逻辑:
    import { useIsAuthorized } from "./hooks/useIsAuthorized";
    
    const PrivateRoute = ({ children }) => {
      const isAuthorized = useIsAuthorized();
      return isAuthorized ? children : <Navigate to="/unauthorized" />;
    };
    

方案二:调用Microsoft Graph API校验

通过Graph API查询用户的应用分配状态,适合需要更复杂权限逻辑的场景:

  1. 在Entra ID「应用注册」→「API权限」中,添加委托权限User.Read.All并完成管理员同意
  2. 实现权限校验逻辑:
    import { useMsal, useMsalAuthentication } from "@azure/msal-react";
    import { InteractionType } from "@azure/msal-browser";
    
    const CheckAuthorization = () => {
      const { instance } = useMsal();
      const { result } = useMsalAuthentication(InteractionType.Silent, {
        scopes: ["User.Read.All"]
      });
    
      const verifyAppAssignment = async () => {
        if (!result?.accessToken) return false;
        const response = await fetch("https://graph.microsoft.com/v1.0/me/appRoleAssignments", {
          headers: { Authorization: `Bearer ${result.accessToken}` }
        });
        const assignments = await response.json();
        // 替换为你的应用客户端ID
        const APP_CLIENT_ID = "your-app-client-id";
        // 检查用户是否有当前应用的分配记录
        return assignments.value.some(item => item.resourceId === APP_CLIENT_ID);
      };
    
      // 组件挂载时调用校验,根据结果跳转或渲染内容
      useEffect(() => {
        verifyAppAssignment().then(isAuthorized => {
          if (!isAuthorized) {
            instance.logoutRedirect();
          }
        });
      }, [result]);
    
      return <></>;
    };
    

3. 补充注意事项

  • 若使用用户组管理权限,确保组ID正确,且所有允许访问的用户已加入该组
  • 令牌有效期内,前端校验逻辑会基于缓存的令牌执行,若在Entra ID中移除用户权限,需用户重新登录才会生效
  • 建议在后端API调用时也添加一层校验:解析请求中的ID令牌,验证groups或应用分配状态,避免前端校验被绕过

内容的提问来源于stack exchange,提问作者Ben in CA

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 21:35:04