Используйте пользовательские исключения в Spring Security

Я создал пользовательский AuthenticationProviderдля выполнения пользовательских проверок безопасности. Я также создал пользовательские исключения, которые унаследованы от AccountStatusException, чтобы уведомлять о проблемах со статусом пользователя, например, когда пользователь не подтвердил свою учетную запись в течение определенного периода времени. Мой UserDetailsтакже является пользовательской реализацией.

Вот код проверки безопасности, которую я выполняю. Код, не имеющий отношения к делу, опущен.

public class SsoAuthenticationProvider implements AuthenticationProvider {

    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        String username = (String) authentication.getPrincipal();
        User user = null;
        if (username != null) {
            user = getUserRepository().findByUserName(username);
            if (user != null) {
                if (user.getEnabled() != 0) {
                    if ((user.getUserDetail().getConfirmed() != 0)
                            || ((new Date().getTime() - user.getUserDetail().getRequestDate().getTime()) / (1000 * 60 * 60 * 24)) <= getUnconfirmedDays()) {
                        if (getPasswordEncoder().isPasswordValid(user.getPassword(),
                                (String) authentication.getCredentials(), user)) {
                            user.authenticated = true;
                            user.getAuthorities();
                        }
                    } else {
                        throw new UserNotConfirmedAndTimeExceeded(
                                "User has not been cofirmed in the established time period");
                    }
                } else {
                    throw new DisabledException("User is disabled");
                }
            } else {
                throw new BadCredentialsException("User or password incorrect");
            }
        } else {
            throw new AuthenticationCredentialsNotFoundException("No credentials found in context");
        }
        return user;
    }
}

SsoAuthenticationProviderпроверяет:

  1. То, что имя пользователя зарегистрировано (, существует в БД)
  2. Что пользователь подтвердил свой адрес электронной почты
  3. Если пользователь не подтвердил свой адрес электронной почты, убедитесь, что он все еще находится в льготном периоде (, это несколько дней, которые мы даем пользователям, чтобы подтвердить свой адрес электронной почты, позволяя им получить доступ к сайту)
  4. Если пользователь не подтвердил электронную почту и он не находится в льготном периоде, создайте исключение безопасности, чтобы сообщить об этом статусе и отклонить аутентификацию

. Проблема в том, что не все эти исключения выбрасываются вверх по стеку до контроллера, поэтому кажется невозможным сообщить пользователю о проблеме входа.

Использование UserDetailsметодов, таких какisEnabled()(и подобное )невозможно, поскольку семантика наших различных статусов учетных записей пользователей совершенно различна.

Является ли это правильным подходом для создания пользовательской безопасности с пользовательскими исключениями? Должен ли я реализовать что-то еще, чтобы это сработало?

5
задан Mike Partridge 12 August 2014 в 14:10
поделиться