Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Java Новый топик    Ответить
 Control Auth Header in Spring MVC,когда Frontend и Backend один проект?  [new]
_webdev_
Member

Откуда: Germany
Сообщений: 538
Здравствуйте,

Я пытаюсь понять, смогу ли я сделать следующее.

У меня настроен Spring Security. Cтандартный процесс авторизации через фильтры на основе заголовка Auth. С отдельными сессиями для пользователей и админов. Все это отлично работает, если у меня есть фронтенед и бекенд отдельно. До сих пор так было.

Сейчас я хочу фронтенд и бэкэнд в одном проекте? Например Spring + Tymeleaf. Как я могу контролировать Auth Request Header, чтоб сохранить существующий порядок вещей?

В этом случае страницы рендерятся на сервере, и у меня нет возможности управлять Auth Request Header.

Как и что мне нужно перенастроить, чтобы использовать существующий механизм безопасности?

Или в данном случае я могу настроить Spring Security только с помощью Spring Session? Или как быть в данном случае?

Спасибо за советы и полезные ссылки.
17 апр 21, 08:13    [22310101]     Ответить | Цитировать Сообщить модератору
 Re: Control Auth Header in Spring MVC,когда Frontend и Backend один проект?  [new]
PetroNotC Sharp
Member

Откуда:
Сообщений: 8254
_webdev_
В этом случае страницы рендерятся на сервере, и у меня нет возможности управлять Auth Request Header.

вот как ты это решил?
Расскажи.
Разве JSP \ Spring или другой MVC не рендерятся на сервере?
17 апр 21, 11:43    [22310122]     Ответить | Цитировать Сообщить модератору
 Re: Control Auth Header in Spring MVC,когда Frontend и Backend один проект?  [new]
PetroNotC Sharp
Member

Откуда:
Сообщений: 8254
_webdev_,
рисуй схему запроса GET. Рассказывай подробнее в чем проблема.
17 апр 21, 11:44    [22310123]     Ответить | Цитировать Сообщить модератору
 Re: Control Auth Header in Spring MVC,когда Frontend и Backend один проект?  [new]
_webdev_
Member

Откуда: Germany
Сообщений: 538
Проблема очень "простая".
У меня немного отсуствуеть звенье в цепочке. Никогда не делал приложений где фронт и бек в одной упаковке.
Раньше был ангуляр в котором я посылал запрос на логин к серверу POST Сервер проверял всё, создавал секюрити контекст, выдавал юзеру токен. С этим токеном я образался к зашищенным ресурсам. У меня всё по спринговски.

вот как-то так.
                .authorizeRequests().anyRequest().authenticated()
                .and()
                .addFilterBefore(new UserAuthenticationFilter(authenticationManager()), UsernamePasswordAuthenticationFilter.class)
                .addFilterBefore(new AdminEndpointAuthenticationFilter(authenticationManager()), UsernamePasswordAuthenticationFilter.class)
                .addFilterBefore(new ActuatorEndpointAuthenticationFilter(authenticationManager()), UsernamePasswordAuthenticationFilter.class)

    @Override
    protected void configure(final AuthenticationManagerBuilder auth) {
        auth.authenticationProvider(authenticationProvider);
    }


Всё работает как надо.
Теперь когда в одном проекте. я немного не понимаю, как мне при запросе вставить хедер, чтоб он уже был видим в фильтре, когда ещё не дошёл запрос к контроллеру?

Вот например, логин. Я немного не понимаю, как передавать токен и как потом с ним работать?
Надеюсь, так моя проблема понятней.

    @GetMapping(value = "/login")
    public ModelAndView login() {
        return new ModelAndView("login");
    }

    @PostMapping(value = "/login")
    public ModelAndView login(@Valid LoginDto login, BindingResult result, HttpServletResponse response, HttpServletRequest request) {
        response.addHeader("bla", "bla-bla");
        return new ModelAndView("redirect:/dashboard");
    }


Что я должен сделать при логине, чтоб сл запрос содержал в себе хедер с токеном? и проверялся фильтрами при доступе к dashboard? Это пока такой, быстрый тестовый вариант. Я не создаю секюрити контекст пока.

