lundi 1 juin 2015

Authorization in Cloud Applications using AD Groups issue with new group

I have an asp.net mvc application and my code is based on this article: http://ift.tt/1M3TwHf

and on this sample code: http://ift.tt/1Je5yPT

I created a controller for the global admin

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

and this is the 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);
                    }
                }
            });
        }
    }

This works perfectly fine if I login with a user which is in the global admin on the organization: http://ift.tt/1M3Twaa

However I created another group and added a user to that group: The group is called Company Admin, and the user companyadmin@

Group http://ift.tt/1M3Twac

Group Members http://ift.tt/1M3TwXx

And I created another controller:

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

I also have this on my home index controller action

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

However the User.IsInRole does not return true for company admin. http://ift.tt/1Je5yPY

Update 1

It looks like the group is indeed being returned on the claim, it just looks like the authorize does not work the right way or I am missing some piece of code.

Group id screenshot: http://ift.tt/1FlWjpD

Claim screenshot: http://ift.tt/1JjMWws

Aucun commentaire:

Enregistrer un commentaire