HttpSession null после замены AuthorizationRequest

Полный код и инструкции по быстрому воспроизведению проблемы приведены ниже.


ПРОБЛЕМА:
HttpSession становится null после пользовательской реализации DefaultOAuth2RequestFactory заменяет текущий AuthorizationRequest с сохраненным AuthorizationRequest. Это приводит к отказу последующего запроса на /oauth/token, потому что CsrfFilter в цепочке фильтров Spring Security, предшествующей конечной точке /oauth/token, не может найдите session Csrf token в null session, чтобы сравнить с Csrf token request.


ПРОЦЕСС УПРАВЛЕНИЯ ВО ВРЕМЯ ОШИБКИ:

На следующей блок-схеме показано, как Шаг 14 и Шаг 15 каким-то образом null уточняют HttpSession. (Или, возможно, не соответствует JSESSIONID.) SYSO в начале CustomOAuth2RequestFactory.java на шаге 14 показывает, что действительно существует HttpSession, который на самом деле содержит правильный CsrfToken. Тем не менее, каким-то образом HttpSession становится null к тому времени, когда Шаг 15 инициирует вызов от клиента по URL-адресу 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 Boot для вызова /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.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher@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


ПОВТОРНОЕ СОЗДАНИЕ ПРОБЛЕМЫ НА ВАШЕМ КОМПЬЮТЕРЕ:

Вы можете воссоздать проблему на любом компьютере всего за несколько минут, выполнив следующие простые действия:

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 Boot будет отображаться МНОГО SYSO, что дает значения переменных, таких как XSRF-TOKEN и HttpSession, на каждом шаге, показанном на блок-схеме. SYSO помогает сегментировать журналы отладки, чтобы их было легче интерпретировать. И все SYSO выполняются одним классом, вызываемым другими классами, поэтому вы можете манипулировать классом, генерирующим SYSO, чтобы изменять отчеты повсюду в потоке управления. Класс, генерирующий SYSO, называется TestHTTP, а его исходный код можно найти в том же пакете demo.


ИСПОЛЬЗУЙТЕ ОТЛАДЧИК:

1.) Выберите окно терминала, в котором запущено приложение authserver, и введите Ctrl-C, чтобы остановить приложение authserver.

2.) Импортируйте три приложения (authserver, resource и ui) в eclipse как существующие проекты maven.

3.) В обозревателе проектов eclipse приложения authserver нажмите, чтобы развернуть папку Maven Dependencies, затем прокрутите ее вниз, чтобы развернуть Spring-Security-web... jar, как показано оранжевым кружком на изображение ниже. Затем прокрутите, чтобы найти и развернуть пакет org.springframework.security.web.context. Затем дважды щелкните, чтобы открыть класс HttpSessionSecurityContextRepository, выделенный синим цветом на снимке экрана ниже. Добавьте точки останова в каждую строку этого класса. Вы можете сделать то же самое с классом SecurityContextPersistenceFilter в том же пакете. Эти точки останова позволят вам увидеть значение HttpSession, которое в настоящее время становится null перед окончанием потока управления, но должно иметь допустимое значение, которое можно сопоставить с XSRF-TOKEN, чтобы решить эту проблему. ОП.

4.) В пакете demo приложения добавьте точки останова внутри файла CustomOAuth2RequestFactory.java. Затем Debug As... Spring Boot App для запуска отладчика.

5.) Затем повторите шаги с 6 по 8 выше. Вы можете очистить кеш браузера перед каждой новой попыткой. И вы можете открыть вкладку «Сеть» инструментов разработчика браузера.


person CodeMed    schedule 30.05.2016    source источник


Ответы (2)


Вы решили свою проблему? Я искал полный образец 2FA вместе с spring-security-oauth2. Здорово, что вы опубликовали свои полные концепции и полные источники.

Я попробовал ваш пакет, и вашу проблему можно просто решить, изменив всего 1 строку кода в вашем AuthserverApplication.java.

@Override
    protected void configure(HttpSecurity http) throws Exception {
        // @formatter:off
        http
            .formLogin().loginPage("/login").permitAll()
        .and()
                .requestMatchers().antMatchers("/login", "/oauth/authorize", "/secure/two_factor_authentication", "/pincode")
        .and()
                .authorizeRequests().anyRequest().authenticated();
        // @formatter:on
    }

Ваша исходная конфигурация прошла цепочку аутентификации весенней безопасности, которая вернула вам нулевой объект аутентификации.

