springboot SpringSecurity(安全)
官网
https://docs.spring.io/spring-security/site/docs/5.2.1.RELEASE/reference/htmlsingle/#saml2
一、安全?
1、非功能性需求
2、设计之初,考虑安全
二、功能
认证、授权
三、使用
1、导入thymeleaf
<dependency> <groupId>org.thymeleaf</groupId> <artifactId>thymeleaf-spring5</artifactId> </dependency>
2、关闭模板引擎
spring:
thymeleaf:
cache: false
3、导入 security
<!-- spring security --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency>
四、用户认证和授权
1、创建config文件夹,创建SecurityConfig.java
固定的架子
package com.wt.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 { super.configure(http); } }
2、示例
package com.wt.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 { // 授权的规则 @Override protected void configure(HttpSecurity http) throws Exception { // 首页所有人可以访问,功能页只有对应有权限的人才能访问 // "/" 首页 http.authorizeRequests() .antMatchers("/").permitAll() .antMatchers("/level1/**").hasRole("vip1") .antMatchers("/level2/**").hasRole("vip2") .antMatchers("/level3/**").hasRole("vip3"); // 没有权限默认到登录页,开启登录页面 http.formLogin(); } // 认证的规则 @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { // auth.jdbcAuthentication() 连接数据库 // 内存 // 通过 and withUser 添加用户 // 密码加密 auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder()) .withUser("wt").password(new BCryptPasswordEncoder().encode("123")).roles("vip1", "vip2") .and() .withUser("root").password(new BCryptPasswordEncoder().encode("123")).roles("vip1", "vip2", "vip3"); } }
JDBC授权
import javax.sql.DataSource;
@Autowired private DataSource dataSource; @Autowired public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { // ensure the passwords are encoded properly UserBuilder users = User.withDefaultPasswordEncoder(); auth .jdbcAuthentication() .dataSource(dataSource) .withDefaultSchema() .withUser(users.username("user").password("password").roles("USER")) .withUser(users.username("admin").password("password").roles("USER","ADMIN")); }
springboot 配置 DataSource
a、导入包
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <!--数据库驱动--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.20</version> </dependency>
b、yml文件
spring: datasource: password: test url: jdbc:mysql://localhost:3306/test?useUnicode=true&useSSL=false driver-class-name: com.mysql.jdbc.Driver username: test
五、注销和权限控制
1、注销
// 链式编程 @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { // 授权的规则 @Override protected void configure(HttpSecurity http) throws Exception { // 首页所有人可以访问,功能页只有对应有权限的人才能访问 // "/" 首页 http.authorizeRequests() .antMatchers("/").permitAll() .antMatchers("/level1/**").hasRole("vip1") .antMatchers("/level2/**").hasRole("vip2") .antMatchers("/level3/**").hasRole("vip3"); // 没有权限默认到登录页,开启登录页面 http.formLogin(); // 开启注销 http.logout(); } }
关于logout的url和其它具体功能看源码
2、与thymeleaf整合
a、导入包
<dependency> <groupId>org.thymeleaf.extras</groupId> <artifactId>thymeleaf-extras-springsecurity4</artifactId> <version>3.0.2.RELEASE</version> </dependency>
b、降版本(如果能用,可以不用降)
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.7.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent>
c、config文件夹
package com.wt.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 { // 授权的规则 @Override protected void configure(HttpSecurity http) throws Exception { // 首页所有人可以访问,功能页只有对应有权限的人才能访问 // "/" 首页 http.authorizeRequests() .antMatchers("/").permitAll() .antMatchers("/level1/**").hasRole("vip1") .antMatchers("/level2/**").hasRole("vip2") .antMatchers("/level3/**").hasRole("vip3"); // 没有权限默认到登录页,开启登录页面 http.formLogin(); // logout 失败的可能原因 http.csrf().disable(); // 开启注销 http.logout(); } // 认证的规则 @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { // auth.jdbcAuthentication() 连接数据库 // 内存 // 通过 and withUser 添加用户 // 密码加密 auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder()) .withUser("wt").password(new BCryptPasswordEncoder().encode("123")).roles("vip1", "vip2") .and() .withUser("root").password(new BCryptPasswordEncoder().encode("123")).roles("vip1", "vip2", "vip3"); } }
d、html文件
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity4"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <!--未登陆,显示 login--> <div sec:authorize="!isAuthenticated()"> <button>login</button> </div> <!--已经登录,显示用户名和角色--> <div sec:authorize="isAuthenticated()"> <a class="item"> 用户名: <span sec:authentication="name"></span> </a> </div> <!--已经登录,显示 logout--> <div sec:authorize="isAuthenticated()"> <button>logout</button> </div> </body> </html>
e、菜单的动态实现
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity4"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <!--有vip1的权限, 显示--> <div sec:authorize="hasRole('vip1')"> <p>一会儿翅膀碰着波浪,一会儿箭一般地直冲向乌云,它叫喊着</p> </div> </body> </html>
3、开启记住我功能
config文件夹
package com.wt.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 { // 授权的规则 @Override protected void configure(HttpSecurity http) throws Exception { // 首页所有人可以访问,功能页只有对应有权限的人才能访问 // "/" 首页 http.authorizeRequests() .antMatchers("/").permitAll() .antMatchers("/level1/**").hasRole("vip1") .antMatchers("/level2/**").hasRole("vip2") .antMatchers("/level3/**").hasRole("vip3"); // 没有权限默认到登录页,开启登录页面 http.formLogin(); // logout 失败的可能原因 http.csrf().disable(); // 开启注销 http.logout(); // 开启记住我功能 http.rememberMe(); } }
六、使用自定义页面
1、使用自定义的登录页面
// 指定自定义的登录页面 http.formLogin().loginPage("/myLogin");
fromLogin()后面的链式编程与前端的form表单配合使用
.usernameParameter("username") // default is username .passwordParameter("password") // default is password
2、记住我功能
与form表单配合使用
http.rememberMe().rememberMeParameter("myRemember");