В этом уроке будет рассмотрен пример реализации аутентификации пользователя используя Spring Security.
Шаг 1. Создание проекта и подключение зависимостей
Начнем с традиционного создания проекта:
Создали Maven проект, теперь добавим зависимости в pom.xml их будет довольно таки много, поэтому прикладываю полный pom файл:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>spring-security-exam</groupId> <artifactId>spring-security-exam</artifactId> <version>1.0-SNAPSHOT</version> <packaging>war</packaging> <properties> <spring.mvc>4.0.0.RELEASE</spring.mvc> <javax.servlet>3.0.1</javax.servlet> <jstl.version>1.2</jstl.version> <spring.securiry>3.2.0.RELEASE</spring.securiry> </properties> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${spring.mvc}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>${spring.mvc}</version> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>${javax.servlet}</version> <scope>provided</scope> </dependency> <dependency> <groupId>jstl</groupId> <artifactId>jstl</artifactId> <version>${jstl.version}</version> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-web</artifactId> <version>${spring.securiry}</version> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-core</artifactId> <version>${spring.securiry}</version> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-config</artifactId> <version>${spring.securiry}</version> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-taglibs</artifactId> <version>${spring.securiry}</version> </dependency> </dependencies> <build> <finalName>secure-exam</finalName> <plugins> <plugin> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.7</source> <target>1.7</target> </configuration> </plugin> </plugins> </build> </project>
По каждому из зависимостей не буду останавливаться, но включил самые обязательные зависимости для реализации Spring Security.
Сразу же покажу вам какая должна быть структура проекта, чтобы вы не терялись в создании классов и файлов.
Шаг 2. Начинаем с конца, делаем внешний вид
Для большей привлекательности как к внешнему виду, так и мотивации изучить этот урок, я решил использовать Bootstrap 3.
Скачиваем bootstrap и в проекте создаем папку webapp/pages/ и копируем туда файлы bootstrap-а. (смотрите на структуре проекта)
Теперь создаем webapp/pages/index.jsp:
<%@ page contentType="text/html; charset=UTF-8" language="java" %> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <%@ taglib uri="http://www.springframework.org/security/tags" prefix="sec" %> <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="description" content=""> <meta name="author" content=""> <title>Spring Security</title> <!-- Bootstrap core CSS --> <link href="<c:url value="/pages/css/bootstrap.css" />" rel="stylesheet"> <!-- Custom styles for this template --> <link href="<c:url value="/pages/css/jumbotron-narrow.css" />" rel="stylesheet"> <!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries --> <!--[if lt IE 9]> <script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script> <script src="https://oss.maxcdn.com/libs/respond.js/1.3.0/respond.min.js"></script> <![endif]--> </head> <body> <div class="container"> <div class="jumbotron" style="margin-top: 20px;"> <h1>Devcolibri.com</h1> <p class="lead"> Devcolibri - это сервис предоставляющий всем желающим возможность обучаться программированию. </p> <sec:authorize access="!isAuthenticated()"> <p><a class="btn btn-lg btn-success" href="<c:url value="/login" />" role="button">Войти</a></p> </sec:authorize> <sec:authorize access="isAuthenticated()"> <p>Ваш логин: <sec:authentication property="principal.username" /></p> <p><a class="btn btn-lg btn-danger" href="<c:url value="/logout" />" role="button">Выйти</a></p> </sec:authorize> </div> <div class="footer"> <p>© Devcolibri 2014</p> </div> </div> </body> </html>
Выглядеть эта страница будет так:
Создаем следующую страницу на которой собственно и будет происходить вход на сайт webapp/pages/login.jsp:
<%@ page contentType="text/html; charset=UTF-8" language="java" %> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="description" content=""> <meta name="author" content=""> <title>Spring Security</title> <!-- Bootstrap core CSS --> <link href="<c:url value="/pages/css/bootstrap.css" />" rel="stylesheet"> <!-- Custom styles for this template --> <link href="<c:url value="/pages/css/signin.css" />" rel="stylesheet"> <!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries --> <!--[if lt IE 9]> <script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script> <script src="https://oss.maxcdn.com/libs/respond.js/1.3.0/respond.min.js"></script> <![endif]--> </head> <body> <div class="container" style="width: 300px;"> <c:url value="/j_spring_security_check" var="loginUrl" /> <form action="${loginUrl}" method="post"> <h2 class="form-signin-heading">Please sign in</h2> <input type="text" class="form-control" name="j_username" placeholder="Email address" required autofocus value="colibri"> <input type="password" class="form-control" name="j_password" placeholder="Password" required value="1234"> <button class="btn btn-lg btn-primary btn-block" type="submit">Войти</button> </form> </div> </body> </html>
Тут обратите особое внимание на обя тега input, а именно на их name:
name=”j_username”
name=”j_password”
В данном случае эти поля должны быть именно с такими значениями.
А также вы возможно уже увидели эту строку:
<c:url value="/j_spring_security_check" var="loginUrl" />
так мы создали переменную, которая будет хранить ссылку на security check, он выполняет аутентификация, где значение value обязательно должно быть таким.
Выглядеть она будет так:
Думаю получилось не плохо :)
Шаг 3. Создаем контроллеры
О создании MVC проекта на Spring можно почитать урок Spring MVC Hello World
Создаем пакет controller и класс MainController:
package com.devcolibri.secure.controller; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; @Controller @RequestMapping("/") public class MainController { @RequestMapping(method = RequestMethod.GET) public String start(Model model){ return "index"; } }
Этот контроллер будет просто направлять пользователя на страницу index.jsp.
А теперь создадим второй аналогичный контроллер, который будет показывать пользователю страничку login.jsp.
Создаем класс и называем его LoginController:
package com.devcolibri.secure.controller; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; @Controller @RequestMapping("/login") public class LoginController { @RequestMapping(method = RequestMethod.GET) public String loginPage(Model model){ return "login"; } }
Теперь мы сможем ходить по страничкам.
Шаг 4. Конфигурирование Spring MVC
Теперь нам нужно сконфигурировать Spring MVC чтобы он имел возможность разворачивать свой контекс и мы могли получать доступ к нашим бинам.
Создаем в пакете config класс WebAppConfig и наследуем его от WebMvcConfigurerAdapter:
package com.devcolibri.secure.config; import com.devcolibri.secure.service.UserDetailsServiceImpl; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; import org.springframework.web.servlet.view.InternalResourceViewResolver; import org.springframework.web.servlet.view.JstlView; import org.springframework.web.servlet.view.UrlBasedViewResolver; @Configuration @EnableWebMvc @ComponentScan("com.devcolibri") public class WebAppConfig extends WebMvcConfigurerAdapter { @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/pages/**").addResourceLocations("/pages/"); } @Bean public UrlBasedViewResolver setupViewResolver() { UrlBasedViewResolver resolver = new UrlBasedViewResolver(); resolver.setPrefix("/pages/"); resolver.setSuffix(".jsp"); resolver.setViewClass(JstlView.class); return resolver; } }
Подробную информацию о Java Config для Spring вы можете посмотреть в уроке Spring 3. JavaConfig на примере Spring MVC.
Шаг 5. Создание Entity
Так как цель урока показать пример использования Spring Security, то я не стал реализовывать работу с БД, а всего лишь создал все необходимое для этого, чтобы в будущем реализовать Spring DATA.
Создаем entity по сути это простой класс, так как мы не используем не ORM фреймворков, назовем его User:
package com.devcolibri.secure.entity; public class User { private String login; private String password; public User(String login, String password) { this.login = login; this.password = password; } public User() { } public String getLogin() { return login; } public void setLogin(String login) { this.login = login; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } }
В будущем вы можете этот объект пополнять своими свойствами, но для примера нам достаточно знать Login (логин) и Password (пароль).
И еще в этом же пакете создадим пакет enums и в нем создаем enum UserRoleEnum, который будет определять роли пользователя:
package com.devcolibri.secure.entity.enums; public enum UserRoleEnum { ADMIN, USER, ANONYMOUS; UserRoleEnum() { } }
Теперь у нас есть 3 роли, которые мы немного позже будем использовать.
Шаг 6. Создаем слой Services
Обычно проекты имеют несколько уровней слоёв, о которых я еще напишу статью, но один из этих слоёв мы реализуем прям сейчас.
Нам нужно реализовать Service tier (сервис слой либо уровень обслуживания). Создаем пакет service и в нем создаем интерфейс UserService:
package com.devcolibri.secure.service; import com.devcolibri.secure.entity.User; public interface UserService { User getUser(String login); }
Этот сервисный интерфейс говорит о том, что у нас будет сервис который позволит получать User не важно как и откуда, но он позволит нам это.
А теперь давайте напишем первую реализацию данного интерфейса, для этого создаем на том же уровне класс UserServiceImpl:
package com.devcolibri.secure.service; import com.devcolibri.secure.entity.User; import org.springframework.stereotype.Service; @Service public class UserServiceImpl implements UserService { @Override public User getUser(String login) { User user = new User(); user.setLogin(login); user.setPassword("7110eda4d09e062aa5e4a390b0a572ac0d2c0220"); return user; } }
Как видите реализация довольно простая, тут мы просто заполняем объект User используя setters, но мы также можем в этом сервис методе вызвать метод из DAO, который бы достал нам этого юзера с БД например либо получил бы его с Web Service.
Обратите внимание, что я установил в поле Password специфичный пароль, а именно зашифрованный в SHA1 формате.
То есть я взял пароль “1234” и зашифровал его в SHA1 формат с помощью online сервиса SHA1 online generator и получил уже зашифрованный пароль “7110eda4d09e062aa5e4a390b0a572ac0d2c0220“.
Шаг 7. Создаем реализацию UserDetailsService
Для того, чтобы связать наш сервис UserService со Spring Security, нам нужно реализовать специальный интерфейс фреймворка Spring Security который позволит выполнять аутентификацию пользователя на основании данных полученных с UserService написанного выше.
Создаем класс UserDetailsServiceImpl и реализуем его от UserDetailsService:
package com.devcolibri.secure.service; import com.devcolibri.secure.entity.User; import com.devcolibri.secure.entity.enums.UserRoleEnum; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.stereotype.Service; import java.util.HashSet; import java.util.Set; @Service public class UserDetailsServiceImpl implements UserDetailsService { @Autowired private UserService userService; @Override public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException { // с помощью нашего сервиса UserService получаем User User user = userService.getUser("colibri"); // указываем роли для этого пользователя Set<GrantedAuthority> roles = new HashSet(); roles.add(new SimpleGrantedAuthority(UserRoleEnum.USER.name())); // на основании полученных данных формируем объект UserDetails // который позволит проверить введенный пользователем логин и пароль // и уже потом аутентифицировать пользователя UserDetails userDetails = new org.springframework.security.core.userdetails.User(user.getLogin(), user.getPassword(), roles); return userDetails; } }
Этот сервис и является основной логикой аутентификаци c использованием Spring Security.
Шаг 8. Добавляем инициализацию бина UserDetailsServiceImpl в конфигурацию WebAppConfig
Для того чтобы наша реализация интерфейса UserDetailsService смогла инициализыроваться контейнером Spring нам нужно добавить его в WebAppConfig:
@Bean public UserDetailsService getUserDetailsService(){ return new UserDetailsServiceImpl(); }
После этого Spring контейнер будет знать какую реализацию интерфейса UserDetailsService нужно брать.
Шаг 9. Конфигурирование Spring Security
Теперь самое главное, заставить все это заработать :)
Создаем в пакете config класс SecurityConfig и наследуем его от WebSecurityConfigurerAdapter:
package com.devcolibri.secure.config; import com.devcolibri.secure.service.UserDetailsServiceImpl; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.authentication.encoding.ShaPasswordEncoder; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; @Configuration @EnableWebSecurity @EnableGlobalMethodSecurity(securedEnabled = true) public class SecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private UserDetailsServiceImpl userDetailsService; // регистрируем нашу реализацию UserDetailsService // а также PasswordEncoder для приведения пароля в формат SHA1 @Autowired public void registerGlobalAuthentication(AuthenticationManagerBuilder auth) throws Exception { auth .userDetailsService(userDetailsService) .passwordEncoder(getShaPasswordEncoder()); } @Override protected void configure(HttpSecurity http) throws Exception { // включаем защиту от CSRF атак http.csrf() .disable() // указываем правила запросов // по которым будет определятся доступ к ресурсам и остальным данным .authorizeRequests() .antMatchers("/resources/**", "/**").permitAll() .anyRequest().permitAll() .and(); http.formLogin() // указываем страницу с формой логина .loginPage("/login") // указываем action с формы логина .loginProcessingUrl("/j_spring_security_check") // указываем URL при неудачном логине .failureUrl("/login?error") // Указываем параметры логина и пароля с формы логина .usernameParameter("j_username") .passwordParameter("j_password") // даем доступ к форме логина всем .permitAll(); http.logout() // разрешаем делать логаут всем .permitAll() // указываем URL логаута .logoutUrl("/logout") // указываем URL при удачном логауте .logoutSuccessUrl("/login?logout") // делаем не валидной текущую сессию .invalidateHttpSession(true); } // Указываем Spring контейнеру, что надо инициализировать ShaPasswordEncoder // Это можно вынести в WebAppConfig, но для понимаемости оставил тут @Bean public ShaPasswordEncoder getShaPasswordEncoder(){ return new ShaPasswordEncoder(); } }
Это базовая конфигурация, которая нужна для наших нужд, она может расширятся.
Шаг 10. Регистрация конфигураций в контексте Spring
Чтобы Spring видел наши конфигурации, а именно WebAppConfig и SecurityConfig их нужно зарегистрировать в контексте Spring.
Создаем в пакете config класс Initializer и реализуем WebApplicationInitializer:
package com.devcolibri.secure.config; import org.springframework.web.WebApplicationInitializer; import org.springframework.web.context.ContextLoaderListener; import org.springframework.web.context.support.AnnotationConfigWebApplicationContext; import org.springframework.web.servlet.DispatcherServlet; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.ServletRegistration.Dynamic; public class Initializer implements WebApplicationInitializer { private static final String DISPATCHER_SERVLET_NAME = "dispatcher"; @Override public void onStartup(ServletContext servletContext) throws ServletException { AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext(); // регистрация конфигураций в Spring контексте ctx.register(WebAppConfig.class); ctx.register(SecurityConfig.class); servletContext.addListener(new ContextLoaderListener(ctx)); ctx.setServletContext(servletContext); Dynamic servlet = servletContext.addServlet(DISPATCHER_SERVLET_NAME, new DispatcherServlet(ctx)); servlet.addMapping("/"); servlet.setLoadOnStartup(1); } }
На этом этап конфигурации проекта можно считать законченным.
B web.xml нужно добавить фильтр, который будет определять наши реквесты и проверять валидность сессии:
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0"> <filter> <filter-name>springSecurityFilterChain</filter-name> <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> </filter> <filter-mapping> <filter-name>springSecurityFilterChain</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> </web-app>
Шаг 11. Развертывание и тестирование
Пора все собрать и развернуть на сервере приложений.
Собираем проект с помощью Maven:
Теперь развертываем собранный собранный war на сервере приложений, я выбрал Tomcat 8.
Конфигурируем Intellij IDEA под Tomcat. Заходим в Edit Configuration…
Нажимаем по плюсику (Add New Configuration…) ищем там Tomcat Server -> Local:
Конфигурируем также как показано на скриншоте, потом переходим в раздел Deployment:
Жмем Add -> External Source… в корне вашего проекта будет папка target в ней будет secure-exam.war выбираем его и в поле Application context пишем /secure.
После этого запускаем. Попадем на главное окно жмем Войти переходим на форму с логином и нажимаем Войти, после этого вас перенаправит на главную страницу где вы увидите свой логин.
На этом все. Надеюсь данный урок вам поможет.
Также читайте серию статей «Spring Data JPA. Работа с БД»: часть 1, часть 2 и часть 3
ПОХОЖИЕ ПУБЛИКАЦИИ
- None Found
65 комментариев к статье "Быстрый старт в Spring Security"
Добавить комментарий
Для отправки комментария вам необходимо авторизоваться.
Спасибо за статью! еще бы ссылочку для скачивания
НА начале урока есть кнопка СКАЧАТЬ :)
:) меня можно было сразу посылать к окулисту после такого комментария. А куда жертвовать деньги за такие статьи?
:) Как я понял вам понравился урок :)
Как в eclipse открыть?
вот это пост! первый раз вижу настоящий спринг, и руку программиста.
Спасибо, приятно слышать :)
Замечательная статья, кратко и все по делу.
Для того чтобы наша реализация интерфейса UserDetailsService согла – опечатка 8 пункт
Спасибо, поправил.
Шаг 8. Добавляем инициализацию бина UserDetailsServiceUmpl в конфигурацию WebAppConfig – тоже опечатка — UserDetailsServiceUmpl
Геннадий, спасибо)) Исправил.
Описать радость которую принесла даная статья просто невозможно!
Отличная статья. Да и ресурс хороший)
очепятка – “Создаем класс UserDetailsServiceImpl и реализуем его от UserDetailsServiceImpl:”
Спасибо за исправление)
Практически вся конфигурация приложения без использования xml, но в web.xml присутствует пару строчек, без которых авторизация не работает. Поясните пожалуйста для чего они и возможно добавьте в туториал, без них у меня не работало, пока не скачал проект и не сравнил, а Вам лично спасибо за статью.
Спасибо за правку, добавил.
Или если работать без web.xml, а с JavaConfig нужно добавить такой класс
public class SpringSecurityInitializer extends AbstractSecurityWebApplicationInitializer {
}
Шаг 8 делать не нужно, т.к. в 7-м шаге проставлена аннотация @Service. Верно?
Я могу ошибаться, но думаю нужно, так как интерфейс спринговый а реализация наша, и думаю что спрингу не будет видно эту реализацию.
У меня на шаге 10 возникли проблемы
servletContext.addListener(new ContextLoaderListener(ctx)); addListener подсвечен красным
servletContext.addServlet(DISPATCHER_SERVLET_NAME, new DispatcherServlet(ctx)); addServlet подсвечен красным
и следовательно не запускается
как можно исправить или какой web.xml должен быть для него?
А можете рассказать поподробнее, как именно в этом примере реализовать регистрацию пользователя и запись данных в БД используя hibernate и логин по данным котоыре хранятся в БД. Ибо я так понял, тут при логине просто сверняются данные которые мы прописали в нашем классе userserviceImp
${spring.securiry} – secutiry*
Очепятка ${spring.securiry}
Столкнулся с проблемой, во время запуска выскакивает ошибка 04-Mar-2015 12:48:30.449 WARNING [http-apr-8080-exec-10] org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver.handleHttpRequestMethodNotSupported Request method ‘HEAD’ not supported
не могу решить проблему!
получилось разобраться довольно бытро) Спасибо
Спасибо, всё хорошо и понятно описано.
Ждем-с статью про регистрацию новых пользователей :)
Спасибо огромное и низкий поклон автору сайта за такой содержательный и полезный материал! Я все сделал, как написано, но у меня почему-то в jsp-страницах не распознаются теги: taglib uri, prefix пишет : taglib uri is not allowed here, форумы тоже особо ничего не дали. С остальными описанными тегами ситуация тоже такая же, как с uri. Еще не видит пути. Не могли бы подсказать как правильно сделать, что бы все заработало. Был бы очень благодарен
В зависимости добавь jstl core
Зачем в проекте томкат из idea? Ведь те кто изучают язык явно используют community-edition. Проще добавить к зависимостям плагин, хоть проект откроется. За урок спасибо.
org.apache.tomcat.maven
tomcat7-maven-plugin
2.2
/
Здравствуйте. Есть несколько вопросов, которые просто уже некому задать. Я в полном замешательстве. Не могли бы вы написать мне на e-mail, чтобы как-то связаться с вами???
Добрый день, прочитал вашу статью, очень интересно, пробую на примере, все получилось. НО, как только попробовал настроить Матчеры под свои нужны тут началась беда. Вопрос, если брать на данном примере как настроить доступ к ресурсам в зависимости от роли? Как я сделал:
http.csrf()
.disable()
// указываем правила запросов
// по которым будет определятся доступ к ресурсам и остальным данным
.authorizeRequests()
.antMatchers(“/login”, “/registration”).permitAll()
.antMatchers(“/”).hasAnyRole(Roles.USER.name(), Roles.ADMIN.name(), Roles.ANONYMOUS.name())
.and();
При успешной авторизации меня перебрасывает на корневую страничку приложения (http://localhost:9999/myapp/) и выпадает ошибка 403. Почему так происходит? Я ведь указал, что пользователь с любой из перечисленных ролей может посетить данную страницу. Что не так, подскажите пожалуйста.
Пытаюсь проверить в контроллере корректно ли инициализируется юзер:
UserDetails userDetails = (UserDetails) SecurityContextHolder.getContext().
getAuthentication().getPrincipal();
System.out.println(userDetails.getPassword());
System.out.println(userDetails.getUsername());
System.out.println(userDetails.getAuthorities().toString());
получаю такой вывод:
null
colibri
USER
У меня входит даже если я вместо логина пишу любую цифру, в чем может быть проблема? as – wildfly, скачал архив
Максим. Это нормально. Там нет проверки на логин. В SecurityConfig передаётся userDetailsService, который в свою очередь, берёт логин и паротль из UserServiceImpl. Пероль там задаётся зашифрованным, а логин будет любым
Благодарю за ответ) уже привязал с хибернейтом) все ок)
Просто великолепная статья, спасибо огромное)
В браузере название вкладки – Быстрый страт) Исправь)
Немного не понял вот этот момент:
// включаем защиту от CSRF атак
http.csrf()
.disable()
Насколько я знаю, по умолчанию защита включена, а эта строчка ее как раз выключает. Так ведь?
все так )
Спасибо за отличную статью! У меня вопрос. Обязательна ли эта переменная , ведь url можно было сразу в форму прописать?
c:url value=”/j_spring_security_check” var=”loginUrl”
Можно ли вместо страницы login.jsp, использовать в классе контроллере LoginController, метод который будет принимать JSONObject с параметрами для входа?
в файле index.jsp у меня не отображается в браузере все что лежит в sec:authorize. в чем может быть проблема?
при запуске проекта следующая проблема
HTTP Status 500 – No WebApplicationContext found: no ContextLoaderListener registered?
Проект скачал и запустил на Tomcat 6.
В чём может быть проблема?
я обожаю ваш сайт))
В шаге 9, в SecurityConfig, в строке 28, вроде должно быть: .userDetailsService(userDetailsService())
Верно ?
Привет,Александр Барчук! Может подскажете, как мне отмапить или правильно сказать словить ситуацию после того как пользователь прошел проверку. @RequestMapping(value = “КАКОЙ URL сюда писать?”, method=GET) Это перед методом.
Форма у меня такая: <form class="signin" action="
” method=”post”>но если я ловлю вот так: @RequestMapping(value = “/static/j_spring_security_check”, method=GET) то не срабатывает.
Все, я решил вопрос сам.
Святая корова! Спасибо за такие подробные статьи. Я по ним сейчас активно учусь. Вы реально очень помогаете понять очень многие моменты.
спасибо
в шаге 8 ошибка, бин надо добавлять в SecurityConfig или если не хотим лишнего кода добавляем в SecurityConfig аннотацию @ComponentScan(“com.devcolibri”)
статья безусловно хорошая, даже превосходная, но я жду статьи на основе этой с использованием hibernate и хранением данных о пользователе в таблице с полями типа:
user_role (роль)
user_name (выводимое имя)
user_login (логин для авторизации)
user_password (пароль)
будет гораздо гораздее создать и такой пример
спасибо
<link href="” rel=”stylesheet”> на это мне идея отвечает, мол cannot resolve symbol ‘/pages/css/jumbotron-narrow.css’. я новичек. подскажите, плиз как его зарезолвить)
ЗЫ
вышеуказанные строчки в jsp указаны…
Замечательно. Статья очень помогла. Спасибо автору! Умеет грамотно объяснить и оформить.
Спасибо за статью) Александр, подскажите как выполнить почти такую же задачу только в ответе на запрос “/login” не перенаправлять на форму логина, а отдавать данные в виде json? В чем принципиальные отличия?
очепятка:
Быстрый страт в Spring Security
опечатки две: на основании данных полученых с UserService написанного высше
Здравствуйте я заметил некую деталь, неважно вводим ли мы логин, если пароль правильный оно пускает, почему так ?
Быстрый старт в никуда.
.antMatchers(“/resources/**”, “/**”).permitAll()
эта строка разрешает открывать ЛЮБЫЕ страницы. хоть авторизован хоть нет.
Легко убедиться – создаем контроллер типа СекретКонтроллер, который отдает Секрет.жсп и эта страница опять же отдается без авторизации, как и все остальные.
А должно быть так:
.antMatchers(“/resources/**”, “/”).permitAll()
Разрешить ТОЛЬКО корень, и ничего более
Пока исправишь все ошибки в таких уроках уже и опыт появится