详解springboot springsecuroty中的注销和权限控制问题
作者:从0开始丿 发布时间:2023-04-05 15:09:51
上篇文章给大家介绍了springboot对接第三方微信授权及获取用户的头像和昵称等等
1 账户注销
1.1 在SecurityConfig中加入开启注销功能的代码
src/main/java/com/lv/config/SecurityConfig.java
package com.lv.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 : * !
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
//授权
@Override
public 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().logoutSuccessUrl("/");
//防止跨站工具, get,post
http.csrf().disable();//关闭csrf功能,注销失败可能的原因
}
//认证,springboot 2.1.x 可以直接使用
//密码编码:PasswordEncoder
//在Spring Security 5.0+ 新增了很多加密方法~
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
//这些数据正常应该从数据库中读
auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder())
.withUser("lv").password(new BCryptPasswordEncoder().encode("123456")).roles("vip2","vip3")
.and()
.withUser("root").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1","vip2","vip3")
.withUser("guest").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1");
}
1.2 在index.html 添加注销的按钮
src/main/resources/templates/index.html
<!--登录注销-->
<div class="right menu">
<div>
<a class="item" th:href="@{/toLogin}">
<i class="address card icon"></i>登录
</a>
</div>
<div>
<a class="item" th:href="@{/logout}">
<i class="sign-out icon"></i>注销
</a>
</div>
</div>
1.3 启动项目测试
访问登录页面,登录 guest 账户,该账户可以访问 level1的页面
登录成功后,点击 level1的链接,成功跳转到 level 页面,然后点击注销按钮
弹回到首页,再次点击点击 level1 页面
跳转到了登录页面
说明账户注销成功
2 权限控制
2.1 导入springsecurity和thymeleaf的整合依赖
pom.xml
<!-- springSecurity和thymeleaf整合包 -->
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity4</artifactId>
<version>3.0.2.RELEASE</version>
</dependency>
2.2 springboot版本降级
pom.xml
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.9.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
必须将springboot的版本降到2.0.9以下,否则 sec:authorize="isAuthenticated()" 不会生效.版本降低后,需要手动导入junit依赖,否则测试类会报错
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>RELEASE</version>
<scope>test</scope>
</dependency>
2.3 引入约束
在index.html的头文件中添加springsecurity和thymeleaf的整合约束
src/main/resources/templates/index.html
<html xmlns:th="http://www.thymeleaf.org"
xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity4">
2.4 修改页面代码
主要修改两部分,一部分是登录状态下显示用户名,和注销按钮,未登录显示登录按钮 通过 sec:authorize="isAuthenticated()" 实现.另一部分是根据登录用户的权限显示不同的页面菜单,通过 sec:authorize="hasRole('vip1')" 实现.
src/main/resources/templates/index.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity4">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<title>首页</title>
<!--semantic-ui-->
<link href="https://cdn.bootcss.com/semantic-ui/2.4.1/semantic.min.css" rel="stylesheet">
<link th:href="@{/qinjiang/css/qinstyle.css}" rel="stylesheet">
</head>
<body>
<!--主容器-->
<div class="ui container">
<div class="ui segment" id="index-header-nav" th:fragment="nav-menu">
<div class="ui secondary menu">
<a class="item" th:href="@{/index}">首页</a>
<!--登录注销-->
<div class="right menu">
<!--如果未登录:显示登录按钮-->
<div sec:authorize="!isAuthenticated()">
<a class="item" th:href="@{/toLogin}">
<i class="address card icon"></i>登录
</a>
</div>
<!--如果已登录:显示用户名和注销按钮-->
<div sec:authorize="isAuthenticated()">
<a class="item">
用户名:<span sec:authentication="name"></span>
</a>
</div>
<div sec:authorize="isAuthenticated()">
<a class="item" th:href="@{/logout}">
<i class="sign-out icon"></i>注销
</a>
</div>
</div>
</div>
</div>
<div class="ui segment" style="text-align: center">
<h3>Spring Security Study by 秦疆</h3>
</div>
<div>
<br>
<div class="ui three column stackable grid">
<!--菜单根据用户的角色动态实现-->
<div class="column" sec:authorize="hasRole('vip1')">
<div class="ui raised segment">
<div class="ui">
<div class="content">
<h5 class="content">Level 1</h5>
<hr>
<div><a th:href="@{/level1/1}"><i class="bullhorn icon"></i> Level-1-1</a></div>
<div><a th:href="@{/level1/2}"><i class="bullhorn icon"></i> Level-1-2</a></div>
<div><a th:href="@{/level1/3}"><i class="bullhorn icon"></i> Level-1-3</a></div>
</div>
</div>
</div>
</div>
<div class="column" sec:authorize="hasRole('vip2')">
<div class="ui raised segment">
<div class="ui">
<div class="content">
<h5 class="content">Level 2</h5>
<hr>
<div><a th:href="@{/level2/1}"><i class="bullhorn icon"></i> Level-2-1</a></div>
<div><a th:href="@{/level2/2}"><i class="bullhorn icon"></i> Level-2-2</a></div>
<div><a th:href="@{/level2/3}"><i class="bullhorn icon"></i> Level-2-3</a></div>
</div>
</div>
</div>
</div>
<div class="column" sec:authorize="hasRole('vip3')">
<div class="ui raised segment">
<div class="ui">
<div class="content">
<h5 class="content">Level 3</h5>
<hr>
<div><a th:href="@{/level3/1}"><i class="bullhorn icon"></i> Level-3-1</a></div>
<div><a th:href="@{/level3/2}"><i class="bullhorn icon"></i> Level-3-2</a></div>
<div><a th:href="@{/level3/3}"><i class="bullhorn icon"></i> Level-3-3</a></div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<script th:src="@{/qinjiang/js/jquery-3.1.1.min.js}"></script>
<script th:src="@{/qinjiang/js/semantic.min.js}"></script>
</body>
</html>
2.5 重启程序测试
未登录页面
登录 lv 用户的页面
登录 geust 用户的页面
登录 root 用户的页面
页面显示都不同,权限控制成功实现
来源:https://www.cnblogs.com/lv1024/p/15979629.html


