Как настроить spring security

Безопасность Web-приложения

Этот урок освещает процесс создания простого web-приложения с ресурсами, которые защищены Spring Security.

Что вы создадите

Вы создадите Spring MVC приложение, которое обеспечивает защиту страницы входа фиксированным списком пользователей.

Что вам потребуется

  • Примерно 15 минут свободного времени
  • Любимый текстовый редактор или IDE
  • JDK 6 и выше
  • Gradle 1.11+ или Maven 3.0+
  • Вы также можете импортировать код этого урока, а также просматривать web-страницы прямо из Spring Tool Suite (STS), собственно как и работать дальше из него.

Как проходить этот урок

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

Чтобы начать с нуля, перейдите в Настройка проекта.

Чтобы пропустить базовые шаги, выполните следующее:

  • Загрузите и распакуйте архив с кодом этого урока, либо кнонируйте из репозитория с помощью Git: git clone https://github.com/spring-guides/gs-securing-web.git
  • Перейдите в каталог gs-securing-web/initial
  • Забегая вперед, настройте Spring Security

Когда вы закончите, можете сравнить получившийся результат с образцом в gs-securing-web/complete .

Настройка проекта

Для начала вам необходимо настроить базовый скрипт сборки. Вы можете использовать любую систему сборки, которая вам нравится для сборки проетов Spring, но в этом уроке рассмотрим код для работы с Gradle и Maven. Если вы не знакомы ни с одним из них, ознакомьтесь с соответсвующими уроками Сборка Java-проекта с использованием Gradle или Сборка Java-проекта с использованием Maven.

Создание структуры каталогов

В выбранном вами каталоге проекта создайте следующую структуру каталогов; к примеру, командой mkdir -p src/main/java/hello для *nix систем:

Создание файла сборки Gradle

Ниже представлен начальный файл сборки Gradle. Файл pom.xml находится здесь. Если вы используете Spring Tool Suite (STS), то можете импортировать урок прямо из него.

Spring Boot gradle plugin предоставляет множество удобных возможностей:

  • Он собирает все jar’ы в classpath и собирает единое, исполняемое «über-jar», что делает более удобным выполнение и доставку вашего сервиса
  • Он ищет public static void main() метод, как признак исполняемого класса
  • Он предоставляет встроенное разрешение зависимостей, с определенными номерами версий для соответсвующих Spring Boot зависимостей. Вы можете переопределить на любые версии, какие захотите, но он будет по умолчанию для Boot выбранным набором версий

Создание незащищенного web приложения

До того, как применить защиту к вашему приложению, вам необходимо само приложение. Шаги в этой главе освещают процесс создания очень простого web-приложения. Затем в следующей главе вы защитите его с помощью Spring Security.

Приложение включает два простых представления: домашнюю страницу и «Hello World» страницу. Домашняя страница предствлена ниже как Thymeleaf шаблон:

Как вы можете увидеть, это простое приложение включает ссылку на страницу «/hello», которая представлена ниже также как Thymeleaf шаблон.

Приложение основано на Spring MVC. Т.о. вам необходимо настроить Spring MVC и контроллеры представлений для отображения этих шаблонов. Ниже конфигурационный класс для настройки Spring MVC в приложении.

Метод addViewControllers() (переопределение метода с таким же названием в WebMvcConfigurerAdapter ), добавляющий четыре контроллера. Двое из них настроены на представление с именем «home»( home.html ), другой настроен на «hello». Четвертый контроллер настроен на представление с названием «login». Вы создадите это представление в следующей главе.

На данном этапе вы можете перейти к созданию приложения исполняемым и запустить приложени без входа в систему.

Фундамент простого web-приложения создано, теперь вы можете добавить защиту к нему.

Настройка Spring Security

Предположим, что вы хотите предотвратить неавторизованный доступ к просмотру представления «/hello». Сейчас, если пользователь нажмет на ссылку на домашней странице, он увидит приветствие без каких либо помех к нему. Вам необходимо добавить барьер, который заставляет пользователя войти в систему до того, как он увидит страницу.

Читайте также:  Как настроить компьютер если клавиатура не работает

Для этого вы настраиваете Spring Security в приложении. Если Spring Security в classpath’е, Spring Boot автоматически обеспечивает защиту для всех HTTP путей с «базовой» аутентификацией. Но вы сможете в дальнейшем изменить под себя настройки безопасности. Первое, что вам нужно сделать, это добавить Spring Security в classpath.

C Gradle это достигается одной строчкой в блоке dependencies :

C Maven — добавлением дополнительного блока в :

Ниже приведена настройка безопасности, которая гарантирует, что только авторизованные пользователи могут увидеть секретное приветствие:

