Привет всем, у меня есть секретный вопрос для новичков в Grails / Spring. Мы настроили oauth2 в нашем проекте Grails 3, используя spring-security-oauth2- провайдер, и, кажется, все работает для защиты наших REST API.
Но затем мы начали добавлять веб-интерфейс в тот же проект, используя GSP, и пришли к распутью. Обычно oauth2 работает, аутентифицируясь в конечной точке и получая токен, который он может использовать в заголовке HTTP в последующих запросах для сохранения доступа к защищенным ресурсам. Но у моего веб-интерфейса есть страница входа. Поэтому изначально мы думали рассматривать веб-интерфейс как одного из клиентов (у нас есть 1 клиент для нашего приложения для iOS и 1 клиент для нашего приложения для Android, так почему бы не иметь еще 1 для нашего веб-приложения). Но кажется странным делать HTTP-запрос из кода нашего контроллера (для входа в систему) к конечной точке нашего провайдера oauth2, потому что он находится в том же проекте; и большинство последующих запросов, которые должен сделать мой веб-интерфейс, мы хотим получить прямой доступ к базовым службам и объектам домена, поэтому добавление дополнительного прыжка кажется контрпродуктивным.
Итак, что мы выбрали, так это то, что когда я вхожу в систему, используя свой login.gsp, в коде контроллера, я обхожу вход в систему oauth2 и просто выполняю прямую аутентификацию безопасности spring, используя authenticationManager.authenticate() с UsernamePasswordAuthenticationToken, который я создаю из имени пользователя и поля пароля, переданные в мою форму, а затем вызов SecurityContextHolder.getContext().setAuthentication() в ответе. Эта половина решает мою проблему, потому что мне сказали из это сообщение о том, что при этом SecurityContextHolder будет установлен только в текущем потоке, а поскольку SecurityContextHolder очищается в конце цепочки фильтров, последующие запросы не будут аутентифицироваться. Итак, что я сделал, так это то, что если эта аутентификация проходит (т. Е. Никаких исключений), то я помещаю свой пользовательский объект в сеанс HTTP и во всех последующих запросах пытаюсь получить его как способ «сказать», что я аутентифицирован. Но это кажется и хакерским, и грязным; и это приводит к тому, что мой пользовательский объект не подключен к сеансу БД (вызывая ленивые исключения инициализации).
Я нашел другие подобные предложения из таких сообщений, как , который помещает весь SecurityContext в сеанс HTTP, но, похоже, не указывает, как использовать этот SecurityContext в последующих запросах.
Я предполагаю, что мой главный вопрос в том, что мы идем по этому пути неправильно? Есть ли лучший и более чистый способ выполнить то, что я хочу сделать? Я полагаю, что мы не можем быть первыми, кто попытается это сделать.