使用 SpringSecutity 安全管理做到 :登录&认证&授权&权限控制&注销&记住我
项目结构:
引入maven依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <dependency> <groupId>org.thymeleaf.extras</groupId> <artifactId>thymeleaf-extras-springsecurity5</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency>
登录&认证&授权&权限控制&注销&记住我
编写 SpringSecurity 的配置类 RootConfig类
注解 @EnableWebSecurity 和继承 extends WebSecurityConfigurerAdapter
package com.lh.springboot.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; /** * @program: springbootwen05 * @description: * @author: li hui * @create: 2020-12-22 20:08 */ @EnableWebSecurity public class RootConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { //定制请求的授权规则 http.authorizeRequests().antMatchers("/").permitAll() // 路径'/' 可全部通过 .antMatchers("/login").permitAll() //路径 '/login' 可全部通过 .antMatchers("/pu/**").hasRole("VIP1") // 路径 '/pu/**' 包下的所有文件 必须有VIP1的身份才可通过 .antMatchers("/gao/**").hasRole("VIP2") // 路径 '/gao/**' 包下的所有文件 必须有 VIP2的身份才可通过 .antMatchers("/ss/**").hasRole("VIP3"); // 路径 '/ss/**' 包下的所有文件 必须有 VIP3的身份才可通过 //开启自动配置登录的功能 没有登录没有权限就会来到登录页面 http.formLogin(); //http.csrf().disable(); http.formLogin() // 没有身份验证的需要登录 单独 http.formLogin(); 登录页面是 springsecurity 的一个登录页 /login .usernameParameter("name") // 需要自己的登录页 表单提交过来的name和pwd .passwordParameter("pwd") .loginProcessingUrl("/userLogin") // 登录提交的后台接口路径,默认不写就是 loginPage(/login)的路径 .loginPage("/login"); /* 1. /login 来到登陆页 2. 登陆失败重定向到 /login?error 3. 默认 post 形式的/login 代表处理登陆 */ //开启自动配置注销功能 注销成功并再次访问/接口 http.logout().logoutSuccessUrl("/"); /* 1. 访问 /logout 表示用户注销, 清空session 2. 注销成功会返回 /login?logout 页面 */ //开启记住我功能 http.rememberMe().rememberMeParameter("remember"); //remenber 是 我们登录页的记住的标签的名字 /* 登陆成功以后,将cookie 发送给浏览器保存,以后访问网页带上这个cookie 只要通过就免登录 点击注销就销毁cookie */ } //定义认证规则 @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.inMemoryAuthentication() .passwordEncoder(new MyPasswordEncoder()) // 自己引用的类,用于账号密码 .withUser("admin").password("admin").roles("VIP1") //提交过来的是账号密码 给一个VIP1的身份 .and() // 和 .withUser("123").password("123").roles("VIP2") .and() // 和 .withUser("321").password("321").roles("VIP1","VIP2","VIP3"); // 可以给多个身份 } }
MyPasswordEncoder 类 配置我们自己的登录时使用的账号密码
package com.lh.springboot.config; import org.springframework.security.crypto.password.PasswordEncoder; /** * @program: springbootwen05 * @description: * @author: li hui * @create: 2020-12-23 08:36 */ public class MyPasswordEncoder implements PasswordEncoder { @Override public String encode(CharSequence charSequence) { return charSequence.toString(); } @Override public boolean matches(CharSequence charSequence, String s) { return s.equals(charSequence.toString()); } }
RootController 类
package com.lh.springboot.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; /** * @program: springbootweb05 * @description: * @author: li hui * @create: 2020-12-28 08:25 */ @Controller public class RootController { @GetMapping("/login") public String login2(){ return "login"; } @GetMapping("/") public String success(){ return "success"; } @GetMapping("/pu/1") public String pu1(){ return "/pu/1"; } @GetMapping("/pu/2") public String pu2(){ return "/pu/2"; } @GetMapping("/pu/3") public String pu3(){ return "/pu/3"; } @GetMapping("/gao/1") public String gao1(){ return "/gao/1"; } @GetMapping("/gao/2") public String gao2(){ return "/gao/2"; } @GetMapping("/gao/3") public String gao3(){ return "/gao/3"; } @GetMapping("/ss/1") public String ss1(){ return "/ss/1"; } @GetMapping("/ss/2") public String ss2(){ return "/ss/2"; } @GetMapping("/ss/3") public String ss3(){ return "/ss/3"; } }
登录页面,表单提交。login.html
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <form th:action="@{/userLogin}" method="post"> 账号 <input name="name" type="text"/><br> 密码 <input name="pwd" type="text"/><br> <input type="checkbox" name="remember"/> 记住我<br> <input type="submit" value="登录"/> </form> </body> </html>
success.html
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity5" > <!--引入了thymeleaf 和 springsecurity5 的命名空间--> <head> <meta charset="UTF-8"> <title>江湖</title> </head> <body> <h1>武林秘籍管理系统</h1> <div sec:authorize="!isAuthenticated()"> <!-- 判断是否有身份 没有就显示这个div 登录 如果有就不显示--> <h3>游客你好!先要查看武林秘籍,<a th:href="@{/login}">请先登录</a></h3> </div> <div sec:authorize="isAuthenticated()"> <!-- 判断是否有身份 有就显示这个div 注销 如果没有就不显示 --> <h2><span sec:authentication="name"><!--打印账号名 --></span>, 你好! 您的角色有:<span sec:authentication="principal.authorities"><!--打印角色身份--></span></h2> <form th:action="@{/logout}" method="post"> <input type="submit" value="注销"/> <!-- form 表单 注销 --> </form> </div> <hr> <div sec:authorize="hasAnyRole('VIP1')"> <!--如果身份有 VIP1 显示这个div 高级 绝世都一样的道理--> <ul> 普通 <li><a th:href="@{/pu/1}">1</a></li> <li><a th:href="@{/pu/2}">2</a></li> <li><a th:href="@{/pu/3}">3</a></li> </ul> </div> <div sec:authorize="hasAnyRole('VIP2')"> <ul> 高级 <li><a th:href="@{/gao/1}">1</a></li> <li><a th:href="@{/gao/2}">2</a></li> <li><a th:href="@{/gao/3}">3</a></li> </ul> </div> <div sec:authorize="hasAnyRole('VIP3')"> <ul> 绝世 <li><a th:href="@{/ss/1}">1</a></li> <li><a th:href="@{/ss/2}">2</a></li> <li><a th:href="@{/ss/3}">3</a></li> </ul> </div> </body> </html>
pu/gao/ss 文件夹里面的网页都是一些标志 例如 pu/1.thml
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>普通</title> </head> <body> <a th:href="@{/}">返回</a> <h1>1</h1> </body> </html>
初学如有什么不对的或者不懂得都可联系我!