当前位置: 首页 > news >正文

SpringSecurity配合Thymeleaf实现详解,以及实战用例

目录

Spring Security介绍

Spring Security的核心功能:

配合Thymeleaf的Spring Security用法解析

1. 引入Spring Security和Thymeleaf依赖

2. 配置Spring Security

3. Thymeleaf与Spring Security标签

4. Spring Security表单认证

5. 示例:登录页面与权限控制

SpringBoot+Thymeleaf完成安全认证,登录登出操作。


Spring Security介绍

Spring Security是一个强大的认证和授权框架,用于保护基于Spring的应用程序。它提供了全面的安全功能,包括认证、授权、攻击防护等,能够有效地帮助开发者构建安全的Web应用程序。

Spring Security的核心功能:

        1.认证(Authentication)

  • 用于确认用户身份,常见的认证方式有用户名密码、OAuth、LDAP等。
  • Spring Security支持多种身份验证机制,如基于表单的认证、HTTP基本认证等。

        2.授权(Authorization)

  • 用于确定用户是否有权限访问特定资源或操作。
  • 可以基于角色、权限进行细粒度的控制,也可以根据访问路径、HTTP方法进行安全控制。

        3.CSRF防护:

  • Spring Security内置了对跨站请求伪造(CSRF)攻击的防护。

        4.会话管理

  • 提供会话固定 Fixation)防护和并发会话控制。攻击(Session)

        5.密码加密:

  • 提供了多种密码加密方式,常用的如BCrypt、PBKDF2等。

        6.自定义过滤器

  • 可以在Spring Security的过滤链中插入自定义过滤器,满足业务需求。

配合Thymeleaf的Spring Security用法解析

Thymeleaf是一个流行的Java模板引擎,广泛用于Web应用程序中构建动态内容。与Spring Security结合使用时,Thymeleaf可以通过其springSecurity命名空间来帮助处理与安全相关的元素。

1. 引入Spring Security和Thymeleaf依赖

pom.xml中添加以下依赖:

<dependencies><!-- Spring Security --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId></dependency><!-- Spring Thymeleaf --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency><!-- Spring Security Thymeleaf --><dependency><groupId>org.springframework.security</groupId><artifactId>spring-security-taglibs</artifactId></dependency>
</dependencies>
2. 配置Spring Security

在Spring Boot中,可以通过application.properties或者application.yml来配置Spring Security的基础功能。

# 禁用默认的登录页面
spring.security.form.login.enabled=false
# 自定义登录页面URL
spring.security.form.login.login-page=/login
3. Thymeleaf与Spring Security标签

在Thymeleaf模板中,可以使用Spring Security提供的标签来进行权限控制、条件判断等。

登录表单:通过<form>和Spring Security的标签,可以创建一个登录表单。

<form th:action="@{/login}" method="post"><div><label for="username">Username:</label><input type="text" name="username" id="username" required="required"/></div><div><label for="password">Password:</label><input type="password" name="password" id="password" required="required"/></div><div><button type="submit">Login</button></div>
</form>

授权控制:使用sec:authorize标签来控制某些元素的可见性或执行的条件。

<div sec:authorize="isAuthenticated()"><!-- 只有已认证用户才能看到的内容 --><p>Welcome, authenticated user!</p>
</div><div sec:authorize="hasRole('ADMIN')"><!-- 只有ADMIN角色用户能看到的内容 --><p>Admin dashboard</p>
</div>

退出登录:通过Thymeleaf与Spring Security集成,可以创建一个退出登录的链接。

<a sec:authorize="isAuthenticated()" href="/logout">Logout</a>
4. Spring Security表单认证

Spring Security提供了一些基本的配置来启用基于表单的认证。可以在配置类中自定义登录页面、注销页面、登录失败和成功的处理等。

@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {@Overrideprotected void configure(HttpSecurity http) throws Exception {http.authorizeRequests().antMatchers("/login", "/css/**", "/js/**").permitAll()  // 允许所有人访问登录页面和静态资源.anyRequest().authenticated()  // 其他页面需要认证.and().formLogin().loginPage("/login")  // 自定义登录页面.permitAll().and().logout().permitAll();}@Overrideprotected void configure(AuthenticationManagerBuilder auth) throws Exception {// 配置内存中的用户和角色auth.inMemoryAuthentication().withUser("user").password(passwordEncoder().encode("password")).roles("USER").and().withUser("admin").password(passwordEncoder().encode("admin")).roles("ADMIN");}@Beanpublic PasswordEncoder passwordEncoder() {return new BCryptPasswordEncoder();}
}
5. 示例:登录页面与权限控制

创建一个简单的登录页面login.html,通过Spring Security控制访问权限:

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity5">
<head><title>Login</title>
</head>
<body><h1>Login</h1><form action="#" th:action="@{/login}" method="post"><div><label for="username">Username:</label><input type="text" name="username" id="username" /></div><div><label for="password">Password:</label><input type="password" name="password" id="password" /></div><button type="submit">Login</button></form><div sec:authorize="isAuthenticated()"><p>You are logged in!</p></div>
</body>
</html>

SpringBoot+Thymeleaf完成安全认证,登录登出操作。

1.导入Maven坐标

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency><groupId>org.springframework.security</groupId><artifactId>spring-security-config</artifactId>
</dependency>
<dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.3.31</version>
</dependency>

2.AuthInterceptor拦截器

package com.book.interceptor;import org.springframework.web.servlet.HandlerInterceptor;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
public class AuthInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request,HttpServletResponse response,Object handler) throws Exception {HttpSession session = request.getSession(false);// 排除登录、注册等公开页面String uri = request.getRequestURI();if (uri.startsWith("/user/login") || uri.startsWith("/user/register") ||uri.startsWith("/static/") || uri.equals("/")) {return true;}// 检查session中的用户信息if (session == null || session.getAttribute("user") == null) {response.sendRedirect("/user/login");return false;}return true;}
}

