> ## Documentation Index
> Fetch the complete documentation index at: https://translations.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Java Spring Boot API

> 保護されたエンドポイントを持つ Spring Boot API に Auth0 JWT 認証を追加する

export const HowToSchema = () => <script type="application/ld+json">
    {'{"@context":"https://schema.org","@type":"HowTo"}'}
  </script>;

<HowToSchema />

<Callout icon="pencil" color="#FFC107" iconType="solid">
  このクイックスタートは現在 **ベータ版** です。ぜひフィードバックをお寄せください。
</Callout>

<Accordion title="AI を使って Auth0 を統合する" icon="microchip-ai" iconType="solid" defaultOpen>
  Claude Code、Cursor、GitHub Copilot などの AI コーディングアシスタントを使用している場合は、[agent skills](https://agentskills.io/home) を使って、数分で Auth0 認証を自動的に追加できます。

  **インストール:**

  ```bash theme={null}
  npx skills add auth0/agent-skills --skill auth0-quickstart --skill auth0-springboot-api
  ```

  **次に、AI アシスタントに次のように依頼します。**

  ```text theme={null}
  Add Auth0 JWT authentication to my Spring Boot API
  ```

  AI アシスタントは、Auth0 API の作成、認証情報の取得、Auth0 Spring Boot API SDK 依存関係の追加、`application.yml` の設定、JWT 検証と保護されたエンドポイントを備えた `SecurityFilterChain` の実装を自動的に行います。[agent skills の完全なドキュメント →](/ja/docs/quickstart/agent-skills)
</Accordion>

<Note>
  **前提条件:** 開始する前に、次のものがインストールされていることを確認してください。

  * **[JDK 17+](https://openjdk.org/projects/jdk/17/)**: Spring Boot 3.2+ との互換性のため
  * **[Maven 3.6+](https://maven.apache.org/download.cgi)** または **[Gradle 7+](https://gradle.org/install/)**: 依存関係管理のため
  * 使用する IDE (IntelliJ IDEA、Eclipse、または Java をサポートする VS Code)

  **Java バージョンの互換性:** このクイックスタートは **Java 17+** および **Spring Boot 3.2+** に対応しています。
</Note>

<div id="get-started">
  ## はじめに
</div>

このクイックスタートでは、Spring Boot API に Auth0 JWT 認証を追加する方法を説明します。Auth0 Spring Boot API SDK を使用して、保護されたエンドポイントを持つ安全な API を構築します。

<Steps>
  <Step title="新しいプロジェクトを作成" stepNumber={1}>
    このクイックスタート用の新しい Spring Boot API プロジェクトを作成します。

    **Spring Initializr を使用する場合:**

    ```bash theme={null}
    curl -L https://start.spring.io/starter.zip \
        -d dependencies=web,security \
        -d javaVersion=17 \
        -d name=auth0-api \
        -d artifactId=auth0-api \
        -d packageName=com.example.auth0api \
        -o auth0-api.zip

    mkdir auth0-api && unzip auth0-api.zip -d auth0-api && cd auth0-api
    ```

    **または、Maven で手動作成します。**

    ```bash theme={null}
    mvn archetype:generate \
        -DgroupId=com.example \
        -DartifactId=auth0-api \
        -DarchetypeArtifactId=maven-archetype-quickstart \
        -DinteractiveMode=false

    cd auth0-api
    ```
  </Step>

  <Step title="Auth0 SDK を追加" stepNumber={2}>
    Auth0 Spring Boot API SDK を、プロジェクトの依存関係に追加します。

    **Maven (`pom.xml`):**

    ```xml theme={null}
    <dependency>
        <groupId>com.auth0</groupId>
        <artifactId>auth0-springboot-api</artifactId>
        <version>1.0.0-beta.0</version>
    </dependency>
    ```

    **Gradle (`build.gradle`) ：**

    ```gradle theme={null}
    dependencies {
        implementation 'com.auth0:auth0-springboot-api:1.0.0-beta.0'
    }
    ```
  </Step>

  <Step title="Auth0 API を設定する" stepNumber={3}>
    次に、Auth0テナントで新しいAPIを作成し、その設定をプロジェクトに追加します。

    CLIコマンドを実行して自動的に行う方法と、Dashboardから手動で行う方法のいずれかを選択できます。

    <Tabs>
      <Tab title="CLI">
        Auth0 API を作成し、`application.yml` ファイルを更新するには、プロジェクトのルートディレクトリで次のシェルコマンドを実行します。

        <Tabs>
          <Tab title="Mac/Linux">
            ```bash expandable theme={null}
            AUTH0_API_NAME="My Spring Boot API" && \
            AUTH0_API_IDENTIFIER="https://my-springboot-api" && \
            brew tap auth0/auth0-cli && \
            brew install auth0 && \
            auth0 login --no-input && \
            auth0 apis create -n "${AUTH0_API_NAME}" -i "${AUTH0_API_IDENTIFIER}" --offline-access --token-lifetime 86400 --signing-alg RS256 --json > auth0-api-details.json && \
            DOMAIN=$(auth0 tenants list --json | jq -r '.[] | select(.active == true) | .name') && \
            AUDIENCE=$(jq -r '.identifier' auth0-api-details.json) && \
            mkdir -p src/main/resources && \
            printf 'auth0:\n  domain: %s\n  audience: %s\n\nspring:\n  application:\n    name: auth0-api\n' "$DOMAIN" "$AUDIENCE" > src/main/resources/application.yml && \
            rm auth0-api-details.json && \
            echo "✅ application.yml created with your Auth0 API details:" && \
            cat src/main/resources/application.yml
            ```
          </Tab>

          <Tab title="Windows (PowerShell)">
            ```powershell expandable theme={null}
            $ApiName = "My Spring Boot API"
            $ApiIdentifier = "https://my-springboot-api"
            $latestRelease = Invoke-RestMethod -Uri "https://api.github.com/repos/auth0/auth0-cli/releases/latest"
            $latestVersion = $latestRelease.tag_name
            $version = $latestVersion -replace "^v"
            Invoke-WebRequest -Uri "https://github.com/auth0/auth0-cli/releases/download/${latestVersion}/auth0-cli_${version}_Windows_x86_64.zip" -OutFile ".\auth0.zip"
            Expand-Archive ".\auth0.zip" .\
            [System.Environment]::SetEnvironmentVariable('PATH', $Env:PATH + ";${pwd}")
            auth0 login --no-input
            auth0 apis create -n "$ApiName" -i "$ApiIdentifier" --offline-access --token-lifetime 86400 --signing-alg RS256 --json | Set-Content -Path auth0-api-details.json
            $Domain = (auth0 tenants list --json | ConvertFrom-Json | Where-Object { $_.active -eq $true }).name
            $Audience = (Get-Content -Raw auth0-api-details.json | ConvertFrom-Json).identifier
            New-Item -ItemType Directory -Force -Path "src\main\resources"
            @"
            auth0:
              domain: "$Domain"
              audience: "$Audience"

            spring:
              application:
                name: auth0-api
            "@ | Set-Content "src\main\resources\application.yml"
            Remove-Item auth0-api-details.json
            Write-Output "✅ application.yml created with your Auth0 API details:"
            Get-Content "src\main\resources\application.yml"
            ```
          </Tab>
        </Tabs>
      </Tab>

      <Tab title="Dashboard">
        始める前に、`src/main/resources/application.yml` ファイルに Auth0 の設定を追加します。

        ```yaml src/main/resources/application.yml expandable theme={null}
        auth0:
          domain: "YOUR_AUTH0_DOMAIN"
          audience: "YOUR_AUTH0_API_IDENTIFIER"

        spring:
          application:
            name: auth0-api
        ```

        1. [Auth0 Dashboard](https://manage.auth0.com) → **Applications** → **APIs** に移動します
        2. **Create API** を選択します
        3. API の詳細を入力します。
           * **Name**: My Spring Boot API
           * **Identifier**: `https://my-springboot-api` (これがオーディエンスになります)
           * **Signing Algorithm**: RS256
        4. **Create** を選択します
        5. `application.yml` の `YOUR_AUTH0_DOMAIN` を、テストタブの **Domain** で置き換えます (例: `your-tenant.auth0.com`)
        6. `application.yml` の `YOUR_AUTH0_API_IDENTIFIER` を **Identifier** で置き換えます。例: `https://my-springboot-api`。

        <Info>
          **Domain** には `https://` を含めないでください。ドメインとリージョンのみを使用します。例: `your-tenant.auth0.com`。

          **Audience** (API Identifier) は API の一意の識別子であり、有効な URI であれば任意の値を指定できます。一般公開された URL である必要はありません。
        </Info>
      </Tab>
    </Tabs>
  </Step>

  <Step title="認証を設定する" stepNumber={4}>
    Auth0 JWT 認証を有効にするセキュリティ構成クラスを作成します。`src/main/java/com/example/auth0api/SecurityConfig.java` を作成します。

    ```java src/main/java/com/example/auth0api/SecurityConfig.java lines expandable theme={null}
    package com.example.auth0api;

    import com.auth0.spring.boot.Auth0AuthenticationFilter;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.security.config.annotation.web.builders.HttpSecurity;
    import org.springframework.security.config.http.SessionCreationPolicy;
    import org.springframework.security.web.SecurityFilterChain;
    import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

    @Configuration
    public class SecurityConfig {

        @Bean
        SecurityFilterChain apiSecurity(HttpSecurity http, Auth0AuthenticationFilter authFilter) throws Exception {
            return http
                .csrf(csrf -> csrf.disable())
                .sessionManagement(session ->
                    session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
                .authorizeHttpRequests(auth -> auth
                    .requestMatchers("/api/public").permitAll()
                    .requestMatchers("/api/private").authenticated()
                    .anyRequest().permitAll())
                .addFilterBefore(authFilter, UsernamePasswordAuthenticationFilter.class)
                .build();
        }
    }
    ```
  </Step>

  <Step title="公開エンドポイントと保護エンドポイントを作成する" stepNumber={5}>
    認証をテストするための API エンドポイントを作成します。`src/main/java/com/example/auth0api/ApiController.java` を作成します。

    ```java src/main/java/com/example/auth0api/ApiController.java expandable theme={null}
    package com.example.auth0api;

    import com.auth0.spring.boot.Auth0AuthenticationToken;
    import org.springframework.http.ResponseEntity;
    import org.springframework.security.core.Authentication;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;

    import java.util.Map;

    @RestController
    @RequestMapping("/api")
    public class ApiController {

        // パブリックエンドポイント - 認証不要
        @GetMapping("/public")
        public ResponseEntity<Map<String, String>> publicEndpoint() {
            return ResponseEntity.ok(Map.of(
                "message", "This endpoint is public - no authentication required"
            ));
        }

        // 保護されたエンドポイント - 認証が必要
        @GetMapping("/private")
        public ResponseEntity<Map<String, Object>> privateEndpoint(Authentication authentication) {
            Auth0AuthenticationToken auth0Token = (Auth0AuthenticationToken) authentication;

            return ResponseEntity.ok(Map.of(
                "message", "This endpoint requires authentication",
                "user", authentication.getName(),
                "scopes", auth0Token.getAuthorities()
            ));
        }
    }
    ```
  </Step>

  <Step title="API を起動する" stepNumber={6}>
    Spring Boot アプリケーションを起動します。

    **Maven:**

    ```bash theme={null}
    ./mvnw spring-boot:run
    ```

    **Gradle:**

    ```bash theme={null}
    ./gradlew bootRun
    ```

    API は `http://localhost:8080` で実行中です (正確な URL はコンソール出力を確認してください) 。
  </Step>
</Steps>

<Check>
  **チェックポイント**

  これで、Auth0 で保護された API が [localhost](http://localhost:8080/) 上で完全に動作しているはずです。
</Check>

***

<div id="advanced-usage">
  ## 高度な使い方
</div>

<Accordion title="保護されたAPIの呼び出し">
  アクセストークンを使用して、保護されたエンドポイントをテストします。

  **1. Client Credentials フローを使用して** Auth0 **からアクセストークンを取得します。**

  ```bash theme={null}
  curl --request POST \
    --url https://YOUR_DOMAIN/oauth/token \
    --header 'content-type: application/json' \
    --data '{"client_id":"YOUR_CLIENT_ID","client_secret":"YOUR_CLIENT_SECRET","audience":"YOUR_AUDIENCE","grant_type":"client_credentials"}'
  ```

  <Info>
    `YOUR_CLIENT_ID` と `YOUR_CLIENT_SECRET` を取得するには、[Auth0 Dashboard](https://manage.auth0.com/#/applications) で
    Machine to Machine Application を作成し、
    API へのアクセスを認可します。
  </Info>

  **2. 公開エンドポイントをテストします** (200 OK が返されるはずです) 。

  ```bash theme={null}
  curl http://localhost:8080/api/public
  ```

  **3. 認証なしで保護されたエンドポイントをテストします** (401 Unauthorized が返されるはずです) 。

  ```bash theme={null}
  curl http://localhost:8080/api/private
  ```

  **4. トークンを使用して保護されたエンドポイントを呼び出します。**

  ```bash theme={null}
  curl http://localhost:8080/api/private \
    --header 'Authorization: Bearer YOUR_ACCESS_TOKEN'
  ```
</Accordion>

<Accordion title="JWT クレームへのアクセス">
  エンドポイントで、追加のユーザー情報やトークンクレームにアクセスします。

  ```java theme={null}
  @GetMapping("/profile")
  public ResponseEntity<Map<String, Object>> getUserProfile(Authentication authentication) {
      Auth0AuthenticationToken auth0Token = (Auth0AuthenticationToken) authentication;
      Map<String, Object> claims = auth0Token.getAuthenticationContext().getClaims();

      return ResponseEntity.ok(Map.of(
          "userId", authentication.getName(),
          "email", claims.get("email"),
          "scope", claims.get("scope"),
          "issuer", claims.get("iss"),
          "audience", claims.get("aud")
      ));
  }
  ```
</Accordion>

<Accordion title="スコープベースの認可">
  セキュリティをさらに強化するために、JWT スコープを使用したきめ細かなアクセス制御を実装します。

  **1. Auth0 API でスコープを定義します。**

  [Auth0 Dashboard](https://manage.auth0.com) → APIs → Your API → Permissions で、スコープを追加します。

  * `read:users` - ユーザーデータの読み取り
  * `write:users` - ユーザーデータの書き込み
  * `admin` - 管理者アクセス

  **2. 認可ポリシーを設定します。**

  ```java theme={null}
  @Configuration
  public class SecurityConfig {
      @Bean
      SecurityFilterChain apiSecurity(HttpSecurity http, Auth0AuthenticationFilter authFilter) throws Exception {
          return http
              .csrf(csrf -> csrf.disable())
              .sessionManagement(s -> s.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
              .authorizeHttpRequests(auth -> auth
                  .requestMatchers("/api/admin/**").hasAuthority("SCOPE_admin")
                  .requestMatchers("/api/users/**").hasAnyAuthority("SCOPE_read:users", "SCOPE_write:users")
                  .requestMatchers("/api/private").authenticated()
                  .anyRequest().permitAll())
              .addFilterBefore(authFilter, UsernamePasswordAuthenticationFilter.class)
              .build();
      }
  }
  ```

  アクセストークンをリクエストする際は、必要なスコープを含めます。

  ```bash theme={null}
  curl --request POST \
    --url https://YOUR_DOMAIN/oauth/token \
    --header 'content-type: application/json' \
    --data '{"client_id":"YOUR_CLIENT_ID","client_secret":"YOUR_CLIENT_SECRET","audience":"YOUR_AUDIENCE","grant_type":"client_credentials","scope":"read:users write:users admin"}'
  ```
</Accordion>

<Accordion title="DPoPによるセキュリティ強化">
  アクセストークンを暗号鍵に関連付けてトークンのセキュリティを強化するため、DPoP (Demonstration of Proof-of-Possession) を有効にします。

  **application.yml で DPoP サポートを設定します。**

  ```yaml theme={null}
  auth0:
    domain: "your-tenant.auth0.com"
    audience: "https://my-springboot-api"
    dpopMode: ALLOWED # DISABLED、ALLOWED（デフォルト）、REQUIRED
    dpopIatOffsetSeconds: 300 # 5分（デフォルト）
    dpopIatLeewaySeconds: 60 # 1分の許容時間（デフォルト: 30秒）
  ```

  **DPoP モード:**

  * `ALLOWED` (デフォルト) : Bearer トークンと DPoP トークンの両方を受け入れます
  * `REQUIRED`: DPoP トークンのみを受け入れ、Bearer トークンは拒否します
  * `DISABLED`: 標準の JWT Bearer 検証のみ

      <Info>
        DPoP の詳細については、[Auth0 DPoP Documentation](https://auth0.com/docs/secure/sender-constraining/demonstrating-proof-of-possession-dpop) を参照してください。
      </Info>
</Accordion>

***

<div id="common-issues">
  ## よくある問題
</div>

<AccordionGroup>
  <Accordion title="401 Unauthorized - 無効なオーディエンス">
    **問題:** 有効なトークンを使用していても、API から 401 が返されます。

    **解決策:** `auth0.audience` が Auth0 API 識別子と完全に一致していることを確認してください。トークン内の audience クレームは、この値と一致している必要があります。

    ```yaml theme={null}
    # ❌ 誤り
    auth0:
      audience: "my-api"

    # ✅ 正しい
    auth0:
      audience: "https://my-springboot-api"
    ```
  </Accordion>

  <Accordion title="401 Unauthorized - 無効な発行元">
    **問題:** トークンの発行元の検証に失敗します。

    **解決策:** ドメインが正しく、`https://` が含まれていないことを確認してください。`https://` プレフィックスなしのドメインを使用します。

    ```yaml theme={null}
    # ❌ 誤り
    auth0:
      domain: "https://your-tenant.auth0.com"

    # ✅ 正しい
    auth0:
      domain: "your-tenant.auth0.com"
    ```
  </Accordion>

  <Accordion title="設定値が見つかりません">
    **問題:** 設定エラーにより、アプリケーションの起動に失敗します。

    **解決策:** `application.yml` の構造とプロパティ名を確認してください。auth0 セクションにドメインとオーディエンスの値が含まれていることを確認します。

    ```yaml theme={null}
    # ✅ 正しい構造
    auth0:
      domain: "your-tenant.auth0.com"
      audience: "https://your-api-identifier"

    spring:
      application:
        name: auth0-api
    ```
  </Accordion>

  <Accordion title="フィルター順序の問題">
    **問題:** 設定が正しいにもかかわらず、認証が機能しません。

    **解決策:** Auth0AuthenticationFilter が Spring Security チェーンに適切に組み込まれていることを確認してください。フィルターは UsernamePasswordAuthenticationFilter より前に追加する必要があります。

    ```java theme={null}
    // ✅ 正しいフィルター順序
    .addFilterBefore(authFilter, UsernamePasswordAuthenticationFilter.class)
    ```
  </Accordion>

  <Accordion title="ネットワーク接続の問題">
    **問題:** JWKS の取得に失敗するか、接続タイムアウトが発生します。

    **解決策:** 企業のファイアウォールが Auth0 エンドポイントをブロックしている可能性があります。HTTPS アクセス用に Auth0 ドメインを許可リストに追加してください。

    ```bash theme={null}
    # 必要なファイアウォールルール（アウトバウンド HTTPS/443）
    *.auth0.com
    *.us.auth0.com  # US リージョンのテナント用
    *.eu.auth0.com  # EU リージョンのテナント用
    *.au.auth0.com  # AU リージョンのテナント用
    ```
  </Accordion>

  <Accordion title="認可ポリシーで Scopes が機能しない">
    **問題:** スコープベースの認可ポリシーが常に失敗します。

    **解決策:** アクセストークンに必要なスコープが含まれていることを確認してください。トークンをリクエストするときは、スコープを指定します。

    ```bash theme={null}
    curl --request POST \
      --url https://YOUR_DOMAIN/oauth/token \
      --data '{"client_id":"...","client_secret":"...","audience":"...","grant_type":"client_credentials","scope":"read:users write:users admin"}'
    ```

    また、Auth0 API の設定でスコープが定義されていることも確認してください (Dashboard → APIs → Your API → Permissions) 。
  </Accordion>
</AccordionGroup>

***

<div id="additional-resources">
  ## 追加リソース
</div>

<CardGroup cols={3}>
  <Card title="SDK ドキュメント" icon="book" href="https://github.com/auth0/auth0-auth-java/tree/main/auth0-springboot-api">
    SDK の完全なドキュメントと API リファレンス
  </Card>

  <Card title="コード例" icon="code" href="https://github.com/auth0/auth0-auth-java/blob/main/auth0-springboot-api/EXAMPLES.md">
    包括的なコード例と統合パターン
  </Card>

  <Card title="DPoP ドキュメント" icon="shield" href="https://auth0.com/docs/secure/sender-constraining/demonstrating-proof-of-possession-dpop">
    proof-of-possession によるセキュリティ強化について確認する
  </Card>

  <Card title="Spring Security リファレンス" icon="book" href="https://docs.spring.io/spring-security/reference/">
    Spring Security の公式ドキュメント
  </Card>

  <Card title="Auth0 Dashboard" icon="settings" href="https://manage.auth0.com/">
    Auth0 の API とアプリケーションを管理する
  </Card>

  <Card title="コミュニティフォーラム" icon="comments" href="https://community.auth0.com/">
    Auth0 コミュニティからサポートを受ける
  </Card>
</CardGroup>

***

<div id="sample-application">
  ## サンプルアプリケーション
</div>

すべての機能を実演する完全なサンプルアプリケーションが、SDK リポジトリで公開されています。

<Card title="プレイグラウンドアプリケーション" icon="github" href="https://github.com/auth0/auth0-auth-java/tree/main/auth0-springboot-api-playground">
  公開エンドポイントと保護されたエンドポイント、DPoP サポート、および包括的な
  サンプルが含まれています
</Card>

クローンして実行します:

```bash theme={null}
git clone https://github.com/auth0/auth0-auth-java.git
cd auth0-auth-java/auth0-springboot-api-playground

# Auth0の設定でsrc/main/resources/application.ymlを更新してください
# 次に実行してください:
./mvnw spring-boot:run
```

**curl でのテスト:**

```bash theme={null}
# 公開エンドポイントをテスト
curl http://localhost:8080/api/public

# アクセストークンを取得（Auth0の認証情報に置き換えてください）
curl -X POST https://YOUR_DOMAIN/oauth/token \
  -H "Content-Type: application/json" \
  -d '{
    "client_id": "YOUR_CLIENT_ID",
    "client_secret": "YOUR_CLIENT_SECRET",
    "audience": "https://my-springboot-api",
    "grant_type": "client_credentials"
  }'

# Bearerトークンを使用して保護されたエンドポイントをテスト
curl -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
     http://localhost:8080/api/private
```