Спасибо!
17 апр 21, 15:43    [22310214]     Ответить | Цитировать Сообщить модератору
 Re: Control Auth Header in Spring MVC,когда Frontend и Backend один проект?  [new]
Stanislav Bashkyrtsev
Member

Откуда: СПб
Сообщений: 137
Как делпоится бек и фронт - вообще не важно. Страница всегда загружается в браузере, запрос всегда уходит на апп сервер. Так что хоть ты генерируешь страницы на сервере с помощью Tymeleaf/JSP/Velocity/etc, хоть с помощью JS - ты можешь продолжать в любом случае использовать JS и слать AJAX POST запрос. Это не взаимоисключающие вещи.

Альтернатива такому подходу (когда запросы шлет JS): HTML формы. Сам браузер будет формировать список параметров исходя из данных в форме и отсылать такой запрос на BE. Со стороны BE мы проверяем креды и устанавливаем SESSIONID в куках response header'a (это как раз делает Spring Security). Ну и делаем редирект на какую-то страницу после удачного логина.

автор
Сервер проверял всё, создавал секюрити контекст, выдавал юзеру токен
Какой токен? Счас речь не про OAuth2 случайно? Или все таки может SESSIONID а не токен? И что за Auth, может Authorization header?

Сообщение было отредактировано: 17 апр 21, 18:36
17 апр 21, 18:41    [22310288]     Ответить | Цитировать Сообщить модератору
 Re: Control Auth Header in Spring MVC,когда Frontend и Backend один проект?  [new]
_webdev_
Member

Откуда: Germany
Сообщений: 538
Stanislav Bashkyrtsev,

Спасибо за ответ. Я думаю, тут немного проблема с определениями.

автор
Со стороны BE мы проверяем креды и устанавливаем SESSIONID в куках response header'a (это как раз делает Spring Security).
- Вот. Давай вот о этом поговорим. SESSIONID(Spring Session) я вижу. Но У меня например кастомный хедер куда я после удачного логина кладу токен/SESSIONID(можно как угодно назвать), это просто рандомный стринг. Я залогинился, записал My-X-Auth хедер в response. Сделал редирект на dashboard. В request хедер My-X-Auth отсутствует.

Я понимаю, что я секюрити могу сделать со (Spring Session), но хочу понять, могу ли я сделать так как я делал раньше.

автор
Какой токен? Счас речь не про OAuth2 случайно? Или все таки может SESSIONID а не токен?
- Нет.

Как и писал выше - SESSIONID / токен - это просто рандомный стринг который определяет сессию.
17 апр 21, 18:54    [22310300]     Ответить | Цитировать Сообщить модератору
 Re: Control Auth Header in Spring MVC,когда Frontend и Backend один проект?  [new]
_webdev_
Member

Откуда: Germany
Сообщений: 538
_webdev_,

автор
И что за Auth, может Authorization header
- Да, только он у меня кастомный и называется например "My-X-Auth"
17 апр 21, 19:34    [22310312]     Ответить | Цитировать Сообщить модератору
 Re: Control Auth Header in Spring MVC,когда Frontend и Backend один проект?  [new]
Stanislav Bashkyrtsev
Member

Откуда: СПб
Сообщений: 137
Да, давай сначала в терминологии и подходах разберемся. При логине нам нужно создавать HTTP Session (речь даже не про спринг). По сути все сводится к:
1. Если имя/пароль верные, то сервер обратно браузеру в Response Headers отдает куки. Назовем ее SESSIONCOOKIE.
2. Т.к. кука - это такой хедер, который с каждым запросом шлется на сервер, то этот SESSIONCOOKIE теперь и будет приходить со всеми последующими на наш сервер.
3. Когда мы на сервере генерили эту SESSIONCOOKIE, то мы ассоциировали ее с каким-то состоянием (как правило за нас это делает Tomcat, мы просто дергаем метод getSession()). Т.е. под капотом у нас есть мапа: Map<String, SessionContent> - в этой мапе ключом является SESSIONCOOKIE, а значением - ну что захотим. Обычно там хранится как минимум имя пользователя который эту сессию создал.
3.1 И т.к. с клиента нам пришел SESSIONCOOKIE, то мы можем проверить есть ли такой ключ в мапе, и если есть - вытащить имя пользователя.