3.WebConfig注册拦截器

package com.book.config;
import com.book.interceptor.AuthInterceptor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;@Configuration
@Slf4j
public class WebConfig implements WebMvcConfigurer {/*** 注册自定义拦截器** @param registry*/@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new AuthInterceptor()).addPathPatterns("/**").excludePathPatterns("/user/login","/user/register","/css/**","/js/**","/error");}@Overridepublic void addResourceHandlers(ResourceHandlerRegistry registry) {// 映射本地文件系统到 "/uploads/**"registry.addResourceHandler("/uploads/**").addResourceLocations("file:///F:/SpringBoot/libraryManagement/uploads/");}
}

4.SecurityConfig安全配置

package com.book.config;import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.web.csrf.CookieCsrfTokenRepository;@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {@Overrideprotected void configure(HttpSecurity http) throws Exception {http.authorizeRequests().antMatchers("/user/login", "/user/register", "/css/**","/js/**").permitAll().anyRequest().authenticated().and()// 完全禁用Spring Security的表单登录.formLogin().disable()// 禁用默认的/logout处理.logout().disable().csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()).and().sessionManagement().sessionFixation().migrateSession().maximumSessions(1).maxSessionsPreventsLogin(false).expiredUrl("/user/login?expired=true");}
}

5.Controller-登录登出操作

登录成功后重定向至book/list

@PostMapping("/login")
public String handleLogin(@RequestParam String username,@RequestParam String password,HttpSession session) {log.info("登录请求 - username: {}", username);User loginUser = userService.getUserByUsername(username);if (loginUser == null || !HashUtils.verifyPassword(password, loginUser.getPassword(), loginUser.getSalt())) {return "redirect:/user/login?error=true";}// 1. 设置sessionsession.setAttribute("user", loginUser);// 2. 设置Spring Security认证上下文(关键)Authentication auth = new UsernamePasswordAuthenticationToken(loginUser.getUsername(),null,Collections.singletonList(new SimpleGrantedAuthority("ROLE_USER")) // 假设所有用户都有USER角色);SecurityContextHolder.getContext().setAuthentication(auth);return "redirect:/book/list";
}//登出操作,使session事物失效
@GetMapping("/logout")
public String logout(HttpSession session) {session.invalidate();return "redirect:/user/login";
}

6.login.html用户登录页面

ps:表单一定要包含这部分

​​​​​​​<input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}"/>
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><title>用户登录</title><link rel="stylesheet" th:href="@{/css/bootstrap.min.css}"/>
</head>
<body>
<div class="container mt-5"><div class="row justify-content-center"><div class="col-md-6 col-lg-4"><div class="card shadow"><div class="card-body"><h3 class="card-title text-center mb-4">用户登录</h3><!-- 错误消息 --><div th:if="${errorMsg}" class="alert alert-danger" th:text="${errorMsg}"></div><!-- 传统表单提交到自定义Controller --><form th:action="@{/user/login}" method="post"><input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}"/><div class="mb-3"><label for="username" class="form-label">用户名</label><input type="text" class="form-control" id="username" name="username" required></div><div class="mb-3"><label for="password" class="form-label">密码</label><input type="password" class="form-control" id="password" name="password" required></div><div class="d-grid gap-2"><button type="submit" class="btn btn-primary">登录</button></div></form><div class="mt-3 text-center"><a th:href="@{/user/register}" class="text-decoration-none">还没有账号?立即注册</a></div></div></div></div></div>
</div>
</body>
</html>

总结

Spring Security和Thymeleaf结合使用,可以轻松地在Web应用中实现认证和授权功能。通过Spring Security的标签(如sec:authorize)和Thymeleaf的模板引擎,可以在页面中实现动态的权限控制、用户认证等操作,增强了Web应用的安全性。

相关文章:

  • 【计网】ipconfig、ping、arp、tracert
  • mysql中select 1 from的作用
  • 嵌入式MCU语音识别算法及实现方案
  • 自动生成 te.extern 接口:TVM 中第三方库的智能化接入方案
  • 达梦DM数据库安装步骤
  • GuassDB如何创建兼容MySQL语法的数据库
  • linux 如何防止内存碎片化?
  • 企业CMS中的内容中台是什么?
  • 【JS逆向基础】WEB基础
  • RN学习笔记 ✅
  • 如何将C#程序打包成软件绿色包
  • 快速学会Linux的WEB服务
  • 极新月报·2025.4人工智能投融资观察
  • 系统级编程(二):通过读取PE文件获取EXE或者DLL的依赖
  • 使用hybird做接口配置
  • SUPER-VLAN基础配置
  • 获取或比对文件的MD5值或SHA值(C#项目源码)
  • C++ this关键字
  • SpringBoot Starter简介-笔记
  • JavaSE核心知识点01基础语法01-03(流程控制:顺序、分支、循环)
  • 习近平《在庆祝中华全国总工会成立100周年暨全国劳动模范和先进工作者表彰大会上的讲话》单行本出版
  • 创新创业50人论坛开幕在即,双创青年为何选择来上海筑梦?
  • 金球看淡,不服就干!这是抬不起腿却昂着头的劳塔罗
  • 中国证监会:帮助受关税政策影响较大的上市公司纾困解难
  • 央行将增加3000亿元科技创新和技术改造再贷款额度
  • 巴基斯坦宣布关闭全国空域48小时