security - 为什么 Azure AD 在 Multi-Tenancy 场景中无法登录非管理员?

标签 security azure azure-active-directory

环境:

两个 Azure AD:公司客户

公司发布了一个名为Portal的 ASP.NET5 Web 应用程序,该应用程序设置为 Multi-Tenancy 。

客户有 2 个用户:user(只是用户)和 admin(目录中的全局管理员)。

门户最初设置为请求 1 个应用程序权限:读取目录数据

-

这是我经历的流程,我相信 Azure AD 在多个步骤中行为不当。如果我遗漏了什么,请指出。

  1. 我打开网络应用,首先尝试以管理员身份登录
  2. 我必须同意读取目录数据权限,所以我这样做了
  3. 应用程序出现(我还没有分配角色,这很好)——到目前为止一切正常。
  4. 我在新的隐身 session 中重新打开网络应用,并尝试以用户身份登录
  5. 现在,我得到 [AADSTS90093:此操作只能由管理员执行。注销并以管理员身份登录或联系您组织的一位管理员。] -- 管理员已经同意了,那为什么我会收到此消息?
  6. 我转到公司 AD 并更改应用程序权限以包含读取和写入目录数据
  7. 我前往客户 AD 检查应用门户,仪表板已显示列出的新权限。无需任何人同意!即使在下次登录时,管理员也看不到任何更改。 这怎么不是一个安全漏洞?

我对https://msdn.microsoft.com/en-us/library/azure/dn132599.aspx的理解是应用程序权限并未被弃用。

更新

我在 WebApp 中的配置:

app.UseOpenIdConnectAuthentication(options =>
{
   options.ClientId = Configuration.Get("ActiveDirectory:ClientId");
   options.Authority = String.Format(Configuration.Get("ActiveDirectory:AadInstance"), "common/");   //"AadInstance": "https://login.windows.net/{0}"
   options.PostLogoutRedirectUri = Configuration.Get("ActiveDirectory:PostLogoutRedirectUri");    //"PostLogoutRedirectUri": "https://localhost:44300/"

   options.TokenValidationParameters = new System.IdentityModel.Tokens.TokenValidationParameters
   {
       // The following commented-out line should work according to
       // http://stackoverflow.com/questions/29317910/why-does-the-role-claim-have-incorrect-type
       // But, it does not work in ASP.NET5 (currently), so see the "Hack." down below
       // RoleClaimType = "roles",

       ValidIssuers = new[] { "https://sts.windows.net/a1028d9b-bd77-4544-8127-d3d42b9baebb/", "https://sts.windows.net/47b68455-a2e6-4114-90d6-df89d8468abc/" }
   };

   options.Notifications = new OpenIdConnectAuthenticationNotifications
   {
       RedirectToIdentityProvider = (context) =>
       {
           // This ensures that the address used for sign in and sign out is picked up dynamically from the request,
           // which is neccessary if we want to deploy the app to different URLs (eg. localhost/immerciti-dev, immerciti.azurewebsites.net/www.immerciti.com)
           string appBaseUrl = context.Request.Scheme + "://" + context.Request.Host + context.Request.PathBase;
           context.ProtocolMessage.RedirectUri = appBaseUrl;
           context.ProtocolMessage.PostLogoutRedirectUri = appBaseUrl;
           return Task.FromResult(0);
       },

       AuthorizationCodeReceived = async context =>
       {
           // Get Access Token for User's Directory
           try
           {
               var identity = (ClaimsIdentity)context.AuthenticationTicket.Principal.Identity;

               // Hack. TODO: keep an eye on developments around here
               foreach (var claim in identity.FindAll("roles"))
               {
                   // Readd each role with the proper claim type
                   identity.AddClaim(new Claim(identity.RoleClaimType, claim.Value, claim.ValueType, claim.Issuer, claim.OriginalIssuer));
               }
           }
           catch (AdalException)
           {
               context.HandleResponse();
               context.Response.Redirect("/Error/ShowError?errorMessage=Were having trouble signing you in&signIn=true");
           }
       }
   }; 
};

最佳答案

感谢您提供的信息。我首先要回答#7,因为它看起来非常令人担忧。乍一看它确实像是一个安全漏洞,但事实并非如此。这是 Azure 管理门户中的一个错误,我们正在努力修复。在“客户”租户 View 中,UX 显示应用程序(在公司租户中定义)请求的权限。它应该显示“客户”租户中实际授予的权限。在这种情况下,如果您的应用实际上尝试调用写入图形 API,它将收到访问被拒绝错误。无论如何 - 不是一个安全漏洞 - 但可以肯定理解为什么它看起来像这样 - 对此感到非常抱歉。我们会尽快修复此问题。

关于您关于同意行为的一些其他问题...顺便说一句,这是我们希望在文档中改进的内容。无论如何,我将尝试从设计行为方面广泛回答这个问题,因为看起来您已经多次更改了应用程序配置。

如果您选择任何应用权限(不是委派权限),同意用户体验将默认为“代表组织同意”体验。在此模式下,无论管理员之前是否同意,同意页面始终显示。如果您使用 QS 参数提示 = admin_consent 向授权端点发出请求,您也可以强制执行此行为。因此,假设您走了这条路,并且您拥有的唯一权限是仅应用程序的“读取目录”并且管理员同意。现在,用户来了,用户没有任何授权来允许他们登录并获取应用程序的 id_token(仅读取目录应用程序目前对此不适用),因此同意对话框尝试代表管理员显示组织同意,但这是非管理员,因此您会收到错误。 现在,如果您为应用程序添加委派的“登录并阅读我的个人资料”权限,并获得管理员的重新同意,您将看到现在不会提示用户同意。 我要做的是返回我们的团队,查看任何目录权限(仅限应用程序或委派)是否应允许任何用户获取登录 token 。有人可能会说情况应该如此。

HTH,

关于security - 为什么 Azure AD 在 Multi-Tenancy 场景中无法登录非管理员?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29791557/

相关文章:

Windows Azure 应用程序 - 黑客尝试?

security - 在 bash 文件中隐藏/加密密码以防止意外看到它

javascript - 是否可以使用客户端 javascript 连接到 sftp 服务器。安全吗?

azure - 从 Internet 访问 Service Fabric

Node.JS + SQL Server + MongoDB + 云上的 Redis

c# - 按 DocumentDB 中的字段分组

azure - 我为我的特定 Azure 应用程序启用了 MFA。第一次登录 Azure 的用户,为这些用户启用 MFA。如何为所有现有用户启用 MFA?

Azure 应用程序代理应用程序不会传递输入的 Active Directory 凭据

azure - 没有 "Common Data Service"API 选项 Azure

reactjs - 如何在React js应用程序的响应中添加http标题