Я также рекомендовал бы вам изменить создание компонента CustomOAuth2RequestFactory на следующее, которое переопределяет все OAuth2RequestFactory в цепочке.

@Bean
    public OAuth2RequestFactory customOAuth2RequestFactory(){
        return new CustomOAuth2RequestFactory(clientDetailsService);
    }

Для кода, который вы добавили для обработки CSRF, вы можете просто удалить их, например. контроллер 2FA:

@Controller
@RequestMapping(TwoFactorAuthenticationController.PATH)
public class TwoFactorAuthenticationController {
    private static final Logger LOG = LoggerFactory.getLogger(TwoFactorAuthenticationController.class);
    public static final String PATH = "/secure/two_factor_authentication";
    public static final String AUTHORIZE_PATH = "/oauth/authorize";
    public static final String ROLE_TWO_FACTOR_AUTHENTICATED = "ROLE_TWO_FACTOR_AUTHENTICATED";

    private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();

    @RequestMapping(method = RequestMethod.GET)
    public String auth(HttpServletRequest request, HttpSession session, HttpServletResponse resp/*, ....*/) {
        System.out.println("-------- inside GET /secure/two_factor_authentication --------------");
        if (AuthenticationUtil.isAuthenticatedWithAuthority(ROLE_TWO_FACTOR_AUTHENTICATED)) {
            LOG.info("User {} already has {} authority - no need to enter code again", ROLE_TWO_FACTOR_AUTHENTICATED);
//            throw ....;
        }
        else if (session.getAttribute(CustomOAuth2RequestFactory.SAVED_AUTHORIZATION_REQUEST_SESSION_ATTRIBUTE_NAME) == null) {
//            LOG.warn("Error while entering 2FA code - attribute {} not found in session.", CustomOAuth2RequestFactory.SAVED_AUTHORIZATION_REQUEST_SESSION_ATTRIBUTE_NAME);
//          throw ....;
        }
        return "pinCode";
    }

    @RequestMapping(method = RequestMethod.POST)
    public String auth(FormData formData, HttpServletRequest req, HttpServletResponse resp,
                                            SessionStatus sessionStatus, Principal principal, Model model)
        throws IOException{

        if (formData.getPinVal()!=null) {
            if(formData.getPinVal().equals("5309")){
                AuthenticationUtil.addAuthority(ROLE_TWO_FACTOR_AUTHENTICATED);
                return "redirect:"+AUTHORIZE_PATH;
            };
        };

        return "pinCode";
    }
}

Пожалуйста, дайте мне знать, если вы хотите получить полный исходный код после очистки.

person Alan Chow    schedule 13.06.2016
comment
Большое тебе спасибо. Вы решили проблему. Я отмечаю это как принятый ответ. Я хотел бы, чтобы наше время позволило награде все еще быть доступной, когда вы дали свой ответ, потому что ваш ответ является истинным решением проблемы. Добро пожаловать в переполнение стека. - person CodeMed; 14.06.2016
comment
Это беспроигрышный вариант, поскольку мне нужен полный образец и четкая концептуальная диаграмма, с которой моя команда сможет работать. Большое спасибо за ваш вклад, спасший мои дни создания моих собственных. Ваш проект — единственный законченный источник, который я могу найти в сообществе. - person Alan Chow; 14.06.2016
comment
Это небольшое изменение также может решить проблему в другом вопросе. stackoverflow.com/questions/37061697/ - person Alan Chow; 14.06.2016
comment
Я также сталкиваюсь с той же проблемой. Исходный код больше недоступен, не могли бы вы прикрепить код. Пожалуйста, дайте мне знать, что это была за строка - person user1047873; 16.08.2018

Сеанс не является нулевым в вашем приложении authserver во время последнего вызова localhost :9999/uaa/oauth/token. Существует не только сеанс, но и токен JSESSIONID и csrf действительного сеанса соответствуют значениям, присутствующим в потоке управления между точкой, где пользователь отправляет правильный PIN-код, и точкой, где не удалось выполнить запрос на /oauth/token сделано.

Проблема в том, что есть два значения JSESSIONID, и для входа в вызов /oauth/token выбрано неправильное из двух значений. Следовательно, решение должно исходить из изменения фильтров для удаления неверных JSESSIONID, чтобы можно было отправить правильное значение.

Подведем итоги:


HttpSessionListener определил действительный JSESSIONID

Чтобы изолировать проблему, я создал реализацию HttpSessionListener, а затем вызвал ее из пользовательской реализации HttpLListener следующим образом:

