关于 auth0-java-mvc-common
auth0-java-mvc-common 是面向 Java Servlet Web 应用的 Auth0 集成库,适用于实现基于会话的登录。它提供授权 URL 构建和回调处理,并支持 Organizations 与 Multiple Custom Domains。
主要功能
- 01使用 AuthenticationController 构建授权 URL
- 02处理身份验证回调和令牌
- 03支持基于会话的身份验证
- 04配置范围、受众和 Organizations
- 05通过 DomainResolver 路由多个自定义域
适用场景
- 01为 Java Servlet 应用添加 Auth0 登录
- 02处理登录回调和会话身份验证
- 03使用自定义范围和受众请求 API 令牌
- 04支持 Organizations 或多个 Auth0 域
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ auth0/ agent-skills --skill auth0-java-mvc-common安装后在 Claude Code 中输入/auth0-java-mvc-common确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/api.mdintegration.mdsetup.md详细介绍
Auth0 Java MVC Common 集成
使用 com.auth0:mvc-auth-commons 为 Java Servlet Web 应用添加 Auth0 身份验证。提供 AuthenticationController,用于构建授权 URL 和处理回调,并支持基于会话的身份验证、Organizations 和 Multiple Custom Domains。
Agent 指令: 提供 SDK 设置说明前,运行以下命令获取最新发布版本:
gh api repos/auth0/auth0-java-mvc-common/releases/latest --jq '.tag_name'在所有依赖项行中使用返回的版本,而不是以下内容中任何硬编码的版本。如果 API 调用失败,则使用
1.12.0。
前置条件
- Java 8+(推荐 Java 17+)
- Servlet 容器(Tomcat、Jetty 等),并支持 javax.servlet 3+
- Maven 3.6+ 或 Gradle 7+
- 已配置的 Auth0 Regular Web Application
- 如果尚未设置 Auth0,请先使用
auth0-quickstart技能
不适用场景
| 使用场景 | 推荐技能 |
|---|---|
| 带自动配置的 Spring Boot Web 应用 | 使用 Spring Boot + Okta starter 实现自动配置的 Spring Boot 登录 |
| Spring Boot REST API(无状态 JWT) | 使用 auth0-springboot-api 验证 JWT Bearer 令牌 |
| 单页应用 | 使用 auth0-react、auth0-vue 或 auth0-angular 实现客户端身份验证 |
| 移动应用 | 使用 auth0-android 或 auth0-swift 实现原生移动应用 |
| 机器对机器 API 调用 | 使用 Auth0 Management API SDK 实现服务器到服务器的调用 |
快速入门工作流
Agent 指令: 不要自行写入或复述凭据值(域名、客户端 ID、客户端密钥)。如果用户的提示中已提供 Auth0 凭据,则跳过凭据问题,并指示用户填写其
.env文件——提供变量名称和文件路径,但使用占位符(<YOUR_DOMAIN>、<YOUR_CLIENT_ID>、<YOUR_CLIENT_SECRET>),绝不要使用实际值。回复中绝不要复述凭据。
密钥处理规则:
- 绝不要从 Auth0 CLI 输出中获取或解析
client_secret。- 绝不要使用 Write 或 Edit 工具将实际凭据值写入任何文件——始终使用占位符,并指示用户替换为其真实值。
- 不要读取
.env文件(以避免在上下文中暴露现有密钥)。- 始终确保
.env位于.gitignore中——如果缺少该条目,请自动添加。
1. 安装 SDK
Gradle (build.gradle):
implementation 'com.auth0:mvc-auth-commons:1.12.0'
Maven (pom.xml):
<dependency>
<groupId>com.auth0</groupId>
<artifactId>mvc-auth-commons</artifactId>
<version>1.12.0</version>
</dependency>
2. 创建 Auth0 应用
你需要在 Auth0 中创建一个 Regular Web Application(不是 SPA 或 Native)。
停止——继续前先询问用户。
必须原样提出以下问题,并在采取任何其他操作前等待用户回答:
"你希望如何创建 Auth0 应用?
- 自动创建——我将运行 Auth0 CLI 命令来创建应用,并自动将相关值写入配置。
- 手动创建——你在 Auth0 Dashboard 中自行创建应用(或通过
auth0 apps create创建),并向我提供 Domain、Client ID 和 Client Secret。你倾向哪种方式?(1 = 自动创建 / 2 = 手动创建)"
在用户回答前,不要继续任何设置步骤。不要默认选择手动创建。
如果用户选择自动创建,请按照 设置指南 完成 Auth0 CLI 步骤。自动创建流程会为你写入配置——跳过下面的步骤 3,直接继续步骤 4。
如果用户选择手动创建,请按照 设置指南(手动设置部分)操作。然后继续步骤 3。
手动创建应用的快速参考:
# Using Auth0 CLI
auth0 apps create \
--name "My Java Web App" \
--type regular \
--callbacks http://localhost:3000/callback \
--logout-urls http://localhost:3000
或者,在 Auth0 Dashboard 中手动创建:Applications → Applications → Create Application → Regular Web Applications
3. 配置凭据
将凭据存储为环境变量(切勿在源代码中硬编码):
export AUTH0_DOMAIN="your-tenant.auth0.com"
export AUTH0_CLIENT_ID="your-client-id"
export AUTH0_CLIENT_SECRET="your-client-secret"
或者使用 .env 文件(将其添加到 .gitignore):
AUTH0_DOMAIN=your-tenant.auth0.com
AUTH0_CLIENT_ID=your-client-id
AUTH0_CLIENT_SECRET=your-client-secret
**Agent 指令:**切勿将实际凭据值写入文件。应指导用户使用自己的凭据创建或更新
.env。仅提供带占位符的模板。如果.env尚未添加到.gitignore,请务必添加。提醒用户:“如果之前配置过,请检查.env中是否有重复的 Auth0 条目。”Java 不会自动加载
.env文件。System.getenv()只会读取操作系统级别的环境变量。如果生成.env文件,还必须选择以下一种方式:(1) 将 dotenv-java 添加为依赖,并使用Dotenv.load().get("AUTH0_DOMAIN")代替System.getenv();或者 (2) 指导用户在启动服务之前运行source .env。不要生成同时使用.env文件和System.getenv()、却没有加载机制的代码——这样会导致值为null。
**重要:**Domain 不得包含 https://。该库会自动构造 issuer URL。
4. 初始化 AuthenticationController
创建一个单例 AuthenticationController 实例:
import com.auth0.AuthenticationController;
import com.auth0.jwk.JwkProviderBuilder;
import com.auth0.jwk.JwkProvider;
public class Auth0Config {
private static final AuthenticationController controller = createController();
private static AuthenticationController createController() {
String domain = System.getenv("AUTH0_DOMAIN");
String clientId = System.getenv("AUTH0_CLIENT_ID");
String clientSecret = System.getenv("AUTH0_CLIENT_SECRET");
JwkProvider jwkProvider = new JwkProviderBuilder(domain).build();
return AuthenticationController.newBuilder(domain, clientId, clientSecret)
.withJwkProvider(jwkProvider)
.build();
}
public static AuthenticationController getAuthController() {
return controller;
}
}
5. 创建登录 Servlet
import com.auth0.AuthenticationController;
import com.auth0.AuthorizeUrl;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet(urlPatterns = {"/login"})
public class LoginServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
AuthenticationController controller = Auth0Config.getAuthController();
// Build callback URL — omit port for standard ports (80/443) to avoid
// mismatch with the URL registered in Auth0 Dashboard, especially behind proxies.
String scheme = request.getScheme();
int port = request.getServerPort();
String redirectUrl = scheme + "://" + request.getServerName()
+ ((port == 80 || port == 443) ? "" : ":" + port) + "/callback";
AuthorizeUrl authorizeUrl = controller.buildAuthorizeUrl(request, response, redirectUrl)
.withScope("openid profile email");
response.sendRedirect(authorizeUrl.build());
}
}
6. 创建回调 Servlet
import com.auth0.AuthenticationController;
import com.auth0.IdentityVerificationException;
import com.auth0.Tokens;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet(urlPatterns = {"/callback"})
public class CallbackServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
AuthenticationController controller = Auth0Config.getAuthController();
try {
Tokens tokens = controller.handle(request, response);
request.getSession().setAttribute("accessToken", tokens.getAccessToken());
request.getSession().setAttribute("idToken", tokens.getIdToken());
response.sendRedirect("/dashboard");
} catch (IdentityVerificationException e) {
response.sendRedirect("/login?error=" + e.getCode());
}
}
}
7. 使用身份验证中间件(Servlet 过滤器)保护路由
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
@WebFilter(urlPatterns = {"/dashboard/*", "/api/private/*"})
public class AuthenticationFilter implements Filter {
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
HttpSession session = request.getSession(false);
if (session == null || session.getAttribute("idToken") == null) {
response.sendRedirect("/login");
return;
}
chain.doFilter(req, res);
}
@Override
public void init(FilterConfig filterConfig) {}
@Override
public void destroy() {}
}
8. 测试应用
**Agent 指令:**编写完所有代码后,验证构建是否成功:
./gradlew build或运行
mvn package。如果构建失败,请诊断并修复。连续失败 5–6 次后,使用AskUserQuestion寻求帮助。
- 启动应用并访问
http://localhost:3000/login - 应重定向到 Auth0 Universal Login 页面
- 登录后,回调 Servlet 会处理响应并重定向到
/dashboard
常见错误
| 错误 | 修复方法 |
|---|---|
Domain 包含 https:// | 仅使用 your-tenant.auth0.com 格式,不要添加协议前缀 |
| 在源代码中硬编码 Client secret | 使用环境变量或 .env 文件,并将其添加到 .gitignore |
| 创建了 SPA 或 Native 应用,而不是 Regular Web 应用 | 必须在 Auth0 Dashboard 中创建 Regular Web Application |
| Callback URL 不匹配 | 代码中的 Callback URL 必须与 Auth0 Dashboard 中注册的内容完全一致 |
缺少 openid scope | scope 中务必包含 openid,这是 ID token 的必需项 |
未处理 IdentityVerificationException | 回调处理程序中务必捕获此异常,以显示登录错误 |
使用 response_type=token | Regular Web 应用必须使用 code 流程(默认),切勿使用 implicit 流程 |
| 登出时未使 Session 失效 | 重定向到 Auth0 登出页面之前,调用 request.getSession().invalidate() |
Scope 和 Audience 配置
如需请求自定义 scope、API 访问 token 的 audience,以及使用 Organizations,请参阅集成指南。
多个自定义域(MCD)
内置支持通过 DomainResolver 将用户路由到正确的 Auth0 域。配置详情请参阅集成指南。
相关技能
auth0-quickstart— Auth0 基础设置和账户创建auth0-springboot-api— 使用 JWT Bearer token 验证的 Spring Boot REST API
快速参考
核心类:
AuthenticationController— 主入口,用于构建授权 URL 并处理回调AuthenticationController.Builder— 通过newBuilder(domain, clientId, clientSecret)配置控制器AuthorizeUrl— 用于设置/authorizeURL 参数的流式构建器Tokens— 回调中的访问令牌、ID 令牌和刷新令牌IdentityVerificationException— 包含错误代码的身份验证错误DomainResolver— 用于支持多个自定义域名的接口
构建器方法(AuthorizeUrl):
.withScope("openid profile email")— 设置请求的权限范围.withAudience("https://my-api")— 请求 API 访问令牌.withOrganization("org_xxx")— 限定到特定组织.withInvitation("invite_xxx")— 接受组织邀请.withConnection("google-oauth2")— 跳转到指定连接.withParameter("key", "value")— 添加自定义授权参数
令牌访问(Tokens):
tokens.getAccessToken()— 访问令牌字符串tokens.getIdToken()— ID 令牌(JWT)字符串tokens.getRefreshToken()— 刷新令牌(需请求offline_access权限范围)tokens.getExpiresIn()— 令牌过期时间(秒)tokens.getType()— 令牌类型(通常为 "Bearer")tokens.getDomain()— 签发令牌的 Auth0 域名tokens.getIssuer()— 令牌签发者 URL