Рестлет: Использование классов SecretVerifier и Enroler вызывает 2 обращения к базе данных. Эффективен ли этот шаблон? - PullRequest
1 голос
/ 14 августа 2011

В Restlet у вас есть класс SecretVerifier с абстрактным методом verify(String identifier, char[] secret), который вы должны переопределить в своем подклассе.Базовый класс также создаст объект User, инициализированный идентификатором.Пока все хорошо.

Теперь необходимо реализовать интерфейс Enroler для «добавления» ролей к вышеупомянутому объекту User (который передается подклассу через объект ClientInfo).Здесь вы «добавляете» роли к объекту User.

Предположим, что ChallengeAuthenticator используется для аутентификации.

Вопрос : Оба эти класса довольноотличается, и у вас нет доступа к соответствующим объектам запроса / ответа.Сама конструкция вынуждает вас выполнить 2 поездки в БД - одну для проверки пароля и одну для получения ролей пользователя.Это эффективный дизайн?

Вы можете, так сказать, получить все в одном запросе.И так как оба класса будут вызывать соответствующие DAO по отдельности, к БД будет 2 вызова.

Конечно, вы можете получить слегка запутанный код, переопределив SecretVerifier.getIdentifier(Request req, Response resp), а затем использовать его для извлечения всего и добавления ролей.- но метод verify, кажется, является частью шаблона template, и вы не можете реально контролировать то, что происходит в базовом классе, если вы непосредственно не реализуете Verifier, не изобретаете колесо и не настраиваете код когда-либотак немного ... но вопрос о дизайнерском решении.Я не хочу начинать дебаты.Я просто хочу знать, что-то вроде этого (2 поездки) один для проверки подлинности, другой для ролей довольно распространен и эффективен при умеренно высоких нагрузках?

1 Ответ

3 голосов
/ 30 августа 2011

Я хорошо понимаю ваш вопрос.На самом деле аутентификация и авторизация - это две разные проблемы.В вашем случае вы обрабатываете оба приложения, но это не всегда так, особенно если вы используете внешние поставщики аутентификации через OpenID.В этом случае выбранный поставщик выполняет проверку подлинности, а затем вы управляете ролями для текущего пользователя.

Что касается вашего вопроса, вы можете выполнить проверку подлинности и авторизацию за один вызов базы данных.Вам необходимо получить подсказки пользователя / роли в объекте верификатора, а затем передать их объекту регистратора, используя текущий экземпляр запроса.

Вот пример:

  • Verifier:

    public class MySecretVerifier extends SecretVerifier {
        private SecurityDao securityDao = (...);
    
        public int verify(String identifier, char[] secret)
                             throws IllegalArgumentException {
            ApplicationUser user = securityDao.loadUser(identifier);
            //user contains both user hints and roles
            if (user!=null
                  && compare(user.getPassword().toCharArray(), secret)) {
                Request request = Request.getCurrent();
                request.getAttributes().put("currentUser", user);
                return SecretVerifier.RESULT_VALID;
            } else {
                return SecretVerifier.RESULT_INVALID;
            }
        }
    }
    
  • Enroler:

    public class MyEnroler implements Enroler {
        public void enrole(ClientInfo clientInfo) {
            Request request = Request.getCurrent();
            User user = request.getAttributes().put("currentUser");
            if (user!=null) {
                List<UserRole> roles = user.getRoles();
                if (roles!=null) {
                    for (UserRole userRole : roles) {
                        // example of role creation
                        Role role = new Role(userRole.getName(), "");
                        clientInfo.getRoles().add(role);
                    }
                }
            }
        }
    }
    

Надеюсь, это поможет вам.Thierry

...