Предлагается 500 баллов.. Полный код и инструкции по быстрому воспроизведению проблемы приведены ниже.
ПРОБЛЕМА:
HttpSession
становится null
после пользовательской реализации DefaultOAuth2RequestFactory
заменяет текущую AuthorizationRequest
с сохраненным AuthorizationRequest
.. Это приводит к сбою последующего запроса до /oauth/token
, потому что CsrfFilter в цепочке фильтров безопасности Spring, предшествующей конечной точке /oauth/token
, не может найти session
Csrf token
в null
session
для сравнения с request
Csrf token
.
КОНТРОЛЬНЫЙ ПОТОК ВО ВРЕМЯ ОШИБКИ:
Следующая блок-схема иллюстрирует, где Шаг 14 и Шаг 15 как-то null
-ify HttpSession
. (Или, возможно, несоответствие a JSESSIONID
.) A SYSO
в начале CustomOAuth2RequestFactory.java
в Шаг 14 показывает, что действительно есть HttpSession
, который действительно содержит правильный CsrfToken
, Тем не менее, как-то, HttpSession
стал null
к моменту Шаг 15 запускает вызов от клиента по адресу localhost:8080/login
обратно к конечной точке localhost:9999/oauth/token
.
Точки останова были добавлены в каждую строку HttpSessionSecurityContextRepository
, указанную в журналах отладки ниже. (Он находится в папке Maven Dependencies
проекта authserver
eclipse.) Эти точки останова подтвердили, что HttpSession
null
, когда окончательный запрос /oauth/token
сделан в блок-схеме ниже. (Внизу слева от блок-схемы.) null
HttpSession
может быть из-за JSESSIONID
, который остается в браузере, устаревшем после выполнения пользовательского кода DefaultOAuth2RequestFactory
.
Как эта проблема может быть исправлена, так что тот же HttpSession
остается во время окончательного вызова конечной точки /oauth/token
после завершения шага 15 в блок-схеме?
СООТВЕТСТВУЮЩИЙ КОД И ЛОГИСТИКИ:
Полный код CustomOAuth2RequestFactory.java
можно просмотреть на сайте совместного доступа к файлам, нажав на эту ссылку. Мы можем догадаться что null
session
обусловлено либо 1.) JSESSIONID
не обновляется в браузере кодом в CustomOAuth2RequestFactory
, либо 2.) HttpSession
на самом деле null
.
Spring Загрузочные журналы отладки для вызова /oauth/token
после Шаг 15 четко указывают, что нет HttpSession
к этой точке и могут быть прочитаны следующим образом:
2016-05-30 15:33:42.630 DEBUG 13897 --- [io-9999-exec-10] o.s.security.web.FilterChainProxy : /oauth/token at position 1 of 12 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
2016-05-30 15:33:42.631 DEBUG 13897 --- [io-9999-exec-10] o.s.security.web.FilterChainProxy : /oauth/token at position 2 of 12 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
2016-05-30 15:33:42.631 DEBUG 13897 --- [io-9999-exec-10] w.c.HttpSessionSecurityContextRepository : No HttpSession currently exists
2016-05-30 15:33:42.631 DEBUG 13897 --- [io-9999-exec-10] w.c.HttpSessionSecurityContextRepository : No SecurityContext was available from the HttpSession: null. A new one will be created.
2016-05-30 15:33:42.631 DEBUG 13897 --- [io-9999-exec-10] o.s.security.web.FilterChainProxy : /oauth/token at position 3 of 12 in additional filter chain; firing Filter: 'HeaderWriterFilter'
2016-05-30 15:33:42.631 DEBUG 13897 --- [io-9999-exec-10] o.s.s.w.header.writers.HstsHeaderWriter : Not injecting HSTS header since it did not match the requestMatcher org.springframework.se[email protected]2fe29f4b
2016-05-30 15:33:42.631 DEBUG 13897 --- [io-9999-exec-10] o.s.security.web.FilterChainProxy : /oauth/token at position 4 of 12 in additional filter chain; firing Filter: 'CsrfFilter'
2016-05-30 15:33:42.644 DEBUG 13897 --- [io-9999-exec-10] o.s.security.web.csrf.CsrfFilter : Invalid CSRF token found for http://localhost:9999/uaa/oauth/token
2016-05-30 15:33:42.644 DEBUG 13897 --- [io-9999-exec-10] w.c.HttpSessionSecurityContextRepository : SecurityContext is empty or contents are anonymous - context will not be stored in HttpSession.
2016-05-30 15:33:42.644 DEBUG 13897 --- [io-9999-exec-10] s.s.w.c.SecurityContextPersistenceFilter : SecurityContextHolder now cleared, as request processing completed
RE-СОЗДАНИЕ ПРОБЛЕМЫ НА ВАШЕМ КОМПЬЮТЕРЕ:
Вы можете воссоздать проблему на любом компьютере всего за несколько минут, выполнив следующие простые шаги:
1.) Загрузите сжатую версию приложения с сайта совместного доступа к файлам, нажав на эту ссылку.
2.) Разархивируйте приложение, набрав: tar -zxvf oauth2.tar(4).gz
3.) Запустите приложение authserver
, перейдя на oauth2/authserver
, а затем введите mvn spring-boot:run
.
4.) Запустите приложение resource
, перейдя на oauth2/resource
, а затем введите mvn spring-boot:run
5.) Запустите приложение ui
, перейдя на oauth2/ui
, а затем введите mvn spring-boot:run
6.) Откройте веб-браузер и перейдите к http : // localhost : 8080
7.) Нажмите Login
, а затем введите Frodo
в качестве пользователя и MyRing
в качестве пароля и нажмите, чтобы отправить.
8.) Введите 5309
в качестве Pin Code
и нажмите "Отправить". Это вызовет ошибку, показанную выше.
Журналы отладки Spring будут отображать LOT SYSO
, который дает значения переменных, таких как XSRF-TOKEN
и HttpSession
на каждом шаге, показанном на блок-схеме. SYSO
помогает сегментировать журналы отладки, чтобы их было легче интерпретировать. И все SYSO
выполняется одним классом, называемым другими классами, поэтому вы можете манипулировать классом SYSO
-generating, чтобы изменить отчетность везде в потоке управления. Имя SYSO
-генерирующего класса TestHTTP
, а его исходный код может быть найден в том же пакете demo
.
ИСПОЛЬЗУЙТЕ ДЕВУШЕР:
1.) Выберите окно терминала, в котором запущено приложение authserver
, и введите Ctrl-C
, чтобы остановить приложение authserver
.
2.) Импортируйте три приложения (authserver
, resource
и ui
) в eclipse как существующие проекты maven.
3.) В authserver
приложении eclipse Project Explorer щелкните, чтобы развернуть папку Maven Dependencies
, затем прокрутите ее вниз, чтобы открыть значок Spring-Security-web...
jarкак показано на рисунке ниже, оранжевым. Затем прокрутите, чтобы найти и развернуть пакет org.springframework.security.web.context
. Затем дважды щелкните, чтобы открыть класс HttpSessionSecurityContextRepository
, выделенный синим цветом на снимок экрана ниже. Добавьте точки останова в каждую строку этого класса. Возможно, вы захотите сделать то же самое с классом SecurityContextPersistenceFilter
в том же пакете. Эти точки останова позволят вам увидеть значение HttpSession
, которое в настоящее время становится null
до конца потока управления, но должно иметь допустимое значение, которое может быть сопоставлено с XSRF-TOKEN
, чтобы разрешить этот OP.
4.) В пакете app demo
добавьте точки останова внутри CustomOAuth2RequestFactory.java
. Затем Debug As... Spring Boot App
, чтобы запустить отладчик.
5.) Затем повторите шаги с 6 по 8 выше. Вы можете очистить кеш браузера перед каждой новой попыткой. И вы можете открыть вкладку "Сеть" в инструментах разработчика браузера.