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")); }
// // 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")); }
// // 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)); }
// // 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")); }
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")); }
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)); } } }); }