Spring Security не использует повторно данные аутентификации с помощью Spring Session EnableRedisHttpSession

Мне удалось успешно запустить эту конфигурацию, используя образец реализации Groovy Maven с весенней загрузкой из https://github.com/dsyer/spring-security-angular/blob/master/vanilla/README.md. Это не работает, когда код приложения был реализован на Java и Gradle 2.3. В этом случае ответ OPTIONS содержит новый X-Auth-Token.

Пытался использовать предоставленную сборку maven с моими java-классами и по-прежнему получать тот же несанкционированный ответ OPTIONS 401. Так что это не проблема Gradle.

Скопировал два класса ResourceApplication Groovy в мою сборку Gradle, и пользовательский интерфейс Angular успешно получил OPTIONS 200 OK. Таким образом, существует проблема с фильтром Spring CORS в java.

У меня есть плагины Gradle для java и groovy, sourceCompatibility и targetCompatibility = 1.7.

java версия "1.8.0_31" Java (TM) SE Runtime Environment (сборка 1.8.0_31-b13) 64-разрядная серверная виртуальная машина Java HotSpot (TM) (сборка 25.31-b07, смешанный режим)

Журнал консоли разработчика проверяет, что тот же токен был отправлен с сервера пользовательского интерфейса и получен клиентом angular, но есть сообщение об ошибке CORS.

Запрос на другой источник заблокирован: та же политика происхождения запрещает чтение удаленного ресурса по адресу http://localhost:9000/. Это можно исправить, переместив ресурс в тот же домен или включив CORS. локальный: 9000

@SpringBootApplication
@RestController
@EnableRedisHttpSession
public class AngularDemoApplication {
@RequestMapping("/user")
public Principal user(Principal user) {
  return user;
}

@RequestMapping("/token")
@ResponseBody
public Map<String,String> token(HttpSession session) {
  logger.debug("********** TOKEN *********** = "+session.getId());
  return Collections.singletonMap("token", session.getId());
}

@Configuration
@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
protected static class SecurityConfiguration extends WebSecurityConfigurerAdapter {
  @Override
  protected void configure(HttpSecurity http) throws Exception {
      http.httpBasic().and().logout().and().authorizeRequests()
        .antMatchers("/index.html", "/home.html", "/login.html", "/").permitAll()
        .anyRequest().authenticated().and().csrf().csrfTokenRepository(csrfTokenRepository())
        .and().addFilterAfter(csrfHeaderFilter(), CsrfFilter.class);
  }

