Как получить доступ к значению XSRF cook ie в Angular? - PullRequest
0 голосов
/ 22 апреля 2020

Я работал над этим в течение последних 7 часов и, похоже, ничего не добился. Я пытаюсь сделать свой XSRF-TOKEN доступным для внешнего интерфейса (Angular 6). Тем не менее, кажется, что это никогда не доступно. Когда я выполняю анализ на вкладке "Сеть" и смотрю в разделе "Готовить ie", кажется, что он находится там во всем своем великолепии. Однако, если я использую CookieService Angular и пытаюсь получить его, ничего не возвращается.

Что нужно иметь в виду:

  1. При запуске на моей локальной машине я могу чтобы получить XSRF-TOKEN и поместить его в будущие запросы заголовков.
  2. Проблема возникает, когда два интерфейса и серверная часть (Spring-boot) размещены на двух разных хостах, но в одном домене. Например: Frontend может быть frontend.home.com; Backend может быть backend.home.com.
  3. HttpOnly имеет значение False.
  4. Angular Свойство withCredentials также имеет значение true.

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

Спасибо.

Backend:

http.httpBasic()
    .authenticationEntryPoint(new AuthenticationFailureHandler())
    .and()
        .authorizeRequests()
        .antMatchers("List of URL").permitAll()
        .anyRequest().authenticated()
    .and()
        .csrf()
        .ignoringAntMatchers("List of API to ignore CSRF Token")
        .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
    .and()
        .addFilterAfter(new CsrfHeaderFilter(), CsrfFilter.class);
http.logout()
    .permitAll()
    .logoutSuccessHandler((new HttpStatusReturningLogoutSuccessHandler(HttpStatus.OK)));
}

@Autowired
private CsrfTokenRepository csrfTokenRepository() {
    HttpSessionCsrfTokenRepository repository = new HttpSessionCsrfTokenRepository();
    repository.setHeaderName("X-XSRF-TOKEN");
    return repository;
}

Внешний интерфейс:

intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    let newHeaders: HttpHeaders = req.headers;

    let csrfToken = this.cookieService.get("XSRF-TOKEN");
    if (csrfToken === null || csrfToken === undefined) {
        newHeaders = newHeaders.append('X-XSRF-TOKEN', 'undefined');
    } else {
        newHeaders = newHeaders.append('X-XSRF-TOKEN', csrfToken);
    }

    const authReq = req.clone({headers: newHeaders, withCredentials: true});
    return next.handle(authReq);
}

Кроме того, когда я смотрю на инструменты разработчика, я вижу три разных домена.

  1. home.com
  2. бэкэнд .home.com (XSRF cook ie находится только здесь и недоступен в других местах)
  3. frontend.home.com

1 Ответ

0 голосов
/ 23 апреля 2020

Исходя из правок и комментариев, вам, вероятно, потребуется изменить домен Cook ie для CSRF cook ie, чтобы он был установлен в домене home.com, а не только в домене backend.home.com. Вы можете достичь этого, изменив CookieCsrfTokenRepository:

CookieCsrfTokenRepository repository = CookieCsrfTokenRepository.withHttpOnlyFalse();
repository.setCookieDomain("home.com");

http.httpBasic()
    .authenticationEntryPoint(new AuthenticationFailureHandler())
    .and()
        .authorizeRequests()
        .antMatchers("List of URL").permitAll()
        .anyRequest().authenticated()
    .and()
        .csrf()
        .ignoringAntMatchers("List of API to ignore CSRF Token")
        .csrfTokenRepository(repository)
    .and()
        .addFilterAfter(new CsrfHeaderFilter(), CsrfFilter.class);
http.logout()
    .permitAll()
    .logoutSuccessHandler((new HttpStatusReturningLogoutSuccessHandler(HttpStatus.OK)));
}

Посмотрите первые две строки, где хранилище настроено, как я писал выше, а затем используется в качестве хранилища токенов.

...