【问题标题】:Authorization in Cloud Applications using AD Groups issue with new group使用 AD 组的云应用程序中的授权问题与新组有关
【发布时间】:2015-06-01 13:26:14
【问题描述】:

我有一个 asp.net mvc 应用程序,我的代码基于这篇文章:http://www.dushyantgill.com/blog/2014/12/10/authorization-cloud-applications-using-ad-groups/

在这个示例代码中: https://github.com/dushyantgill/VipSwapper/tree/master/TrainingPoint

我为全局管理员创建了一个控制器

public class GlobalAdminController : Controller
    {
        // GET: GlobalAdmin
        [AuthorizeUser(Roles = "admin")]
        public ActionResult Index()
        {
            return View();
        }
    }

这是startup.cs

public void ConfigureAuth(IAppBuilder app)
        {
            // configure the authentication type & settings
            app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
            app.UseCookieAuthentication(new CookieAuthenticationOptions());

            // configure the OWIN OpenId Connect options
            app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
            {
                ClientId = SettingsHelper.ClientId,
                Authority = SettingsHelper.AzureADAuthority,
                TokenValidationParameters = new System.IdentityModel.Tokens.TokenValidationParameters
                {
                    // we inject our own multitenant validation logic
                    ValidateIssuer = false,
                    // map the claimsPrincipal's roles to the roles claim
                    RoleClaimType = "roles",
                },
                Notifications = new OpenIdConnectAuthenticationNotifications()
                {
                    RedirectToIdentityProvider = (context) =>
                    {
                        // This ensures that the address used for sign in and sign out is picked up dynamically from the request
                        // this allows you to deploy your app (to Azure Web Sites, for example) without having to change settings
                        // Remember that the base URL of the address used here must be provisioned in Azure AD beforehand.
                        //string appBaseUrl = context.Request.Scheme + "://" + context.Request.Host + context.Request.PathBase;
                        context.ProtocolMessage.RedirectUri = HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Path);
                        context.ProtocolMessage.PostLogoutRedirectUri = new UrlHelper(HttpContext.Current.Request.RequestContext).Action("Index", "Home", null, HttpContext.Current.Request.Url.Scheme);
                        context.ProtocolMessage.Resource = SettingsHelper.GraphResourceId;

                        return Task.FromResult(0);
                    },

                    // when an auth code is received...
                    AuthorizationCodeReceived = (context) => {
                        // get the OpenID Connect code passed from Azure AD on successful auth
                        string code = context.Code;

                        // create the app credentials & get reference to the user
                        ClientCredential creds = new ClientCredential(SettingsHelper.ClientId, SettingsHelper.ClientSecret);
                        string userObjectId = context.AuthenticationTicket.Identity.FindFirst(System.IdentityModel.Claims.ClaimTypes.NameIdentifier).Value;

                        // use the ADAL to obtain access token & refresh token...
                        //  save those in a persistent store...
                        EfAdalTokenCache sampleCache = new EfAdalTokenCache(userObjectId);
                        AuthenticationContext authContext = new AuthenticationContext(SettingsHelper.AzureADAuthority, sampleCache);

                        // obtain access token for the AzureAD graph
                        Uri redirectUri = new Uri(HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Path));
                        AuthenticationResult authResult = authContext.AcquireTokenByAuthorizationCode(code, redirectUri, creds, SettingsHelper.AzureAdGraphResourceId);

                        if (GraphUtil.IsUserAADAdmin(context.AuthenticationTicket.Identity))
                            context.AuthenticationTicket.Identity.AddClaim(new Claim("roles", "admin"));

                        // successful auth
                        return Task.FromResult(0);
                    },
                    AuthenticationFailed = (context) => {
                        context.HandleResponse();
                        return Task.FromResult(0);
                    }
                }
            });
        }
    }

如果我使用组织的全局管理员中的用户登录,这将非常有效: http://screencast.com/t/jLVNWGN7MgZR

但是,我创建了另一个组并将用户添加到该组: 该组称为 Company Admin,用户名为 companyadmin@

http://screencast.com/t/Y6vueAxjRPo

组成员 http://screencast.com/t/BBRUoOxaD

我创建了另一个控制器:

 public class CompanyAdminController : Controller
    {
        [AuthorizeUser(Roles = "company admin")]
        public ActionResult Index()
        {
            return View();
        }
    }

我的家庭索引控制器操作中也有这个

public ActionResult Index()
        {
            if (User.IsInRole("admin"))
            {
                return RedirectToAction("Index", "GlobalAdmin");
            }
            if (User.IsInRole("company admin"))
            {
                return RedirectToAction("Index", "CompanyAdmin");
            }
            return View();
        }

但是,对于公司管理员,User.IsInRole 不会返回 true。 http://screencast.com/t/msVfvUt1g

更新 1

看起来该组确实在索赔中被退回,只是看起来授权没有以正确的方式工作,或者我错过了一些代码。

群id截图:http://screencast.com/t/0Doz9DcD

领取截图:http://screencast.com/t/tbRGJPoc

【问题讨论】:

    标签: c# asp.net asp.net-mvc asp.net-mvc-3 adal


    【解决方案1】:

    Azure AD 中的组是主体(用户、服务、组)的集合。而 Azure AD 中的应用角色表示应用的权限集合。用户的组成员身份不会出现在角色声明中。应用程序向 Azure AD 声明其角色(例如管理员、读取器、写入器)。当组织购买/部署应用程序时,该组织的管理员可以将其组织中的用户/组/服务分配给应用程序的角色(例如 john@contoso.com -> 应用程序管理员、project1team 组 -> 应用程序作者,所有用户组->应用程序的读者)。然后,当用户登录应用时,Azure AD 会发出角色声明并指定分配给用户的所有应用角色(直接分配或通过组)。更多细节在这里:http://blogs.technet.com/b/ad/archive/2014/12/18/azure-active-directory-now-with-group-claims-and-application-roles.aspx

    因此,对于您的示例,您似乎需要创建一个名为公司管理员的应用角色,并允许您应用的客户将用户/组分配给该角色。

    希望对您有所帮助。

    我很好奇,您是否正在创建一个有助于管理 Azure AD 身份的应用程序?

    【讨论】:

    • 不,我正在创建一个具有不同模块的APP,会计模块,库存模块等。我们不想使用应用程序角色,因为它们必须用powershell创建,我们不想购买 AAD 高级版。而且我们不需要那种复杂程度。因此,在下面我的答案示例中,我能够使其仅与组而不是应用程序角色一起使用,因为我们认为这样更简单,一组人可以在控制器中执行特定的操作,就是这样。
    【解决方案2】:

    由于 bluefeet 版主和 martij Pieters 版主删除了我的答案,答案中最重要的部分在 owin 管道中

    var groups = GraphUtil.GetMemberGroups(context.AuthenticationTicket.Identity).Result;
                            //For each group, we have its, ID, we need to get the display name, and then we have to add the claim
                            foreach(string groupid in groups)
                            {
                                var displayname=GraphUtil.LookupDisplayNameOfAADObject(groupid, context.AuthenticationTicket.Identity);
                                context.AuthenticationTicket.Identity.AddClaim(new Claim("roles", displayname));
                            }
    

    但是,Stackoverflow 不允许超过 30,000 个字符,答案大约是 45,000 个字符,所以对于读者来说,您可以到这里获得完整的解释: http://www.luisevalencia.com/2015/06/02/using-azure-aad-graph-office-365-add-in-with-groups-authorization/

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-23
      • 1970-01-01
      • 2014-05-22
      相关资源
      最近更新 更多