  private Filter csrfHeaderFilter() {
        return new OncePerRequestFilter() {
            @Override
            protected void doFilterInternal(HttpServletRequest request,
                    HttpServletResponse response, FilterChain filterChain)
                    throws ServletException, IOException {
                CsrfToken csrf = (CsrfToken) request.getAttribute(CsrfToken.class
                        .getName());
                if (csrf != null) {
                    Cookie cookie = WebUtils.getCookie(request, "XSRF-TOKEN");
                    String token = csrf.getToken();
                    if (cookie == null || token != null
                            && !token.equals(cookie.getValue())) {
                        cookie = new Cookie("XSRF-TOKEN", token);
                        cookie.setPath("/");
                        response.addCookie(cookie);
                    }
                }
                filterChain.doFilter(request, response);
            }
        };
    }


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

public static void main(String[] args) {
    SpringApplication.run(AngularDemoApplication.class, args);
}

}

@SpringBootApplication
@RestController
@EnableRedisHttpSession
public class ResourceApplication {

@RequestMapping("/")
public Map<String,Object> home() {
      Map<String,Object> model = new HashMap<String,Object>();
      model.put("id", UUID.randomUUID().toString());
      model.put("content", "Hello World");
      return model;
}


@Bean
public HeaderHttpSessionStrategy sessionStrategy() {
    return new HeaderHttpSessionStrategy();
 }

public static void main(String[] args) {
    SpringApplication.run(ResourceApplication.class, args);
}

}

@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
class CorsFilter implements Filter {

@Override
public void doFilter(ServletRequest req, ServletResponse res,
        FilterChain chain) throws IOException, ServletException {
    HttpServletResponse response = (HttpServletResponse) res;
    HttpServletRequest request = (HttpServletRequest) req;
    response.setHeader("Access-Control-Allow-Origin", "*");
    response.setHeader("Access-Control-Allow-Methods", "POST, PUT, GET, OPTIONS, DELETE");
    response.setHeader("Access-Control-Max-Age", "3600");
    response.setHeader("Access-Control-Allow-Headers", "x-auth-token, x-requested-with");
    if (request.getMethod() != "OPTIONS" ) {
        chain.doFilter(req, res);
    } else {
         }

}

@Override
public void init(FilterConfig filterConfig) throws ServletException {
    // TODO Auto-generated method stub

}

@Override
public void destroy() {
    // TODO Auto-generated method stub

}

}

Groovy-версия:

Метод запроса: ОПЦИИ
Код состояния: 200 ОК

Заголовки запроса:
Хост: localhost: 9000
Пользовательский агент: Mozilla / 5.0 (Windows NT 6.1; WOW64; rv: 36.0) Gecko / 20100101 Firefox / 36.0
Принять: text / html, application / xhtml + xml, application / xml; q = 0.9, /; q = 0.8
Accept-Language: en-US, en; q = 0.5
Принять -Encoding: gzip, deflate
Origin: localhost: 8080
Access-Control-Request-Method: GET
Access-Control-Request-Headers: x-auth-token, x-requested-with
Подключение: keep-alive

Заголовки ответа:
Access-Control-Allow-Headers: x-auth-token, x-required-with
Access-Control-Allow-Methods: POST, PUT, GET, OPTIONS , УДАЛИТЬ
Access-Control-Allow-Origin: *
Access-Control-Max-Age: 3600
Content-Length: 0
Дата: Вт, 31 марта 2015 г., 21:20:28 GMT
Сервер: Apache-Coyote / 1.1

Метод запроса: ПОЛУЧИТЬ
Код состояния: 200 ОК

Заголовки запроса:
Хост: localhost: 9000 Пользовательский агент: Mozilla / 5.0 (Windows NT 6.1; WOW64; rv: 36.0) Gecko / 20100101 Firefox / 36.0
Принять: application / json , text / plain, /
Accept-Language: en-US, en; q = 0.5
Accept-Encoding: gzip, deflate
X-Auth-Token: 80e0c2d2- dab4-435d-886e-ae28bc8e636f
X-Requested-With: XMLHttpRequest

Заголовки ответа:
Access-Control-Allow-Headers: x-auth-token, x-required-with
Access-Control-Allow-Methods: POST, PUT, GET, OPTIONS , УДАЛИТЬ
Access-Control-Allow-Origin: *
Access-Control-Max-Age: 3600
Content-Type: application / json; charset = UTF-8
Дата: Вт, 31 Мар 2015 21:20:28 GMT
Сервер: Apache-Coyote / 1.1
Строгая безопасность транспорта: max-age = 31536000; includeSubDomains
Кодирование передачи: фрагментировано
Referer: localhost: 8080 /
Источник: localhost: 8080
Соединение: keep-alive

Ключи сервера Redis:
1) "spring: session: expirations: 1427838660000"
2) "spring: session: sessions: 80e0c2d2-dab4-435d-886e-ae28bc8e636f"

Версия Java:

Метод запроса: OPTIONS
Код состояния: 401 Unauthorized

Заголовки запроса:
Хост: localhost: 9000
Пользовательский агент: Mozilla / 5.0 (Windows NT 6.1; WOW64; rv: 36.0) Gecko / 20100101 Firefox / 36.0
Принять: text / html, application / xhtml + xml, application / xml; q = 0.9, /; q = 0.8
Accept-Language: en-US, en; q = 0.5
Принять -Encoding: gzip, deflate
Origin: localhost: 8080
Access-Control-Request-Method: GET
Access-Control-Request-Headers: x-auth-token, x-requested-with
Подключение: keep-alive

Заголовки ответа:
Access-Control-Allow-Headers: x-auth-token, x-required-with
Access-Control-Allow-Methods: POST, PUT, GET, OPTIONS , УДАЛИТЬ
Access-Control-Allow-Origin: *
Access-Control-Max-Age: 3600
Разрешить: GET, HEAD, POST, PUT, DELETE, TRACE, OPTIONS, PATCH
Содержание -Длина: 0
Дата: Вт, 31 марта 2015 г. 20:50:26 GMT
Сервер: Apache-Coyote / 1.1
Строгая безопасность транспорта: max-age = 31536000; includeSubDomains
WWW-Authenticate: Basic realm = "Spring"
X-Auth-Token: 8af7e1f4-e723-4ce6-8d21-54a7b10369f8

Ключи сервера Redis:
1) "spring: session: sessions: 8af7e1f4-e723-4ce6-8d21-54a7b10369f8"
2) "spring: session: expirations: 1427836860000"
3) «весна: сеанс: сеансы: c6a6cc31-eddc-40dd-99de-a6e1eecbf519»


person Paul    schedule 31.03.2015    source источник


Ответы (1)


В Java оператор "! =" Отличается от Groovy. Для сравнения строковых объектов используйте метод equals. т.е.

if( !"OPTIONS".equals(request.getMethod()))   
person Paul    schedule 01.04.2015