当 Spring 应用在到达控制器或服务中的断点之前返回 403 或 401 时,问题可能不在开发者想要检查的逻辑中,而在请求执行之前的授权层。IntelliJ IDEA 提供了一种检查正在运行的应用中的实际安全规则的方法,然后在调试会话期间为请求授予临时身份和权限,而无需修改 SecurityConfig 或重启应用。
该功能是 IntelliJ IDEA Ultimate 中 Spring Debugger plugin 的一部分,自 2026.2 版本起可用。运行调试器时,Security inlays 默认显示,无论应用是在本地运行还是在远程 JVM 上运行。
先了解路径实际要求什么
编辑器或 HTTP 文件中的界面会显示端点现有的基于角色和权限的要求,包括基于 hasRole 和 hasAuthority 的规则。IntelliJ IDEA 在这里并不只是读取配置文件,而是在 Spring 上下文初始化后检查 JVM 内实际的 SecurityFilterChain。当多个 SecurityFilterChain、匹配器顺序、活动配置文件或配置的条件注册会影响最终结果时,这一点非常重要。
如果某条规则无法转换为角色列表,例如某些自定义 AuthorizationManager 实现中的规则,该规则会显示为未知状态,并附带指向相关安全配置代码的链接。在这种情况下,无法使用基于角色列表的自动解锁,仍然需要返回 SecurityConfig 进行处理。
在调试会话期间临时打开路径
Unlock 操作提供两个选项。第一个选项会将请求视为已通过认证,并为其授予该路径所需的一组角色;当开发者希望测试受保护路径背后的控制器或服务逻辑时,这一选项很合适。第二个选项允许指定用户名和自定义权限列表,例如使用 admin 以及 ROLE_ADMIN 和 ROLE_MANAGER,以测试应用在特定权限集合下的行为。
执行该操作时,调试器会在正在运行的应用的 SecurityContext 中创建一个 TestingAuthenticationToken。hasRole 和 hasAuthority 检查,以及 SecurityContextHolder.getContext().getAuthentication() 和 Principal 或 Authentication 参数,都会看到开发者指定的身份和权限。该操作不会修改应用代码或配置文件;应用重启时所有解锁都会消失,包括通过 Spring Boot DevTools 在进程内重启,以及手动锁定路径时的情况。
其影响并不局限于从 IntelliJ IDEA 发送的请求。打开特定路径的 GET 会影响任何访问相同 URI 和 HTTP 方法的客户端,例如 curl、Postman 或浏览器。如果在控制器映射中打开了路径模式,可能会涵盖与该模式匹配的所有值。因此,完成后应重新锁定路径或结束调试会话,尤其是在应用可通过网络访问时。
Unlock 不会绕过什么?
该操作不会完全禁用 Spring Security,也不会绕过 CSRF 保护。如果 POST、PUT 或 DELETE 请求需要有效的 CSRF 令牌,CsrfFilter 仍然能够拒绝该请求。此外,其范围仅限于 Servlet 堆栈中通过 AuthorizationFilter 实现的端点授权;不支持使用 AuthorizationWebFilter 的 Spring WebFlux。
目前没有直接的界面用于显示或打开方法级别的安全要求,例如 @PreAuthorize、@PostAuthorize 和 @Secured。不过,注入 SecurityContext 的权限之后可以被方法安全拦截器读取,因此如果授予的权限满足其条件,使用 @PreAuthorize 保护的服务调用可能会通过。这并不意味着 IntelliJ IDEA 打开了方法本身的保护,而是因为检查读取了同一个人工认证上下文。
身份限制与测试工具集成
调试器创建的身份是 TestingAuthenticationToken 中的文本用户名,而不是应用的 UserDetails 或自定义用户对象类型。因此,带有 @AuthenticationPrincipal 的参数可能返回 null;这是已知问题,编号为 IDEA-389767,发布本文时影响 2026.2 版本。
可以将 Principal 或 Authentication 用作参数类型,但依赖 JwtAuthenticationToken 等具体类型可能导致 IllegalStateException,因为注入的对象不属于该类型。依赖 claims、credentials 或与会话或特定令牌类型关联的身份的部分,其结果也可能不同或失败。
该解锁功能适用于来自内置 .http 文件、curl、Postman 和测试框架的请求,前提是正在运行的应用就是打开该路径的应用。对于自动化工作流或依赖人工智能代理的工作流,目前没有用于执行该操作的编程接口。JetBrains 计划在 2026.3 版本中添加 MCP 工具及与其关联的技能,但当前版本要求先在 IDE 内手动点击一次。
为什么这种做法很重要?
这里的实际价值不在于禁用安全保护,而在于将授权层与开发者想要测试的逻辑隔离开,同时避免在配置文件中留下可能被遗忘并进入其他环境的临时修改。另一方面,解锁是对正在运行的进程进行的临时安全更改,并不是仅限于 IDE 请求的本地模拟。因此,应将其视为范围受控的调试工具,而不是实际认证测试的替代方案;使用前应确认路径、方法以及受影响的客户端。
还应注意,该功能在远程应用中打开路径时不会在日志中记录消息,也不会通过 Actuator 提供指示器。根据本文,只有通过连接到应用的 IDE 内部界面才能验证状态。不需要时,可以在 IntelliJ IDEA 的 Registry 中通过 spring.debugger.security.enabled 设置禁用 Security inlays。