200_SpringSecurity
SpringSecurity简介
SpringSecurity环境搭建
创建项目
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.1</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.qing</groupId>
<artifactId>springboot-06-security</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>springboot-06-security</name>
<description>springboot-06-security</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
添加thymeleaf依赖
<!--thymeleaf-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
配置:关闭thymeleaf缓存,方便调试,不需要每次修改都重启,生产环境开启
spring.thymeleaf.cache=false
添加页面和静态资源
添加controller
package com.qing.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class RouterController {
@RequestMapping({"/","/index"})
public String index() {
return "index";
}
@RequestMapping("/toLogin")
public String toLogin() {
return "views/login";
}
@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;
}
}
测试
认证和授权
添加依赖spring-boot-starter-security
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
创建SecurityConfig,继承WebSecurityConfigurerAdapter
授权 configure(HttpSecurity http)
源码注释
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/**").hasRole("USER")
.and().formLogin();
}
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/admin/**").hasRole("ADMIN")
.antMatchers("/**").hasRole("USER")
.and().formLogin();
}
package com.qing.config;
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;
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
/**
* 授权
* @param http
* @throws Exception
*/
@Override
protected void configure(HttpSecurity http) throws Exception {
// 链式编程
// 授权首页所有人可以访问,功能页只有有权限的人才能访问
// 请求授权规则
http.authorizeRequests() // 授权请求
.antMatchers("/").permitAll() // /请求,所有用户可以访问
.antMatchers("/level1/**").hasRole("vip1") // /level1/**请求,有角色vip1的才能访问
.antMatchers("/level2/**").hasRole("vip2") // /level2/**请求,有角色vip2的才能访问
.antMatchers("/level3/**").hasRole("vip3"); // /level3/**请求,有角色vip3的才能访问
}
}
http.formLogin(); // 没有权限默认会跳到登录页面/login,需要开启登录的页面
package com.qing.config;
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;
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// 链式编程
// 授权首页所有人可以访问,功能页只有有权限的人才能访问
// 请求授权规则
http.authorizeRequests() // 授权请求
.antMatchers("/").permitAll() // /请求,所有用户可以访问
.antMatchers("/level1/**").hasRole("vip1") // /level1/**请求,有角色vip1的才能访问
.antMatchers("/level2/**").hasRole("vip2") // /level2/**请求,有角色vip2的才能访问
.antMatchers("/level3/**").hasRole("vip3"); // /level3/**请求,有角色vip3的才能访问
// 开启登录,没有权限默认会跳到登录页面/login
http.formLogin();
}
}
认证 configure(AuthenticationManagerBuilder auth)
源码注释
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("user").password("password").roles("USER")
.and()
.withUser("admin").password("password").roles("ADMIN", "USER");
}
package com.qing.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;
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
/**
* 授权
* @param http
* @throws Exception
*/
@Override
protected void configure(HttpSecurity http) throws Exception {
// 链式编程
// 授权首页所有人可以访问,功能页只有有权限的人才能访问
// 请求授权规则
http.authorizeRequests() // 授权请求
.antMatchers("/").permitAll() // /请求,所有用户可以访问
.antMatchers("/level1/**").hasRole("vip1") // /level1/**请求,有角色vip1的才能访问
.antMatchers("/level2/**").hasRole("vip2") // /level2/**请求,有角色vip2的才能访问
.antMatchers("/level3/**").hasRole("vip3"); // /level3/**请求,有角色vip3的才能访问
// 开启登录,没有权限默认会跳到登录页面/login
http.formLogin();
}
/**
* 认证
* @param auth
* @throws Exception
*/
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// 内存中认证,正常数据应该从数据库读取
auth.inMemoryAuthentication()
// 在SpringSecurity5.0+ 新增了很多的加密方法
.passwordEncoder(new BCryptPasswordEncoder()) // 密码加密方式,不加密会报错
.withUser("zhangsf").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1","vip2")
.and() // 拼接下一个认证
.withUser("admin").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1","vip2","vip3")
.and()
.withUser("zhangdl").password(new BCryptPasswordEncoder().encode("123456")).roles("vip3");
}
}
测试
用户“zhangsf”登录,有roles("vip1","vip2")的权限,应该可以访问/level1/和/level2/,不能访问/level3/**
JDBC
注销
开启注销
<!--注销-->
<a class="item" th:href="@{/logout}">
<i class="sign-out icon"></i> 注销
</a>
// 开启注销
http.logout();
package com.qing.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.core.userdetails.User;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
/**
* 授权
* @param http
* @throws Exception
*/
@Override
protected void configure(HttpSecurity http) throws Exception {
// 链式编程
// 授权首页所有人可以访问,功能页只有有权限的人才能访问
// 请求授权规则
http.authorizeRequests() // 授权请求
.antMatchers("/").permitAll() // /请求,所有用户可以访问
.antMatchers("/level1/**").hasRole("vip1") // /level1/**请求,有角色vip1的才能访问
.antMatchers("/level2/**").hasRole("vip2") // /level2/**请求,有角色vip2的才能访问
.antMatchers("/level3/**").hasRole("vip3"); // /level3/**请求,有角色vip3的才能访问
// 开启登录,没有权限默认会跳到登录页面/login
http.formLogin();
// 开启注销
http.logout();
}
/**
* 认证
* @param auth
* @throws Exception
*/
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// 内存中认证,正常数据应该从数据库读取
auth.inMemoryAuthentication()
// 在SpringSecurity5.0+ 新增了很多的加密方法
.passwordEncoder(new BCryptPasswordEncoder()) // 密码加密方式,不加密会报错
.withUser("zhangsf").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1","vip2")
.and() // 拼接下一个认证
.withUser("admin").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1","vip2","vip3")
.and()
.withUser("zhangdl").password(new BCryptPasswordEncoder().encode("123456")).roles("vip3");
}
}
开启注销,并跳转指定页面
// 开启注销,注销后跳转到首页
http.logout().logoutSuccessUrl("/");
package com.qing.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.core.userdetails.User;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
/**
* 授权
* @param http
* @throws Exception
*/
@Override
protected void configure(HttpSecurity http) throws Exception {
// 链式编程
// 授权首页所有人可以访问,功能页只有有权限的人才能访问
// 请求授权规则
http.authorizeRequests() // 授权请求
.antMatchers("/").permitAll() // /请求,所有用户可以访问
.antMatchers("/level1/**").hasRole("vip1") // /level1/**请求,有角色vip1的才能访问
.antMatchers("/level2/**").hasRole("vip2") // /level2/**请求,有角色vip2的才能访问
.antMatchers("/level3/**").hasRole("vip3"); // /level3/**请求,有角色vip3的才能访问
// 开启登录,没有权限默认会跳到登录页面/login
http.formLogin();
// 开启注销
// http.logout();
// 开启注销,注销后跳转到首页
http.logout().logoutSuccessUrl("/");
}
/**
* 认证
* @param auth
* @throws Exception
*/
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// 内存中认证,正常数据应该从数据库读取
auth.inMemoryAuthentication()
// 在SpringSecurity5.0+ 新增了很多的加密方法
.passwordEncoder(new BCryptPasswordEncoder()) // 密码加密方式,不加密会报错
.withUser("zhangsf").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1","vip2")
.and() // 拼接下一个认证
.withUser("admin").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1","vip2","vip3")
.and()
.withUser("zhangdl").password(new BCryptPasswordEncoder().encode("123456")).roles("vip3");
}
}
页面权限控制
security-thymeleaf整合包
页面显示权限控制:登录认证显示,未登录未认证不显示
页面显示权限控制:指定角色显示页面
记住我
// 开启记住我,实际就是cookie,默认保存两周,关闭浏览器,下次打开还是登录状态
http.rememberMe();
package com.qing.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.core.userdetails.User;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
/**
* 授权
* @param http
* @throws Exception
*/
@Override
protected void configure(HttpSecurity http) throws Exception {
// 链式编程
// 授权首页所有人可以访问,功能页只有有权限的人才能访问
// 请求授权规则
http.authorizeRequests() // 授权请求
.antMatchers("/").permitAll() // /请求,所有用户可以访问
.antMatchers("/level1/**").hasRole("vip1") // /level1/**请求,有角色vip1的才能访问
.antMatchers("/level2/**").hasRole("vip2") // /level2/**请求,有角色vip2的才能访问
.antMatchers("/level3/**").hasRole("vip3"); // /level3/**请求,有角色vip3的才能访问
// 开启登录,没有权限默认会跳到登录页面/login
http.formLogin();
// 开启注销
// http.logout();
// 开启注销,注销后跳转到首页
http.logout().logoutSuccessUrl("/");
// 开启记住我,实际就是cookie,默认保存两周,关闭浏览器,下次打开还是登录状态
http.rememberMe();
}
/**
* 认证
* @param auth
* @throws Exception
*/
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// 内存中认证,正常数据应该从数据库读取
auth.inMemoryAuthentication()
// 在SpringSecurity5.0+ 新增了很多的加密方法
.passwordEncoder(new BCryptPasswordEncoder()) // 密码加密方式,不加密会报错
.withUser("zhangsf").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1","vip2")
.and() // 拼接下一个认证
.withUser("admin").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1","vip2","vip3")
.and()
.withUser("zhangdl").password(new BCryptPasswordEncoder().encode("123456")).roles("vip3");
}
}
定制登录页
// 开启登录,自定义登录页时
http.formLogin()
.loginPage("/toLogin") // 设置登录页
.usernameParameter("user") // 设置登录用户名传参名称
.passwordParameter("pwd") // 设置登录密码传参名称
.loginProcessingUrl("/login"); // 设置登录接口
// 开启记住我,自定义登录页时,设置记住我标签传参名称
http.rememberMe().rememberMeParameter("remember");
package com.qing.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.core.userdetails.User;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
/**
* 授权
* @param http
* @throws Exception
*/
@Override
protected void configure(HttpSecurity http) throws Exception {
// 链式编程
// 授权首页所有人可以访问,功能页只有有权限的人才能访问
// 请求授权规则
http.authorizeRequests() // 授权请求
.antMatchers("/").permitAll() // /请求,所有用户可以访问
.antMatchers("/level1/**").hasRole("vip1") // /level1/**请求,有角色vip1的才能访问
.antMatchers("/level2/**").hasRole("vip2") // /level2/**请求,有角色vip2的才能访问
.antMatchers("/level3/**").hasRole("vip3"); // /level3/**请求,有角色vip3的才能访问
// 开启登录,没有权限默认会跳到登录页面/login
// http.formLogin();
// 开启登录,自定义登录页时
http.formLogin()
.loginPage("/toLogin") // 设置登录页
.usernameParameter("user") // 设置登录用户名传参名称
.passwordParameter("pwd") // 设置登录密码传参名称
.loginProcessingUrl("/login"); // 设置登录接口
// 开启注销
// http.logout();
// 开启注销,注销后跳转到首页
http.logout().logoutSuccessUrl("/");
// 开启记住我,实际就是cookie,默认保存两周,关闭浏览器,下次打开还是登录状态
// http.rememberMe();
// 开启记住我,自定义登录页时,设置记住我标签传参名称
http.rememberMe().rememberMeParameter("remember");
}
/**
* 认证
* @param auth
* @throws Exception
*/
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// 内存中认证,正常数据应该从数据库读取
auth.inMemoryAuthentication()
// 在SpringSecurity5.0+ 新增了很多的加密方法
.passwordEncoder(new BCryptPasswordEncoder()) // 密码加密方式,不加密会报错
.withUser("zhangsf").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1","vip2")
.and() // 拼接下一个认证
.withUser("admin").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1","vip2","vip3")
.and()
.withUser("zhangdl").password(new BCryptPasswordEncoder().encode("123456")).roles("vip3");
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)