Для веб-системы необходимо контролировать права доступа к страницам и API-интерфейсам, например, необходимо запретить доступ несистемным пользователям и контролировать права доступа разных страниц или интерфейсов. В разработке Java обычно используются среды безопасности Spring Security и Apache Shiro.
Spring Security — это инфраструктура безопасности экосистемы Spring, реализованная на основе фильтров Spring AOP и сервлетов и рекомендованная Spring Boot. Он обеспечивает комплексное решение для обеспечения безопасности при обработке аутентификации и авторизации как на уровне веб-запросов, так и на уровне вызова метода.
Spring Security в основном включает следующие две части:
Авторизация при входе (Аутентификация)
Авторизация
В этом разделе фактическая загрузка Spring будет интегрирована с Spring Security,Реализовать контроль доступа для регистрации пользователей, входа в систему и прав доступа к ролям..
База данных использует MySQL, а структура уровня сохраняемости данных использует MyBatis.
Spring Security использует сеанс по умолчанию, поэтому он не использует RESTful API и использует шаблон MVC. Thymeleaf как шаблонизатор для веб-страниц
1) Введение зависимости и конфигурация проекта
Новый проект 05-весна-безопасность,Обратите внимание, что версия Spring Boot должна быть версии 2.1.X.
1.1) Введение зависимости
Starter (стартер), предоставляемый Spring Security для Spring Boot, позволяет Spring Boot интегрировать Security практически без разработки конфигурации.
thymeleaf-extras-springsecurity5 — это расширение Thymeleaf для управления отображением веб-элементов на веб-страницах.
@MapperScan("org.xian.security.mapper")
public class SecurityApplication {}
2) Начните работу с Spring Security
В проекте используется трехуровневая модель, подобная MVC.
Просмотр уровня представления: Веб-страница, созданная Thymeleaf.Контроллер: Основная логическая часть приложения.Слой модели модели: Напишите соответствующий интерфейс MyBatis Mapper для взаимодействия с базой данных MySQL.
2.1) Структура таблицы данных и класс объектов Mapper
С Spring Security вам нужно только реализовать интерфейс UserDetailsService и наследовать от WebSecurityConfigurerAdapter.
Создайте новый пакет безопасности, создайте новый класс MyUserDetailsServiceImpl, SpringSecurityConfig
Реализовать службу UserDetails
@Service
public class MyUserDetailsServiceImpl implements UserDetailsService {
@Resource
private SysUserMapper sysUserMapper;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
SysUser sysUser = sysUserMapper.selectByUsername(username);
if (null == sysUser) {
throw new UsernameNotFoundException(username);
}
List<SimpleGrantedAuthority> authorities = new ArrayList<>();
authorities.add(new SimpleGrantedAuthority("ROLE_" + sysUser.getUserRole()));
return new User(sysUser.getUsername(), sysUser.getPassword(), authorities);
}
}
Анализ кода:
loadUserByUsername: переопределив метод loadUserByUsername интерфейса UserDetailsService, передайте имя пользователя, пароль пользователя и роль пользователя в Spring Security.
List<SimpleGrantedAuthority>:authorities.add может добавить несколько ролей пользователей.Для системы, в которой у пользователя есть несколько ролей, вы можете хранить информацию о нескольких ролях пользователей, добавив таблицу ролей пользователей и таблицу сопоставления ролей пользователей.
"ROLE_" + sysUser.getUserRole(): Имена ролей Spring Security по умолчанию начинаются с «ROLE_».
Пароль пользователя не проверяется при запросе информации о пользователе здесь, потому что часть проверки пароля выполняется через Spring Security.
BCryptPasswordEncoder: хранить пароль в зашифрованном виде с помощью надежного хэш-метода BCrypt. Для веб-систем пароли редко хранятся в открытом виде. Класс BCryptPasswordEncoder, предоставляемый Spring Security, реализует функцию шифрования паролей. Сильный метод хэширования BCrypt каждый раз приводит к разному шифрованию.
Тег в начале th: указывает на рендеринг Thymeleaf. th:if означает суждение, URL-адрес th:action отправляет путь, дополнительные функции Thymeleaf можно найти на официальном сайте.www.thymeleaf.org/
Создайте новый пакет контроллера и создайте в нем новый класс RegisterController:
@Controller
public class RegisterController {
@Resource
private SysUserMapper sysUserMapper;
@RequestMapping("/register")
public String register() {
return "register";
}
@RequestMapping("/register-error")
public String registerError(Model model) {
// Model 的作用是往 Web 页面穿数据
// model 添加一个参数 error 其作用是如果此参数为 true,就显示下面一行 HTML 代码
// <p th:if="${error}" class="error">注册错误</p>
model.addAttribute("error", true);
return "register";
}
@RequestMapping("/register-save")
public String registerSave(@ModelAttribute SysUser sysUser,
Model model) {
// 判断 username password 不能为空
if (sysUser.getUsername() == null || sysUser.getPassword() == null || sysUser.getUserRole() == null) {
model.addAttribute("error", true);
return "register";
}
try {
// 密码加密存储
BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
String password = bCryptPasswordEncoder.encode(sysUser.getPassword());
sysUser.setPassword(password);
// 写入数据库
sysUserMapper.insert(sysUser);
// 重定向到 login 页面
return "redirect:/login";
} catch (Exception e) {
// 注册错误
model.addAttribute("error", true);
return "register";
}
}
}
Разбор кода:
@ControllerАннотация указывает, что возвращается HTML-страница. return "register" означает возврат register.html, return "redirect:/xxx" перенаправляет на определенную страницу.
@ModelAttribute SysUser sysUser: Аналогично @RequestBody, считывает данные из формы и назначает их SysUser.
Запустите проект и получите к нему доступ через браузерhttp://localhost:8080/register, введите имя пользователя и пароль, выберите роль пользователя и нажмите «Зарегистрироваться».
Не забудьте добавить параметр запуска -Djava.security.egd=file:/dev/./urandom JVM, который кажется ошибкой в случайном числе Security.
2.4) Реализовать функцию входа пользователя
Создайте новые login.html и index.html (в разделе 2.6).
Создайте новый класс LoginController в пакете контроллера:
@Controller
public class LoginController {
@RequestMapping("/login")
public String login() {
return "login";
}
@RequestMapping("/login-error")
public String loginError(Model model) {
// 登录错误
model.addAttribute("error", true);
return "login";
}
}
Поскольку мы указали роли двух путей /login и /login-error, Spring Security реализует конкретную реализацию входа в систему и ошибки входа в систему.
Запустите проект и получите к нему доступ через браузерhttp://localhost:8080/login, введите имя пользователя и пароль, выберите роль пользователя и нажмите Войти.
2.5) Контроль разрешений роли пользователя
Контроль разрешений роли пользователя, который может быть аннотирован в @RequestMapping через @PreAuthorize, указывающий, что для этого URL-адреса требуется определенное разрешение роли; другой — реализовать некоторые элементы страницы через Thymeleaf, что требует указания разрешения роли для доступа.
Вот первый способ ввести аннотацию @PreAuthorize:
Создайте новый AdminController в пакете контроллера, и соответствующий admin.html сможет просматривать исходный код хранилища:
@Controller
public class AdminController {
// 需要 ROLE_ADMIN 角色才行访问 /admin
// 这也是为什么 MyUserDetailsServiceImpl 需要 "ROLE_" + sysUser.getUserRole()
@PreAuthorize("hasRole('ADMIN')")
@RequestMapping("/admin")
public String admin() {
return "admin";
}
}
На одной и той же странице некоторые элементы могут быть видны АДМИНИСТРАТОРУ, а некоторые — ПОЛЬЗОВАТЕЛЮ. Они реализованы через плагин расширения Thymeleaf thymeleaf-extras-springsecurity.
Этот раздел в основном посвящен интеграции Spring Boot с Spring Security для реализации регистрации пользователей, входа в систему и управления ролями. В следующем разделе мы интегрируем JJWT с Spring Boot, чтобы реализовать интерфейс API RESTful для аутентификации и авторизации токена.