一、需要的组件支持:

新版本这里的组件有些问题:

https://blog.csdn.net/qq_36488647/article/details/104532754
https://blog.csdn.net/YzVermicelli/article/details/106417610

然后我这里就是需要降低下一个版本,Maven依赖就不会爆红了【SpringBoot2.3.4版本】

<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity5</artifactId>
<version>3.0.3.RELEASE</version>
</dependency>

Security本体的组件:

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency> <dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
</dependency>

Web支持 + Thymeleaf模板引擎:

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

二、属性获取

然后要使用的模板目录内的页面文件需要导入Thyemleaf + Security的约束

注意一定是使用这个约束地址,新版本的地址反而无效了。。。

<html lang="en"xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/extras/spring-security">

我们可以获取的用户信息:

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/extras/spring-security">
<head>
<meta charset="UTF-8">
<title>Main-Page</title>
</head>
<body>
<h3>This is main page</h3> <p>登录账号 <span sec:authentication="name"></span></p>
<p>登录账号 <span sec:authentication="principal.username"></span></p>
<p>凭证 <span sec:authentication="credentials"></span></p>
<p>权限角色集合 <span sec:authentication="authorities"></span></p>
<p>IP地址 <span sec:authentication="details.remoteAddress"></span></p>
<p>会话ID <span sec:authentication="details.sessionId"></span></p>

</body>
</html>

访问查看:

三、权限判断:

现在我在用户权限赋予中增加角色和权限:

package cn.zeal4j.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service; /**
* @author Administrator
* @file IntelliJ IDEA Spring-Security-Tutorial
* @create 2020 09 27 21:57
*/
@Service
public class UserDetailsServiceImpl implements UserDetailsService { @Autowired
private PasswordEncoder passwordEncoder; @Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { // 1、通过提供的用户名参数访问数据库,查询记录返回过来,如果记录不存在则抛出异常
// username = "admin";
if (!"admin".equals(username)) throw new UsernameNotFoundException("用户名不存在"); // 2、查询出来的凭证是被加密了的,这里是模拟查询的密码
String encode = passwordEncoder.encode("123456"); // 权限不可以为空,所以需要这么一个工具方法简单实现
return new User(username, encode, AuthorityUtils.commaSeparatedStringToAuthorityList("admin,normal,ROLE_vip-01,ROLE_A,ROLE_B,ROLE_C,/create,/update,/delete"));
}
}

在页面中的权限控制案例:

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/extras/spring-security">
<head>
<meta charset="UTF-8">
<title>Main-Page</title>
<style type="text/css">
h3, p {
text-align: center;
}
</style>
</head>
<body>
<h3>This is main page</h3> <p>登录账号 <span sec:authentication="name"></span></p>
<p>登录账号 <span sec:authentication="principal.username"></span></p>
<p>凭证 <span sec:authentication="credentials"></span></p>
<p>权限角色集合 <span sec:authentication="authorities"></span></p>
<p>IP地址 <span sec:authentication="details.remoteAddress"></span></p>
<p>会话ID <span sec:authentication="details.sessionId"></span></p> <h3>权限控制展示</h3>
<p> <button sec:authorize="hasRole('A')" >角色A</button> </p>
<p> <button sec:authorize="hasRole('B')" >角色B</button> </p>
<p> <button sec:authorize="hasRole('C')" >角色C</button> </p>
<p> <button sec:authorize="hasRole('D')" >角色D</button> </p> <p> <button sec:authorize="hasAuthority('/create')" >创建权限</button> </p>
<p> <button sec:authorize="hasAuthority('/update')" >更新权限</button> </p>
<p> <button sec:authorize="hasAuthority('/delete')" >删除权限</button> </p>
<p> <button sec:authorize="hasAuthority('/select')" >查询权限</button> </p>

</body>
</html>

访问查看:

可以看到角色D和SELECT权限都没有,Security对应也不会显示这些按钮

四、退出功能:

Security默认提供了Logout退出控制

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Project-Index</title>
</head>
<body>
<h1>Hello Spring-Security !!!</h1>
<a href="/logout">click to logout</a>
</body>
</html>

点击会自动重定向到登录页面来,并且会有一个logout参数值在地址中:

如果不希望附带这个参数,则需要配置退出的处理:

package cn.zeal4j.configuration;

