Недавно я столкнулся с проблемой в проекте: передний и задний и задний ход разделены, передняя часть выполняется с помощью VUE, все запросы на данные используют VUE-Resource, и форма не используется, поэтому взаимодействие данных используется JSON, фон использует Spring Boot, а проверка разрешений использует безопасность Spring. Поскольку Spring Security использовалась ранее, они обрабатывали страницы, и на этот раз они просто обрабатывали запросы Ajax, поэтому они записали некоторые проблемы, с которыми они столкнулись. Решение здесь не только подходит для запросов AJAX, но и разрешает проверку мобильных запросов.
Создать проект
Прежде всего, нам нужно создать проект Spring Boot. При его создании нам нужно представить Web, Spring Security, MySQL и Mybatis (структура базы данных на самом деле произвольна, я использую Mybatis здесь). После создания файл зависимости заключается в следующем:
<Depective> <groupId> org.mybatis.spring.boot </GroupId> <straCactId> mybatis-spring-boot-starter </artifactid> <sersive> 1.3.1 </version> </gropect> <seyedy> <groupd> <Artifactid> Spring-boot-starter-security </artifactid> </deperency> <dependency> <groupid> org.springframework.boot </groupid> <artifactid> Spring-boot-starter-web </artifactid> </jepertive> <DeyEdend> <groupID> mySQL </GroupId> <artifactid> mysql-connector-java </artifactid> <cracpe> выполнение времени </scope> </depertive> <dependency> <groupid> commons-codec </groupid> <artifactid> commons-codec </artifactid> <sersive> 1.11 </version> </regy>
Обратите внимание, что последняя зависимость от кодека общего пользования была добавлена мной вручную. Это проект Apache с открытым исходным кодом, который можно использовать для генерации диварийных сообщений MD5. Я просто обработаю пароль в следующем тексте.
Создайте базу данных и настройте ее
Чтобы упростить логику, я создал здесь три таблицы, а именно таблицу пользователей, таблицу ролей и таблицу ассоциации ролей пользователей следующим образом:
Далее нам нужно сделать простую конфигурацию нашей базы данных в Application.properties. Здесь мы определены вашей конкретной ситуацией.
spring.datasource.url = jdbc: mysql: ///vueblogspring.datasource.username=rootspring.datasource.password=123
Построить класс сущности
Здесь в основном относится к созданию классов пользователей. Классы пользователей здесь очень особенные и должны реализовать интерфейс userdetails следующим образом:
Пользователь общедоступного класса реализует userdetails {private Long Id; частное имя пользователя; Private String Password; Приватный прозвище; Частный логический включен; Частный список <Роль> Роли; @Override public boolean isaccountnonexpired () {return true; } @Override public boolean isAccountnonlocked () {return true; } @Override public boolean iscredentialsnonexpired () {return true; } @Override public boolean isEnabled () {return включен; } @Override public list <wretedAuthority> getAuthorities () {list <wletedAuthority> worthes = new ArrayList <> (); Для (роли роли: роли) {holations.add (new SimplegrantedAuthority ("role_" + role.getName ())); } return Outhorations; } // getter/setter olmit ...} После реализации интерфейса userdetails в этом интерфейсе есть несколько методов, которые нам нужно реализовать. Четыре метода, которые возвращают логические, все известны и известны. Включено указывает, включена ли учетная запись периода. Это поле существует в моей базе данных. Следовательно, согласно результатам запроса, другой возвращается напрямую для простых периодов. Метод Getauthorities возвращает информацию о роли текущего пользователя. Роль пользователя на самом деле - данные в ролях. Данные в ролях конвертируются в список <wetsedAuthority>, а затем возвращаются. Здесь есть момент, чтобы отметить. Поскольку названия ролей, которые я хранят в базе данных, все такие, как «супер -администратор», «обычный пользователь» и т. Д., И не начинаются с таких символов, как ROLE_ , поэтому вам нужно вручную добавить ROLE_ здесь, помните.
Существует также рок объекта, который относительно прост и может быть создан в соответствии с областями базы данных. Я не буду повторять это здесь.
Создать пользовательский сервис
Пользовательская служба здесь также является очень особенным, и необходимо реализовать интерфейс userdetailsservice следующим образом:
@ServicePublic Class UserService реализует userDetailsService {@autowired usermapper usermapper; @Autowired Rolesmapper Rolesmapper; @Override public userDetails lokuserByusername (String S) выбрасывает usernameNotFoundException {user user = usermapper.loadUserbyusername (ы); if (user == null) {// избегание возврата NULL, здесь возвращает пользовательский объект, который не содержит никакого значения, и проверка также не удастся в процессе последующего сравнения пароля возврата New user (); } // Запросить информацию о роли пользователя и вернуться к пользователю. List <Rele> roles = RolesMapper.getRolesByuid (user.getId ()); user.setRoles (роли); вернуть пользователь; }}После реализации интерфейса userdetailsservice нам необходимо реализовать метод LoadUserByusername в интерфейсе, то есть запросить пользователя на основе имени пользователя. Здесь вводится два уровня в Mybatis, Usermapper используется для запроса пользователей, а Rolesmapper используется для запроса ролей. В методе LoadUserByUsername сначала запрашивайте пользователя в соответствии с передаваемыми параметрами (параметр - это имя пользователя, введенное при входе в систему пользователя). Если пользователь обнаружил, что NULL, вы можете напрямую бросить исключение UsernameNotFoundException. Однако для удобства обработки я вернул пользовательский объект без какого -либо значения. Таким образом, во время последующего процесса сравнения паролей вы обнаружите, что вход не удался (здесь вы можете настроить его в соответствии с потребностями вашего бизнеса). Если пользователь обнаружил, что не является нулевым, мы рассмотрим роль пользователя на основе идентификатора пользователя и поместим результат запроса в объект пользователя. Этот результат запроса будет использоваться в методе Getauthorities объекта пользователя.
Конфигурация безопасности
Давайте сначала посмотрим на мою конфигурацию безопасности, а затем я объясню это один за другим:
@Configurationpublic class websecurityconfig Extends WebseCurityConfigurerAdapter {@autowired userservice userservice; @Override Protected void configure (AuthenticationManagerBuilder auth) Throws Exception {auth.userDetailsService (userservice) .passwordencoder (new passwordEncoder () {@override public String Encode (charexecence charebence) {return digestutils.md5digestashex (charedsering () getbytes (); @param char -seculty plunext* @param s ciphertext* @return*/ @override public boolean matches (char -sequence char -sevence, string s) {return s.equals (digestutils.md5digestashex (char -sevectence.tostring (). getbytes ())); } @Override Protected void configure (httpsecurity http) выбрасывает исключение {http.authorizerequests () .antmatchers ("/admin/**"). Hasrole ("Super Admin"). AnyRequest (). Authenticated () // другие пути доступны после сжигания. in.and().formLogin().loginPage("/login_page").successHandler(new AuthenticationSuccessHandler() { @Override public void onAuthenticationSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, Servletexception {httpservletresponse.setContentType ("Application/json; charset = utf-8"); }) .failureHandler (new AuthenticationFailureHandler () {@Override public void onauthenticationFailure (httpservletrequest httpservletrequest, httpservletresponse httpservletrespons httpservletresponse.setcontenttype ("Application/json; charset = utf-8"); }). LoginProcessingUrl ("/login") .usernameparameter ("username"). PasswordParameter ("пароль"). armitall (). и (). logout (). armitall (). и (). csrf (). Disable (); } @Override public void configure (Websecurity Web) бросает исключение {web.ignoring (). Antmatchers ("/reg"); }}Это ядро нашей конфигурации. Пожалуйста, послушайте меня:
1. Прежде всего, это класс конфигурации, поэтому не забудьте добавить аннотацию @Configuration. Поскольку это конфигурация Spring Security, вы должны унаследовать WebSecurityConfigurerAdapter.
2. Включите только что только что созданный пользовательский сервис, и мы будем использовать его позже.
3. Метод конфигурации (AuthenticationManagerBuilder Auth) используется для настройки нашего метода аутентификации и прохождения пользовательского обслуживания в методе Auth.UserDetailsService (), чтобы метод LoatuserByusernamer в пользовательском обслуживании будет автоматически, когда пользователь входит в систему. Пароль с открытым текстом также необходим для его обработки при входе в систему, поэтому я добавил пароль, и после добавления PasswordEncoder я могу непосредственно новый анонимный внутренний класс PasswordEncoder. Здесь есть два метода для реализации, и вы можете узнать значение метода, посмотрев на имя. Первый метод кодирует, очевидно, шифрует открытый текст. Здесь я использую Digest Messe Digest MD5. Конкретный метод реализации обеспечивается зависимостью Commons-Codec; Второй метод соответствует сравнению пароля, два параметра, первый параметр - пароль с открытым текстом, а второй - Ciphertext. Здесь вам нужно только шифровать открытый текст и сравнить его с шифровым текстом (если вы заинтересованы в этом, вы можете продолжать рассмотреть возможность добавления соли в пароль).
4. Конфигурирование (httpsecurity http) используется для настройки наших правил аутентификации и т. Д. Метод AuthorizeRequests означает, что конфигурация правила аутентификации включена, Antmatchers («/Admin/**»). Hasrole («супер -администратор») означает, что путь /admin/** должен быть доступен пользователями с «супер -администратором». В Интернете я видел, что у моих друзей есть вопросы о том, добавлять ли ROLE_ в методе Hasrole. Не добавляйте его здесь. Если вы используете метод Hasauthority, вам нужно добавить его. AnyRequest (). Authenticated () означает, что все другие пути должны быть аутентифицированы/вошли в систему перед доступом. Затем мы настроили страницу входа в систему в качестве login_page, путь обработки входа в систему является /входит в систему, имя пользователя входа в систему - имя пользователя, а пароль - пароль. Мы настроили эти пути для доступа непосредственно, и вход из входа в систему также можно получить напрямую и, наконец, закрыть CSRF. В SuccessHandler используйте ответ, чтобы вернуть JSON, который успешно вошел в систему. Не забудьте не использовать Defauccessurl. Defauccessurl - это страница, которая перенаправляется только после успешного входа в систему. Та же причина также используется для сбоя.
5. Я настроил некоторые правила фильтрации в методе конфигурации (Websecurity Web), поэтому я не буду вдаваться в подробности.
6. Кроме того, для статических файлов, таких как /images/** , /css/** и /js/** , по умолчанию не перехватывается.
Контроллер
Наконец, давайте посмотрим на наш контроллер следующим образом:
@RestControllerPublic Class LoginRegController {/** * Если вы автоматически перейдете на эту страницу, это означает, что пользователь не вошел в систему, и вы можете вернуть соответствующую подсказку * <p> * Если вы хотите поддержать форму, вы можете судить о типе запроса в этом методе, а затем вернуть ли json или html page * @return * @Requestmappopeppor Respbean loginpage () {return new Respbean («ошибка», «еще не вошел в систему, пожалуйста, войдите в систему!»); }} В целом, этот контроллер относительно прост. Respbean возвращает простой JSON, который не подробно. На что вам нужно обратить внимание на login_page . Страница для входа, которую мы настроили, является login_page . Но на самом деле, login_page - это не страница, а JSON. Это связано с тем, что когда я посещаю другие страницы без входа в систему, Spring Security автоматически перейдет на страницу login_page . Однако в запросе AJAX этот вид прыжков не нужен. Все, что я хочу, - это подсказка для входа или нет, поэтому я могу вернуть здесь JSON.
тест
Наконец, друзья могут использовать такие инструменты, как почтальон или RestClient, для проверки входа в систему и проблем с разрешением, поэтому я не буду их демонстрировать.
ОК, после введения выше, я считаю, что друзья уже поняли обработку Spring Boot+Spring Security по запросам входа в систему AJAX. Хорошо, это все для этой статьи. Если у вас есть какие -либо вопросы, пожалуйста, оставьте сообщение для обсуждения.