package com.ttstd.signaling.config;
import jakarta.servlet.http.HttpServletRequest;
import java.util.Set;
/**
* 统一管理“无需鉴权即可访问”的端点。
*
*
所有免登录/免令牌的公开接口集中在此登记,避免各过滤器各自硬编码放行规则
* 导致遗漏或冲突(例如登录接口被误拦截返回 401)。
*
*
匹配规则:
*
* - {@link #EXACT} 中的精确路径(含任意 HTTP 方法)一律放行;
* - {@link #PREFIXES} 中的前缀路径一律放行;
* - OPTIONS 预检请求一律放行;
* - 其余路径交由对应鉴权过滤器处理。
*
*/
public final class PublicEndpoints {
private PublicEndpoints() {
}
/** 精确免鉴权路径(不区分 HTTP 方法)。 */
public static final Set EXACT = Set.of(
// 主控端用户体系
"/api/auth/register",
"/api/auth/login",
"/api/auth/refresh",
// 设备激活 / 设备令牌
"/api/device/provision",
"/api/device/token",
// 后台管理员:登录接口免鉴权(其余后台接口均需 admt_ 令牌)
"/api/admin/login",
// 后台健康检查(运维探针)
"/api/admin/health"
);
/** 免鉴权前缀。 */
public static final Set PREFIXES = Set.of(
// WebSocket 握手前的公开信令协商路径(如有)
);
/** 判断请求是否免鉴权。 */
public static boolean isPublic(HttpServletRequest request) {
if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
return true;
}
String path = request.getServletPath();
if (path == null) {
return false;
}
if (EXACT.contains(path)) {
return true;
}
for (String prefix : PREFIXES) {
if (path.startsWith(prefix)) {
return true;
}
}
return false;
}
}