/// <summary> /// Override of Identity ExternalLoginSignInAsync to validate a User's membership to a SecurityPool is active /// </summary> /// <param name="tenantKey">The TenantKey of the OIDC server</param> /// <param name="loginProvider">The Pogin Provider used</param> /// <param name="providerKey">The user's identifier provided by the Login Provider</param> /// <param name="poolId">The security pool to check for user membership</param> /// <param name="isPersistent">Flag indicating whether to persist the login cookie when the browser is closed</param> /// <returns></returns> public async Task <SignInResultCustom> ExternalLoginSignInAsync(string tenantKey, string loginProvider, string providerKey, bool isPersistent = false) { Ensure.Argument.NotNull(tenantKey); Ensure.Argument.NotNull(loginProvider); Ensure.Argument.NotNull(providerKey); var tenant = await _tenantManager.GetByKeyAsync(tenantKey); var user = await UserManager.FindByLoginAsync(tenant?.Id, loginProvider, providerKey); if (user == null) { return(SignInResultCustom.Failed()); } var validTenantUser = await IsValidTenantUser(tenant.Id, user); if (!validTenantUser) { return(SignInResultCustom.NotAllowed(user)); } // else var result = await ExternalLoginSignInAsync(loginProvider, providerKey, isPersistent); return(new SignInResultCustom(user, result)); }
private async Task <SignInResultCustom> TenantSignInAsync(Tenant tenant, string username, string password, bool isPersistent = false, bool lockoutOnFailure = false) { var user = await UserManager.FindByNameAsync(tenant.Id, username); var ldapEnabled = await _directoryManager.CheckForLdapSupport(tenant); var passwordSuccess = false; // Local users will immediately succeed if the password matches // NOTE: Skip if password hash is null since local users can't have null passwords if (user != null && user.PasswordHash != null) { passwordSuccess = VerifyPasswordHash(user, password); } // If user could not be signed in locally then let's try ldap if (ldapEnabled && !passwordSuccess) { var ldapUser = await LdapSignInAsync(tenant, username, password); if (ldapUser != null) { // Success, ldap user found.... // Sync the user and sign in using external auth scheme user = await SyncUserWithLdap(user, ldapUser); await SignInAsync(user, isPersistent, "Ldap"); return(SignInResultCustom.Success(user)); } } // fail if the user could not be found if (user == null) { return(SignInResultCustom.Failed()); } // Return any abnormal user states only if the user supplied the correct password if (passwordSuccess) { if (user.MustChangePassword) { return(SignInResultCustom.ChangePasswordRequired(user)); } // fail if the user's email address has not been confirmed (custom) if (!user.EmailConfirmed) { return(SignInResultCustom.EmailNotConfirmed()); } } // If we get this far then continue processing using base SignInManager to handle // two factor authentication, lockout policies, and password rehashing var baseResult = await PasswordSignInAsync(user, password, isPersistent, lockoutOnFailure); return(new SignInResultCustom(user, baseResult)); }
/// <summary> /// Override of Identity PasswordSignInAsync to validate a User's membership to a SecurityPool is active /// </summary> /// <param name="tenantKey">The TenantKey of the OIDC server</param> /// <param name="user">The User object</param> /// <param name="password">The provided unencryped password</param> /// <param name="poolId">The security pool to check for user membership</param> /// <param name="isPersistent">Flag indicating whether to persist the login cookie when the browser is closed</param> /// <param name="lockoutOnFailure">Flag indicating whether to lockout the user after upon reaching the invalid login attempt threshold</param> /// <returns></returns> public async Task <SignInResultCustom> PasswordSignInAsync(string tenantKey, string username, string password, bool isPersistent = false, bool lockoutOnFailure = false) { Ensure.Argument.NotNull(tenantKey); Ensure.Argument.NotNull(username); Ensure.Argument.NotNull(password); Tenant tenant = null; string seperator = null; if (username.Contains("/")) { seperator = "/"; } if (username.Contains(@"\")) { seperator = @"\"; } // Handle full qualified user names if (seperator != null) { var corpTenantKey = IdentityConstants.CorpTenantKey; var userTenantKey = username.Split(seperator.ToCharArray()).First(); // If the tenant specified by the user is valid, sign-in using this tenant if (userTenantKey.ToLower() == tenantKey.ToLower() || userTenantKey.ToLower() == corpTenantKey.ToLower()) { tenant = await _tenantManager.GetByKeyAsync(userTenantKey); username = username.Replace(userTenantKey + seperator, ""); } } else { // use the tenant supplied by the request tenant = await _tenantManager.GetByKeyAsync(tenantKey); } if (tenant != null) { return(await TenantSignInAsync(tenant, username, password, isPersistent, lockoutOnFailure)); } // if we get here we failed return(SignInResultCustom.Failed()); }