Пример #1
0
        public async Task <ActionResult> CreateLocalAccountPost(EducationRegisterViewModel model)
        {
            var tenantId           = User.GetTenantId();
            var graphServiceClient = await AuthenticationHelper.GetGraphServiceClientAsync();

            IGraphClient graphClient = new MSGraphClient(graphServiceClient);
            var          user        = await graphClient.GetCurrentUserAsync();

            var tenant = await graphClient.GetTenantAsync(tenantId);

            model.Email          = user.Mail ?? user.UserPrincipalName;
            model.FavoriteColors = Constants.FavoriteColors;

            // Create a new local user
            var localUser = new ApplicationUser
            {
                Email         = model.Email,
                UserName      = model.Email,
                FavoriteColor = model.FavoriteColor
            };
            var result = await userManager.CreateAsync(localUser);

            if (!result.Succeeded)
            {
                AddErrors(result);
                return(View(model));
            }

            // Update the local user
            await applicationService.UpdateLocalUserAsync(localUser, user, tenant);

            SetCookiesForO365User(user.GivenName + " " + user.Surname, user.Mail);
            return(RedirectToAction("Index", "Schools"));
        }
        private async Task CallGraphInternalAsync(DialogContext dc, string token, HttpClient httpClient, CancellationToken cancellationToken)
        {
            IGraphServiceClient graphClient = MSGraphClient.GetAuthenticatedClient(token, httpClient);

            var parameters = new Dictionary <string, object>(StringComparer.OrdinalIgnoreCase);

            this.PopulateParameters(dc.State, parameters);

            Stopwatch sw       = new Stopwatch();
            Exception exCaught = null;

            try
            {
                sw.Start();
                await this.CallGraphServiceAsync(graphClient, parameters, cancellationToken).ConfigureAwait(false);
            }
            catch (ServiceException ex)
            {
                exCaught = ex;

                this.HandleServiceException(ex);
            }
#pragma warning disable CA1031 // Do not catch general exception types. We're firing an event for this exception.
            catch (Exception ex)
#pragma warning restore CA1031 // Do not catch general exception types
            {
                exCaught = ex;
            }
            finally
            {
                sw.Stop();

                this.FireTelemetryEvent(sw.ElapsedMilliseconds, exCaught);
            }
        }
Пример #3
0
        //
        // GET: /Link/LoginLocal
        public async Task <ActionResult> LoginLocal(LoginViewModel model)
        {
            var graphServiceClient = await AuthenticationHelper.GetGraphServiceClientAsync();

            IGraphClient graphClient = new MSGraphClient(graphServiceClient);
            var          user        = await graphClient.GetCurrentUserAsync();

            var localUser = userManager.FindByEmail(string.IsNullOrEmpty(user.Mail)? user.UserPrincipalName:user.Mail);

            if (localUser == null)
            {
                foreach (var modelValue in ModelState.Values)
                {
                    modelValue.Errors.Clear();
                }
                return(View(model));
            }
            var tenantId = User.GetTenantId();

            if (localUser.O365UserId.IsNotNullAndEmpty())
            {
                ModelState.AddModelError("Email", "The local account has already been linked to another Office 365 account.");
                return(View(model));
            }

            var tenant = await graphClient.GetTenantAsync(tenantId);

            await applicationService.UpdateLocalUserAsync(localUser, user, tenant);

            SetCookiesForO365User(user.GivenName + " " + user.Surname, user.Mail);
            TempData["Message"] = Resources.LinkO365AccountSuccess;
            TempData[HandleAdalExceptionAttribute.ChallengeImmediatelyTempDataKey] = true;

            return(RedirectToAction("Index", "Schools"));
        }
