为什么在多租户方案中Azure AD无法登录非管理员? [英] Why Azure AD fails to login non-admins in multi-tenant scenario?

查看:64
本文介绍了为什么在多租户方案中Azure AD无法登录非管理员?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

环境:

两个Azure AD:公司客户

Two Azure ADs: Company, Customers

公司发布了一个名为 Portal 的ASP.NET5 Web应用程序,该应用程序设置为多租户.

Company publishes an ASP.NET5 web app called Portal, the app is setup to be multi-tenant.

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

Customers have 2 user: user (who is just a user) and admin (who is a Global Administrator in the directory).

门户,最初设置为要求1个应用程序许可:读取目录数据

Portal, is initially set up to ask for 1 Application Permission: Read Directory Data

-

这是我经历的流程,并且我相信Azure AD在多个步骤中行为不当.请指出我是否缺少什么.

Here comes the flow that I went through, and I believe Azure AD misbehaves at multiple steps. Please point out if I am missing something.

  1. 我打开Web应用程序,然后首先尝试以 admin
  2. 身份登录
  3. 我必须同意读取目录"数据权限,所以我这样做.
  4. 出现应用程序(我尚未分配角色,很好)–到目前为止,一切正常.
  5. 我在新的隐身会话中重新打开了网络应用,并尝试以用户
  6. 的身份登录
  7. 现在,我得到[AADSTS90093: This operation can only be performed by an administrator. Sign out and sign in as an administrator or contact one of your organization's administrators.]-管理员已经同意,为什么要得到这个??
  8. 我转到公司 AD并将应用程序权限更改为包括读与写";写入目录数据
  9. 我转到客户,检查应用程序 Portal ,并且信息中心已经显示了列出的新权限.没人同意! admin 甚至在下次登录时也看不到任何更改. 这不是安全漏洞吗?
  1. I open the web app, and first try to sign in as admin
  2. I have to consent to the Read Directory data permission, so I do that
  3. Application appears (I have no roles assigned yet, which is fine) -- so far everything works.
  4. I re-open the web-app in a new incognito session, and try to sign in as the user
  5. Now, I get [AADSTS90093: This operation can only be performed by an administrator. Sign out and sign in as an administrator or contact one of your organization's administrators.] -- the admin already consented, so why do I get this??
  6. I go to Company AD and change the application permissions to include Read & Write Directory data
  7. I go to Customer AD check the app Portal and the dashboard already shows the new permission listed. No one had to consent! The admin do not see any change even on next login. How is this not a security hole?

我对https://msdn.microsoft.com/en -us/library/azure/dn132599.aspx 是应用权限未被弃用.

更新

我在WebApp中的配置:

My configuration in the 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管理门户中的错误.在客户"租户视图中,UX显示应用程序(在公司租户中定义)正在请求的权限.它应该显示客户"租户中实际授予的权限.在这种情况下,如果您的应用程序实际上尝试调用写入Graph API的程序,则会收到拒绝访问错误.无论如何-不是安全漏洞-但可以肯定地理解为什么它看起来像您一样-对此感到抱歉.我们将尝试尽快解决此问题.

Thanks for the information you've provided. I'm going to answer #7 first, because it looks pretty alarming. It does at first glance look like a security hole, but it's not. It's a bug in the Azure Management Portal that we are working to fix. In the "customers" tenant view, the UX is showing the permissions that the application (defined in the company tenant) is requesting. It should be showing the permissions actually granted in the "customers" tenant. In this case, if your app actually tries a call to write to the Graph API it'll get an access denied error. Anyways - not a security hole - but can sure understand why it looked that way to you - so sorry about this. We'll try to get this fixed as soon as we can.

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

On to some of your other questions about consent behavior... BTW this is something we are looking to improve in our documentation. Anyways, I'll try and answer this broadly in terms of the design behavior, because it looks like you've changed your app config multiple times.

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

If you pick any app permissions (not delegated permissions), the consent UX defaults to the "consent on behalf of the organization" experience. In this mode the consent page ALWAYS shows, whether the admin consented previously or not. You can also force this behavior if you make a request to the authorize endpoint with the QS parameter of prompt=admin_consent. So let's say you went down this path AND the only permission you have is app-only "Read Directory" and the admin consents. Now a user comes the user doesn't have any grant that allows them to sign in and get an id_token for the app (Read Directory app-only is not currently good for this), so the consent dialog tries to show the admin on behalf of org consent, but this is a non-admin so you get the error. Now, if you add the delegated "sign me in and read my profile" permission for the app, and have your admin reconsent, you'll see that now the user will not be prompted for consent. What I'll do is go back to our team and see whether ANY directory permission (app only or delegated) should allow any user to get a sign in token. One could argue that this should be the case.

HTH,

这篇关于为什么在多租户方案中Azure AD无法登录非管理员?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