Токен CSRF не обновлен должным образом (Ioni c + Spring Security) - PullRequest
2 голосов
/ 07 апреля 2020

Я занимаюсь разработкой приложения с использованием Ioni c Framework и сгенерировал проект JHipster для своего бэкэнда. Мой проект JHipster выполняется на дополнительном сервере и вызывается с помощью запросов REST из моего приложения. Итак, моя проблема сейчас - обработка конфигурации CORS и CSRF.

Мой проект JHipster имеет собственный интерфейс, который работает в том же домене, и во время тестирования я могу без проблем получить доступ к своему бэкэнду. Однако, когда я хочу вызвать свой бэкэнд на сервере из моего приложения Ioni c, мои токены xsrf не обновляются должным образом, и поэтому я не могу получить доступ к своему бэкэнду. Я уже пробовал несколько решений из разных постов переполнения стека, но ни одно из них не помогло мне.

Например:

Что я сделал до сих пор:

  1. Я включил csrf в моей конфигурации SecurityConfiguration в моем проекте JHipster
        http
            .csrf()
            .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
            .and()
            .addFilterBefore(corsFilter, UsernamePasswordAuthenticationFilter.class)
            .exceptionHandling()
            .authenticationEntryPoint(problemSupport)
            .accessDeniedHandler(problemSupport)
добавлена ​​конфигурация CORS
  cors:
    allowed-origins: 'http://localhost:8100, ionic://localhost, http://localhost'
    allowed-methods: 'POST, GET, OPTIONS, DELETE, PUT, HEAD'
    allowed-headers: 'Origin, X-Requested-With, Content-Type, Accept, x-auth-token, Authorization, X-CSRF-Token, x-xsrf-token, XSRF-TOKEN'
    exposed-headers: 'Authorization,Link,X-Total-Count,XSRF-TOKEN, X-XSRF-TOKEN'
    allow-credentials: true
    max-age: 86400
написал перехватчик
@Injectable()
export class HttpXSRFInterceptor implements HttpInterceptor {

  constructor(private tokenExtractor: HttpXsrfTokenExtractor, private csrfService:CSRFService,  private $sessionStorage: SessionStorageService) {
  }

  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    const headerName = 'XSRF-TOKEN';
    const respHeaderName = 'X-XSRF-TOKEN';
    let token = this.tokenExtractor.getToken() as string;

    if (token !== null && !req.headers.has(headerName)) {
      req = req.clone({ headers: req.headers.set(respHeaderName, token) });
      req.clone({
        withCredentials: true
      });
    }
    return next.handle(req);
  }
}
добавлен HttpClientXsrfModule в моем app.module.ts и перехватчик
    HttpClientXsrfModule.withOptions({
      cookieName: 'XSRF-TOKEN',
      headerName: 'X-XSRF-TOKEN',
    }),
    {
      provide: HTTP_INTERCEPTORS,
      useClass:  HttpXSRFInterceptor,
      multi: true
    },

Моя проблема:

Я не получаю xsrf токен при запуске моего приложения в браузере, но после отправки запроса на публикацию токен устанавливается как повар ie.

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

Из моего понимания

  1. при первом получении токена быть сразу после загрузки стартовой страницы моего приложения

  2. токен должен обновляться после каждого ответа от сервера (бэкэнда), а обновленный токен используется для следующего запроса

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

Я ценю любую помощь!

ура

1 Ответ

2 голосов
/ 07 апреля 2020

Я автор Ioni c для JHipster, так что, надеюсь, я могу помочь вам в этом.

Прежде всего, CSRF не должен быть проблемой , если вы не запускаете свои приложения на одном и том же порту. По моему опыту, когда вы запускаете их на отдельных портах, ваш клиент не может прочитать повар ie. Что касается CORS, это не проблема для меня при локальном запуске. Я полагаю, это потому, что настройки CORS для профиля dev широко открыты. Можете ли вы попробовать использовать настройки из профиля dev в вашем профиле prod и посмотреть, поможет ли это?

Для справки:

jhipster:
  cors:
    allowed-origins: '*'
    allowed-methods: '*'
    allowed-headers: '*'
    exposed-headers: 'Authorization,Link,X-Total-Count'
    allow-credentials: true
    max-age: 1800

Если это работает, я попробуйте изменить разрешенное происхождение на массив или просто использовать его. http://localhost:8100 должно быть все, что вам нужно, если вы работаете локально.

...