Пример #4
0
 public MicrosoftGraphController(ReadAppSettings settings)
 {
     tenant       = settings.microsoft_tenant;
     clientId     = settings.microsoft_client_id;
     clientSecret = settings.microsoft_client_secret;
     client       = new MSGraphClient(clientId, clientSecret, tenant);
 }
        // GET: UserProfile
        public async Task <ActionResult> Index()
        {
            try
            {
                MSGraphClient msGraphClient = new MSGraphClient(ConfigHelper.Authority, new ADALTokenCache(Util.GetSignedInUsersObjectIdFromClaims()));

                User user = await msGraphClient.GetMeAsync();

                UserGroupsAndDirectoryRoles userGroupsAndDirectoryRoles = await msGraphClient.GetCurrentUserGroupsAndRolesAsync();

                //IList<Group> groups = await msGraphClient.GetCurrentUserGroupsAsync();
                //IList<DirectoryRole> directoryRoles = await msGraphClient.GetCurrentUserDirectoryRolesAsync();

                ViewData["overageOccurred"]  = userGroupsAndDirectoryRoles.HasOverageClaim;
                ViewData["myGroups"]         = userGroupsAndDirectoryRoles.Groups;
                ViewData["myDirectoryRoles"] = userGroupsAndDirectoryRoles.DirectoryRoles;
                return(View(user));
            }
            catch (AdalException)
            {
                // Return to error page.
                return(View("Error"));
            }
            // if the above failed, the user needs to explicitly re-authenticate for the app to obtain the required token
            catch (Exception)
            {
                return(View("Relogin"));
            }
        }
Пример #6
0
        public void InitializeTest()
        {
            this.testGraphClient = new Mock <IGraphServiceClient>();
            this.TestUsers       = new List <User>();
            this.UserRequests    = new Dictionary <string, IUserRequestBuilder>(StringComparer.OrdinalIgnoreCase);

            this.SetupMe();
            this.SetupSearch();

            MSGraphClient.RegisterTestInstance(this.testGraphClient.Object);
        }
        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            // inject msgraph client as transient to make sure bearer token is always renewed
            services.AddTransient(provider =>
            {
                var options = new MSGraphOptions();
                Configuration.Bind("MicrosoftGraph", options);

                var client = new MSGraphClient(options);
                return(client);
            });

            // add AADB2C authentication
            services.AddAuthentication(AzureADB2CDefaults.BearerAuthenticationScheme)
            .AddAzureADB2CBearer(
                AzureADB2CDefaults.BearerAuthenticationScheme,
                AzureADB2CDefaults.JwtBearerAuthenticationScheme,
                options => { Configuration.Bind("AzureAdB2C", options); });

            // configure identity post token validation to retrieve user roles and add them to identity claims
            services.PostConfigure <JwtBearerOptions>(AzureADB2CDefaults.JwtBearerAuthenticationScheme,
                                                      options =>
            {
                options.Events = new JwtBearerEvents
                {
                    OnTokenValidated = async context =>
                    {
                        // get AADB2C identity by client ID
                        var applicationId = Configuration["AzureAdB2C:ClientId"];
                        var identity      = context.Principal.Identities.First(o => o.HasClaim("aud", applicationId));

                        // get authenticated user ID
                        var subjectId = identity.FindFirst(ClaimTypes.NameIdentifier).Value;

                        // query user roles
                        var client = _serviceProvider.GetRequiredService <MSGraphClient>();
                        var roles  = await client.GetUserRolesAsync(subjectId);

                        // add roles to identity's claims collection with the right type
                        foreach (var role in roles)
                        {
                            var roleClaim = new Claim(identity.RoleClaimType, role);
                            identity.AddClaim(roleClaim);
                        }
                    }
                };
            });

            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);

            // save DI container reference
            _serviceProvider = services.BuildServiceProvider();
        }
        public async Task GetUser()
        {
            var client   = new HttpClient();
            var SFResult = await client.GetAsync(sfEndPoint);

            var           SFUsers  = JsonConvert.DeserializeObject <List <SalesforceUser> >(await SFResult.Content.ReadAsStringAsync());
            MSGraphClient msclient = new MSGraphClient(clientId, clientSecret, tenant);
            var           msusers  = await msclient.GetUsers("");

            var ADUsersResponse = JsonConvert.DeserializeObject <MSGraphUserListResponse>(msusers);
            var ADUsers         = ADUsersResponse.value;

            var ADUsersToDelete = new List <User>();
            var SFUsersToDelete = new List <SalesforceUser>();

            foreach (var adUser in ADUsers)
            {
                foreach (var sfUser in SFUsers)
                {
                    if (sfUser.EMail == adUser.mail)
                    {
                        SFUsersToDelete.Add(sfUser);
                        ADUsersToDelete.Add(adUser);
                    }
                }
            }

            foreach (var adUser in ADUsersToDelete)
            {
                ADUsers.Remove(adUser);
            }
            foreach (var sfUser in SFUsersToDelete)
            {
                SFUsers.Remove(sfUser);
            }


            foreach (var sfUser in SFUsers)
            {
                var inviteResponse = await inviteClient.InviteUser(sfUser);

                var invitation = JsonConvert.DeserializeObject <Invitation>(inviteResponse);
                var uid        = invitation.invitedUser.id;
                Console.WriteLine(inviteResponse);
            }
        }
