Моя компания оценивает Spring MVC чтобы определить, следует ли использовать ее в одном из следующих наших проектов. Пока мне нравится то, что я видел, и сейчас я смотрю модуль Spring Security, чтобы определить, можно ли это использовать/использовать.Тестирование модулей с помощью Spring Security
Наши требования к безопасности довольно просты; пользователь просто должен иметь возможность указать имя пользователя и пароль для доступа к определенным частям сайта (например, чтобы получить информацию об их учетной записи); и на сайте есть несколько страниц (часто задаваемые вопросы, поддержка и т. д.), где анонимному пользователю должен быть предоставлен доступ.
В прототипе, который я создавал, я хранили объект «LoginCredentials» (который просто содержит имя пользователя и пароль) в сеансе для аутентифицированного пользователя; некоторые из контроллеров проверяют, есть ли этот объект в сеансе, например, для получения ссылки на имя входа в систему. Вместо этого я хочу заменить эту доморощенную логику Spring Security, которая будет иметь приятную выгоду от удаления любого типа «как мы отслеживаем вход в систему пользователей?» и «как мы аутентифицируем пользователей?» от моего контроллера/бизнес-кода.
Похоже, Spring Security обеспечивает (каждый поток) «контекст» объект, чтобы иметь возможность получить доступ к имени пользователя/основную информации из любого места в вашем приложении ...
Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
... который, кажется, очень un-Spring, так как этот объект является (глобальным) singleton, в некотором роде.
Мой вопрос заключается в следующем: если это стандартный способ доступа к информации об аутентифицированном пользователе в Spring Security, каков приемлемый способ ввода объекта аутентификации в SecurityContext, чтобы он был доступен для моих модульных тестов, когда для единичных тестов требуется аутентифицированный пользователь?
Нужно ли это подключать в методе инициализации каждого тестового примера?
protected void setUp() throws Exception {
...
SecurityContextHolder.getContext().setAuthentication(
new UsernamePasswordAuthenticationToken(testUser.getLogin(), testUser.getPassword()));
...
}
Это кажется чересчур подробным. Есть ли более простой способ?
Сам SecurityContextHolder
объект кажется очень не-весеннему ...
Спасибо, это полезный совет. То, что я сделал до сих пор, в основном заключается в продолжении вызова SecurityContextHolder.getContext() (через несколько собственных методов-оболочек, поэтому, по крайней мере, он вызван только из одного класса). – 2008-12-16 19:56:39
Хотя одна заметка - я не думаю, что у ServletContextHolder есть какая-либо концепция HttpSession или способ узнать, работает ли она в среде веб-сервера - она использует ThreadLocal, если вы не настроите ее на использование чего-то другого (только два других встроенных режима: InheritableThreadLocal и Global) – 2008-12-16 19:57:19
Единственный недостаток использования бобов, зависящих от сеанса/запроса, весной заключается в том, что они потерпят неудачу в тесте JUnit. Что вы можете сделать, так это реализовать настраиваемую область, которая будет использовать сеанс/запрос, если она доступна, и вернуться к потоку. Я предполагаю, что Spring Security делает что-то подобное ... – 2008-12-16 21:30:07