public class HttpSessionCollector implements HttpSessionListener, ServletContextListener {

    private static final Set<HttpSession> sessions = ConcurrentHashMap.newKeySet();

    public void sessionCreated(HttpSessionEvent event) {
        sessions.add(event.getSession());
    }

    public void sessionDestroyed(HttpSessionEvent event) {
        sessions.remove(event.getSession());
    }

    public static Set<HttpSession> getSessions() {
        return sessions;
    }

    public void contextCreated(ServletContextEvent event) {
        event.getServletContext().setAttribute("HttpSessionCollector.instance", this);
    }

    public static HttpSessionCollector getCurrentInstance(ServletContext context) {
        return (HttpSessionCollector) context.getAttribute("HttpSessionCollector.instance");
    }

    @Override
    public void contextDestroyed(ServletContextEvent arg0) {
    }

    @Override
    public void contextInitialized(ServletContextEvent arg0) {
    }

}

Затем я вызвал указанный выше HttpSessionListener в пользовательской реализации OncePerRequestFilter, которую я вставил в Spring Security Filter Chain вашего приложения authserver для предоставления диагностической информации следующим образом:

@Component
public class DiagnoseSessionFilter extends OncePerRequestFilter implements ServletContextAware {

    @Override
    protected void doFilterInternal(HttpServletRequest req, HttpServletResponse res, FilterChain fc) throws ServletException, IOException {

    System.out.println("...........///////////// START OF DiagnoseSessionFilter.doFilterInternal() ///////////...........");
    //start of request stuff
    System.out.println("\\\\\\\\\\ REQUEST ATTRIBUTES ARE: ");
    if(req.getAttribute("_csrf")!=null){
        System.out.println("_csrf is: " + req.getAttribute("_csrf").toString());
    }
    if(req.getAttribute("org.springframework.security.web.csrf.CsrfToken")!=null){
        CsrfToken ucsrf = (CsrfToken) req.getAttribute("org.springframework.security.web.csrf.CsrfToken");
        System.out.println("ucsrf.getToken() is: " + ucsrf.getToken());
    }
    String reqXSRF = req.getHeader("XSRF-TOKEN");
    System.out.println("request XSRF-TOKEN header is: " + reqXSRF);
    String reqCookie = req.getHeader("Cookie");
    System.out.println("request Cookie header is: " + reqCookie);
    String reqSetCookie = req.getHeader("Set-Cookie");
    System.out.println("request Set-Cookie header is: " + reqSetCookie);
    String reqReferrer = req.getHeader("referrer");
    System.out.println("request referrer header is: " + reqReferrer);
    HttpSession rsess = req.getSession(false);
    System.out.println("request.getSession(false) is: " + rsess);
    if(rsess!=null){
        String sessid = rsess.getId();
        System.out.println("session.getId() is: "+sessid);
    }
    System.out.println("/////////// END OF REQUEST ATTRIBUTES ");

    //end of request stuff
    ServletContext servletContext = req.getServletContext();
    System.out.println("\\\\\\\\\\ START OF SESSION COLLECTOR STUFF ");

    HttpSessionCollector collector = HttpSessionCollector.getCurrentInstance(servletContext);
    Set<HttpSession> sessions = collector.getSessions();

    System.out.println("sessions.size() is: " + sessions.size());
    for(HttpSession sess : sessions){
        System.out.println("sess is: " + sess);
        System.out.println("sess.getId() is: " + sess.getId());
        CsrfToken sessCsrf = (CsrfToken) sess.getAttribute("org.springframework.security.web.csrf.HttpSessionCsrfTokenRepository.CSRF_TOKEN");
        System.out.println("csrf is: " + sessCsrf);
        if(sessCsrf!=null){
            if(sessCsrf.getToken()!=null){
                System.out.println("sessCsrf.getToken() is: " + sessCsrf.getToken());
            } else { System.out.println("sessCsrf.getToken() is: null "); }
        } else { System.out.println("sessCsrf is: null "); }

        System.out.println("sess.getAttribute(SPRING_SECURITY_SAVED_REQUEST) is: " + sess.getAttribute("SPRING_SECURITY_SAVED_REQUEST") );
        if(sess.getAttribute("SPRING_SECURITY_SAVED_REQUEST") instanceof DefaultSavedRequest){
            System.out.println("_____ START PRINTING SAVED REQUEST");
            DefaultSavedRequest savedReq = (DefaultSavedRequest) sess.getAttribute("SPRING_SECURITY_SAVED_REQUEST");
            List<Cookie> savedCookies = savedReq.getCookies();
            for(Cookie cook : savedCookies){
                String name = cook.getName();String value = cook.getValue();
                System.out.println("cookie name, value are: " + name + " , " + value);
            }
            Collection<String> savedHeaderNames = savedReq.getHeaderNames();
            for(String headerName : savedHeaderNames){
                System.out.println("headerName is: " + headerName);
            }
            List<Locale> savedLocales = savedReq.getLocales();
            for(Locale loc : savedLocales){
                System.out.println("loc.getLanguage() is: " + loc.getLanguage());
            }
            String savedMethod = savedReq.getMethod();
            System.out.println("savedMethod is: " + savedMethod);
            Map<String, String[]> savedParamMap = savedReq.getParameterMap();
            Iterator<Entry<String, String[]>> it = savedParamMap.entrySet().iterator();
            while (it.hasNext()) {
                Entry<String, String[]> pair = it.next();
                System.out.println("savedParamMap: " + pair.getKey() + " = " + pair.getValue());
                it.remove(); // avoids a ConcurrentModificationException
            }
            Collection<String> savedParamNames = savedReq.getParameterNames();
            for(String savedParamName : savedParamNames){
                System.out.println("savedParamName: " + savedParamNames);
            }
            System.out.println("_____ DONE PRINTING SAVED REQUEST");

        }

//      System.out.println("sess.getAttribute(SPRING_SECURITY_CONTEXT) is: " + sess.getAttribute("SPRING_SECURITY_CONTEXT") );
        if(sess.getAttribute("SPRING_SECURITY_CONTEXT") instanceof SecurityContextImpl){
            SecurityContext ctxt = (SecurityContext) sess.getAttribute("SPRING_SECURITY_CONTEXT");
            Authentication auth = ctxt.getAuthentication();

            if(auth.getDetails() instanceof WebAuthenticationDetails){
                WebAuthenticationDetails dets = (WebAuthenticationDetails) auth.getDetails();
                System.out.println( "dets.getSessionId() is: " + dets.getSessionId() );
            }
            System.out.println("auth.getAuthorities() is: " + auth.getAuthorities() );
            System.out.println("auth.isAuthenticated() is: " + auth.isAuthenticated() );
        }
    }

    SecurityContext context = SecurityContextHolder.getContext();
    System.out.println("...........///////////// END OF DiagnoseSessionFilter.doFilterInternal() ///////////...........");
    fc.doFilter(req, res);

    }
}