Пример #9
0
        /// <summary>
        /// Get all loggedon user groups and display name from AD.
        /// </summary>
        /// <param name="key"></param>
        /// <param name="dn"></param>
        /// <returns></returns>
        public static async Task <List <string> > GetAllGroups(System.Security.Claims.ClaimsIdentity claimsIdentity)
        {
            List <string> lgroups  = new List <string>();
            ObjectCache   cache    = MemoryCache.Default;
            var           cacheKey = GetCacheKey(claimsIdentity);

            // If the claims identity is not populated, return an empty list
            if (String.IsNullOrEmpty(cacheKey))
            {
                return(lgroups);
            }

            // If the claims identity is populated and already in the cache, just return the cached list
            if (cache.Contains(cacheKey))
            {
                return(cache.Get(cacheKey) as List <string>);
            }

            // If the claims identity is populated and NOT in the cache, call the Graph API and populate the cache
            try
            {
                MSGraphClient msGraphClient = new MSGraphClient(
                    ConfigHelper.Authority,
                    new ADALTokenCache(claimsIdentity.FindFirst("oid")?.Value));

                System.Collections.Generic.IList <Group> groups = await msGraphClient.GetCurrentUserGroupsAsync();

                var groupNameList = await GetGroupNameList(groups);

                return(cache.AddOrGetExisting(cacheKey, groupNameList, _CacheItemPolicy) as List <string>);
            }
            catch (AdalException ex)
            {
                //TODO: error handling
                return(new List <string>());
            }
            catch (Exception ex)
            {
                //TODO: error handling
                return(new List <string>());
            }
        }
Пример #10
0
        //
        // GET: /Link/Index
        public async Task <ActionResult> Index()
        {
            var userContext = await applicationService.GetUserContextAsync();

            if (userContext.IsO365Account && !userContext.AreAccountsLinked)
            {
                var graphServiceClient = await AuthenticationHelper.GetGraphServiceClientAsync();

                var graphClient = new MSGraphClient(graphServiceClient);
                var user        = await graphClient.GetCurrentUserAsync();

                var email = user.Mail ?? user.UserPrincipalName;

                if (await userManager.Users.AnyAsync(i => i.Email == email))
                {
                    ViewBag.LocalAccountExistedMessage = $"There is a local account: {email} matching your O365 account.";
                }
            }
            return(View(userContext));
        }