import cn.zeal4j.handler.CustomAccessDeniedHandler;
import cn.zeal4j.handler.FarsAuthenticationFailureHandler;
import cn.zeal4j.handler.FarsAuthenticationSuccessHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.parameters.P;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.access.AccessDeniedHandler;
import org.springframework.security.web.authentication.rememberme.JdbcTokenRepositoryImpl;
import org.springframework.security.web.authentication.rememberme.PersistentTokenRepository; import javax.sql.DataSource; /**
* @author Administrator
* @file IntelliJ IDEA Spring-Security-Tutorial
* @create 2020 09 27 21:55
*/
@Configuration
public class SecurityConfiguration extends WebSecurityConfigurerAdapter { @Autowired
private AccessDeniedHandler accessDeniedHandler;
@Qualifier("userDetailsServiceImpl")
@Autowired
private UserDetailsService userDetailsService;
@Autowired
private DataSource dataSource;
@Autowired
private PersistentTokenRepository persistentTokenRepository; @Bean
public PersistentTokenRepository getPersistentTokenRepository() {
JdbcTokenRepositoryImpl jdbcTokenRepository = new JdbcTokenRepositoryImpl();
jdbcTokenRepository.setDataSource(dataSource); // 数据源注入
jdbcTokenRepository.setCreateTableOnStartup(false); // 由Security完成Token表的创建,如果有了就设置false关闭
return jdbcTokenRepository;
} @Bean
public PasswordEncoder getPasswordEncoder() {
return new BCryptPasswordEncoder();
} @Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity.formLogin(). // 设置登陆行为方式为表单登陆
// 登陆请求参数设置
usernameParameter("username").
passwordParameter("password"). loginPage("/login.html"). // 设置登陆页面URL路径
loginProcessingUrl("/login.action"). // 设置表单提交URL路径 successForwardUrl("/main.page"). // 设置认证成功跳转URL路径 POST请求
failureForwardUrl("/error.page"); // 设置认证失败跳转URL路径 POST请求 // successHandler(new FarsAuthenticationSuccessHandler("https://www.acfun.cn/")). // 使用自定义的重定向登陆
// failureHandler(new FarsAuthenticationFailureHandler("/error.html")).; // 跨域处理,不需要跳转了 httpSecurity.authorizeRequests().
regexMatchers(HttpMethod.POST, "正则表达式").permitAll(). // 还可以对符合正则表达式的请求方式进行要求,这个属性使用来制定请求的方式 antMatchers("/**/*.js", "/**/*.css", "/**/images/*.*").permitAll(). // 静态资源放行 antMatchers("/login.html").permitAll(). // 登陆页面允许任意访问
antMatchers("/error.html").permitAll(). // 失败跳转后重定向的页面也需要被允许访问
antMatchers("/admin.page").hasAnyAuthority("admin"). /*antMatchers("/vip-01.page").hasAnyAuthority("vip-01").*/
antMatchers("/vip-01.page").hasRole("vip-01").
antMatchers("/ip.page").hasIpAddress("192.168.43.180"). // mvcMatchers("/main.page").servletPath("/xxx").permitAll(). // mvcMatchers资源放行匹配
// antMatchers("/xxx/main.page").permitAll(). // 或者多写MSP的前缀 anyRequest().authenticated(); // 其他请求均需要被授权访问
// anyRequest().access("@customServiceImpl.hasPermission(request, authentication)"); // 自定义Access配置 // CSRF攻击拦截关闭
httpSecurity.csrf().disable();
httpSecurity.exceptionHandling().accessDeniedHandler(accessDeniedHandler); // 记住我
httpSecurity.rememberMe().
tokenValiditySeconds(60). // 设置Token有效时间, 以秒为单位取值
userDetailsService(userDetailsService).
tokenRepository(persistentTokenRepository); // 退出登录处理
httpSecurity.logout().logoutSuccessUrl("/login.html"
);
}
}

如果需要配置独特的退出URL也可以设置:

// 退出登录处理
httpSecurity.
logout().
// logoutUrl("/xxx/xxx/logout").
logoutSuccessUrl("/login.html");