Выделение кода проблемы:

Далее объединяются и обобщаются диагностические данные из HttpSessionListener с инструментами разработчика веб-браузера для шагов между нажатием пользователем кнопки «Отправить» в представлении отправки пин-кода и возвратом браузером отказа от конечной точки /oauth/token.

Как видите, существуют два плавающих значения JSESSIONID. Одно из значений правильное, а другое — нет. Неверное значение передается в запрос к /oauth/token и вызывает отклонение, даже если переданное csrf является правильным. Таким образом, решение этой проблемы, скорее всего, будет заключаться в изменении приведенных ниже шагов, чтобы перестать размещать плохой JSESSIONID вместо хорошего:

1.) POST http://localhost:9999/uaa/secure/two_factor_authentication
    request headers:
        Referer: 9999/uaa/secure/two_factor_authentication
        Cookie: 
            JSESSIONID: ....95CB77     
                        ....918636
            XSRF-TOKEN: ....862a73
    filter chain:
        DiagnoseSessionFilter:
            request stuff:
                Cookie header:
                    JSESSIONID: ....95CB77
                                ....918636
                    XSRF-TOKEN: ....862a73
                request.getSession(false).getId(): ....95CB77
            session collector stuff:
                JSESSIONID: ....95CB77
                csrf: ....862a73
                SPRING_SECURITY_SAVED_REQUEST is null
            user details (from Authentication object with user/request
                JSESSIONID: ....ED927C
                Authenticated = true, with roles
        Complete the filter chain
        DiagnoseSessionFilter (again)
            request stuff:
                csrf attribute: ....862a73
                Cookie header: 
                    JSESSIONID: ....95CB77 
                                ....918636
                    XSRF-TOKEN: ....862a73
                request.getSession(false).getId(): 95CB77
            session collector stuff:
                JSESSIONID: ....95CB77
                csrf is: 862a73
                SPRING_SECURITY_SAVED_REQUEST is null
            user details (Authentication for user/session/request)
                JSESSIONID: ....ED927C
                Authenticated = true, with authorities
        POST/secure/two_factor_authenticationControllerMethod
            do some stuff
    response:
        Location: 9999/uaa/oauth/authorize?....
        XSRF-TOKEN: ....862a73

2.) GET http://localhost:9999/uaa/oauth/authorize?...
    request headers:
        Host: localhost:9999
        Referer: 9999/uaa/secure/two_factor_authentication
        Cookie: 
            JSESSIONID: ....95CB77    
                        ....918636
            XSRF-TOKEN: ....862a73
    FilterChain
        DiagnoseSessionFilter
            request stuff:
                Cookie header is: JSESSIONID: ....95CB77
                                              ....918636
                                  XSRF-TOKEN: ....862a73
                request.getSession(false).getId(): 95CB77
            session collector stuff: 
                JSESSIONID: ....95CB77
                csrf is: ....862a73
                SPRING_SECURITY_SAVED_REQUEST is: null
            user details (Authentication object with user/session/req)
                JSESSIONID: ....ED927C
                Authenticated = true with ALL roles.
        rest of filter chain
        TwoFactorAuthenticationFilter
            request stuff:
                csrf request attribute is: ....862a73
                cookie header:
                    JSESSIONID: ....95CB77
                                ....918636
                    XSRF-TOKEN: ....862a73
                request.getSession(false).getId() is: ....95CB77
                updateCsrf is: ....862a73
            response stuff:
                XSRF-TOKEN header (after manual update): ....862a73
        DiagnoseSessionFilter:
            request stuff:
                _csrf request attribute: ....862a73
                Cookie header:
                    JSESSIONID: ....95CB77
                                ....918636
                    XSRF-TOKEN: ....862a73
                    request.getSession(false).getId() is: ....95CB77
            session collector stuff: 
                JSESSIONID: ....95CB77
                csrf is: ....862a73
                SPRING_SECURITY_SAVED_REQUEST is: null
            user details (Authentication for user/session/request) 
                JSESSIONID: ....ED927C
                Authenticated is true, with ALL roles.
        CustomOAuth2RequestFactory
            request stuff:  
                _csrf request parameter is: ....862a73
                Cookie header: 
                    JSESSIONID: ....95CB77
                                ....918636
                    XSRF-TOKEN: ....862a73
                request.getSession(false).getId() is: ....95CB77
                updateCsrf: ....862a73
            response stuff:
                XSRF-TOKEN header: ....862a73
            session attribute printout
                csrf: ....862a73
                SPRING_SECURITY_CONTEXT (not printed, so don't know values)
    response:
        Location: 8080/login?code=myNwd7&state=f6b3Km
        XSRF-TOKEN: ....862a73

3.) GET http://localhost:8080/login?code=myNwd7&state=f6b3Km
    request headers:
        Host: localhost:8080
        Referer: 9999/uaa/secure/two_factor_authentication
        Cookie:  
            JSESSIONID: ....918636
            XSRF-TOKEN: ....862a73
    UiAppFilterChain:
        HttpSessionSecurityContextRepository
            creates new SPRING_SECURITY_CONTEXT to replace null one
        OAuth2ClientAuthenticationProcessingFilter (position 8 of 14)
            AuthorizationCodeAccessTokenProvider
                Retrieving token from 9999/uaa/oauth/token
    AuthServerFilterChain:
        DiagnoseSessionFilter
            request stuff:
                XSRF-TOKEN header is: null
                Cookie header is: null
                Set-Cookie header is: null
                referrer header is: null
                request.getSession(false) is: null
            session collector stuff:
                JSESSIONID: ....95CB77
                sessCsrf.getToken() is: 862a73
                SPRING_SECURITY_SAVED_REQUEST is: null
                Authenticated is true but with ONLY these roles: 
                    ROLE_HOBBIT, ROLE_TWO_FACTOR_AUTHENTICATION_ENABLED
            SecurityContextPersistenceFilter
                reports no HttpSession and no SPRING_SECURITY_CONTEXT
            CsrfFilter
                rejects request to /oauth/token due to no session % csrf

    response headers:
        Set-Cookie: 
            XSRF-TOKEN: ....527fbe
            X-Frame-Options: DENY

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

Я публикую это до того, как оно будет полностью завершено, потому что срок вашего вознаграждения истекает.

person FarmHand    schedule 08.06.2016