Да, название куки не принципиально - это может быть SESSIONID или Auth. Но все-таки мы привыкли называть его SESSIONID, другое название может сбить с толку. Но важно что он не является отдельным хедером, он хранится внутри хедера Cookies. Именно его браузер сохраняет и сам будет добавлять в каждый запрос. И именно из него сервер будет его потом доставать.

Если же ты создашь просто хедер SESSIONID, то JS может его и получит, однако после рефреша страницы все состояние JS'a сотрется и прийдется логиниться заново. А вот Cookies браузер сохранит в своем хранилище автоматически. И после рефреша страницы он останется.

Так же есть понятие Authorization header'a - это штука совсем другая, это альтернативный способ аутентификации. Это еще один спец хедер. В зависимости от типа авторизации там могут быть разные данные, однако когда речь идет про браузер, то как правило используют тип Basic Auth. В таком случае туда складывают username & password пользователя. Для этого серверу нужно вернуть в запросе информацию о том он хочет авторизовывать именно с помощью Basic Auth. И тогда браузе покажет свое нативное окошко (не HTML & JS), куда пользователь введет имя и пароль. И они при каждом запросе будут слаться на сервер. Этот хедер браузер запомнит на какое-то время, но после рестарта браузера оно потрется.

Все другие кастомные хедеры которые ты будешь создавать - их нужно явно в JS слать с каждым запросом. Браузер их не будет добавлять автоматически. И это не то как мы обычно реализуем аутентификацию.

Сообщение было отредактировано: 17 апр 21, 20:10
17 апр 21, 20:18    [22310331]     Ответить | Цитировать Сообщить модератору
 Re: Control Auth Header in Spring MVC,когда Frontend и Backend один проект?  [new]
PetroNotC Sharp
Member

Откуда:
Сообщений: 8254
Stanislav Bashkyrtsev,
Все верно, только боюсь ему надо именно магию спринг и спринг бут и Spring Security.
17 апр 21, 22:33    [22310396]     Ответить | Цитировать Сообщить модератору
 Re: Control Auth Header in Spring MVC,когда Frontend и Backend один проект?  [new]
_webdev_
Member

Откуда: Germany
Сообщений: 538
Stanislav Bashkyrtsev - Спасибо, кажется твоим объяснением недостающее звено заполнилось.


Stanislav Bashkyrtsev
2. Т.к. кука - это такой хедер, который с каждым запросом шлется на сервер, то этот SESSIONCOOKIE теперь и будет приходить со всеми последующими на наш сервер.
- Вот, это я упустил. У меня в голове было, что это должен делать я. Как я говорил в своём примере с "My-X-Auth". Теперь понятно, что это будет делать браузер. Я знаю, что сождаётся сессия с каждым юзером, но она меня мало интересовала у меня бьла своя имплементация.

Значит в данном случае только такой вариант security. Нужно будет немного переделать свой вариант и найти соответсвующие фильтры и интерсепторы, которые проверяют HttpSession, а не стандартный SpringSecurity Filter Chain. Хотяяя, наверное можно и в стандартном, только надо проверять грубо говоря не мой "My-X-Auth" который я не могу установить в request, a request.getSession().getSessionID().

автор
Если же ты создашь просто хедер SESSIONID, то JS может его и получит, однако после рефреша страницы все состояние JS'a сотрется и прийдется логиниться заново. А вот Cookies браузер сохранит в своем хранилище автоматически. И после рефреша страницы он останется.
- вооот, именно этого понимания мне не хватало, что браузер сделает это для меня и будет слать с каждым запросом эту переменную. Спасибо.


