前言
基本的Java知识推荐阅读:
1. 基本知识
HttpSecurity 是 Spring Security 的核心类之一,负责配置基于 HTTP 的安全性,提供了用于定义安全规则、身份验证、授权、会话管理、跨站请求伪造(CSRF)保护等一系列功能的 API
HttpSecurity 主要知识点
功能 | 方法 | 说明 |
---|---|---|
认证机制配置 | .authorizeRequests() | 用于定义请求的访问权限规则。例如,哪些 URL 需要认证,哪些允许匿名访问 |
禁用 CSRF 保护 | .csrf().disable() | CSRF 是跨站请求伪造,默认启用。可以使用此方法禁用它 |
跨域资源共享(CORS) | .cors() | 允许配置跨域请求处理。通常用于解决跨域资源共享问题 |
表单登录 | .formLogin() | 使用表单认证方式,配置登录页面、登录处理 URL 等 |
HTTP Basic 认证 | .httpBasic() | 使用 HTTP Basic 认证方式,在每个请求的 Authorization 头中传递凭据 |
会话管理 | .sessionManagement() | 定义会话的管理方式,比如会话超时、是否创建新会话、并发会话控制等 |
记住我功能 | .rememberMe() | 允许用户通过“记住我”功能进行持久化登录 |
异常处理 | .exceptionHandling() | 配置访问被拒绝时的处理器或未登录时的处理行为 |
用户登出 | .logout() | 配置登出功能,包括登出 URL、清除 Cookie、登出成功后的跳转页面等 |
自定义过滤器 | .addFilter() / .addFilterBefore() / .addFilterAfter() | 添加自定义过滤器,可以在指定的过滤器链中插入额外的处理逻辑 |
禁用默认的头部配置 | .headers().disable() | 禁用默认的安全头部配置,例如 X-Content-Type-Options、X-Frame-Options 等 |
强制 HTTPS | .requiresChannel() | 配置强制 HTTPS 的通道安全 |
基本的一个配置过程如下:
- 身份验证和授权:通过
.authorizeRequests()
设置每个 URL 的访问权限 - 会话管理:使用
.sessionManagement()
管理会话行为,包括并发会话和超时 - 异常处理:通过
.exceptionHandling()
定义未授权请求的处理逻辑 - 跨域配置:使用
.cors() 和 .csrf()
设置跨域和跨站请求伪造保护 - 自定义过滤器:通过
.addFilter()
方法插入自定义过滤器,以实现更多灵活的安全控制
2. Demo
给一个基本的Demo复杂场景示例:
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
// 1. 禁用 CSRF 保护(根据需要禁用)
.csrf().disable()
// 2. 开启 CORS 支持
.cors().and()
// 3. 配置授权规则
.authorizeRequests()
// 允许静态资源和主页访问
.antMatchers("/", "/home", "/css/**", "/js/**").permitAll()
// 需要用户登录的请求
.antMatchers("/user/**").authenticated()
// 只允许 ADMIN 角色访问的请求
.antMatchers("/admin/**").hasRole("ADMIN")
// 所有其他请求需要认证
.anyRequest().authenticated()
// 4. 表单登录配置
.and()
.formLogin()
.loginPage("/login") // 自定义登录页面
.loginProcessingUrl("/perform_login") // 登录表单提交 URL
.defaultSuccessUrl("/home", true) // 登录成功后跳转的默认页面
.failureUrl("/login?error=true") // 登录失败后跳转的页面
.permitAll() // 允许所有人访问登录页面
// 5. 记住我功能
.and()
.rememberMe()
.key("uniqueAndSecret") // rememberMe 的密钥
.tokenValiditySeconds(86400) // token 有效期 1 天
// 6. HTTP Basic 认证
.and()
.httpBasic() // 启用 HTTP Basic 验证
// 7. 配置登出功能
.and()
.logout()
.logoutUrl("/perform_logout") // 自定义登出 URL
.deleteCookies("JSESSIONID") // 删除 session ID 的 cookie
.logoutSuccessUrl("/login?logout") // 登出成功后跳转页面
.permitAll()
// 8. 配置异常处理
.and()
.exceptionHandling()
.accessDeniedPage("/403") // 无权限时跳转到 403 页面
// 9. 会话管理
.and()
.sessionManagement()
.maximumSessions(1) // 限制最多 1 个并发会话
.maxSessionsPreventsLogin(true); // 超过限制时不允许再次登录
}
}
3. 实战
为更好的展示案例,以JimuReport报表为例
详细分析其代码含义:
@Configuration
@EnableWebSecurity // 启用 Spring Security 的Web安全功能
public class SpringSecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
// 禁用 CSRF 保护
http.csrf().disable()
.authorizeRequests() // 开始定义请求的授权规则
// 允许所有人访问登录相关的请求
.antMatchers("/login/**").permitAll()
// 允许访问静态资源,放行相关路径
.antMatchers("/jmreport/**/cdn/**", // CDN 资源
"/jmreport/desreport_/**/*.js", // JavaScript 文件
"/jmreport/desreport_/**/*.css", // CSS 文件
"/jmreport/desreport_/**/*.png") // PNG 图片
.permitAll()
// 允许访问无需登录的接口
.antMatchers("/jmreport/excelQueryByTemplate", // 模板查询接口
"/jmreport/img/**", // 图片接口
"/jmreport/download/image", // 下载图片接口
"/jmreport/verificationToken", // 验证令牌接口
"/jmreport/link/queryByIds", // 查询链接的接口
"/jmreport/test/getUserMsg", // 获取用户信息接口
"/jmreport/test/getOrder", // 获取订单接口
"/jmreport/auto/export/download/**") // 导出下载接口
.permitAll()
// 允许访问分享页面相关接口
.antMatchers("/jmreport/shareView/**", // 分享视图
"/jmreport/checkParam/**", // 检查参数
"/jmreport/share/verification", // 分享验证
"/jmreport/getQueryInfo", // 获取查询信息
"/jmreport/show", // 显示接口
"/jmreport/addViewCount/**") // 增加访问量接口
.permitAll()
// 允许访问 view 页面,使用自定义访问控制逻辑
.antMatchers("/jmreport/view/**").access("@viewPageCustomAccess.check(request,authentication)")
// 任何其他请求必须经过身份验证
.anyRequest().authenticated()
.and()
// 配置表单登录
.formLogin()
.loginPage("/login/login.html") // 自定义登录页面
.loginProcessingUrl("/login") // 登录请求处理的 URL
.successHandler(new CustomLoginSuccessHandler()) // 登录成功处理器
.permitAll() // 允许所有人访问登录页面
.and()
// 配置登出
.logout()
.invalidateHttpSession(true) // 登出时无效化 HTTP 会话
.clearAuthentication(true) // 清除认证信息
.permitAll(); // 允许所有人访问登出功能
return http.build(); // 构建 SecurityFilterChain
}
}
另外一个实战代码示例:
@Bean
protected SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception {
// 开启跨域保护
httpSecurity
// 开启跨域资源共享(CORS)
.cors().and()
// 禁用 CSRF(因为不使用 Session 机制,使用 Token 验证)
.csrf().disable()
// 配置 Session 管理为无状态,因为基于 Token 机制,不需要会话
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
// 关闭浏览器框架选项(防止点击劫持)
.headers().frameOptions().disable().and()
// 配置自定义的异常处理器
.exceptionHandling()
.authenticationEntryPoint(authenticationEntryPoint) // 处理未认证用户的访问异常
.accessDeniedHandler(accessDeniedHandler); // 处理已认证用户的访问权限异常
// 使用自定义的登录机制,不依赖 Spring Security 自带的登录逻辑
// 登录暂时不使用 Spring Security 的扩展点,以减少复杂度和用户学习成本
// 获取 @PermitAll 注解标注的 URL 列表,这些 URL 免登录
Multimap<HttpMethod, String> permitAllUrls = getPermitAllUrlsFromAnnotations();
// 配置请求权限
httpSecurity
// 定义授权规则
.authorizeRequests()
// ① 全局共享规则
// 1.1 静态资源可以匿名访问
.antMatchers(HttpMethod.GET, "/*.html", "/**/*.html", "/**/*.css", "/**/*.js").permitAll()
// 1.2 设置 @PermitAll 标注的接口无需认证
.antMatchers(HttpMethod.GET, permitAllUrls.get(HttpMethod.GET).toArray(new String[0])).permitAll()
.antMatchers(HttpMethod.POST, permitAllUrls.get(HttpMethod.POST).toArray(new String[0])).permitAll()
.antMatchers(HttpMethod.PUT, permitAllUrls.get(HttpMethod.PUT).toArray(new String[0])).permitAll()
.antMatchers(HttpMethod.DELETE, permitAllUrls.get(HttpMethod.DELETE).toArray(new String[0])).permitAll()
// 1.3 基于配置文件中的 permit-all-urls,无需认证
.antMatchers(securityProperties.getPermitAllUrls().toArray(new String[0])).permitAll()
// 1.4 设置应用 API(如 `/app/api/**`),无需认证
.antMatchers(buildAppApi("/**")).permitAll()
// 1.5 验证码接口允许匿名访问
.antMatchers("/captcha/get", "/captcha/check").permitAll()
// ② 各个模块的自定义规则(通过 registry 定制)
.and().authorizeRequests(registry ->
authorizeRequestsCustomizers.forEach(customizer -> customizer.customize(registry)))
// ③ 兜底规则,其他请求必须认证
.authorizeRequests()
.anyRequest().authenticated();
// 在 UsernamePasswordAuthenticationFilter 前添加 Token 过滤器,用于 Token 验证
httpSecurity.addFilterBefore(authenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);
// 返回配置好的 SecurityFilterChain
return httpSecurity.build();
}
本站资源均来自互联网,仅供研究学习,禁止违法使用和商用,产生法律纠纷本站概不负责!如果侵犯了您的权益请与我们联系!
转载请注明出处: 免费源码网-免费的源码资源网站 » Spring Security 基础配置详解(附Demo)
发表评论 取消回复