Класс WebSecurityConfig содержит аннотацию @EnableWebMvcSecurity для включения поддержки безопасности Spring Security и Spring MVC интеграцию. Он также расширяет WebSecurityConfigurerAdapter и переопределяет пару методов для установки некоторых настроек безопасности.

Метод configure(HttpSecurity) определяет, какие URL пути должны быть защищены, а какие нет. В частности, «/» и «/home» настроены без требования к авторизации. Ко всем остальным путям должна быть произведена аутентификация.

Когда пользователь успешно войдет в систему, он будет перенаправлен на предыдущую запрашиваемую страницу, требующую авторизацию. Здесь вы определили собственную «/login» страницу в loginPage() и каждый имеет доступ к ней.

Что касается метода configure(AuthenticationManagerBuilder) , то он создает в памяти хранилище пользователей с единственным пользователем. Этому пользователю дано имя «user», пароль «password» и роль «ROLE».

Теперь нам нужно создать страницу входа. Т.к. уже есть сопоставление контроллера с представлением «login», то вам нужно только создать это представления входа:

Как видите, этот Thymeleaf шаблон просто представляет собой форму, которая собирает значения имени пользователя и пароля и отправляет их к «/login». Рассмотрим, как настроен Spring Security фильтр, который перхватывает запрос и идентифицирует пользователя. Если пользователь не прошел проверку, то он будет перенаправлен на страницу «/login?error» и наша страница отобразит соответсвующее сообщение об ошибке. При удачной авторизации, приложение отправит к «/login?logout» и наша страница отобразит соответственное сообщение об успехе.

Последнее, что нам нужно, это предоставить пользователю способ для отображения текущего имени и выхода из системы. Обновим hello.html , чтобы сказать привет текущему пользователю и добавить в форму «Sign Out», как показано ниже:

Мы отображаем имя пользователя с использованием интеграции Spring Security с HttpServletRequest#getRemoteUser() . По кнопке «Sign Out» форма отправляет POST запрос к «/logout». При успешном выходе пользователь будет перенаправлен к «/login?logout».

Создание приложения исполняемым

Несмотря на то, что пакет этого сервиса может быть в составе web-приложения и WAR файлов, более простой подход, продемонстрированный ниже создает отдельное самостоятельное приложение. Вы упаковываете все в единый, исполняемый JAR-файл, который запускается через хорошо знакомый старый main() Java-метод. Попутно, вы используете поддержку Spring для встроенного Tomcat контейнера сервлетов как HTTP среду выполнения вместо развертывания на сторонний экземпляр.

main() метод передает управление вспомогательному классу SpringApplication, где Application.class — аргумент его run() метода. Это сообщает Spring о чтении метаданных аннотации из Application и управлении ею как компонента в Spring application context.

Аннотация @ComponentScan говорит Spring’у рекурсивно искать в пакете hello и его потомках классы, помеченные прямо или косвенно Spring аннотацией @Component. Эта директива гарантирует, что Spring найдет и зарегистрирует WebConfig и WebSecurityConfig , потому что он отмечен @Configuration , который, в свою очередь, является своего рода @Component аннотацией. По факту, эти конфигурационные классы также используются для настройки Spring.

Аннотация @EnableAutoConfiguration переключает на приемлемое по умолчанию поведение, основанное на содержании вашего classpath. К примеру, т.к. приложение зависит от встраиваемой версии Tomcat (tomcat-embed-core.jar), Tomcat сервер установлен и сконфигурирован на приемлемое по умолчанию поведение от вашего имени. И т.к. приложение также зависит от Spring MVC (spring-webmvc.jar), Spring MVC DispatcherServlet сконфигурирован и зарегестрирован для вас — web.xml не нужен! Автоконфигурация полезный и гибкий механизм. Подробную информацию смотрите в API документации.

Сборка исполняемого JAR

Вы можете собрать единый исполняемый JAR-файл, который содержит все необходимые зависимости, классы и ресурсы. Это делает его легким в загрузке, версионировании и развертывании сервиса как приложения на протяжении всего периода разработки, на различных средах и так далее.

Затем вы можете запустить JAR-файл:

Если вы используете Maven, вы можете запустить приложение, используя mvn spring-boot:run , либо вы можете собрать приложение с mvn clean package и запустить JAR примерно так:

Читайте также:  Можно ли отремонтировать варочную панель если треснуло стекло

Если вы используете Gradle, вы можете запустить ваш сервис из командной строки:

Как вариант, вы можете запустить ваш сервис напрямую из Gradle примерно так:

как только приложение запустится, откройте в вашем браузере адрес http://localhost:8080. Вы должны увидеть домашнюю страницу:

Когда вы нажмете на ссылку, то она попытается открыть вам сстраницу приветствия /hello . Но т.к. эта страница защищена и вы ещё не вошли в систему, вы увидите страницу входа:

