Цикл статей
SpringBoot 01-HelloSpringBoot, конфигурация yaml, проверка данных, переключение нескольких сред
SpringBoot 02-Простое исследование Интернета, система управления сотрудниками
SpringBoot 03-Spring Безопасность
SpringBoot 04-Shiro
Каталог статей
Одиннадцать, Весенняя безопасность
Введение
Spring Security - это мощный и настраиваемый фреймворк для аутентификации и контроля доступа. Это стандарт защиты приложений на основе Spring.
Spring Security призван решить проблему безопасности веб-разработки, как и фильтры и перехватчики, которые мы писали ранее, а Spring Security эквивалентен структуре фильтров, которая может помочь нам опустить большой объем кода.
Например, мы раньше использовали перехватчики или фильтры для управления доступом, требуя, чтобы пользователи входили в систему для входа на главную страницу, или страницы, введенные пользователями с разными разрешениями, не совпадают, но код, написанный ранее, более сложен и избыточен, и использование Фреймворк может быть легко реализован.
Следует помнить несколько ключевых категорий :
- WebSecurityConfigurerAdapter: настраиваемая политика безопасности
- AuthenticationManagerBuilder: настраиваемая стратегия аутентификации
- @EnableWebSecurity: включить функцию WebSecurity (видеть, что @EnableXXX означает включение определенной функции)
Две основные цели Spring Security - это «аутентификация» и «авторизация» (то есть контроль доступа). Широ позже узнал то же самое.
Официальный документ: https://spring.io/guides/gs/securing-web/
Давайте создадим обычный веб-проект SpringBoot.
11.1 Построение экспериментальной среды
1. Создайте проект SpringBoot, добавьте веб-модуль и импортируйте пакет Thymeleaf.
<!--thymeleaf—— 命名空间xmlns:th="http://www.thymeleaf.org“ -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
2. Импортируйте статический файл ресурсов (вы можете найти его в Интернете, этот шаг вам не нужен, просто чтобы интерфейс выглядел лучше, текущая операция не связана с безопасностью)
Ссылка для скачивания ресурса
Ссылка: https://pan.baidu.com/s/1UoUJg6CsHm5bQbouYt609A Код извлечения: nv8p
CSDN: https: //download.csdn.net/download/qq_39763246/15982736
Необходимо отключить кеш Thymeleaf
3. Напишите контроллер маршрутизации и пересылки для пересылки каждой страницы.
package com.zcy.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
//用户路由转发的Controller
public class RouterController {
//输入 localhost:8080或者localhost:8080/index都会跳转到首页
@RequestMapping({
"/index", "/"})
public String index(){
return "index";
}
@RequestMapping("/toLogin")
public String toLogin(){
return "views/login";
}
//通过Restful风格,在URL输入 level1/1就会跳转到1.html,输入level2/2就跳转到2.html
@RequestMapping("/level1/{id}")
public String level1(@PathVariable("id") int id){
return "views/level1/"+id;
}
@RequestMapping("/level2/{id}")
public String level2(@PathVariable("id") int id){
return "views/level2/"+id;
}
@RequestMapping("/level3/{id}")
public String level3(@PathVariable("id") int id){
return "views/level3/"+id;
}
}
4. Эффект
11.2 Аутентификация и авторизация
Создайте новый SecurityConfig.java
package com.zcy.config;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
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;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
//这里用到了AOP,横切的思想,不会去改变我们Controller的代码。类似于拦截器,但更强大!
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
//授权
@Override
protected void configure(HttpSecurity http) throws Exception {
//链式编程
//实现的功能:首页index 所有人都能访问,具体的功能也level 只能被有相应权限的人访问
//给请求添加规则,使的访问level1下的所有请求都要有vip1权限
http.authorizeRequests()
.antMatchers("/").permitAll()
.antMatchers("/level1/**").hasRole("vip1")
.antMatchers("/level2/**").hasRole("vip2")
.antMatchers("/level3/**").hasRole("vip3");
//如果没有权限,默认跳转至登录页面。这是Spring Security里内置的
http.formLogin();
}
//认证(Spring Security 5.0+ 要求对密码加密才能正常使用)
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
//从内存中读取用户(提前设定好的用户,真实开发还是从数据库中读取,后面Shiro再讲)
auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder())
.withUser("zcy1").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1")
.and()
.withUser("zcy2").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1", "vip2")
.and()
.withUser("zcy3").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1", "vip2", "vip3");
//从数据库读用户
}
}
эффект:
1. Когда вы посещаете каждую страницу, когда вы не вошли в систему, вы будете перенаправлены на страницу входа. Можно обнаружить, что запрос в строке URL - это / login, но мы не писали эту страницу, наш логин - views / login. Эта страница http.formLogin();
предоставляется в Spring Security .
http.formLogin();
Аннотация исходного кода:
2. Входящий в систему пользователь zcy1 имеет только привилегии vip1 и может получить доступ только к страницам ниже level1, а доступ к другим страницам будет заблокирован.
3. Зарегистрированный пользователь zcy3, владеющий vip1, vip2, vip3, может получить доступ ко всем страницам.
11.3, выход из системы и контроль разрешений
Изображение эффекта:
- Когда не авторизован
- Войдите в систему zcy1 (обратите внимание, что в настоящее время у нас нет настраиваемой страницы входа, мы используем встроенную систему безопасности, поэтому нажатие кнопки входа в систему недопустимо, только ввод / вход URL)
-
Выйдите из zcy1 и вернитесь на домашнюю страницу
-
Войти в zcy2
Выполнение:
1. Добавьте выход в index.html.
<!--登录注销-->
<div class="right menu">
<!--未登录-->
<a class="item" th:href="@{/toLogin}">
<i class="address card icon"></i> 登录
</a>
<!-- 注销 -->
<a class="item" th:href="@{/logout}">
<i class="sign-out card icon"></i> 注销
</a>
</div>
2. Добавьте выход в SecurityConfig.java.
//授权
@Override
protected void configure(HttpSecurity http) throws Exception {
//链式编程
//实现的功能:首页index 所有人都能访问,具体的功能也level 只能被有相应权限的人访问
//给请求添加规则,使的访问level1下的所有请求都要有vip1权限
http.authorizeRequests()
.antMatchers("/").permitAll()
.antMatchers("/views/level1/**").hasRole("vip1")
.antMatchers("/views/level2/**").hasRole("vip2")
.antMatchers("/views/level3/**").hasRole("vip3");
//如果没有权限,默认跳转至一个内置登录页面/login。这是Spring Security里内置的。
http.formLogin(); //.loginPage("可以在这里指定自己的登录页面);
//关闭网站防攻击,默认会开启,因为我们前端用的<a>,是用get方式提交,不安全。
http.csrf().disable();//如果没有这句,注销会404
//开启注销功能,logoutSuccessUrl作用是注销成功跳转到新url,点击注销跳转到首页
http.logout().logoutSuccessUrl("/");
}
http.logout()
Комментарии к исходному коду:
3. Thymeleaf интегрирует Spring Security
Наша оригинальная настроенная домашняя страница использовала серверную часть для передачи значения во внешний интерфейс, передняя часть оценивала, а затем отображалась, например
<div th:if="${session.user.name}">
...显示专属内容
</div>
Теперь мы напрямую интегрируем Spring Security в Thymeleaf.
- Пилотный пакет
<!-- https://mvnrepository.com/artifact/org.thymeleaf.extras/thymeleaf-extras-springsecurity4 -->
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity4</artifactId>
<version>3.0.4.RELEASE</version>
</dependency>
-
Уменьшите версию Spring Boot до 2.0.7 (Thymeleaf не поддерживает более высокие версии для интеграции безопасности, и теперь обычно не интегрирует безопасность)
После понижения будет загружена новая версия, версия 2.0.7, нам также необходимо изменить пакет junit, подробности смотрите на картинке ниже.
-
Измените index.html
11.4, запомнить меня и настроенную страницу входа
1. Запомнить меня: не выходите из системы, вы автоматически войдете в систему при повторном входе на страницу.
Добавьте код в метод настройки SecurityConfig.java:
//记住我,原理:添加Cookie到浏览器,关闭浏览器重新进入页面后保持登录状态
http.rememberMe();//默认保存两周
эффект:
2. Настройте страницу входа в систему.
Измените метод настройки SecurityConfig.java:
//如果没有权限,默认跳转至一个内置登录页面/login。这是Spring Security里内置的。
//usernameParameter和passwordParameter指定前端传递过来的参数名称
//loginPage指定自己的登录页面
http.formLogin()
.loginPage("/toLogin")
.usernameParameter("user")
.passwordParameter("pwd");
//.loginProcessingUrl("/login")可指定真正的URL,即在浏览器输入/toLogin,但请求是/login
//记住我,原理:添加Cookie到浏览器,关闭浏览器重新进入页面后保持登录状态
//默认保存两周.rememberMeParameter指定前端传递的参数名称
http.rememberMe()
.rememberMeParameter("remember");
Измените index.html, исходные имена параметров - имя пользователя и пароль, теперь они изменены. И добавь радиокнопку, запомни меня.
Эффект: нажмите кнопку входа на главной странице, чтобы войти в систему в обычном режиме, и она имеет функцию запоминания меня.