Java之SpringSecurity使用心得

在这里插入图片描述

文章目录

  • 一、内存身份认证
  • 二、jdbc身份认证
  • 三、自定义登录页

一、内存身份认证

添加pom依赖

<!-- Spring Security提供的安全管理依赖启动器 -->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId>
</dependency>

身份认证核心代码

@EnableWebSecurity
public class SecurityConfigMemory {@Beanpublic static PasswordEncoder passwordEncoder(){// 或者Pbkdf2PasswordEncoder、ScryptPasswordEncoderreturn new BCryptPasswordEncoder();}@BeanSecurityFilterChain securityFilterChain(HttpSecurity httpSecurity) throws Exception{httpSecurity.csrf().disable().authorizeHttpRequests((authorize) ->{authorize.anyRequest().authenticated();}).httpBasic(Customizer.withDefaults());return httpSecurity.build();}/*** 内存身份认证* @return*/@Beanpublic UserDetailsService userDetailsService(){UserDetails tom = User.builder().username("tom").password(passwordEncoder().encode("111222"))// 角色.roles("common","vip").build();UserDetails jerry = User.builder().username("jerry").password(passwordEncoder().encode("111222"))// 权限.authorities("ROLE_vip").build();return new InMemoryUserDetailsManager(tom,jerry);}}

实际效果
在这里插入图片描述

二、jdbc身份认证

就是把用户密码数据存到数据库里,不用直接放代码里,每次修改都是重新部署
需要到org.springframework.security.core.userdetails.jdbc.users.ddl中复制出创建sql脚本,创建两张表,首次运行服务后自动插入数据。
在这里插入图片描述

具体sql如下:users.ddl

create table users(username varchar_ignorecase(50) not null primary key,password varchar_ignorecase(500) not null,enabled boolean not null);
create table authorities (username varchar_ignorecase(50) not null,authority varchar_ignorecase(50) not null,constraint fk_authorities_users foreign key(username) references users(username));
create unique index ix_auth_username on authorities (username,authority);

核心代码

<!-- JDBC数据库连接启动器 -->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
@EnableWebSecurity
public class SecurityConfigDb {@Autowiredprivate DataSource dataSource;@Beanpublic static PasswordEncoder passwordEncoder() {// 或者Pbkdf2PasswordEncoder、ScryptPasswordEncoderreturn new BCryptPasswordEncoder();}// 用户授权管理自定义配置,用户名密码弹框登录,放行静态资源@BeanSecurityFilterChain securityFilterChain(HttpSecurity httpSecurity) throws Exception {httpSecurity.authorizeHttpRequests((authorize) -> {authorize.anyRequest().authenticated();}).httpBasic(Customizer.withDefaults()).csrf().disable();return httpSecurity.build();}/*** jdbc身份认证* 首次登录成功后,第二次重启服务后可以无须登录直接访问,应该是把登录结果存到浏览器缓存或token里了,重新打开浏览器即需要重新登录* @return*/@Beanpublic UserDetailsService userDetailsService() {return new JdbcUserDetailsManager(dataSource);}}

实际效果同第一个
在上面代码的userDetailService方法中,也可以通过代码添加用户密码

@Bean
public UserDetailsService userDetailsService() {JdbcUserDetailsManager manager = new JdbcUserDetailsManager(dataSource);if (!manager.userExists("ddd")) {manager.createUser(User.withUsername("ddd").password(passwordEncoder().encode("123123")).roles("common", "vip").build());}if (!manager.userExists("jerry")) {manager.createUser(User.withUsername("jerry").password(passwordEncoder().encode("111222")).authorities("ROLE_vip").build());}return manager;
}

三、自定义登录页

1,pom依赖

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

2,修改properties配置

#prefix中后边的斜杠不能少
spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.suffix=.html
spring.thymeleaf.mode=HTML
spring.thymeleaf.encoding=UTF-8
spring.thymeleaf.servlet.content-type=text/html

3,新建login.html

<!DOCTYPE html>
<html lang="zh-cn" xmlns:th="http://www.thymeleaf.org"><head><title>Login Page</title><link th:href="@{/css/login.css}" href="/css/login.css"  th:rel="stylesheet"/></head><body><div class="login-container"><h2>登录页面</h2><form th:action="@{/doLogin}" method="post"><div th:class="form-group"><label> 用户名 : <input type="text" name="username" required/> </label></div><div th:class="form-group"><label> 密 码: <input type="password" name="password" required/> </label></div><div th:class="form-group"><input type="submit" value="登 录"/></div></form></div></body>
</html>

关联的样式login.css

body {font-family: Arial, sans-serif;background-color: #f4f4f4;margin: 0;padding: 0;display: flex;justify-content: center;align-items: center;height: 100vh;
}
.login-container {background-color: #fff;padding: 20px;border-radius: 5px;box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}
.form-group {margin-bottom: 15px;
}
.form-group label {display: block;margin-bottom: 5px;
}
.form-group input {width: 100%;padding: 10px;border: 1px solid #ddd;border-radius: 5px;box-sizing: border-box; /* ensures padding doesn't affect width */
}
.form-group input[type="submit"] {background-color: #5c79b8;color: white;cursor: pointer;
}
.form-group input[type="submit"]:hover {background-color: #4cae97;
}
.h2{width: 100%;
}

4,新建Controller

@Controller
public class IndexController {@RequestMapping("/entry")public String index(){System.out.println("访问登录页面");return "login";}@RequestMapping("/entry-success")public String success(){System.out.println("访问登录success页面");// return "登录成功";return "success";}@RequestMapping("/entry-failure")public String failure(){System.out.println("访问登录failure页面");// return "登录失败";return "failure";}
}
@Slf4j
@RestController
@RequestMapping("/api")
public class ApiController {@GetMapping("/test")public String test() {return "this is ngrok info test for xmliu";}
}

5,Security配置优化:添加放行css文件,登录页接口,登录成功和登录失败以及登录提交表单方法
在第二个配置的基础上修改securityFilterChain方法

// 用户授权管理自定义配置,用户名密码弹框登录,放行静态资源
@Bean
SecurityFilterChain securityFilterChain(HttpSecurity httpSecurity) throws Exception {httpSecurity.authorizeHttpRequests((authorize) -> {authorize.antMatchers("/css/**","/img/**").permitAll().anyRequest().authenticated();}).httpBasic(Customizer.withDefaults())// .authorizeRequests().antMatchers("/css/**").permitAll().anyRequest().authenticated().and()// 开启基于表单的用户登录.formLogin()// 自定义登录页面接口.loginPage("/entry")// 用户名参数,默认username,如果表单中用户名参数是username可以忽略此项.usernameParameter("username")// 用户名参数,默认password,如果表单中密码参数是password可以忽略此项.passwordParameter("password")// 登录表单提交按钮处理方法.loginProcessingUrl("/doLogin")// 登录成功后跳转到首页index.html.defaultSuccessUrl("/")// 登录失败跳转到失败页的接口.failureUrl("/entry-failure")// 允许放行,spring security不会对这个端点做授权检查.permitAll().and().csrf().disable();return httpSecurity.build();
}

6,resources目录结构如下图
在这里插入图片描述

除了login.html,其他几个html文件都差不多,就是文字不一样而已,这里以index.html为例

<!DOCTYPE html>
<html lang="zh-cn" xmlns:th="http://www.thymeleaf.org"><head><title>Login Page</title><style>body {font-family: Arial, sans-serif;background-color: #f4f4f4;margin: 0;padding: 0;display: flex;justify-content: center;align-items: center;height: 100vh;}</style></head><body><div><h2>首页</h2></div></body>
</html>

7,由于项目中我添加了拦截器,所以关于资源放行这块,还需要在拦截器中做处理

@Configuration
@Component
public class MyInterceptor implements HandlerInterceptor {@ResourceMyComp myComp;@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {// 获取接口地址String url = request.getRequestURL().toString();...// 添加判断,防止css文件访问不了报错if(url.endsWith("/xmliu/") || url.endsWith("css")){return true;}...return false}

拦截器配置

@Configuration
public class MyWebConfig implements WebMvcConfigurer {@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(interceptor())// 不拦截哪些请求.excludePathPatterns("/city/**")// 不拦截自定义的spring security登录页面.excludePathPatterns("/error").excludePathPatterns("/entry").excludePathPatterns("/entry-failure").excludePathPatterns("/entry-success").excludePathPatterns("/api/**");}/*** @return myInterceptor*/@Beanpublic MyInterceptor interceptor() {return  new MyInterceptor();}
}

8,实际效果
在这里插入图片描述

用户名和密码输入错误
在这里插入图片描述

输入正确登录成功,进入首页
在这里插入图片描述

如果刚开始就是访问的接口页,那么登录成功后页会直接访问接口,而不是进入首页

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/330683.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

必示科技参与智能运维国家标准预研线下编写会议并做主题分享

近日&#xff0c;《信息技术服务 智能运维 第3部分&#xff1a;算法治理》&#xff08;拟定名&#xff09;国家标准预研阶段第一次编写工作会议在杭州举行。本次会议由浙商证券承办。 此次编写有来自银行、证券、保险、通信、高校研究机构、互联网以及技术方等29家单位&#xf…

YoloV8改进策略:蒸馏改进|CWDLoss|使用蒸馏模型实现YoloV8无损涨点|特征蒸馏

摘要 在本文中&#xff0c;我们成功应用蒸馏策略以实现YoloV8小模型的无损性能提升。我们采用了CWDLoss作为蒸馏方法的核心&#xff0c;通过对比在线和离线两种蒸馏方式&#xff0c;我们发现离线蒸馏在效果上更为出色。因此&#xff0c;为了方便广大读者和研究者应用&#xff…

1076: 判断给定有向图是否存在回路

解法&#xff1a; 直观的方法用邻接矩阵dfs,这是错误的代码 #include<iostream> #include<vector> using namespace std; int arr[100][100]; int f 0; void dfs(vector<int>& a, int u) {a[u] 1;for (int i 0; i < a.size(); i) {if (arr[u][i]…

Github 2024-05-25 Rust开源项目日报Top10

根据Github Trendings的统计,今日(2024-05-25统计)共有10个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量Rust项目10Svelte项目1TypeScript项目1Python项目1Go项目1Dart项目1RustDesk: 用Rust编写的开源远程桌面软件 创建周期:1218 天开发语言:Rust…

Linux--动静态库制作使用及使用

目录 0.文件系统 1.软硬链接 2.静态库 2.1先见一见 2.2 制作静态库&#xff0c;并使用制作的静态库 3.动态库 3.1制作动态库&#xff0c;并使用制作的动态库 4.推荐一个第三方库&#xff08;ncurses&#xff09; 5.动态库的加载 6.动态库VS静态库 0.文件系统 Linux…

北理工提出 LTrack 双摄像头系统 | 专注于暗场景多目标跟踪,自动驾驶和夜间监控的福音!

低光照场景在现实世界应用中很普遍&#xff08;例如自动驾驶和夜间监控&#xff09;。最近&#xff0c;在各种实际用例中的多目标跟踪受到了很多关注&#xff0c;但在暗场景中的多目标跟踪却鲜少被考虑。 在本文中&#xff0c;作者专注于暗场景中的多目标跟踪。为了解决数据集…

9.5 Go语言入门(条件语句和循环语句)

Go语言入门&#xff08;条件语句和循环语句&#xff09; 目录四、条件语句和循环语句1. 条件语句1.1 if 语句1.2 if-else 语句1.3 if-else if-else 语句1.4 带初始化语句的 if1.5 switch 语句1.6 带条件的 switch1.7 多个条件的 case 2. 循环语句2.1 基本 for 循环2.2 省略初始…

转行3年涨薪300%,我总结了一套产品经理快速入门指南!

想转行的产品小白&#xff0c;初期一定会遇到这个问题——我要如何 0 基础转行产品经理&#xff1f; 要想 0 基础快速转行产品经理&#xff0c;我通过个人实践总结了 5 个关键点&#xff0c;可以参考。 一、熟悉产品经理的工作全流程 转行的产品小白&#xff0c;首先要建立产…

Amesim应用篇-制冷剂压焓图软件Coolpack简介与冷媒流量评估

前言 空调系统仿真不可避免的会涉及到冷媒的物性参数、压焓图等信息。冷媒的物性可以在Amesim中自带的模型中查看。而压焓图可以通过Coolpack软件绘制。 一 软件介绍 Coolpack是个独立的小程序&#xff0c;集成了各种冷媒的性能参数&#xff0c;可以直观查看冷媒工作工况曲线…

c语言:摆脱对指针的恐惧【4】

在上一期指针我们讲到了二级指针是的作用是存放一级指针的地址&#xff0c;还讲了指针数组是一个可以存放若干个指针变量的数组&#xff0c;这里我们再复习一下&#xff0c;下面指针数组是什么意思&#xff1f; int* arr1[10]; //整形指针的数组 char *arr2[4]; //一级字符指针…

Python中动态调用C#的dll动态链接库中方法

在Python中调用C#的dll库_哔哩哔哩_bilibili 环境准备&#xff1a; 安装 pythonnet pip install pythonnet在Python中调用C#动态链接库&#xff08;DLL&#xff09;&#xff0c;可以使用pythonnet库&#xff0c;它允许直接使用 .NET 的程序集。以下是一个示例&#xff0c;…

C++ 写的_string类,兼容std::string, MFC CString和 C# 的string

代码例子&#xff1a; using namespace lf; int main() { CString s1 _t("http://www.csdn.net"); _string s2 s1; CString s3 s2; _pcn(s1); _pcn(s2); _pcn(s3); return 0; } 输出&#xff1a; _Str.h /***************************************…

在使用LabVIEW控制多个串口设备进行数据读取时,读取时间过长

在使用LabVIEW控制多个串口设备进行数据读取时&#xff0c;如果发现数据更新时间超过5秒&#xff0c;可以从以下几个方面进行分析和解决&#xff1a; 1. 串口配置与通信参数 确保每个串口的通信参数&#xff08;波特率、数据位、停止位、校验位等&#xff09;配置正确&#x…

【数据结构】二叉树的功能实现

文章目录 关于二叉树的创建如何创建二叉树实现二叉树的前、中、后序遍历层序遍历 关于二叉树的创建 在笔者的上一篇文章中堆进行了一个详细介绍&#xff0c;而二叉树是以堆为基础进行创建&#xff0c;它与堆的显著不同是 堆像是一个线性结构&#xff0c;堆的结构往往是一个数…

springboot项目,@Test写法 @Before @After

某文件示例 package cn.xxx.crm.boss;import cn.xxxx.crm.manager.mq.rabbit.AliyunCredentialsProvider; import com.rabbitmq.client.AMQP; import com.rabbitmq.client.Channel; import com.rabbitmq.client.Connection; import com.rabbitmq.client.ConnectionFactory; im…

2024电工杯数学建模B题Python代码+结果表数据教学

2024电工杯B题保姆级分析完整思路代码数据教学 B题题目&#xff1a;大学生平衡膳食食谱的优化设计及评价 以下仅展示部分&#xff0c;完整版看文末的文章 import pandas as pd df1 pd.read_excel(附件1&#xff1a;1名男大学生的一日食谱.xlsx) df1# 获取所有工作表名称 e…

XSS漏洞:pikachu靶场中的XSS通关

目录 1、反射型XSS&#xff08;get&#xff09; 2、反射性XSS&#xff08;POST&#xff09; 3、存储型XSS 4、DOM型XSS 5、DOM型XSS-X 6、XSS之盲打 7、XSS之过滤 8、XSS之htmlspecialchars 9、XSS之href输出 10、XSS之js输出 最近在学习XSS漏洞&#xff0c;这里使用…

与WAF的“相爱相杀”的RASP

用什么来保护Web应用的安全&#xff1f; 猜想大部分安全从业者都会回答&#xff1a;“WAF&#xff08;Web Application Firewall,应用程序防火墙&#xff09;。”不过RASP&#xff08;Runtime Application Self-Protection&#xff0c;应用运行时自我保护&#xff09;横空出世…

LeetCode198:打家劫舍

题目描述 你是一个专业的小偷&#xff0c;计划偷窃沿街的房屋。每间房内都藏有一定的现金&#xff0c;影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统&#xff0c;如果两间相邻的房屋在同一晚上被小偷闯入&#xff0c;系统会自动报警。 给定一个代表每个房屋存…

【LeetCode】【5】最长回文子串

文章目录 [toc]题目描述样例输入输出与解释样例1样例2 提示Python实现动态规划 个人主页&#xff1a;丷从心 系列专栏&#xff1a;LeetCode 刷题指南&#xff1a;LeetCode刷题指南 题目描述 给一个字符串s&#xff0c;找到s中最长的回文子串 样例输入输出与解释 样例1 输入…