【Spring-Security】Re08 Thymeleaf权限控制 与 退出功能的更多相关文章

  1. Spring Security 动态url权限控制(三)

    一.前言 本篇文章将讲述Spring Security 动态分配url权限,未登录权限控制,登录过后根据登录用户角色授予访问url权限 基本环境 spring-boot 2.1.8 mybatis-p ...

  2. 别再让你的微服务裸奔了,基于 Spring Session & Spring Security 微服务权限控制

    微服务架构 网关:路由用户请求到指定服务,转发前端 Cookie 中包含的 Session 信息: 用户服务:用户登录认证(Authentication),用户授权(Authority),用户管理(R ...

  3. spring security采用自定义登录页和退出功能

    更新... 首先采用的是XML配置方式,请先查看  初识Spring security-添加security 在之前的示例中进行代码修改 项目结构如下: 一.修改spring-security.xml ...

  4. Spring Security实现RBAC权限管理

    Spring Security实现RBAC权限管理 一.简介 在企业应用中,认证和授权是非常重要的一部分内容,业界最出名的两个框架就是大名鼎鼎的 Shiro和Spring Security.由于Spr ...

  5. 登陆模块,这个是很重要的模块,有shiro和spring security专门的权限认证框架

    登陆模块,这个是很重要的模块,有shiro和spring security专门的权限认证框架

  6. spring security实现记住我下次自动登录功能

    目录 spring security实现记住我下次自动登录功能 一.原理分析 二.实现方式 2.1 简单实现方式 2.2 数据库实现方式 三.区分是密码登录还是rememberme登录 spring ...

  7. Atitit.用户权限服务 登录退出功能

    Atitit.用户权限服务 登录退出功能 参数说明 /com.attilax/user/loginOut.jsp?url="+url Utype=mer 作者::  ★(attilax)&g ...

  8. Spring Security 自定义 登陆 权限验证

    转载于:https://www.jianshu.com/p/6b8fb59b614b 项目简介 基于Spring Cloud 的项目,Spring Cloud是在Spring Boot上搭建的所以按照 ...

  9. spring security 登录、权限管理配置

    登录流程 1)容器启动(MySecurityMetadataSource:loadResourceDefine加载系统资源与权限列表)  2)用户发出请求  3)过滤器拦截(MySecurityFil ...

  10. 基于Spring AOP实现的权限控制

    1.AOP简介 AOP,面向切面编程,往往被定义为促使软件系统实现关注点的分离的技术.系统是由许多不同的组件所组成的,每一个组件负责一块特定的功能.除了实现自身核心功能之外,这些组件还经常承担着额外的 ...

随机推荐

  1. c# winfrom DataGridView 动态UI下载功能(内含GIF图) || 循环可变化的集合 数组 datatable 等

    Gif演示 分解步骤 1,使用组件DataGridView 2,使用DataSource来控制表格展示的数据来源(注意:来源需要是DataTable类型) 3,需要用到异步线程.如果是不控制数据源的话 ...

  2. Cannot set properties of undefined (setting 'dataIndex')""

    前端写桑基图的时候碰到以上bug 原因是: 桑基图中的name值有重复的,把重复的name值去掉就好了

  3. 项目管理--PMBOK 读书笔记(7)【项目成本管理】

    1.成本术语: 2.三点估算(PERT): 平均估算值=(最可能持续时间*4+最乐观+最悲观)/6 标准差=(最乐观-最悲观)/6 68.26%.95.46%.99.73% 3.估算成本的工具:质量成 ...

  4. nginx 信号量

    nginx支持的信号量 TERM, INT fast shutdown QUIT graceful shutdown HUP changing configuration, keeping up wi ...

  5. Android自动化-如何获取视图元素属性?

    在做Android自动化时候,我们需要知道视图有哪些元素,元素都有哪些属性,获取到属性我们才能获取到元素从而做自动化控制,所以做Android自动化获取元素属性是必要的第一步 获取视图元素属性最便捷的 ...

  6. 面试官:Java类是如何被加载到内存中的?

    面试连环call Java类是如何被加载到内存中的? Java类的生命周期都有哪些阶段? JVM加载的class文件都有哪些来源? JVM在加载class文件时,何时判断class文件的格式是否符合要 ...

  7. P3806 题解

    看到现有的一篇 DSU on tree 的题解复杂度假了,于是我来再写一篇. 首先重新梳理思路,维护每棵子树内深度为某个值的节点是否存在. 维护这个东西可以直接 DSU on tree 也就是把小的子 ...

  8. ComfyUI进阶篇:ComfyUI核心节点(一)

    ComfyUI进阶篇:ComfyUI核心节点(一) 前言: 学习ComfyUI是一场持久战.当你掌握了ComfyUI的安装和运行之后,会发现大量五花八门的节点.面对各种各样的工作流和复杂的节点种类,可 ...

  9. Math.random()方法的使用及公式

    条件1:取n-m范围的随机数(不包含m) 公式1:(int)(Math.random() * (m - n) + n); 条件2:取n-m范围的随机数(包含m) 公式2:(int)(Math.rand ...

  10. vue3 'alex' is defined but never used

    解决方法 在package.json中的rules下加入 "no-unused-vars":"off" 即可