Stanislav Bashkyrtsev
Так же есть понятие Authorization header'a - это штука совсем другая, это альтернативный способ аутентификации. Это еще один спец хедер. В зависимости от типа авторизации там могут быть разные данные, однако когда речь идет про браузер, то как правило используют тип Basic Auth. В таком случае туда складывают username & password пользователя. Для этого серверу нужно вернуть в запросе информацию о том он хочет авторизовывать именно с помощью Basic Auth. И тогда браузе покажет свое нативное окошко (не HTML & JS), куда пользователь введет имя и пароль. И они при каждом запросе будут слаться на сервер. Этот хедер браузер запомнит на какое-то время, но после рестарта браузера оно потрется.
- Ну вот, именно по такому принципу у меня и было организовано. Просто я переименовал стандартное имя "Authorization" в своё. ))) Да, но у нас в барузере есть различные storages, где мы можем хранить этот ключ, ну а уже на сервере продлять(ttl)/удалять этот ключ и сессию автентификации.

В общем, спасибо. Кажется, я понял, что у меня сейчас только такой вариант имплементации, если я хочу всё в одном проекте.
18 апр 21, 08:10    [22310470]     Ответить | Цитировать Сообщить модератору
 Re: Control Auth Header in Spring MVC,когда Frontend и Backend один проект?  [new]
_webdev_
Member

Откуда: Germany
Сообщений: 538
PetroNotC Sharp
Все верно, только боюсь ему надо именно магию спринг и спринг бут и Spring Security.
- Потом проверю, но насколько я помню. То можно до сессия из реквеста достучаться. Соответственно, можно и дальше использовать магию спринга, но при этом ключ сессии брать не из своего кастомного хедера "My-X-Auth", а из SESSIONID. Установить ttl сессии. И потом как-то продлять если надо, или она автоматически продляется с каждім запросом. В общем почитать надо.
Спасибо.
18 апр 21, 08:13    [22310471]     Ответить | Цитировать Сообщить модератору
 Re: Control Auth Header in Spring MVC,когда Frontend и Backend один проект?  [new]
Андрей Панфилов
Member

Откуда: Москва > Melbourne
Сообщений: 3852
_webdev_
Да, но у нас в барузере есть различные storages, где мы можем хранить этот ключ, ну а уже на сервере продлять(ttl)/удалять этот ключ и сессию автентификации.
Офигеть...
18 апр 21, 09:58    [22310486]     Ответить | Цитировать Сообщить модератору
 Re: Control Auth Header in Spring MVC,когда Frontend и Backend один проект?  [new]
_webdev_
Member

Откуда: Germany
Сообщений: 538
Андрей Панфилов
_webdev_
Да, но у нас в барузере есть различные storages, где мы можем хранить этот ключ, ну а уже на сервере продлять(ttl)/удалять этот ключ и сессию автентификации.
Офигеть...
- если есть что сказать, то по попрошу по сути и без сарказма. Спасибо
18 апр 21, 10:22    [22310489]     Ответить | Цитировать Сообщить модератору
 Re: Control Auth Header in Spring MVC,когда Frontend и Backend один проект?  [new]
Stanislav Bashkyrtsev
Member

Откуда: СПб
Сообщений: 137
автор
Ну вот, именно по такому принципу у меня и было организовано. Просто я переименовал стандартное имя "Authorization" в своё.
Ну и приходилось опять же - самому слать этот хедер. Authorization браузер без нашего участия может слать. Но это совсем другой тип авторизации где нет сессии (браузер шлет Authorization с кредами каждый раз) и его редко используют.
автор
Соответственно, можно и дальше использовать магию спринга, но при этом ключ сессии брать не из своего кастомного хедера "My-X-Auth", а из SESSIONID.
Да, можно спрингом, можно самому написать. Но наверно надежней все-таки спрингом :)

