/spring-security-jwt-csrf

A demonstration of stateless JWT authentication with Spring Security, Spring Boot and Vue js

Primary LanguageJavaMIT LicenseMIT

README in english

JWT Spring Boot Security

JWT Spring Security Demo

О проекте

Это демонстрация аутентификации на основе токена с использованием JSON Web Token и CSRF, Spring Security, Spring Boot и Vue js. Это решение частично основано на блогах Где хранить ваши JWT-файлы - Cookies vs HTML5 Web Storage и Где хранить JWT в браузере? Как защитить от CSRF?

Стек Технологий

Компонент Технология
Frontend Vue.js 2
Backend (REST) SpringBoot (Java)
Security Token Based (Spring Security, JJWT, CSRF)
Client Build Tools vue-cli, Webpack, npm
Server Build Tools Gradle

Безопасность (Security)

JWT token

Для генерации и проверки JWT я использую JJWT. JJWT - автономная библиотека Java, обеспечивающая создание и верификацию сквозных веб-токенов JSON.

JWT стратегия хранения

У нас есть несколько вариантов, где хранить маркер:

  • Веб-хранилище HTML5 (HTML5 Web Storage, а точнее localStorage или sessionStorage);
  • Cookies.
Основная проблема веб-хранилища

Он доступен через JavaScript в том же домене. Это означает, что любой JavaScript, запущенный на вашем сайте, будет иметь доступ к веб-хранилищу, и из-за этого может быть уязвим для атак межсайтового скриптинга (XSS).

Таким образом, чтобы предотвратить XSS, я храню маркер JWT в Http-Only/Secure куки. Файлы куки, если они используются с флагом HttpOnly, недоступны через JavaScript и невосприимчивы к XSS.

CSRF атака

Тем не менее, файлы куки уязвимы для атаки другого типа: межсайтовой подделки запроса (CSRF). Атака CSRF - это тип атаки, которая возникает, когда вредоносный веб-сайт, электронная почта или блог заставляют веб-браузер пользователя выполнять нежелательные действия на доверенном сайте, на котором пользователь в настоящее время аутентифицирован.

Чтобы предотвратить атаки CSRF, мы должны создать дополнительный Javascript читаемый файл куки, который называется: XSRF-TOKEN. Этот файл куки должен быть создан, когда пользователь вошел в систему и должен содержать случайную, недопустимую строку. Каждый раз, когда JavaScript приложение хочет сделать запрос, ему нужно будет прочитать этот токен и отправить его в пользовательский HTTP-заголовок.

Использование

Импорт проекта (Intellij IDEA)

  1. File -> New -> Project From Existing Source -> укажите путь к проекту;
  2. CTRL + SHIFT + ALT + S -> Modules -> + -> Import Module -> Выберите backend папку, указав что это GRADLE проект;
  3. -//- то же самое для папки frontend, только не указывая что это gradle-проект, а выбрав Create module from existing sources.

Запуск бэкэнда

gradle Build : Перейдите в корневую папку build.gradle и выполните:

gradle bootRun

или запустите из IDE класс com.alexatiks.Application.

Приложение будет запущено на http://localhost:8091.

Запуск фронтэнда

Перейдите в корневую папку frontend (должен содержать package.json)

npm install

npm run serve

Приложение будет запущено на http://localhost:8080.


Чтобы убить процесс на порту 8080 (Windows):

1. netstat -ano | findstr 8080
2. taskkill /pid ПОРТ /F

Аккаунты пользователей:

Admin - admin:password
User - user:password

Эндпоинты:

/login - эндпоинт аутентефикации authentication endpoint with unrestricted access
/secured - пример эндпоинта, который разрешён только для авторизованных пользователей
/onlyforadmin - пример эндпоинта, который разрешён только для пользователей с ролью 'ADMIN'

Скриншоты

JWT Spring Security Demo

JWT Spring Security Demo

JWT Spring Security Demo