На странице входа войдите под тестовым пользователем, введя «user» и «password» в соответствующие поля. Как только вы отправите форму, вы авторизуетесь и увидите страницу приветствия:

Если вы нажмете на кнопку «Sign Out», ваша авторизация отменится и вы вернетесь к странице входа с сообщением о том, что вы вышли из системы.

Поздравляем! Вы только что разработали простое web-приложение, которое защищено Spring Security.

Источник

Spring Security за 15 минут

Что вы сделаете?

Вы интегрируете web-app на Spring Boot с библиотекой Spring Security. Мы возьмем незащищенное приложение, которое мы разбирали в прошлой статье и защитим его с помощью Spring Security:

Что вам понадобится?

  • Около 15-50 минут
  • Ваш любимый текстовый редактор или IDE
  • JDK 1.8 или выше
  • Maven 3.0+

Как пользоваться этой статьей

  • Внимательно прочитайте статью
  • Скачайте исходный код с github
  • Запустите и проверьте работу
  • Удостоверьтесь что код вам понятен
  • Если что то осталось неясно, смело задавайте вопросы мне или google

Первичная настройка Spring-Security

Давайте представим, что нам хочется предотвратить неавторизованный доступ к страничке http://localhost:8080/hello. Сейчас если пользователь нажмет ссылку на базовой странице http://localhost:8080/base ничто не остановит его. Вы должны добавить какой то барьер который бы заставлял пользователя авторизоваться перед тем как увидеть эту страничку. Вы сделаете это сконфигурировав Spring Security. Если Spring Security находится в classpath Spring Boot автоматически защищает все HTTP-endpoints базовой(basic) авторизацией

В дальнейшем вы сможете более тонко настроить security. Первое что вам надо сделать это добавить Spring Security в classpath:

WebSecurityConfigurerAdapter

  • @EnableWebSecurity включает поддержку web security и обеспечивает интеграцию со Spring MVC
  • сonfigure(HttpSecurity) определяет какой URL нужно защищать, а какой не надо(по умолчанию все защищено)
  • .antMatchers(“/”, “/base”).permitAll() данные urls защищать не надо(.permitAll())
  • .loginPage(“/login”) определяется страница для совершения логина в приложение, которая доступна всем
  • .logout().permitAll() определяет что разлогиниться могут все
  • configureGlobal(AuthenticationManagerBuilder) устанавливает in-memory хранилище пользователей с одним пользователем

Создадим login-страницу

Добавим файл src/main/resources/templates/login.html с шаблоном thymeleaf в котором включим интеграцию со Spring-Security — thymeleaf-extras-springsecurity3

И не забудем добавить в MvcConfig для страницы логина натройку контроллера — registry.addViewController(“/login”).setViewName(“login”);

А также изменим страничку hello добавив туда ссылку для разлогинивания:

Мы показываем имя пользователя на страничке благодаря использованию интеграции со Spring Security HttpServletRequest#getRemoteUser() Ссылка “Sign Out” создаст POST запрос к “/logout” и далее переведет пользователя на “/login?logout”. Благодаря чему пользователь увидит это сообщение:

Как это устроено?

Эта простейшая авторизация работает благодаря HTTP_cookie. Рекомендую отследить момент до логина и после и посмотреть на состояние cookie с именем JSESSIONID. Вы увидете что после логина cookie не меняет значение. После разлогинивания это значение поменяется, что и будет означать что пользователь вышел из системы.

В chrome нажмите Ctrl-Shift-I -> Network tab и далее заголовки httml запроса

Тоесть как только пользователь залогинился Spring Security присваивает залогиненому пользователю отдельный JSESSIONID по которому он определяет его при последующих запросах. Это все похоже на работу сессий в сервлетах. Подробнее прочитайте вот эту ссылку how-does-spring-security-sessions-work

Источник

Добавление Spring Security в проект — настройки по умолчанию

В этой статье рассказывается, что будет, если добавить в проект Spring Security — какие настройки включатся по умолчанию.

Подготовка

Сгенерируем на https://start.spring.io/ Spring Boot приложение с зависимостью Web:

Напишем в нем единственный REST-контроллер:

Сейчас к нему имеют доступ все:

Доступный всем контроллер

Добавление Spring Security

Для того, чтобы включить Spring Security, достаточно добавить Maven-зависимость:

И сразу же мы столкнемся с неожиданностью. Теперь при попытке ввести в браузере http://localhost:8080/api/hello мы перенаправляемся на страницу логина http://localhost:8080/login. Если ввести в нее любые наугад взятые данные, получим ошибку:

Отсюда очевидно, что некая проверка выполняется. Но какая?

Что дает зависимость spring-boot-starter-security

Обычно включение любого стартера в POM-файл ничего не дает: чтобы что-то запрограммировать, все равно надо написать дополнительный код. В случае Spring Security все иначе.