автор
И потом как-то продлять если надо, или она автоматически продляется с каждім запросом.
Да, автоматически. В куках есть expiration - браузер считает его от последнего запроса на сервер.
автор
Соответственно, можно и дальше использовать магию спринга
Это не должно быть магией - попробуй подебажить спринговые фильтры/интерсепторы да разобраться где там что.
автор
Да, но у нас в барузере есть различные storages, где мы можем хранить этот ключ, ну а уже на сервере продлять(ttl)/удалять этот ключ и сессию автентификации.
Угумс. Cookies по сути это еще один такой storage. Проблема с твоими другими storage'ами - к ним есть доступ у JS, а это не безопасно. Потому как если у тебя будет бага и тебе сделают HTML Injection (aka XSS), то злоумышленник может получить доступ к этому хранилищу и у знать твой SESSIONID (например, его JS возьмет и незаметно пошлет SESSIONID в посте этого форума, ну а там уже останется только скопировать).

А вот в Cookies можно задавать флажки при изначальном их создании. Одним из них есть HttpOnly (советую прочесть всю страницу) - он значит что такая кука будет передаваться браузером, однако JS не будет иметь к ней доступ.

Открой ради интереса Web Developer в своем браузере (обычно открывается с помощью F12), и посмотри на вкладку Application. У этого форума есть несколько кук, включая ASP.NET_SessionId, у нее проставлен HttpOnly.

Сообщение было отредактировано: 18 апр 21, 10:18
18 апр 21, 10:26    [22310490]     Ответить | Цитировать Сообщить модератору
 Re: Control Auth Header in Spring MVC,когда Frontend и Backend один проект?  [new]
Андрей Панфилов
Member

Откуда: Москва > Melbourne
Сообщений: 3852
_webdev_
Андрей Панфилов
пропущено...
Офигеть...
- если есть что сказать, то по попрошу по сути и без сарказма. Спасибо


Да все вроде по делу.... У вас вопрос на самом деле звучит так: "я пытаюсь сделать невероятную небезопасную хрень, а оно сопротивляется", за такое вам уже пора Станиславу бутылку односолодового высылать.
18 апр 21, 10:39    [22310492]     Ответить | Цитировать Сообщить модератору
 Re: Control Auth Header in Spring MVC,когда Frontend и Backend один проект?  [new]
_webdev_
Member

Откуда: Germany
Сообщений: 538
Stanislav Bashkyrtsev
Это не должно быть магией - попробуй подебажить спринговые фильтры/интерсепторы да разобраться где там что.
- я просто к слову. Я ж уже использую Security Filters Chain.

Stanislav Bashkyrtsev
Угумс. Cookies по сути это еще один такой storage. Проблема с твоими другими storage'ами - к ним есть доступ у JS, а это не безопасно. Потому как если у тебя будет бага и тебе сделают HTML Injection (aka XSS), то злоумышленник может получить доступ к этому хранилищу и у знать твой SESSIONID (например, его JS возьмет и незаметно пошлет SESSIONID в посте этого форума, ну а там уже останется только скопировать).
- да, это я тоже прекрасно понимаю.

За HttpOnly отдельное спасбо. Почитаю,
Да и за расстановку "по полочкам" - пасиб. Думаю, вопрос исчерпан.
18 апр 21, 11:13    [22310501]     Ответить | Цитировать Сообщить модератору
 Re: Control Auth Header in Spring MVC,когда Frontend и Backend один проект?  [new]
_webdev_
Member

Откуда: Germany
Сообщений: 538
Андрей Панфилов
Да все вроде по делу.... У вас вопрос на самом деле звучит так: "я пытаюсь сделать невероятную небезопасную хрень, а оно сопротивляется", за такое вам уже пора Станиславу бутылку односолодового высылать.
- не совсем, работало всё просто по другому принципу. И чтоб понять новый принцип, я здесь спросил. Для этого же форумы и существуют, не? ))
18 апр 21, 11:15    [22310502]     Ответить | Цитировать Сообщить модератору
 Re: Control Auth Header in Spring MVC,когда Frontend и Backend один проект?  [new]
lleming
Member

Откуда:
Сообщений: 1787
cookie http only. если не ошибка в самом браузере вообщем угнать скриптом не так просто. а если header сам генерится или в страницу проставляется то прям беда
23 апр 21, 16:13    [22313287]     Ответить | Цитировать Сообщить модератору
Все форумы / Java Ответить