1. 概述
本文将介绍如何用Spring Security保护Jakarta EE Web应用。通过Java配置和XML配置两种方式,实现基础认证、角色授权和自定义登录流程等安全功能。
2. Maven依赖
首先添加核心Spring Security依赖:
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>5.7.5</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>5.7.5</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-taglibs</artifactId>
<version>5.7.5</version>
</dependency>
当前最新版本为5.7.5,可通过Maven Central获取最新版本。
3. 安全配置
创建基础安全配置类:
@Configuration
@EnableWebSecurity
public class SpringSecurityConfig {
@Bean
public InMemoryUserDetailsManager userDetailsService() {
UserDetails user = User.withUsername("user1")
.password("{noop}user1Pass")
.roles("USER")
.build();
UserDetails admin = User.withUsername("admin")
.password("{noop}adminPass")
.roles("ADMIN")
.build();
return new InMemoryUserDetailsManager(user, admin);
}
}
✅ 关键点说明:
- 使用内存存储实现快速原型开发
{noop}
前缀表示明文密码(生产环境需加密)- 硬编码用户信息仅用于演示
通过SecurityWebApplicationInitializer
加载配置:
public class SecurityWebApplicationInitializer
extends AbstractSecurityWebApplicationInitializer {
public SecurityWebApplicationInitializer() {
super(SpringSecurityConfig.class);
}
}
此时已实现基础安全控制:所有请求默认需要认证。
4. 配置安全规则
通过SecurityFilterChain
自定义安全策略:
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.csrf()
.disable()
.authorizeRequests()
.antMatchers("/auth/login*")
.anonymous()
.antMatchers("/home/admin*")
.hasRole("ADMIN")
.anyRequest()
.authenticated()
.and()
.formLogin()
.loginPage("/auth/login")
.defaultSuccessUrl("/home", true)
.failureUrl("/auth/login?error=true")
.and()
.logout()
.logoutSuccessUrl("/auth/login");
return http.build();
}
4.1 自定义登录页
通过formLogin()
指定登录页:
http.formLogin()
.loginPage("/auth/login")
未指定时Spring Security提供默认登录页(/login
):
<html>
<head></head>
<body>
<h1>Login</h1>
<form name='f' action="/auth/login" method='POST'>
<table>
<tr>
<td>User:</td>
<td><input type='text' name='username' value=''></td>
</tr>
<tr>
<td>Password:</td>
<td><input type='password' name='password'/></td>
</tr>
<tr>
<td><input name="submit" type="submit"
value="submit"/></td>
</tr>
</table>
</form>
</body>
</html>
4.2 自定义着陆页
配置登录成功后的跳转逻辑:
http.formLogin()
.defaultSuccessUrl("/home", true)
⚠️ 参数说明:
alwaysUse=true
:始终跳转到指定URLalwaysUse=false
(默认):优先跳转到原始请求页
配置登录失败页:
http.formLogin()
.failureUrl("/auth/login?error=true")
4.3 授权控制
按角色限制接口访问:
.antMatchers("/home/admin*").hasRole("ADMIN")
非管理员访问/home/admin
接口会收到403错误。
在JSP中实现视图级权限控制:
<%@ taglib prefix="security"
uri="http://www.springframework.org/security/tags" %>
<security:authorize access="hasRole('ADMIN')">
This text is only visible to an admin
<br/>
<a href="<c:url value="/home/admin" />">Admin Page</a>
<br/>
</security:authorize>
5. Spring Security XML配置
在web/WEB-INF/spring/security.xml
中配置:
5.1 认证管理器配置
基础认证配置:
<authentication-manager>
<authentication-provider>
<user-service>
<user name="user"
password="user123"
authorities="ROLE_USER" />
</user-service>
</authentication-provider>
</authentication-manager>
带密码编码器的配置:
<authentication-manager>
<authentication-provider>
<password-encoder hash="sha"/>
<user-service>
<user name="user"
password="d7e6351eaa13189a5a3641bab846c8e8c69ba39f"
authorities="ROLE_USER" />
</user-service>
</authentication-provider>
</authentication-manager>
5.2 安全规则配置
<http auto-config='true' use-expressions="true">
<form-login default-target-url="/secure.jsp" />
<intercept-url pattern="/" access="isAnonymous()" />
<intercept-url pattern="/index.jsp" access="isAnonymous()" />
<intercept-url pattern="/secure.jsp" access="hasRole('ROLE_USER')" />
</http>
✅ 配置说明:
auto-config='true'
启用默认安全行为/secure.jsp
需要ROLE_USER
权限- 首页允许匿名访问
5.3 集成到web.xml
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/spring/*.xml
</param-value>
</context-param>
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>
org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
❌ 避坑提示:同一应用中混用Java配置和XML配置可能导致冲突!
6. 总结
本文展示了在Jakarta EE应用中集成Spring Security的两种方式:
✅ 核心功能实现:
- 内存认证与角色授权
- 自定义登录/失败页
- 接口级和视图级权限控制
- Java配置与XML配置对比
完整代码示例见GitHub仓库。生产环境建议使用持久化存储替代内存用户,并启用密码加密。