mcpField
A
auth0-java-mvc-common

auth0-java-mvc-common

github.com/auth0安全55388 次安装1 天前更新
代码仓库

关于 auth0-java-mvc-common

auth0-java-mvc-common 是面向 Java Servlet Web 应用的 Auth0 集成库,适用于实现基于会话的登录。它提供授权 URL 构建和回调处理,并支持 Organizations 与 Multiple Custom Domains。

主要功能

  1. 01使用 AuthenticationController 构建授权 URL
  2. 02处理身份验证回调和令牌
  3. 03支持基于会话的身份验证
  4. 04配置范围、受众和 Organizations
  5. 05通过 DomainResolver 路由多个自定义域

适用场景

  1. 01为 Java Servlet 应用添加 Auth0 登录
  2. 02处理登录回调和会话身份验证
  3. 03使用自定义范围和受众请求 API 令牌
  4. 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.md
integration.md
setup.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 应用?

  1. 自动创建——我将运行 Auth0 CLI 命令来创建应用,并自动将相关值写入配置。
  2. 手动创建——你在 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 寻求帮助。

  1. 启动应用并访问 http://localhost:3000/login
  2. 应重定向到 Auth0 Universal Login 页面
  3. 登录后,回调 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 scopescope 中务必包含 openid,这是 ID token 的必需项
未处理 IdentityVerificationException回调处理程序中务必捕获此异常,以显示登录错误
使用 response_type=tokenRegular 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 — 用于设置 /authorize URL 参数的流式构建器
  • 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

详细文档

  • 设置指南 — Auth0 CLI 自动化、环境配置、密钥管理
  • 集成指南 — 组织、MCD、自定义权限范围、注销、错误处理、高级模式
  • API 参考 — 完整配置选项、构建器方法、声明参考、测试清单

参考资料

评论

支持 Markdown