public async Task <IActionResult> AddUserAsync(User user, string tenantId) { var tenant = _repo.GetTenantById(tenantId); var newUser = new IS4User { Username = user.Username, Password = user.Password, IsExternalUser = user.IsExternalUser, Provider = user.Provider, ExternalUserId = user.ExternalUserId, Tenant = tenant }; try { await _repo.AddUser(newUser); return(Ok()); } catch { return(BadRequest()); } }
public async Task <IActionResult> ExternalLoginCallback() { // read external identity from the temporary cookie var result = await HttpContext.AuthenticateAsync(IdentityServer4.IdentityServerConstants.ExternalCookieAuthenticationScheme); var returnUrl = result.Properties.Items["returnUrl"]; var context = await _interaction.GetAuthorizationContextAsync(returnUrl); if (result?.Succeeded != true) { throw new Exception("External authentication error"); } // retrieve claims of the external user var externalUser = result.Principal; var claims = externalUser.Claims.ToList(); // try to determine the unique id of the external user (issued by the provider) // the most common claim type for that are the sub claim and the NameIdentifier // depending on the external provider, some other claim type might be used var upn = claims.FirstOrDefault(x => x.Type.Equals("upn")); if (upn == null) { upn = claims.FirstOrDefault(x => x.Type.Equals("userPrincipalName")); } if (upn == null) { throw new Exception("Unknown userid"); } // remove the user id claim from the claims collection and move to the userId property // also set the name of the external authentication provider claims.Remove(upn); claims.Remove(claims.FirstOrDefault(x => x.Type.Equals("sub"))); claims.Add(new Claim("sub", upn.Value)); var provider = result.Properties.Items["scheme"]; var userId = upn.Value; // this is where custom logic would most likely be needed to match your users from the // external provider's authentication result, and provision the user as you see fit. // // check if the external user is already provisioned var user = _repo.FindByExternalProvider(provider, userId); List <UserClaims> userClaims = new List <UserClaims>(); if (user == null) { List <Claims> dbClaims = _repo.GetClaims(); var claimsToRemove = new List <Claim>(); claims.ForEach(claim => { var c = dbClaims.Where(x => x.Type.Equals(claim.Type)).FirstOrDefault(); if (c != null) { var id = c.ClaimId; userClaims.Add(new UserClaims { UserId = userId, ClaimId = id, Value = claim.Value }); } else { claimsToRemove.Add(claim); } }); claimsToRemove.ForEach(c => claims.Remove(c)); userClaims.Add(new UserClaims { UserId = userId, ClaimId = "20", Value = "User" }); claims.Add(new Claim(JwtClaimTypes.Role, "User")); var tenant = new Claim("tenant", context.Tenant.Split(".").First()); claims.Add(tenant); userClaims.Add(new UserClaims { UserId = userId, ClaimId = "17", Value = context.Tenant.Split(".").First() }); user = new IS4User() { ExternalUserId = userId, IsExternalUser = true, Tenant = _repo.GetTenant(context.Tenant.Split(".").First()), Provider = provider, Claims = userClaims }; _repo.RegisterUser(user); } else { claims.RemoveRange(0, claims.Count()); var listOfClaims = _repo.GetUserClaims(userId, true).Select(x => new Claim(x.Claims.Type, x.Value)).ToList(); claims.AddRange(listOfClaims); } // if the external system sent a session id claim, copy it over // so we can use it for single sign-out var sid = claims.FirstOrDefault(x => x.Type == JwtClaimTypes.SessionId); if (sid != null) { claims.Add(new System.Security.Claims.Claim(JwtClaimTypes.SessionId, sid.Value)); } // if the external provider issued an id_token, we'll keep it for signout AuthenticationProperties props = null; var id_token = result.Properties.GetTokenValue("id_token"); if (id_token != null) { props = new AuthenticationProperties(); props.StoreTokens(new[] { new AuthenticationToken { Name = "id_token", Value = id_token } }); } // issue authentication cookie for user await _events.RaiseAsync(new UserLoginSuccessEvent(provider, userId, user.UserId, user.Username)); await HttpContext.SignInAsync(userId, user.Username, provider, props, claims.ToArray()); // delete temporary cookie used during external authentication await HttpContext.SignOutAsync(IdentityServer4.IdentityServerConstants.ExternalCookieAuthenticationScheme); // validate return URL and redirect back to authorization endpoint or a local page if (_interaction.IsValidReturnUrl(returnUrl) || Url.IsLocalUrl(returnUrl)) { return(Redirect(returnUrl)); } return(Redirect("~/")); }
public async Task UpdateUser(IS4User user) { _dbContext.Attach(user).State = EntityState.Modified; await _dbContext.SaveChangesAsync(); }
public void RegisterUser(IS4User user) { _dbContext.Add(user); _dbContext.SaveChanges(); }
public async Task AddUser(IS4User user) { _dbContext.Add(user); await _dbContext.SaveChangesAsync(); }