ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Pinpoint Basic Login 模块详解:JWT Cookie 认证的启用与配置指南

Pinpoint Basic Login 模块详解:JWT Cookie 认证的启用与配置指南 Pinpoint Basic Login 模块详解JWT Cookie 认证的启用与配置指南【免费下载链接】pinpointAPM, (Application Performance Management) tool for large-scale distributed systems.项目地址: https://gitcode.com/gh_mirrors/pi/pinpoint导读Pinpoint 是一个面向大规模分布式系统的 APM应用性能监控工具其 Web 控制台默认没有启用认证。basic-login模块为 Pinpoint Web 提供了基于 Spring Security 的「账号密码 JWT Cookie」登录认证能力通过一个启动参数即可开启。本文基于仓库中 basic-login/README.md 与该模块源码完整讲解启用方法、账号配置、JWT Cookie 安全属性调优HttpOnly / Secure / SameSite、HTTPS 部署下的注意事项以及模块内部的认证调用链与配置校验逻辑帮助你在生产环境中安全地保护 Pinpoint Web 控制台。一、模块定位与启用方式pinpoint-basic-login是 Pinpoint 仓库中的一个独立 Maven 模块见 basic-login/pom.xml以 jar 形式被 Web 应用引入。它本身不参与 Agent 采集链路只负责 Web 控制台的登录认证属于可插拔的「登录模块」。启用方式是在启动 Pinpoint Web 时通过 JVM 系统属性指定登录模块类型-Dpinpoint.modules.web.loginbasicLogin对应的源码开关位于 PinpointBasicLoginConfig.java该类使用ConditionalOnProperty(name pinpoint.modules.web.login, havingValue basicLogin)条件装配只有当该属性值精确等于basicLogin时Spring Security 的整套配置才会生效。也就是说不传该参数时模块完全不加载Web 行为与未集成登录时一致。注意pinpoint.modules.web.login支持的值与 Web 模块支持的登录模块列表有关basicLogin是其中一种实现本文仅围绕该值对应的 basic-login 模块展开。二、账号与角色配置2.1 用户与管理员账号账号通过pinpoint-web.properties即 Web 应用的配置覆盖文件仓库中的默认样例位于 web/src/main/resources/pinpoint-web-root.properties中的两个属性声明# 普通用户可用除 Admin REST API 外的全部功能 web.security.auth.useralice:foo,bob:bar # 管理员可用全部功能包括 /api/admin/** web.security.auth.admineve:baz格式为用户名:密码多个账号用英文逗号分隔密码以明文写在配置文件中由模块在加载时使用 BCrypt 加密BCryptPasswordEncoder见 PinpointBasicLoginConfig.java解析逻辑在 BasicLoginProperties.java按:切分用户名:密码切分后恰好为两段才会被注册否则静默忽略。2.2 角色与路径授权模块区分两类角色ROLE_USER普通用户可访问除 Admin API 外的全部功能ROLE_ADMIN管理员额外拥有/api/admin/**的访问权限。授权规则定义在 PinpointBasicLoginConfig.java 的SecurityFilterChain中http.authorizeHttpRequests(customizer - { customizer.requestMatchers(/api/admin/**).hasRole(ADMIN); }); // ... http.authorizeHttpRequests(customizer - { customizer .requestMatchers(/api-public/**).permitAll() .requestMatchers(/api-ext-auth/**).permitAll() .anyRequest().authenticated(); });即/api/admin/**需要ADMIN角色/api-public/**与/api-ext-auth/**匿名可访问permitAll其余所有请求必须认证anyRequest().authenticated()。无权限访问 Admin API 时会被重定向到 BasicLoginConstants.java 中定义的URI_NOT_AUTHORIZED /not_authorized.html。三、JWT Cookie 安全属性配置登录成功后模块生成pinpointJwtCookieCookie 名称定义在 BasicLoginConstants.java后续请求靠该 Cookie 完成无状态认证。3.1 三个可调属性与默认值配置项pinpoint-web.properties环境变量Docker / Kubernetes默认值说明web.security.auth.jwt.cookie.http-onlyWEB_SECURITY_AUTH_JWT_COOKIE_HTTP_ONLYtrue禁止 JavaScript 读取 Cookie降低 XSS 窃取风险web.security.auth.jwt.cookie.secureWEB_SECURITY_AUTH_JWT_COOKIE_SECUREfalse仅通过 HTTPS 传输Web 走 HTTPS 时应设为trueweb.security.auth.jwt.cookie.same-siteWEB_SECURITY_AUTH_JWT_COOKIE_SAME_SITELax跨站请求携带 Cookie 的策略可设为Lax/Strict/None等属性默认值在 BasicLoginProperties.java 中以 SpringValue注解声明Value(${web.security.auth.jwt.cookie.http-only:true}) private boolean jwtCookieHttpOnly; Value(${web.security.auth.jwt.cookie.secure:false}) private boolean jwtCookieSecure; Value(${web.security.auth.jwt.cookie.same-site:Lax}) private String jwtCookieSameSite;3.2 Cookie 如何被构造Cookie 的构造逻辑在 BasicLoginService.createNewCookie()Path/全站生效HttpOnly按jwtCookieHttpOnly设置默认开启Secure按jwtCookieSecure设置默认关闭SameSite仅当值非空且非空白时才写入 Cookie 属性MaxAge等于 JWT 的过期时长见下文单位为秒。createNewCookie()被登录成功处理器 SaveJwtTokenAuthenticationSuccessHandler.java 调用认证成功后生成 Cookie 写入响应、设置 HTTP 200 与 JSON Content-Type并重定向到主页面/。3.3 配置示例普通 HTTP 内网部署推荐保持默认即可web.security.auth.jwt.cookie.http-onlytrue web.security.auth.jwt.cookie.securefalse web.security.auth.jwt.cookie.same-siteLaxHTTPS 公网部署必须开启 Secureweb.security.auth.jwt.cookie.http-onlytrue web.security.auth.jwt.cookie.securetrue web.security.auth.jwt.cookie.same-siteLaxDocker / Kubernetes 环境下使用环境变量注入WEB_SECURITY_AUTH_JWT_COOKIE_HTTP_ONLYtrue WEB_SECURITY_AUTH_JWT_COOKIE_SECUREtrue WEB_SECURITY_AUTH_JWT_COOKIE_SAME_SITELax安全提示若将same-site设为None浏览器强制要求 Cookie 同时带有Secure属性即必须走 HTTPS否则 Cookie 会被拒绝实际部署时请按协议约束配置。四、JWT 密钥配置必填项启用 basicLogin 后必须配置 JWT 签名密钥否则 Web 启动失败web.security.auth.jwt.secretkeygenerate-a-random-secret对应源码中的强制校验位于 BasicLoginProperties.afterPropertiesSet()启动时检查两件事密钥非空——错误信息提示请在pinpoint-web.properties中设置一个至少 24 个字符的随机字符串密钥不得等于__PINPOINT_JWT_SECRET__——该值曾作为示例值随 4.0.0 之前的版本发布属于公开已知的泄露密钥源码注释明确要求必须更换。对应单元测试 BasicLoginServiceTest.leakedSecretKeyShouldFailStartup() 验证了使用该泄露密钥时容器启动会抛出包含publicly known的IllegalArgumentException。生成随机密钥的参考命令任选其一# Linux / macOS openssl rand -base64 32 # 或 head -c 32 /dev/urandom | base64五、认证流程与实现原理5.1 登录链路用户访问 Web 任意受保护路径被重定向到/loginURI_LOGIN见 BasicLoginConstants.java表单登录formLogin校验账号密码密码由BCryptPasswordEncoder校验认证成功后 SaveJwtTokenAuthenticationSuccessHandler 生成 JWT 并写入pinpointJwtCookie随后重定向回/后续每次请求由 JwtRequestFilter 从 Cookie 中解析 JWT验证通过后把用户信息写入SecurityContext实现无状态认证。5.2 JWT 的结构与过期时间JwtService.java 负责 Token 的签发与解析Claims包含userId与userRole角色列表签发时间issuedAt为当前时间过期时间expiration为「当前时间 过期时长」默认过期时长DEFAULT_EXPIRATION_TIME_SECONDS TimeUnit.HOURS.toSeconds(12)即12 小时定义于 BasicLoginProperties.java签名算法使用密钥通过Keys.hmacShaKeyFor()构造 HMAC-SHA 密钥对应 jjwt 库密钥先经 Base64 编码后参与构造校验解析时使用JwtParser.verifyWith(secretKey)验签。5.3 无状态会话与退出安全配置同时声明了 PinpointBasicLoginConfig.configure() 中的以下行为无状态会话SessionCreationPolicy.STATELESS不创建服务端 Session认证完全依赖 Cookie 中的 JWT禁用 CSRF 与 HTTP Basiccsrf.disable()与httpBasic.disable()退出登录登出时删除pinpointJwtCookielogout.deleteCookies(pinpointJwt)预认证检查PreAuthenticationCheckFilter在登录页请求到来前检查是否已认证若已登录访问/login则直接重定向回/避免重复登录。5.4 用户存储用户保存在内存中PinpointMemoryUserDetailsService 将普通用户与管理员合并进一个MapString, UserDetails管理员覆盖同名普通用户并通过Map.copyOf固化。loadUserByUsername()每次返回 User 对象的凭证副本单元测试 验证了即使外部对返回对象调用eraseCredentials()清空密码也不会影响内存中的原始凭证。用户名不存在时抛出UsernameNotFoundException(User not found: username)。六、异常处理与容错JwtRequestFilter 与 BasicLoginService.getUserDetails() 对以下异常情况做了容错处理均记录 warn 日志后放行请求交由安全框架判定为未认证Cookie 缺失或为空直接放行Token 过期捕获ExpiredJwtException日志提示This token already expired.Token 非法非 JWT 格式或验签失败捕获JwtException日志提示Invalid JWT token.用户不存在捕获UsernameNotFoundException日志提示Could not find user for JWT token.。这些行为均有对应的单元测试覆盖BasicLoginServiceTest.java 分别验证了「用户不存在时忽略 JWT」「非法 JWT 被忽略」「空 JWT 被忽略」。七、典型部署场景总结场景推荐配置内网 HTTP 直连保持默认http-onlytrue、securefalse、same-siteLaxHTTPS 反向代理 / 公网部署追加web.security.auth.jwt.cookie.securetrue环境变量为WEB_SECURITY_AUTH_JWT_COOKIE_SECUREtrue跨站集成如嵌入第三方页面谨慎使用same-siteNone且必须同时开启securetrue并保证 HTTPS任何场景必须设置 ≥24 字符的随机web.security.auth.jwt.secretkey禁止使用__PINPOINT_JWT_SECRET__启用口令为-Dpinpoint.modules.web.loginbasicLogin配合 pinpoint-web-root.properties 中注释示例的账号、密钥与 Cookie 三项配置即可为 Pinpoint Web 控制台开启一套安全、无状态的 JWT Cookie 登录认证方案。更深层的实现细节可继续阅读 basic-login 模块源码与测试用例 BasicLoginServiceTest.java。【免费下载链接】pinpointAPM, (Application Performance Management) tool for large-scale distributed systems.项目地址: https://gitcode.com/gh_mirrors/pi/pinpoint创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进