Читайте также:  Не работает клавиша escape

Давайте заглянем в консоль. В ней видно, что генерируется некий пароль:

В консоли выдается сгенерированный пароль

Да, Spring Security создал некоего пользователя по умолчанию. Имя его user, а пароль генерируется автоматически при запуске программы.

Итак, что происходит при одном только добавлении spring-boot-starter-security в POM-файл:

  • Spring Security создает пользователя с именем user и автоматически сгенерированным паролем, который можно посмотреть в консоли.
  • Создается страница с формой для ввода имени и пароля -имеем Form-based аутентификацию.
  • Имя и пароль реально проверяются.
  • Все url оказываются недоступны, пока мы не «залогинимся» под этим пользователем.
  • И еще создается страница, где можно «разлогиниться». Она находится по адресу logout. Выглядит так:

Страница «разлогина»

In-Memory аутентификация

С точки зрения получения параметров пользователя из запроса, продемонстрированная выше аутентификация является Form-Based — имя и пароль отправляются через форму и берутся на сервере из запроса как POST-параметры.

С точки зрения же хранения пользователей на стороне сервера, продемонстрированная выше аутентификация в Spring Security называется In-Memory authentication. Она означает, что пользователь хранится не в базе, не на LDAP-сервере и не где-либо еще, а в оперативной памяти приложения до тех пор, пока оно запущено. И чтобы отредактировать пользователя, придется заново запускать приложение. Разумеется, этот вариант не годится для среды Production, зато он прост и полезен для экспериментов во время разработки.

Как задать своего пользователя в In-Memory аутентификации

Итак, приложение при запуске генерирует и хранит имя и пароль пользователя в памяти, мы можем подсмотреть пароль в консоли.

Но чтобы не подсматривать пароль в консоли, можно воспользоваться файлом настроек application.yml — зафиксировать имя/пароль там.

Переопределение пользователя и пароля в настройках

Для этого в настройках application.yml нужно задать свойства:

Теперь пароль не генерируется и в консоль не выводится — используется пользователь с именем и паролем, заданным в application.yml .

Можно задать и несколько пользователей — давайте сделаем это в коде. Перейдем наконец к написанию кода — напишем класс-конфигурацию для Spring Security и настроим в нем аутентификацию явно.

Настройка In-Memory аутентификации в коде

Итак, создадим класс SecurityConfig, который расширяет класс WebSecurityConfigurerAdapter. Сделаем его бином с помощью @EnableWebSecurity:

Аутентификацию выполняет AuthenticationManager, но определять этот бин явно нам не надо. Вместо этого надо переопределить метод configure(AuthenticationManagerBuilder auth) класса WebSecurityConfigurerAdapter — так мы получим доступ к билдеру AuthenticationManagerBuilder, а уж через него настроим нужный нам AuthenticationManager. Делается это так:

  • Во первых, в билдере надо задать тип аутентификации — она может быть не In-Memory, а другой: например, Jdbc, LDAP или кастомной (тип аутинтификации задает где в принципе хранится пользователь). У нас In-Memory аутентификация — этот факт задается строкой auth.inMemoryAuthentication().
  • Далее идут специфические настройки выбранного AuthenticationManager. В них уточняется, как AuthenticationManager извлекает хранимого пользователя, чтоб потом сравнить его с введенным. В случае In-Memory аутентификации менеджеру далеко ходить не надо, реальные имя и пароль задаются тут же с помощью withUser() и password():

На самом деле AuthenticationManager достает не только реальные имя и пароль, но еще разрешение пользователя (что ему разрешено делать в приложении). Мы задали двух пользователей с разрешением ROLE_USER. В данном примере разрешения не используются, мы будем их использовать в примере про авторизацию.

Итак, мы настроили AuthenticationManager, который сравнивает переданные имя и пароль со значениями имени и пароля u1 p1 и u2 p2. В случае совпадения с любым из пользователей, аутентификация проходит успешно.

Обратите внимание на бин PasswordEncoder — в нем задается, как шифровать пароль. Мы задали NoOpPasswordEncoder, который не делает ничего — оставляет пароль в первоначальном виде. Это выбрано в учебных целях, чтобы было наглядно, что требуется вводить в форму логина при запуске примера — ведь в методе password(«p2») задается уже зашифрованный пароль. Конечно, в реальном приложении NoOpPasswordEncoder не пригоден — пароль нужно шифровать, например, с помощью BCryptPasswordEncoder.

Итоги

Таким образом, в примере мы вручную воспроизвели In-Memory аутентификацию, которая вообще-то предоставляется по умолчанию при добавлении security-стартера в проект. Правда, немного видоизменили ее, добавив двух своих пользователей.

Код примера есть на GitHub, в следующей статье настроим авторизацию.

Источник

Оцените статью