Столкнулся с проблемой при внедрении CSFR фильтров (Spring). Запрос такого вида :
$('#form').submit(function () {
var uri = '/cp/tryexchange';
var data = $("#form").serialize();
$.ajax({
url: uri,
data: data,
type: "POST"
})
.done(function (data) {
switch (data.type) {
case 'OK':
$('#div1').html('<div class="uk-alert uk-alert-danger"><a href="/cp" class="uk-alert-close uk-close"></a>' + data.message + '</div>');
break;
case 'ERROR':
$('#div1').html('<div class="uk-alert uk-alert-danger"><a href="/cp" class="uk-alert-close uk-close"></a>' + data.message + '</div>');
break;
}
});
return false;
});
отрабатывает на ура. Аналогичный запрос с добавлением ключей в хейдер и сам документ, не работает:
$('#form').submit(function () {
var uri = '/cp/tryexchange';
var data = $("#form").serialize();
const createCookie = (a) => {
return a ? (a ^ Math.random() * 16 >> a / 4).toString(16) : ([1e16] + 1e16).replace(/[01]/g, createCookie)
};
const cookie = createCookie();
document.cookie = CSRF_TOKEN + '=' + cookie;
$.ajax({
url: uri,
data: data,
crossDomain: true,
xhrFields: {
withCredentials: true
},
headers: {'X-CSRF-TOKEN': cookie},
type: "POST"
})
.done(function (data) {
switch (data.type) {
case 'OK':
$('#div1').html('<div class="uk-alert uk-alert-danger"><a href="/cp" class="uk-alert-close uk-close"></a>' + data.message + '</div>');
break;
case 'ERROR':
$('#div1').html('<div class="uk-alert uk-alert-danger"><a href="/cp" class="uk-alert-close uk-close"></a>' + data.message + '</div>');
break;
}
});
return false;
});
Код фильтров
@Slf4j
public static class StatelessCSRFFilter extends OncePerRequestFilter {
public static final String X_CSRF_TOKEN_HEADER = "X-CSRF-TOKEN";
public static final String CSRF_TOKEN_COOKIE = "CSRF-TOKEN";
private static final int EXPIRE = 0;
private final RequestMatcher requireCsrfProtectionMatcher = new DefaultRequiresCsrfMatcher();
private final AccessDeniedHandler accessDeniedHandler = new AccessDeniedHandlerImpl();
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
if (request.getRequestURI().contains("/enter/auth")) {
invalidate(response);
filterChain.doFilter(request, response);
return;
}
log.info("CSRFFilter: " + request.getRequestURI());
if (requireCsrfProtectionMatcher.matches(request)) {
final String csrfTokenValue = request.getHeader(X_CSRF_TOKEN_HEADER);
final Cookie[] cookies = request.getCookies();
String csrfCookieValue = null;
if (cookies != null) {
for (Cookie cookie : cookies) {
if (cookie.getName().equals(CSRF_TOKEN_COOKIE)) {
csrfCookieValue = cookie.getValue();
}
}
}
if (csrfTokenValue == null || !csrfTokenValue.equals(csrfCookieValue)) {
accessDeniedHandler.handle(request, response, new AccessDeniedException("Missing or non-matching CSRF-token"));
log.warn("Missing/bad CSRF-TOKEN while CSRF is enabled for request {}", request.getRequestURI());
return;
}
}
invalidate(response);
filterChain.doFilter(request, response);
}
private void invalidate(HttpServletResponse response) {
Cookie cookie = new Cookie(CSRF_TOKEN_COOKIE, "");
cookie.setMaxAge(EXPIRE);
response.addCookie(cookie);
}
public class DefaultRequiresCsrfMatcher implements RequestMatcher {
private final Pattern allowedMethods = Pattern.compile("^(GET|HEAD|TRACE|OPTIONS)$");
@Override
public boolean matches(HttpServletRequest request) {
return !allowedMethods.matcher(request.getMethod()).matches();
}
}
}
public static class CorsFilter extends OncePerRequestFilter {
private static final String LOCALHOST_DEV = "http://localhost:8080";
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
response.addHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, LOCALHOST_DEV);
response.addHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS, "true");
if (request.getHeader(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD) != null && HttpMethod.OPTIONS.name().equals(request.getMethod())) {
// CORS "pre-flight" request
response.addHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_METHODS, "GET, POST, PUT, DELETE");
response.addHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_HEADERS, HttpHeaders.CONTENT_TYPE + ", " + StatelessCSRFFilter.X_CSRF_TOKEN_HEADER);
response.addHeader(HttpHeaders.ACCESS_CONTROL_MAX_AGE, "1");
}
filterChain.doFilter(request, response);
}
}
Собственно говоря, почему так происходит, и есть ли решение? (тестирую на FireFox)
Виртуальный выделенный сервер (VDS) становится отличным выбором
ЗдравствуйтеПомогите разобраться в чем может быть проблема
У меня есть программно создаваемые записи, это TextView и его CheckboxМне нужно изменить код, чтобы при определенных условиях удалить их вместе
Я создаю приложение аутентификации, у меня есть 3 методы, первый регистрирует юзера, второй получает client id and secret, а третий получает access and refresh...
Подскажите пожалуйстаЕсть ли или как-то можно реализовать систему ответа в websocket на входящее сообщение