Пример #11
0
        private async static Task RunFlow()
        {
            Console.WriteLine("Press A to run AAD Graph API flow/Press any other key to run MS Graph API flow");
            var input = Console.ReadLine();

            if (input.Trim().ToUpper() == "A")
            {
                Console.WriteLine("Press 1 to run as App mode/Press any other key to run in user mode");
                input = Console.ReadLine();
                if (input.Trim().ToUpper() == "1")
                {
                    Console.WriteLine("Getting users using AAD graph api");
                    AADGraphClient graphClient = new AADGraphClient();
                    await graphClient.GetAllUsers();
                }
                else
                {
                    Console.WriteLine("Getting logged in user details using AAD graph api");
                    AADGraphClient graphClient = new AADGraphClient(true);
                    await graphClient.GetLoggedInUserDetails();
                }
            }
            else
            {
                Console.WriteLine("Press 1 to run as App mode/Press any other key to run in user mode");
                input = Console.ReadLine();
                if (input.Trim().ToUpper() == "1")
                {
                    Console.WriteLine("Getting users using MS graph api");
                    MSGraphClient graphClient = new MSGraphClient();
                    await graphClient.GetAllUsers();
                }
                else
                {
                    Console.WriteLine("Getting logged in user details using MS graph api");
                    MSGraphClient graphClient = new MSGraphClient(true);
                    await graphClient.GetLoggedInUserDetails();
                }
            }
        }
Пример #12
0
        //
        // GET: /Link/ProcessCode
        public async Task <ActionResult> ProcessCode(string code, string error, string error_description, string resource, string state)
        {
            if (TempData[StateKey] as string != state)
            {
                TempData["Error"] = "Invalid operation. Please try again";
                return(RedirectToAction("Index"));
            }

            var authResult = await AuthenticationHelper.GetAuthenticationResultAsync(code);

            var tenantId           = authResult.TenantId;
            var graphServiceClient = authResult.CreateGraphServiceClient();

            IGraphClient graphClient = new MSGraphClient(graphServiceClient);
            var          user        = await graphClient.GetCurrentUserAsync();

            var tenant = await graphClient.GetTenantAsync(tenantId);

            var isAccountLinked = await applicationService.IsO365AccountLinkedAsync(user.Id);

            if (isAccountLinked)
            {
                TempData["Error"] = $"Failed to link accounts. The Office 365 account '{ user.Mail ?? user.UserPrincipalName}' is already linked to another local account.";
                return(RedirectToAction("Index"));
            }

            // Link the AAD User with local user.
            var localUser = await applicationService.GetCurrentUserAsync();

            await applicationService.UpdateLocalUserAsync(localUser, user, tenant);

            // Re-sign in user. Required claims (roles, tenent id and user object id) will be added to current user's identity.
            await signInManager.SignInAsync(localUser, isPersistent : false, rememberBrowser : false);

            TempData["Message"] = Resources.LinkO365AccountSuccess;
            TempData[HandleAdalExceptionAttribute.ChallengeImmediatelyTempDataKey] = true;
            SetCookiesForO365User(user.GivenName + " " + user.Surname, user.UserPrincipalName);

            return(RedirectToAction("Index", "Home"));
        }
Пример #13
0
        public async Task <ActionResult> LoginLocalPost(LoginViewModel model)
        {
            if (!ModelState.IsValid)
            {
                return(View(model));
            }

            var localUser = userManager.FindByEmail(model.Email);

            if (localUser == null)
            {
                ModelState.AddModelError("", "Invalid login attempt.");
                return(View(model));
            }
            if (localUser.O365UserId.IsNotNullAndEmpty())
            {
                ModelState.AddModelError("Email", "The local account has already been linked to another Office 365 account.");
                return(View(model));
            }
            if (!await userManager.CheckPasswordAsync(localUser, model.Password))
            {
                ModelState.AddModelError("", "Invalid login attempt.");
                return(View(model));
            }

            var tenantId           = User.GetTenantId();
            var graphServiceClient = await AuthenticationHelper.GetGraphServiceClientAsync();

            IGraphClient graphClient = new MSGraphClient(graphServiceClient);
            var          user        = await graphClient.GetCurrentUserAsync();

            var tenant = await graphClient.GetTenantAsync(tenantId);

            await applicationService.UpdateLocalUserAsync(localUser, user, tenant);

            SetCookiesForO365User(user.GivenName + " " + user.Surname, user.Mail);

            return(RedirectToAction("Index", "Schools"));
        }