猜你喜欢
- Kotlin 是一种在 Java 虚拟机上运行的静态类型编程语言,被称之为 Android 世界的Swift,由 JetBrains 设计开
- 主线程和子线程的区别每个线程都有一个唯一标示符,来区分线程中的主次关系的说法。 线程唯一标示符:Thread.CurrentThread.M
- Android activity和view判断滑动 实例代码://手
- Spring Cache设置缓存条件原理从Spring3.1开始,Spring框架提供了对Cache的支持,提供了一个对缓存使用的抽象,通过
- 1 简介在 Java 语言中,共有 8 个基本的数据类型,分别为:byte、short、int、long、float、double、bool
- 在spring中有很多以XXXAware命名的接口,很多人也不清楚这些接口都是做什么用的,这篇文章将描述常用的一些接口。一,Applicat
- 最近项目需要在浏览器中通过URL预览图片。但发现浏览器始终默认下载,而不是预览。研究了一下,发现了问题:// 设置response的Head
- 一、查询中排除标识字段1.1 测试查询@Testpublic void findAllTest() { List&
- 人每天都要喝8杯水才能保持健康,于是苦逼的程序员总是一遍代码就忘了时间,于是我突发奇想能不能开发一个apk能够实现固定的间隔时间定时提醒我要
- 大致流程客户端根据远程服务的地址,客户端发送请求至服务端,服务端解析信息并找到对应的实现类,进行方法调用,之后将调用结果原路返回,客户端解析
- 前言:事情是这样的:运营人员反馈,通过Excel导入数据时,有一部分成功了,有一部分未导入。初步猜测,是事务未生效导致的。查看代码,发现导入
- 目录前言asyncawait从以往知识推导创建异步任务创建异步任务并返回Task异步改同步说说 await Task说说 async Tas
- Idea运行单个main方法,不编译整个工程直接上图1、选择main方法类右键->create ‘类名.main&
- 一、时间的单位转换1秒=1000毫秒(ms) 1毫秒=1/1,000秒(s)1秒=1,000,000 微秒(μs)&nb
- 一、场景Android项目的开发过程中,我们项目中的gradle的dependencies闭包中会引入很多三方依赖库,引入的库越多,越容易产
- 要说this和super就不得不说Java的封装和继承了,首先说封装,这是一种思想,算不上一种技术,核心思想就是将对象的同一行为和状态看成是
- IDEA 2020.1 版自动导入MAVEN依赖的方法(新版MAVEN无法自动导入/更新POM依赖、MAVEN设置自动更新、自动更新快捷键)
- 效果图代码/** * * 日图表 * zrj 2020/8/25 */class SleepDayChart(context: Contex
- 实现代码一、import java.io.File;import java.io.*;public class DelNullDir {pu
- mybatis in foreach 双层嵌套需求:根据角色id,返回角色名称,入参是List<List> 类型的二维数组,需要