Пример #14
0
        public async Task <ActionResult> ProcessCode(string code, string error, string error_description, string resource, string state)
        {
            var redirectUrl = (TempData[AdminConsentRedirectUrlKey] as string) ?? Url.Action("Index");

            if (TempData[StateKey] as string != state)
            {
                TempData["Error"] = "Invalid operation. Please try again";
                return(Redirect(redirectUrl));
            }

            // Get the tenant
            var authResult = await AuthenticationHelper.GetAuthenticationResultAsync(code);

            var graphServiceClient = authResult.CreateGraphServiceClient();
            var graphClient        = new MSGraphClient(graphServiceClient);
            var tenant             = await graphClient.GetTenantAsync(authResult.TenantId);

            // Create (or update) an organization, and make it as AdminConsented
            await applicationService.CreateOrUpdateOrganizationAsync(tenant, true);

            TempData["Message"] = "Admin consented successfully!";
            redirectUrl        += (redirectUrl.Contains("?") ? "&" : "?") + "consented=true";
            return(Redirect(redirectUrl));
        }
 /// <summary>
 /// Handler for <see cref="ServiceException"/>.
 /// </summary>
 /// <param name="ex">Exception to handle.</param>
 protected virtual void HandleServiceException(ServiceException ex)
 {
     throw MSGraphClient.HandleGraphAPIException(ex);
 }
Пример #16
0
        public void ConfigureAADAuth(IAppBuilder app)
        {
            app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);

            app.UseCookieAuthentication(new CookieAuthenticationOptions {
            });

            app.UseOpenIdConnectAuthentication(
                new OpenIdConnectAuthenticationOptions
            {
                Caption   = "Microsoft Work or school account",
                ClientId  = Constants.AADClientId,
                Authority = Constants.Authority,
                TokenValidationParameters = new System.IdentityModel.Tokens.TokenValidationParameters
                {
                    // instead of using the default validation (validating against a single issuer value, as we do in line of business apps),
                    // we inject our own multitenant validation logic
                    ValidateIssuer = false,
                },
                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           = appBaseUrl + "/";
                        context.ProtocolMessage.PostLogoutRedirectUri = appBaseUrl;
                        CookieService cookieService = new CookieService();
                        string hint = cookieService.GetCookiesOfEmail();
                        if (!string.IsNullOrEmpty(hint))
                        {
                            context.ProtocolMessage.LoginHint = hint;
                        }
                        return(Task.FromResult(0));
                    },
                    AuthorizationCodeReceived = async(context) =>
                    {
                        var identity = context.AuthenticationTicket.Identity;

                        // Get token with authorization code
                        var redirectUri = new Uri(HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Path));
                        var credential  = new ClientCredential(Constants.AADClientId, Constants.AADClientSecret);
                        var authContext = AuthenticationHelper.GetAuthenticationContext(identity, Permissions.Delegated);
                        var authResult  = await authContext.AcquireTokenByAuthorizationCodeAsync(context.Code, redirectUri, credential, Constants.Resources.MSGraph);

                        // Get user's roles and add them to claims
                        var graphServiceClient = authResult.CreateGraphServiceClient();
                        var graphClient        = new MSGraphClient(graphServiceClient);
                        var user = await graphClient.GetCurrentUserAsync();
                        foreach (var role in user.Roles)
                        {
                            identity.AddClaim(ClaimTypes.Role, role);
                        }
                    },
                    AuthenticationFailed = (context) =>
                    {
                        var redirectUrl = "/Error?message=" + Uri.EscapeDataString(context.Exception.Message);
                        context.OwinContext.Response.Redirect(redirectUrl);
                        context.HandleResponse();     // Suppress the exception
                        return(Task.FromResult(0));
                    }
                }
            });
        }