> ## Documentation Index
> Fetch the complete documentation index at: https://auth0-docs-event-stream-action-templates.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Java Servletアプリケーションにログインを追加する

> このガイドは、新規または既存のJava ServletアプリケーションにAuth0を統合する方法を説明します。

export const AuthCodeGroup = ({children, dropdown}) => {
  const [processedChildren, setProcessedChildren] = useState(children);
  useEffect(() => {
    let unsubscribe = null;
    function init() {
      unsubscribe = window.autorun(() => {
        const processChildren = node => {
          if (typeof node === "string") {
            let processedNode = node;
            for (const [key, value] of window.rootStore.variableStore.values.entries()) {
              const escapedKey = key.replaceAll(/[.*+?^${}()|[\]\\]/g, (String.raw)`\$&`);
              processedNode = processedNode.replaceAll(new RegExp(escapedKey, "g"), value);
            }
            return processedNode;
          } else if (Array.isArray(node)) {
            return node.map(processChildren);
          } else if (node && node.props && node.props.children) {
            return {
              ...node,
              props: {
                ...node.props,
                children: processChildren(node.props.children)
              }
            };
          }
          return node;
        };
        setProcessedChildren(processChildren(children));
      });
    }
    if (window.rootStore) {
      init();
    } else {
      window.addEventListener("adu:storeReady", init);
    }
    return () => {
      window.removeEventListener("adu:storeReady", init);
      unsubscribe?.();
    };
  }, [children]);
  return <CodeGroup dropdown={dropdown}>{processedChildren}</CodeGroup>;
};

export const QuickstartButtons = ({githubLink, lang = "en"}) => {
  const translations = {
    en: {
      viewOnGithub: "View On GitHub",
      loginAndDownload: "Download Sample"
    },
    "fr-ca": {
      viewOnGithub: "Afficher sur GitHub",
      loginAndDownload: "Télécharger un exemple"
    },
    "ja-jp": {
      viewOnGithub: "Githubで表示",
      loginAndDownload: "サンプルをダウンロード"
    }
  };
  const text = translations[lang] || translations.en;
  const parseGithubUrl = url => {
    try {
      const urlObj = new URL(url);
      const pathParts = urlObj.pathname.split("/").filter(Boolean);
      if (pathParts.length >= 4 && pathParts[2] === "tree") {
        const repoName = pathParts[1];
        const branch = pathParts[3];
        const path = pathParts.slice(4).join("/") || undefined;
        return {
          repo: repoName,
          branch,
          path
        };
      }
      console.warn("Could not parse GitHub URL:", url);
      return null;
    } catch (error) {
      console.error("Error parsing GitHub URL:", error);
      return null;
    }
  };
  const handleDownload = async () => {
    const params = parseGithubUrl(githubLink);
    if (!params) {
      console.error("Invalid GitHub URL format");
      return;
    }
    try {
      await window.Auth0DocsUI?.getSample(params);
    } catch (error) {
      console.error("Failed to download sample:", error);
    }
  };
  return <div className="quickstart_buttons flex flex-wrap gap-3 mb-4">
      <a href={githubLink} target="_blank" rel="noopener noreferrer" className="no_external_icon quickstart_button inline-flex items-center justify-center px-6 py-3 text-sm font-medium rounded-[18px] bg-black dark:bg-white !text-white dark:!text-black hover:bg-gray-800 dark:hover:bg-gray-100 transition-colors">
        {text.viewOnGithub}
      </a>
      <button onClick={handleDownload} type="button" className="no_external_icon quickstart_button inline-flex items-center justify-center px-6 py-3 text-sm font-medium rounded-[18px] border border-gray-300 dark:border-[#454545] bg-white dark:bg-[#272728] !text-black dark:!text-white hover:bg-gray-50 dark:hover:bg-neutral-800 transition-colors">
        {text.loginAndDownload}
      </button>
    </div>;
};

export const LoggedInForm = ({sampleApp}) => {
  const LS_APPS_KEY = "auth_demo_apps";
  const LS_APP_CFG_KEY = "auth_demo_app_cfg";
  const CHANNEL = "auth_flows_sync_v1";
  const mkChannel = () => new BroadcastChannel(CHANNEL);
  function uid() {
    return Math.random().toString(36).slice(2) + Date.now().toString(36);
  }
  function loadApps() {
    const raw = localStorage.getItem(LS_APPS_KEY);
    if (raw) return JSON.parse(raw);
    const seeded = [{
      id: "{yourClientId}",
      name: "Default App"
    }];
    localStorage.setItem(LS_APPS_KEY, JSON.stringify(seeded));
    return seeded;
  }
  function saveApps(apps) {
    localStorage.setItem(LS_APPS_KEY, JSON.stringify(apps));
  }
  function loadCfg() {
    const raw = localStorage.getItem(LS_APP_CFG_KEY);
    return raw ? JSON.parse(raw) : {};
  }
  function saveCfg(cfg) {
    localStorage.setItem(LS_APP_CFG_KEY, JSON.stringify(cfg));
  }
  const RightChevron = ({className = "w-5 h-5", ...props}) => <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" stroke="currentColor" fill="none" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className={className} {...props}>
      <polyline points="9 18 15 12 9 6" />
    </svg>;
  const LightningIcon = () => <svg width="24" height="24" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg">
      <path fillRule="evenodd" clipRule="evenodd" className="fill-[#3F59E4] dark:fill-[#99A7F1]" d="M24.971 30.152H7.088c-1.786 0-2.745-2.103-1.574-3.453l19.07-21.988c1.33-1.532 3.835-.4 3.569 1.607L24.97 30.152z" />
      <path fillRule="evenodd" clipRule="evenodd" className="fill-[#3F59E4] dark:fill-[#99A7F1]" d="M23.201 17.885h17.885c1.787 0 2.746 2.102 1.575 3.453l-19.073 21.99c-1.33 1.532-3.835.4-3.568-1.607L23.2 17.885z" />
    </svg>;
  const LayersIcon = () => <svg width="24" height="24" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg">
      <path className="fill-[#3F59E4] dark:fill-[#99A7F1]" d="M34.54 29.135l6.373 3.183c1.566.782 1.566 3.017 0 3.8l-14.815 7.396a4.623 4.623 0 01-4.125 0L7.174 36.12c-1.565-.782-1.565-3.017 0-3.798l6.532-3.214" />
      <path className="fill-[#AAB6F3] dark:fill-[#3449BA]" d="M34.54 18.86l6.373 3.183c1.566.782 1.566 3.016 0 3.8L26.098 33.24a4.623 4.623 0 01-4.125 0L7.174 25.843c-1.565-.781-1.565-3.016 0-3.798l6.33-3.164" />
      <path className="fill-[#CFD6F8] dark:fill-[#22307C]" d="M21.94 23.058L7.306 15.745c-1.62-.81-1.62-3.123 0-3.932l14.631-7.319a4.693 4.693 0 014.194 0l14.648 7.319c1.622.81 1.62 3.124 0 3.932L26.13 23.058c-1.321.66-2.873.66-4.191 0z" />
    </svg>;
  const GithubIcon = () => <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className="w-5 h-5">
      <path d="M9 19c-5 1.5-5-2.5-7-3m14 6v-3.87a3.37 3.37 0 0 0-.94-2.61c3.14-.35 6.44-1.54 6.44-7A5.44 5.44 0 0 0 20 4.77 5.07 5.07 0 0 0 19.91 1S18.73.65 16 2.48a13.38 13.38 0 0 0-7 0C6.27.65 5.09 1 5.09 1A5.07 5.07 0 0 0 5 4.77a5.44 5.44 0 0 0-1.5 3.78c0 5.42 3.3 6.61 6.44 7A3.37 3.37 0 0 0 9 18.13V22"></path>
    </svg>;
  function IconTile({children}) {
    return <div className="
          shrink-0 grid place-items-center w-10 h-10 rounded-lg
          bg-indigo-50 ring-1 ring-indigo-200/60
          dark:bg-indigo-950/40 dark:ring-white/10
        ">
        {children}
      </div>;
  }
  function Card({className = "", children}) {
    return <div className={`rounded-2xl shadow-sm ring-1 ring-zinc-200 dark:ring-zinc-800 ${className}`}>{children}</div>;
  }
  function Button({variant = "primary", type = "button", onClick, children}) {
    const base = "inline-flex items-center justify-center gap-2 h-10 px-4 rounded-xl font-medium transition";
    let styles = "";
    if (variant === "primary") {
      styles = "mint-bg-indigo-600 text-white hover:mint-bg-indigo-700";
    } else if (variant === "outline") {
      styles = "border border-zinc-300 dark:border-zinc-700 mint-bg-transparent hover:mint-bg-zinc-50 dark:hover:mint-bg-zinc-800";
    } else if (variant === "ghost") {
      styles = "hover:mint-bg-zinc-100 dark:hover:mint-bg-zinc-800";
    }
    return <button type={type} onClick={onClick} className={`${base} ${styles}`}>
        {children}
      </button>;
  }
  function Input({id, label, value, onChange, placeholder, name}) {
    return <label className="block space-y-1">
        <span className="text-sm text-zinc-700 dark:text-zinc-300">{label}</span>
        <input id={id} name={name} className="w-full h-11 px-3 rounded-xl border border-zinc-300 dark:border-zinc-700 bg-white dark:bg-zinc-900 text-zinc-900 dark:text-zinc-100 focus:outline-none focus:ring-2 focus:ring-indigo-500" placeholder={placeholder} value={value} onChange={e => onChange(e.target.value)} />
      </label>;
  }
  function Select({label, value, onChange, options}) {
    return <label className="block space-y-1 max-w-[300px]">
        <span className="text-sm text-zinc-700 dark:text-zinc-300">{label}</span>
        <div className="relative">
          <select className="w-full h-11 appearance-none px-3 pr-9 rounded-xl border border-zinc-300 dark:border-zinc-700 bg-white dark:bg-zinc-900 text-zinc-900 dark:text-zinc-100 focus:outline-none focus:ring-2 focus:ring-indigo-500" value={value} onChange={e => onChange(e.target.value)}>
            <optgroup label="Generic Applications">
              {options.map(o => <option key={o.id} value={o.id}>
                  {o.name}
                </option>)}
            </optgroup>
          </select>
          <svg className="pointer-events-none absolute right-3 top-1/2 -translate-y-1/2 w-5 h-5 text-zinc-500" viewBox="0 0 24 24">
            <path d="M7 10l5 5 5-5z" fill="currentColor" />
          </svg>
        </div>
      </label>;
  }
  function Toast({open, onClose, children}) {
    useEffect(() => {
      if (!open) return;
      const t = setTimeout(onClose, 2200);
      return () => clearTimeout(t);
    }, [open, onClose]);
    return <div className={`fixed right-4 top-4 z-50 transition ${open ? "opacity-100 translate-y-0" : "opacity-0 -translate-y-2 pointer-events-none"}`}>
        <div className="flex items-center gap-2 rounded-xl shadow ring-1 ring-emerald-200 bg-white dark:bg-zinc-900 px-4 py-2">
          <span className="w-1.5 h-8 rounded-l bg-emerald-500" />
          <svg className="w-5 h-5 text-emerald-600" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
            <path d="M20 6L9 17l-5-5" />
          </svg>
          <span className="text-sm text-zinc-900 dark:text-zinc-100">{children}</span>
        </div>
      </div>;
  }
  function Flows() {
    const [route, setRoute] = useState("menu");
    const [apps, setApps] = useState(loadApps());
    const [cfg, setCfg] = useState(loadCfg());
    const [selected, setSelected] = useState(apps[0]?.id || "");
    const [toast, setToast] = useState(false);
    const [bc] = useState(() => mkChannel());
    useEffect(() => {
      if (!apps.find(a => a.id === selected)) {
        setSelected(apps[0]?.id || "");
      }
    }, [apps, selected]);
    useEffect(() => {
      const onMsg = e => {
        const {type, payload} = e.data || ({});
        switch (type) {
          case "NAV":
            setRoute(payload.route);
            break;
          case "SELECT":
            setSelected(payload.appId);
            break;
          case "APPS_UPDATED":
            setApps(loadApps());
            break;
          case "CFG_UPDATED":
            setCfg(loadCfg());
            setToast(true);
            break;
          default:
            break;
        }
      };
      bc.addEventListener("message", onMsg);
      return () => bc.removeEventListener("message", onMsg);
    }, [bc]);
    const nav = nextRoute => {
      setRoute(nextRoute);
      bc.postMessage({
        type: "NAV",
        payload: {
          route: nextRoute
        }
      });
    };
    const selectApp = appId => {
      setSelected(appId);
      bc.postMessage({
        type: "SELECT",
        payload: {
          appId
        }
      });
    };
    const onCreate = name => {
      const id = uid();
      const next = [...apps, {
        id,
        name: name || "Untitled"
      }];
      setApps(next);
      saveApps(next);
      bc.postMessage({
        type: "APPS_UPDATED"
      });
      selectApp(id);
      nav("integrate");
    };
    const onSaveCfg = (appId, data) => {
      const next = {
        ...cfg,
        [appId]: data
      };
      setCfg(next);
      saveCfg(next);
      setToast(true);
      bc.postMessage({
        type: "CFG_UPDATED"
      });
    };
    return <div>
        {route === "menu" && <Menu onCreate={() => nav("create")} onIntegrate={() => nav("integrate")} />}

        {route === "create" && <CreateForm onCancel={() => nav("menu")} onSave={onCreate} />}

        {route === "integrate" && <IntegrateForm apps={apps} selected={selected} onSelect={selectApp} saved={cfg[selected]} onSave={data => onSaveCfg(selected, data)} onCancel={() => nav("menu")} />}

        <Toast open={toast} onClose={() => setToast(false)}>
          Successfully saved your changes.
        </Toast>
      </div>;
  }
  function Menu({onCreate, onIntegrate}) {
    return <ul className="space-y-4 list-none login_list">
        <li className="list-none !px-0">
          <button onClick={onCreate} className="w-full text-left">
            <Card className="p-5 hover:shadow-md transition">
              <div className="flex items-center justify-between">
                <div className="flex items-center gap-4">
                  <IconTile>
                    <LightningIcon />
                  </IconTile>
                  <h2 className="text-lg">Create a new application</h2>
                </div>
                <RightChevron className="w-4 h-4 text-zinc-500" />
              </div>
            </Card>
          </button>
        </li>
        <li className="list-none !px-0">
          <button onClick={onIntegrate} className="w-full text-left">
            <Card className="p-5 hover:shadow-md transition">
              <div className="flex items-center justify-between">
                <div className="flex items-center gap-4">
                  <IconTile>
                    <LayersIcon />
                  </IconTile>
                  <h2 className="text-lg">Integrate with an existing application</h2>
                </div>
                <RightChevron className="w-4 h-4 text-zinc-500" />
              </div>
            </Card>
          </button>
        </li>
        <li className="list-none !px-0">
          <a className="no_external_icon block" href={sampleApp ? sampleApp : "/"} target="_blank" rel="noreferrer">
            <Card className="p-5 hover:shadow-md transition">
              <div className="flex items-center justify-between">
                <div className="flex items-center gap-4">
                  <IconTile>
                    <GithubIcon />
                  </IconTile>
                  <h2 className="text-lg">View a sample application</h2>
                </div>
                <RightChevron className="w-4 h-4 text-zinc-500" />
              </div>
            </Card>
          </a>
        </li>
      </ul>;
  }
  function CreateForm({onSave, onCancel}) {
    const [name, setName] = useState("");
    return <div className="space-y-6">
        <Input id="app-name" label="Application Name" placeholder="My App" value={name} onChange={setName} />
        <p className="text-sm text-zinc-500">You can change this later in the application settings.</p>
        <div className="flex gap-3">
          <Button onClick={() => onSave(name)}>Save</Button>
          <Button variant="outline" onClick={onCancel}>
            Cancel
          </Button>
        </div>
      </div>;
  }
  function IntegrateForm({apps, selected, onSelect, saved, onSave, onCancel}) {
    const [callbacks, setCallbacks] = useState(saved?.callbacks ?? "");
    const [logouts, setLogouts] = useState(saved?.logouts ?? "");
    const [origins, setOrigins] = useState(saved?.origins ?? "");
    useEffect(() => {
      setCallbacks(loadCfg()[selected]?.callbacks ?? "");
      setLogouts(loadCfg()[selected]?.logouts ?? "");
      setOrigins(loadCfg()[selected]?.origins ?? "");
    }, [selected]);
    return <div className="space-y-6">
        <div>
          <span className="block text-sm text-zinc-600 dark:text-zinc-300 mb-1">Select your Application</span>
          <Select label="" value={selected} onChange={onSelect} options={apps} />
        </div>

        <form className="space-y-4" onSubmit={e => {
      e.preventDefault();
      onSave({
        callbacks,
        logouts,
        origins
      });
    }}>
          <Input id="callbacks" name="callbacks" label="Callback URLs" placeholder="http://localhost:3000" value={callbacks} onChange={setCallbacks} />
          <Input id="logout" name="allowed_logout_urls" label="Logout URLs" placeholder="http://localhost:3000" value={logouts} onChange={setLogouts} />
          <Input id="origins" name="web_origins" label="Allowed Web Origins" placeholder="http://localhost:3000" value={origins} onChange={setOrigins} />

          <div className="flex gap-3 pt-2">
            <Button type="submit">Save</Button>
            <Button variant="outline" type="button" onClick={onCancel}>
              Cancel
            </Button>
          </div>
        </form>
      </div>;
  }
  return <div className="w-full mx-auto py-8">
      <Flows />
    </div>;
};

export const SignUpForm = () => {
  const [isAuthenticated, setIsAuthenticated] = useState(false);
  const [storeReady, setStoreReady] = useState(false);
  useEffect(() => {
    let unsubscribe = null;
    function init() {
      setStoreReady(true);
      unsubscribe = window.autorun(() => {
        const authenticated = window.rootStore?.sessionStore?.isAuthenticated || false;
        setIsAuthenticated(authenticated);
      });
    }
    if (window.rootStore) {
      init();
    } else {
      window.addEventListener("adu:storeReady", init);
    }
    return () => {
      window.removeEventListener("adu:storeReady", init);
      unsubscribe?.();
    };
  }, []);
  function LoggedInForm({sampleApp}) {
    const LS_APPS_KEY = "auth_demo_apps";
    const LS_APP_CFG_KEY = "auth_demo_app_cfg";
    const CHANNEL = "auth_flows_sync_v1";
    const mkChannel = () => new BroadcastChannel(CHANNEL);
    function uid() {
      return Math.random().toString(36).slice(2) + Date.now().toString(36);
    }
    function loadApps() {
      const raw = localStorage.getItem(LS_APPS_KEY);
      if (raw) return JSON.parse(raw);
      const seeded = [{
        id: "{yourClientId}",
        name: "Default App"
      }];
      localStorage.setItem(LS_APPS_KEY, JSON.stringify(seeded));
      return seeded;
    }
    function saveApps(apps) {
      localStorage.setItem(LS_APPS_KEY, JSON.stringify(apps));
    }
    function loadCfg() {
      const raw = localStorage.getItem(LS_APP_CFG_KEY);
      return raw ? JSON.parse(raw) : {};
    }
    function saveCfg(cfg) {
      localStorage.setItem(LS_APP_CFG_KEY, JSON.stringify(cfg));
    }
    const RightChevron = ({className = "w-5 h-5", ...props}) => <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" stroke="currentColor" fill="none" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className={className} {...props}>
        <polyline points="9 18 15 12 9 6" />
      </svg>;
    const LightningIcon = () => <svg width="24" height="24" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg">
        <path fillRule="evenodd" clipRule="evenodd" className="fill-[#3F59E4] dark:fill-[#99A7F1]" d="M24.971 30.152H7.088c-1.786 0-2.745-2.103-1.574-3.453l19.07-21.988c1.33-1.532 3.835-.4 3.569 1.607L24.97 30.152z" />
        <path fillRule="evenodd" clipRule="evenodd" className="fill-[#3F59E4] dark:fill-[#99A7F1]" d="M23.201 17.885h17.885c1.787 0 2.746 2.102 1.575 3.453l-19.073 21.99c-1.33 1.532-3.835.4-3.568-1.607L23.2 17.885z" />
      </svg>;
    const LayersIcon = () => <svg width="24" height="24" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg">
        <path className="fill-[#3F59E4] dark:fill-[#99A7F1]" d="M34.54 29.135l6.373 3.183c1.566.782 1.566 3.017 0 3.8l-14.815 7.396a4.623 4.623 0 01-4.125 0L7.174 36.12c-1.565-.782-1.565-3.017 0-3.798l6.532-3.214" />
        <path className="fill-[#AAB6F3] dark:fill-[#3449BA]" d="M34.54 18.86l6.373 3.183c1.566.782 1.566 3.016 0 3.8L26.098 33.24a4.623 4.623 0 01-4.125 0L7.174 25.843c-1.565-.781-1.565-3.016 0-3.798l6.33-3.164" />
        <path className="fill-[#CFD6F8] dark:fill-[#22307C]" d="M21.94 23.058L7.306 15.745c-1.62-.81-1.62-3.123 0-3.932l14.631-7.319a4.693 4.693 0 014.194 0l14.648 7.319c1.622.81 1.62 3.124 0 3.932L26.13 23.058c-1.321.66-2.873.66-4.191 0z" />
      </svg>;
    const GithubIcon = () => <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className="w-5 h-5">
        <path d="M9 19c-5 1.5-5-2.5-7-3m14 6v-3.87a3.37 3.37 0 0 0-.94-2.61c3.14-.35 6.44-1.54 6.44-7A5.44 5.44 0 0 0 20 4.77 5.07 5.07 0 0 0 19.91 1S18.73.65 16 2.48a13.38 13.38 0 0 0-7 0C6.27.65 5.09 1 5.09 1A5.07 5.07 0 0 0 5 4.77a5.44 5.44 0 0 0-1.5 3.78c0 5.42 3.3 6.61 6.44 7A3.37 3.37 0 0 0 9 18.13V22"></path>
      </svg>;
    function IconTile({children}) {
      return <div className="
            shrink-0 grid place-items-center w-10 h-10 rounded-lg
            bg-indigo-50 ring-1 ring-indigo-200/60
            dark:bg-indigo-950/40 dark:ring-white/10
          ">
          {children}
        </div>;
    }
    function Card({className = "", children}) {
      return <div className={`rounded-2xl shadow-sm ring-1 ring-zinc-200 dark:ring-zinc-800 ${className}`}>{children}</div>;
    }
    function Button({variant = "primary", type = "button", onClick, children}) {
      const base = "inline-flex items-center justify-center gap-2 h-10 px-4 rounded-xl font-medium transition";
      let styles = "";
      if (variant === "primary") {
        styles = "mint-bg-indigo-600 text-white hover:mint-bg-indigo-700";
      } else if (variant === "outline") {
        styles = "border border-zinc-300 dark:border-zinc-700 mint-bg-transparent hover:mint-bg-zinc-50 dark:hover:mint-bg-zinc-800";
      } else if (variant === "ghost") {
        styles = "hover:mint-bg-zinc-100 dark:hover:mint-bg-zinc-800";
      }
      return <button type={type} onClick={onClick} className={`${base} ${styles}`}>
          {children}
        </button>;
    }
    function Input({id, label, value, onChange, placeholder, name}) {
      return <label className="block space-y-1">
          <span className="text-sm text-zinc-700 dark:text-zinc-300">{label}</span>
          <input id={id} name={name} className="w-full h-11 px-3 rounded-xl border border-zinc-300 dark:border-zinc-700 bg-white dark:bg-zinc-900 text-zinc-900 dark:text-zinc-100 focus:outline-none focus:ring-2 focus:ring-indigo-500" placeholder={placeholder} value={value} onChange={e => onChange(e.target.value)} />
        </label>;
    }
    function Select({label, value, onChange, options}) {
      return <label className="block space-y-1 max-w-[300px]">
          <span className="text-sm text-zinc-700 dark:text-zinc-300">{label}</span>
          <div className="relative">
            <select className="w-full h-11 appearance-none px-3 pr-9 rounded-xl border border-zinc-300 dark:border-zinc-700 bg-white dark:bg-zinc-900 text-zinc-900 dark:text-zinc-100 focus:outline-none focus:ring-2 focus:ring-indigo-500" value={value} onChange={e => onChange(e.target.value)}>
              <optgroup label="Generic Applications">
                {options.map(o => <option key={o.id} value={o.id}>
                    {o.name}
                  </option>)}
              </optgroup>
            </select>
            <svg className="pointer-events-none absolute right-3 top-1/2 -translate-y-1/2 w-5 h-5 text-zinc-500" viewBox="0 0 24 24">
              <path d="M7 10l5 5 5-5z" fill="currentColor" />
            </svg>
          </div>
        </label>;
    }
    function Toast({open, onClose, children}) {
      useEffect(() => {
        if (!open) return;
        const t = setTimeout(onClose, 2200);
        return () => clearTimeout(t);
      }, [open, onClose]);
      return <div className={`fixed right-4 top-4 z-50 transition ${open ? "opacity-100 translate-y-0" : "opacity-0 -translate-y-2 pointer-events-none"}`}>
          <div className="flex items-center gap-2 rounded-xl shadow ring-1 ring-emerald-200 bg-white dark:bg-zinc-900 px-4 py-2">
            <span className="w-1.5 h-8 rounded-l bg-emerald-500" />
            <svg className="w-5 h-5 text-emerald-600" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
              <path d="M20 6L9 17l-5-5" />
            </svg>
            <span className="text-sm text-zinc-900 dark:text-zinc-100">{children}</span>
          </div>
        </div>;
    }
    function Flows() {
      const [route, setRoute] = useState("menu");
      const [apps, setApps] = useState(loadApps());
      const [cfg, setCfg] = useState(loadCfg());
      const [selected, setSelected] = useState(apps[0]?.id || "");
      const [toast, setToast] = useState(false);
      const [bc] = useState(() => mkChannel());
      useEffect(() => {
        if (!apps.find(a => a.id === selected)) {
          setSelected(apps[0]?.id || "");
        }
      }, [apps, selected]);
      useEffect(() => {
        const onMsg = e => {
          const {type, payload} = e.data || ({});
          switch (type) {
            case "NAV":
              setRoute(payload.route);
              break;
            case "SELECT":
              setSelected(payload.appId);
              break;
            case "APPS_UPDATED":
              setApps(loadApps());
              break;
            case "CFG_UPDATED":
              setCfg(loadCfg());
              setToast(true);
              break;
            default:
              break;
          }
        };
        bc.addEventListener("message", onMsg);
        return () => bc.removeEventListener("message", onMsg);
      }, [bc]);
      const nav = nextRoute => {
        setRoute(nextRoute);
        bc.postMessage({
          type: "NAV",
          payload: {
            route: nextRoute
          }
        });
      };
      const selectApp = appId => {
        setSelected(appId);
        bc.postMessage({
          type: "SELECT",
          payload: {
            appId
          }
        });
      };
      const onCreate = name => {
        const id = uid();
        const next = [...apps, {
          id,
          name: name || "Untitled"
        }];
        setApps(next);
        saveApps(next);
        bc.postMessage({
          type: "APPS_UPDATED"
        });
        selectApp(id);
        nav("integrate");
      };
      const onSaveCfg = (appId, data) => {
        const next = {
          ...cfg,
          [appId]: data
        };
        setCfg(next);
        saveCfg(next);
        setToast(true);
        bc.postMessage({
          type: "CFG_UPDATED"
        });
      };
      return <div>
          {route === "menu" && <Menu onCreate={() => nav("create")} onIntegrate={() => nav("integrate")} />}

          {route === "create" && <CreateForm onCancel={() => nav("menu")} onSave={onCreate} />}

          {route === "integrate" && <IntegrateForm apps={apps} selected={selected} onSelect={selectApp} saved={cfg[selected]} onSave={data => onSaveCfg(selected, data)} onCancel={() => nav("menu")} />}

          <Toast open={toast} onClose={() => setToast(false)}>
            Successfully saved your changes.
          </Toast>
        </div>;
    }
    function Menu({onCreate, onIntegrate}) {
      return <ul className="space-y-4 list-none login_list">
          <li className="list-none !px-0">
            <button onClick={onCreate} className="w-full text-left">
              <Card className="p-5 hover:shadow-md transition">
                <div className="flex items-center justify-between">
                  <div className="flex items-center gap-4">
                    <IconTile>
                      <LightningIcon />
                    </IconTile>
                    <h2 className="text-lg">Create a new application</h2>
                  </div>
                  <RightChevron className="w-4 h-4 text-zinc-500" />
                </div>
              </Card>
            </button>
          </li>
          <li className="list-none !px-0">
            <button onClick={onIntegrate} className="w-full text-left">
              <Card className="p-5 hover:shadow-md transition">
                <div className="flex items-center justify-between">
                  <div className="flex items-center gap-4">
                    <IconTile>
                      <LayersIcon />
                    </IconTile>
                    <h2 className="text-lg">Integrate with an existing application</h2>
                  </div>
                  <RightChevron className="w-4 h-4 text-zinc-500" />
                </div>
              </Card>
            </button>
          </li>
          <li className="list-none !px-0">
            <a className="no_external_icon block" href={sampleApp ? sampleApp : "/"} target="_blank" rel="noreferrer">
              <Card className="p-5 hover:shadow-md transition">
                <div className="flex items-center justify-between">
                  <div className="flex items-center gap-4">
                    <IconTile>
                      <GithubIcon />
                    </IconTile>
                    <h2 className="text-lg">View a sample application</h2>
                  </div>
                  <RightChevron className="w-4 h-4 text-zinc-500" />
                </div>
              </Card>
            </a>
          </li>
        </ul>;
    }
    function CreateForm({onSave, onCancel}) {
      const [name, setName] = useState("");
      return <div className="space-y-6">
          <Input id="app-name" label="Application Name" placeholder="My App" value={name} onChange={setName} />
          <p className="text-sm text-zinc-500">You can change this later in the application settings.</p>
          <div className="flex gap-3">
            <Button onClick={() => onSave(name)}>Save</Button>
            <Button variant="outline" onClick={onCancel}>
              Cancel
            </Button>
          </div>
        </div>;
    }
    function IntegrateForm({apps, selected, onSelect, saved, onSave, onCancel}) {
      const [callbacks, setCallbacks] = useState(saved?.callbacks ?? "");
      const [logouts, setLogouts] = useState(saved?.logouts ?? "");
      const [origins, setOrigins] = useState(saved?.origins ?? "");
      useEffect(() => {
        setCallbacks(loadCfg()[selected]?.callbacks ?? "");
        setLogouts(loadCfg()[selected]?.logouts ?? "");
        setOrigins(loadCfg()[selected]?.origins ?? "");
      }, [selected]);
      return <div className="space-y-6">
          <div>
            <span className="block text-sm text-zinc-600 dark:text-zinc-300 mb-1">Select your Application</span>
            <Select label="" value={selected} onChange={onSelect} options={apps} />
          </div>

          <form className="space-y-4" onSubmit={e => {
        e.preventDefault();
        onSave({
          callbacks,
          logouts,
          origins
        });
      }}>
            <Input id="callbacks" name="callbacks" label="Callback URLs" placeholder="http://localhost:3000" value={callbacks} onChange={setCallbacks} />
            <Input id="logout" name="allowed_logout_urls" label="Logout URLs" placeholder="http://localhost:3000" value={logouts} onChange={setLogouts} />
            <Input id="origins" name="web_origins" label="Allowed Web Origins" placeholder="http://localhost:3000" value={origins} onChange={setOrigins} />

            <div className="flex gap-3 pt-2">
              <Button type="submit">Save</Button>
              <Button variant="outline" type="button" onClick={onCancel}>
                Cancel
              </Button>
            </div>
          </form>
        </div>;
    }
    return <div className="w-full mx-auto py-8">
        <Flows />
      </div>;
  }
  ;
  function SignUpFormInternal() {
    return <div className="flex flex-col gap-2 items-center h-full">
        <img noZoom src="/docs/img/quickstarts/action_hero_dashboard.svg" alt="Sign up for an Auth0 account" style={{
      width: "250px",
      height: "250px"
    }} />
        <span className="text-center" style={{
      width: "400px"
    }}>
          Sign up for an{" "}
          <a href="https://auth0.com/signup" target="_blank" rel="noopener noreferrer">
            Auth0 account
          </a>{" "}
          or{" "}
          <span className="font-semibold text-primary dark:text-white cursor-pointer" onClick={() => console.log("log in")}>
            log in
          </span>{" "}
          to your existing account to integrate directly with your own tenant.
        </span>
        <button onClick={() => console.log("sign up")} className="bg-primary dark:bg-primary-light text-white dark:text-black px-4 py-2 rounded-md mt-4 font-medium" style={{
      width: "140px"
    }}>
          Sign up
        </button>
      </div>;
  }
  ;
  return <></>;
};

export const SideMenuSectionItem = ({id, children}) => {
  return <div id={`side-menu-item-${id}`} className="recipe-side-menu-item flex flex-col w-full h-full">
      {children}
    </div>;
};

export const SideMenu = ({sections, children}) => {
  const [visibleSection, setVisibleSection] = useState(sections[0]?.id ?? null);
  const checkVisibility = () => {
    let currentVisible = null;
    const viewportHeight = window.innerHeight;
    const scrollY = window.scrollY;
    sections.forEach(({id}) => {
      const section = document.getElementById(id);
      if (section) {
        const rect = section.getBoundingClientRect();
        const sectionTop = rect.top + scrollY;
        const sectionBottom = sectionTop + rect.height;
        const multiplier = viewportHeight > 1600 ? 0.34 : 0.22;
        if (scrollY + viewportHeight * multiplier >= sectionTop && scrollY <= sectionBottom) {
          currentVisible = id;
        }
      }
    });
    if (currentVisible && currentVisible !== visibleSection) {
      setVisibleSection(currentVisible);
    }
  };
  useEffect(() => {
    const throttledCheck = () => {
      setTimeout(checkVisibility, 100);
    };
    checkVisibility();
    window.addEventListener("scroll", throttledCheck);
    return () => {
      window.removeEventListener("scroll", throttledCheck);
    };
  }, [sections, visibleSection]);
  useEffect(() => {
    sections.forEach(({id}) => {
      const section = document.getElementById(id);
      const sideMenuItem = document.getElementById(`side-menu-item-${id}`);
      if (section) {
        if (id === visibleSection) {
          section.classList.add("active-section");
        } else {
          section.classList.remove("active-section");
        }
      }
      if (sideMenuItem) {
        if (id === visibleSection) {
          sideMenuItem.classList.add("active-side-menu-item");
        } else {
          sideMenuItem.classList.remove("active-side-menu-item");
        }
      }
    });
  }, [visibleSection, sections]);
  return <div className="recipe-side-menu sticky px-2 py-1" style={{
    height: "calc(100vh - 7rem)",
    top: "7rem",
    scrollMarginTop: "var(--scroll-mt)"
  }}>
      {children.map(child => {
    if (child.props.id === visibleSection) {
      return child;
    }
    return null;
  })}
    </div>;
};

export const Section = ({id, title, stepNumber, children, isSingleColumn = false}) => {
  return <div id={id} className={`recipe-section flex flex-col transition-opacity duration-200`}>
      {}
      <Step title={title} stepNumber={stepNumber} titleSize="h3">
        {children}
      </Step>
    </div>;
};

export const Content = ({title, children}) => {
  return <div className="recipe-content flex flex-col">
      {title && <h1 className="text-3xl">{title}</h1>}
      {children}
    </div>;
};

export const Recipe = ({children, isSingleColumn = false}) => {
  return <div className={`pl-4 recipe-container mx-auto grid grid-cols-1 gap-10 relative ${isSingleColumn ? "md:grid-cols-1" : "md:grid-cols-2"}`}>
      {children}
    </div>;
};

<QuickstartButtons githubLink="https://github.com/auth0-samples/auth0-servlet-sample/tree/master/01-Login" lang="ja-jp" />

export const sections = [{
  id: "auth0を構成する",
  title: "Auth0を構成する"
}, {
  id: "auth0をアプリケーションに統合する",
  title: "Auth0をアプリケーションに統合する"
}, {
  id: "javaアプリケーションを構成する",
  title: "Javaアプリケーションを構成する"
}, {
  id: "authenticationcontrollerを作成する",
  title: "AuthenticationControllerを作成する"
}, {
  id: "ログインにリダイレクトする",
  title: "ログインにリダイレクトする"
}, {
  id: "トークンの処理",
  title: "トークンの処理"
}, {
  id: "ホームページを表示する",
  title: "ホームページを表示する"
}, {
  id: "ログアウトを処理する",
  title: "ログアウトを処理する"
}, {
  id: "サンプルを実行する",
  title: "サンプルを実行する"
}];

<Recipe>
  <Content>
    Auth0を使用すると、アプリケーションに手軽に認証を追加して、ユーザープロファイル情報にアクセスすることができます。このガイドは、新規または既存のJava ServletアプリケーションにAuth0を統合する方法を説明します。

    <Section id={sections[0].id} title={sections[0].title} stepNumber="1">
      Auth0のサービスを利用するには、Auth0 Dashboadに設定済みのアプリケーションがある必要があります。Auth0アプリケーションは、開発中のプロジェクトに対してどのように認証が動作して欲しいかを構成する場所です。

      ### アプリケーションを構成する

      対話型のセレクターを使ってAuth0アプリケーションを新規作成するか、統合したいプロジェクトを表す既存のアプリケーションを選択します。Auth0のすべてのアプリケーションには英数字からなる一意のクライアントIDが割り当てられており、アプリケーションのコードがSDKを通じてAuth0
      APIを呼び出す際に使用されます。

      このクイックスタートを使って構成されたすべての設定は、[Dashboard](https://manage.auth0.com/#/)のアプリケーションを自動更新します。今後、アプリケーションの管理もDashboardで行えます。

      完了済みの構成を見てみたい場合は、サンプルアプリケーションをご覧ください。

      ### Callback URLを構成する

      Callback URLとは、Auth0がユーザーを認証後にリダイレクトするアプリケーション内URLです。設定されていない場合、ユーザーはログイン後にアプリケーションに戻りません。

      <Info>
        サンプルプロジェクトに沿って進めている場合は、`http://localhost:3000``/callback`に設定してください。
      </Info>

      ### ログアウトURLを構成する

      ログアウトURLとは、Auth0がユーザーをログアウト後にリダイレクトするアプリケーション内URLです。設定されていない場合、ユーザーはアプリケーションからログアウトできず、エラーを受け取ります。

      <Info>
        サンプルプロジェクトに沿って進めている場合は、`http://localhost:3000/logout`に設定してください。
      </Info>
    </Section>

    <Section id={sections[1].id} title={sections[1].title} stepNumber="2">
      ### 依存関係をセットアップする

      Auth0でJavaアプリケーションを統合するには、以下の依存関係を追加します：

      * **javax.servlet-api**
        ：Java Servletsの作成を許可するライブラリーです。TomcatやGrettyのようなサーバー依存関係を追加する必要があります。どれを追加するかは自己判断です。詳細はサンプルコードをご覧ください。
      * **auth0-java-mvc-commons** ：サーバー側のMVC Webアプリ用にJavaでAuth0の使用を許可する[Javaライブラリー](https://github.com/auth0/auth0-java-mvc-common)です。ユーザーを識別する[Auth0トークン](/docs/ja-jp/tokens)を最後に取得する過程で受け取った結果を認証、検証するために呼び出す必要のある認可URLを生成します。

      Gradleを使用している場合は、`build.gradle`に追加します：

      ```text lines theme={null}
      // build.gradle
      compile 'javax.servlet:javax.servlet-api:3.1.0'
      compile 'com.auth0:mvc-auth-commons:1.+'W
      ```

      Mavenを使用している場合は、`pom.xml`に追加します：

      ```xml lines theme={null}
      <!-- pom.xml -->
      <dependency>
      <groupId>com.auth0</groupId>
      <artifactId>mvc-auth-commons</artifactId>
      <version>[1.0, 2.0)</version>
      </dependency>
      <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>3.1.0</version>
      </dependency>
      ```
    </Section>

    <Section id={sections[2].id} title={sections[2].title} stepNumber="3">
      Javaアプリは、Auth0アカウントに対して認証するために、いくつかの情報を必要とします。サンプルではこの情報をデプロイメント記述子ファイル（`src/main/webapp/WEB-INF/web.xml`）から読み取っていますが、任意の場所に保存できます。

      この情報は**auth0-java-mvc-commons** ライブラリーを構成するために使用され、ユーザーがアプリケーションにログインすることを可能にします。ライブラリーや各構成オプションの詳細情報については、[ライブラリーのドキュメント](https://github.com/auth0/auth0-java-mvc-common/blob/master/README.md)をご覧ください。

      ### 入力された属性をチェックする

      このサンプルを\*\*［Download
      Sample（サンプルをダウンロード）］\*\*ボタンでダウンロードした場合は、`domain`、`clientId`、`clientSecret`属性が自動的に入力されます。特にアカウントに複数のAuth0アプリケーションがある場合は、値が正しいことを確認してください。

      ### プロジェクト構造

      **［Download Sample（サンプルをダウンロード）］** ボタンでダウンロードできるサンプルプロジェクトは以下の構造になっています：

      ```text lines theme={null}
      - src
      -- main
      ---- java
      ------ com
      -------- auth0
      ---------- example
      ------------ Auth0Filter.java
      ------------ AuthenticationControllerProvider.java
      ------------ HomeServlet.java
      ------------ CallbackServlet.java
      ------------ LoginServlet.java
      ------------ LogoutServlet.java
      ---- webapp
      ------ WEB-INF
      -------- jsp
      ---------- home.jsp
      -------- web.xml

      build.gradle
      ```

      プロジェクトには単一のJSPがあります：`home.jsp`は、ログイン成功後にユーザーに関連付けられたトークンを表示し、ログアウトオプションを提供します。

      プロジェクトはWebFilterを含みます：`Auth0Filter.java`は、保護された`/portal/*`パスへのユーザーアクセスを付与する前に、既存のトークンを確認します。トークンが存在しない場合、要求は`LoginServlet`へリダイレクトされます。

      プロジェクトにはサーブレットも4つあります：

      * `LoginServlet.java`：ユーザーがログインしようとした時に発動します。`client_id`パラメーターと`domain`パラメーターを使って有効な認可URLを作成し、ユーザーをリダイレクトします。
      * `CallbackServlet.java`：Callback
        URLへの要求をキャッチし、データを処理して資格情報を取得するサーブレットです。資格情報はログイン成功後、要求のHttpSessionに保存されます。
      * `HomeServlet.java`：以前保存されたトークンを読み取り、`home.jsp`リソースで表示するサーブレットです。
      * `LogoutServlet.java`：ユーザーがログアウトリンクをクリックすると発動します。ユーザーセッションを無効化し、`LoginServlet`でハンドリングされたログインページにユーザーをリダイレクトします。
      * `AuthenticationControllerProvider.java`：`AuthenticationController`の単一インスタンスを作成・管理するためのものです。
    </Section>

    <Section id={sections[3].id} title={sections[3].title} stepNumber="4">
      ユーザー認証を可能にするために、`domain`、`clientId`、`clientSecret`を使って`auth0-java-mvc-commons`
      SDKから提供された`AuthenticationController`のインスタンスを作成します。サンプルでは、RS256非対称署名アルゴリズムを使って署名したトークンで使用するためのコンポーネントの構成方法が紹介されています。トークンの署名を検証するために使用された公開鍵を取得する`JwkProvider`が指定されています。その他の構成オプションについての詳細は、[jwks-rsa-javaレポジトリ](https://github.com/auth0/jwks-rsa-java)をご覧ください。HS256を使用している場合は、`JwkProvider`を構成する必要はありません。

      <Info>
        `AuthenticationController`はコンテキストを一切保存せず、再使用を意図しています。不必要な作成はリソースの追加作成を招き、パフォーマンスに影響が出る可能性があります。
      </Info>
    </Section>

    <Section id={sections[4].id} title={sections[4].title} stepNumber="5">
      アプリケーションは、ユーザーがログインできるように、ユニバーサルログインページへリダイレクトします。`AuthenticationController`インスタンスを使うと、`buildAuthorizeUrl(HttpServletRequest request`、`HttpServletResponse response`、`String redirectUrl)`メソッドを呼び出すことでリダイレクトURLを生成できます。リダイレクトURLは、Auth0アプリケーションの\*\*［Allowed
      Callback URLs（許可されているコールバックURL）］\*\*に追加されたURLである必要があります。
    </Section>

    <Section id={sections[5].id} title={sections[5].title} stepNumber="6">
      ユーザーがログインした後、結果はGET要求またはPOST HTTP要求経由で`CallbackServlet`で受信されます。（初期設定として）Authorization Code
      Flowを使用しているため、GET要求が送信されます。ライブラリーを暗黙フロー用に構成している場合は、代わりにPOST要求が送信されます。

      認可URLを`AuthenticationController`で生成することにより、要求はライブラリーで以前設定した呼び出しコンテキストを保持します。コントローラーに渡されると、有効な`Tokens`インスタンスまたは不具合を特定するExceptionが返ってきます。呼び出しに成功した場合、後でアクセスするために資格情報をどこかに保存しておく必要があります。ライブラリーに含まれる`SessionsUtils`クラスを使って、要求の`HttpSession`を使用できます。

      <Info>
        トークンを要求した時刻と受け取った`expiresIn`値は保存することを推奨します。そうすることで、次回トークンを使用する時に、すでに有効期限が切れているか、または引き続き有効かを確認できます。このサンプルでは検証をスキップします。
      </Info>
    </Section>

    <Section id={sections[6].id} title={sections[6].title} stepNumber="7">
      ユーザーは認証される（トークンが存在する）と、`Auth0Filter`によって保護されたリソースへのアクセスを許可されます。`HomeServlet`で要求セッションからトークンが取得され、`userId`属性として設定されることで、JSPコードから使用できるようになります。
    </Section>

    <Section id={sections[7].id} title={sections[7].title} stepNumber="8">
      ログアウトを適切に処理するには、セッションを消去し、ユーザーをAuth0からログアウトさせる必要があります。この処理は、サンプルアプリケーションの`LogoutServlet`で行われます。

      まず、`request.getSession().invalidate()`を呼び出してセッションを消去します。それから、`returnTo`クエリパラメーターを含めることを念頭に置きつつ、ログアウトURLを構築します。ユーザーはログアウト後にこのURLにリダイレクトされます。最後に応答をログアウトURLにリダイレクトします。
    </Section>

    <Section id={sections[8].id} title={sections[8].title} stepNumber="9">
      ターミナルからサンプルを実行するには、ディレクトリをプロジェクトのルートフォルダーに変更して以下のラインを実行します：

      ```text lines theme={null}
      ./gradlew clean app
      ```

      数秒後、アプリケーションが`http://localhost:3000/`でアクセスできるようになります。保護されたリソース（[http://localhost:3000/portal/home](http://localhost:3000/portal/home)）にアクセスしてみて、`Auth0Filter`によるAuth0ログインページへのリダイレクト方法を観察します。ウィジェット
      が、[Dashboard](https://manage.auth0.com/#/)でこのアプリケーションに定義したソーシャル接続とデータベース接続をすべて表示します。

      <Frame>
        <img src="https://mintlify.s3.us-west-1.amazonaws.com/auth0-docs-event-stream-action-templates/docs/images/ja-jp/cdy7uua7fh8z/7L6lZ6xCi1L7sJBFZUPb9g/b7697bfa1bc83a1072c2de2f15cec93c/Login_Screen_-_English.png" />
      </Frame>

      認証成功後、ホームページのコンテンツを見られるようになります。

      <Frame>
        <img src="https://mintlify.s3.us-west-1.amazonaws.com/auth0-docs-event-stream-action-templates/docs/images/ja-jp/cdy7uua7fh8z/FzK3jxfSGoeIDYQamxnJl/6b608e39ff39e044644193cfd2ee0f69/java-step-9-2.png" />
      </Frame>

      ホームページ右上の\*\*［logout（ログアウト）］\*\* ボタン をクリックしてログアウトします。
    </Section>

    ## 次のステップ

    成功です！ここまで来れば、アプリケーションにログイン、ログアウト、ユーザープロファイル情報が備わっているはずです。

    これでクイックスタートチュートリアルは終了ですが、機能はまだまだたくさんあります。Auth0でできることについて詳しくは、以下をご覧ください。

    * [Auth0 Dashboard](https://manage.auth0.com/#) - Auth0のテナントやアプリケーションを構成して管理する方法について説明します
    * [auth0-java-mvc-common SDK](https://github.com/auth0/auth0-java-mvc-common) - このチュートリアルで使用されているSDKをより詳しく説明します
    * [Auth0 Marketplace](https://marketplace.auth0.com/) - Auth0の機能性を拡張できる各種の統合を見つけられます
  </Content>

  <SideMenu sections={sections}>
    <SideMenuSectionItem id={sections[0].id}>
      <SignUpForm />
    </SideMenuSectionItem>

    <SideMenuSectionItem id={sections[1].id}>
      <SignUpForm />
    </SideMenuSectionItem>

    <SideMenuSectionItem id={sections[2].id}>
      <AuthCodeGroup>
        ```xml web.xml lines theme={null}
        <context-param>
            <param-name>com.auth0.domain</param-name>
            <param-value>{yourDomain}</param-value>
        </context-param>

        <context-param>
            <param-name>com.auth0.clientId</param-name>
            <param-value>{yourClientId}</param-value>
        </context-param>

        <context-param>
            <param-name>com.auth0.clientSecret</param-name>
            <param-value>{yourClientSecret}</param-value>
        </context-param>
        ```

        ```java AuthenticationControllerProvider.java highlight={5-26} lines  theme={null}
        class AuthenticationControllerProvider {

            private AuthenticationControllerProvider() {}

            private static AuthenticationController INSTANCE;

            // if multiple threads may call this, synchronize this method and consider double locking
            static AuthenticationController getInstance(ServletConfig config) throws UnsupportedEncodingException {
                if (INSTANCE == null) {
                    String domain = config.getServletContext().getInitParameter("com.auth0.domain");
                    String clientId = config.getServletContext().getInitParameter("com.auth0.clientId");
                    String clientSecret = config.getServletContext().getInitParameter("com.auth0.clientSecret");

                    if (domain == null || clientId == null || clientSecret == null) {
                        throw new IllegalArgumentException("Missing domain, clientId, or clientSecret. Did you update src/main/webapp/WEB-INF/web.xml?");
                    }

                    // JwkProvider required for RS256 tokens. If using HS256, do not use.
                    JwkProvider jwkProvider = new JwkProviderBuilder(domain).build();
                    INSTANCE = AuthenticationController.newBuilder(domain, clientId, clientSecret)
                            .withJwkProvider(jwkProvider)
                            .build();
                }

                return INSTANCE;
            }
        }
        ```

        ```java LoginServlet.java highlight={21-23} lines theme={null}
        @WebServlet(urlPatterns = {"/login"})
        public class LoginServlet extends HttpServlet {
            private AuthenticationController authenticationController;
            private String domain;

            @Override
            public void init(ServletConfig config) throws ServletException {
                super.init(config);
                domain = config.getServletContext().getInitParameter("com.auth0.domain");
                authenticationController = AuthenticationControllerProvider.getInstance(config);
            }

            @Override
            protected void doGet(final HttpServletRequest req, final HttpServletResponse res) throws ServletException, IOException {
                String redirectUri = req.getScheme() + "://" + req.getServerName();
                if ((req.getScheme().equals("http") && req.getServerPort() != 80) || (req.getScheme().equals("https") && req.getServerPort() != 443)) {
                    redirectUri += ":" + req.getServerPort();
                }
                redirectUri += "/callback";

                String authorizeUrl = authenticationController.buildAuthorizeUrl(req, res, redirectUri)
                        .build();
                res.sendRedirect(authorizeUrl);
            }
        }
        ```

        ```java CallbackServlet.java highlight={16-37} lines  theme={null}
        @WebServlet(urlPatterns = {"/callback"})
        public class CallbackServlet extends HttpServlet {

            private String redirectOnSuccess;
            private String redirectOnFail;
            private AuthenticationController authenticationController;

            @Override
            public void init(ServletConfig config) throws ServletException {
                super.init(config);
                redirectOnSuccess = "/portal/home";
                redirectOnFail = "/login";
                authenticationController = AuthenticationControllerProvider.getInstance(config);
            }

            @Override
            public void doGet(HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException {
                handle(req, res);
            }

            @Override
            public void doPost(HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException {
                handle(req, res);
            }

            private void handle(HttpServletRequest req, HttpServletResponse res) throws IOException {
                try {
                    // Parse the request
                    Tokens tokens = authenticationController.handle(req, res);
                    SessionUtils.set(req, "accessToken", tokens.getAccessToken());
                    SessionUtils.set(req, "idToken", tokens.getIdToken());
                    res.sendRedirect(redirectOnSuccess);
                } catch (IdentityVerificationException e) {
                    e.printStackTrace();
                    res.sendRedirect(redirectOnFail);
                }
            }
        }
        ```

        ```java HomeServlet.java highlight={4-14} lines theme={null}
        @WebServlet(urlPatterns = {"/portal/home"})
        public class HomeServlet extends HttpServlet {

            @Override
            protected void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
                final String accessToken = (String) SessionUtils.get(req, "accessToken");
                final String idToken = (String) SessionUtils.get(req, "idToken");
                if (accessToken != null) {
                    req.setAttribute("userId", accessToken);
                } else if (idToken != null) {
                    req.setAttribute("userId", idToken);
                }
                req.getRequestDispatcher("/WEB-INF/jsp/home.jsp").forward(req, res);
            }
        }
        ```

        ```java LogoutServlet.java highlight={13-30} lines  theme={null}
        @WebServlet(urlPatterns = {"/logout"})
        public class LogoutServlet extends HttpServlet {

            private String domain;
            private String clientId;

            @Override
            public void init(ServletConfig config) {
                domain = config.getServletContext().getInitParameter("com.auth0.domain");
                clientId = config.getServletContext().getInitParameter("com.auth0.clientId");
            }

            @Override
            protected void doGet(final HttpServletRequest request, final HttpServletResponse response) throws ServletException, IOException {
                if (request.getSession() != null) {
                    request.getSession().invalidate();
                }
                String returnUrl = String.format("%s://%s", request.getScheme(), request.getServerName());
                if ((request.getScheme().equals("http") && request.getServerPort() != 80) || (request.getScheme().equals("https") && request.getServerPort() != 443)) {
                    returnUrl += ":" + request.getServerPort();
                }
                returnUrl += "/login";
                String logoutUrl = String.format(
                        "https://%s/v2/logout?client_id=%s&returnTo=%s",
                        domain,
                        clientId,
                        returnUrl
                );
                response.sendRedirect(logoutUrl);
            }

        }
        ```
      </AuthCodeGroup>
    </SideMenuSectionItem>

    <SideMenuSectionItem id={sections[3].id}>
      <AuthCodeGroup>
        ```java AuthenticationControllerProvider.java highlight={5-26} lines  theme={null}
        class AuthenticationControllerProvider {

            private AuthenticationControllerProvider() {}

            private static AuthenticationController INSTANCE;

            // if multiple threads may call this, synchronize this method and consider double locking
            static AuthenticationController getInstance(ServletConfig config) throws UnsupportedEncodingException {
                if (INSTANCE == null) {
                    String domain = config.getServletContext().getInitParameter("com.auth0.domain");
                    String clientId = config.getServletContext().getInitParameter("com.auth0.clientId");
                    String clientSecret = config.getServletContext().getInitParameter("com.auth0.clientSecret");

                    if (domain == null || clientId == null || clientSecret == null) {
                        throw new IllegalArgumentException("Missing domain, clientId, or clientSecret. Did you update src/main/webapp/WEB-INF/web.xml?");
                    }

                    // JwkProvider required for RS256 tokens. If using HS256, do not use.
                    JwkProvider jwkProvider = new JwkProviderBuilder(domain).build();
                    INSTANCE = AuthenticationController.newBuilder(domain, clientId, clientSecret)
                            .withJwkProvider(jwkProvider)
                            .build();
                }

                return INSTANCE;
            }
        }
        ```

        ```xml web.xml lines theme={null}
        <context-param>
            <param-name>com.auth0.domain</param-name>
            <param-value>{yourDomain}</param-value>
        </context-param>

        <context-param>
            <param-name>com.auth0.clientId</param-name>
            <param-value>{yourClientId}</param-value>
        </context-param>

        <context-param>
            <param-name>com.auth0.clientSecret</param-name>
            <param-value>{yourClientSecret}</param-value>
        </context-param>
        ```

        ```java LoginServlet.java highlight={21-23} lines theme={null}
        @WebServlet(urlPatterns = {"/login"})
        public class LoginServlet extends HttpServlet {
            private AuthenticationController authenticationController;
            private String domain;

            @Override
            public void init(ServletConfig config) throws ServletException {
                super.init(config);
                domain = config.getServletContext().getInitParameter("com.auth0.domain");
                authenticationController = AuthenticationControllerProvider.getInstance(config);
            }

            @Override
            protected void doGet(final HttpServletRequest req, final HttpServletResponse res) throws ServletException, IOException {
                String redirectUri = req.getScheme() + "://" + req.getServerName();
                if ((req.getScheme().equals("http") && req.getServerPort() != 80) || (req.getScheme().equals("https") && req.getServerPort() != 443)) {
                    redirectUri += ":" + req.getServerPort();
                }
                redirectUri += "/callback";

                String authorizeUrl = authenticationController.buildAuthorizeUrl(req, res, redirectUri)
                        .build();
                res.sendRedirect(authorizeUrl);
            }
        }
        ```

        ```java CallbackServlet.java highlight={16-37} lines  theme={null}
        @WebServlet(urlPatterns = {"/callback"})
        public class CallbackServlet extends HttpServlet {

            private String redirectOnSuccess;
            private String redirectOnFail;
            private AuthenticationController authenticationController;

            @Override
            public void init(ServletConfig config) throws ServletException {
                super.init(config);
                redirectOnSuccess = "/portal/home";
                redirectOnFail = "/login";
                authenticationController = AuthenticationControllerProvider.getInstance(config);
            }

            @Override
            public void doGet(HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException {
                handle(req, res);
            }

            @Override
            public void doPost(HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException {
                handle(req, res);
            }

            private void handle(HttpServletRequest req, HttpServletResponse res) throws IOException {
                try {
                    // Parse the request
                    Tokens tokens = authenticationController.handle(req, res);
                    SessionUtils.set(req, "accessToken", tokens.getAccessToken());
                    SessionUtils.set(req, "idToken", tokens.getIdToken());
                    res.sendRedirect(redirectOnSuccess);
                } catch (IdentityVerificationException e) {
                    e.printStackTrace();
                    res.sendRedirect(redirectOnFail);
                }
            }
        }
        ```

        ```java HomeServlet.java highlight={4-14} lines theme={null}
        @WebServlet(urlPatterns = {"/portal/home"})
        public class HomeServlet extends HttpServlet {

            @Override
            protected void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
                final String accessToken = (String) SessionUtils.get(req, "accessToken");
                final String idToken = (String) SessionUtils.get(req, "idToken");
                if (accessToken != null) {
                    req.setAttribute("userId", accessToken);
                } else if (idToken != null) {
                    req.setAttribute("userId", idToken);
                }
                req.getRequestDispatcher("/WEB-INF/jsp/home.jsp").forward(req, res);
            }
        }
        ```

        ```java LogoutServlet.java highlight={13-30} lines  theme={null}
        @WebServlet(urlPatterns = {"/logout"})
        public class LogoutServlet extends HttpServlet {

            private String domain;
            private String clientId;

            @Override
            public void init(ServletConfig config) {
                domain = config.getServletContext().getInitParameter("com.auth0.domain");
                clientId = config.getServletContext().getInitParameter("com.auth0.clientId");
            }

            @Override
            protected void doGet(final HttpServletRequest request, final HttpServletResponse response) throws ServletException, IOException {
                if (request.getSession() != null) {
                    request.getSession().invalidate();
                }
                String returnUrl = String.format("%s://%s", request.getScheme(), request.getServerName());
                if ((request.getScheme().equals("http") && request.getServerPort() != 80) || (request.getScheme().equals("https") && request.getServerPort() != 443)) {
                    returnUrl += ":" + request.getServerPort();
                }
                returnUrl += "/login";
                String logoutUrl = String.format(
                        "https://%s/v2/logout?client_id=%s&returnTo=%s",
                        domain,
                        clientId,
                        returnUrl
                );
                response.sendRedirect(logoutUrl);
            }

        }
        ```
      </AuthCodeGroup>
    </SideMenuSectionItem>

    <SideMenuSectionItem id={sections[4].id}>
      <AuthCodeGroup>
        ```java LoginServlet.java highlight={21-23} lines theme={null}
        @WebServlet(urlPatterns = {"/login"})
        public class LoginServlet extends HttpServlet {
            private AuthenticationController authenticationController;
            private String domain;

            @Override
            public void init(ServletConfig config) throws ServletException {
                super.init(config);
                domain = config.getServletContext().getInitParameter("com.auth0.domain");
                authenticationController = AuthenticationControllerProvider.getInstance(config);
            }

            @Override
            protected void doGet(final HttpServletRequest req, final HttpServletResponse res) throws ServletException, IOException {
                String redirectUri = req.getScheme() + "://" + req.getServerName();
                if ((req.getScheme().equals("http") && req.getServerPort() != 80) || (req.getScheme().equals("https") && req.getServerPort() != 443)) {
                    redirectUri += ":" + req.getServerPort();
                }
                redirectUri += "/callback";

                String authorizeUrl = authenticationController.buildAuthorizeUrl(req, res, redirectUri)
                        .build();
                res.sendRedirect(authorizeUrl);
            }
        }
        ```

        ```xml web.xml lines theme={null}
        <context-param>
            <param-name>com.auth0.domain</param-name>
            <param-value>{yourDomain}</param-value>
        </context-param>

        <context-param>
            <param-name>com.auth0.clientId</param-name>
            <param-value>{yourClientId}</param-value>
        </context-param>

        <context-param>
            <param-name>com.auth0.clientSecret</param-name>
            <param-value>{yourClientSecret}</param-value>
        </context-param>
        ```

        ```java AuthenticationControllerProvider.java highlight={5-26} lines  theme={null}
        class AuthenticationControllerProvider {

            private AuthenticationControllerProvider() {}

            private static AuthenticationController INSTANCE;

            // if multiple threads may call this, synchronize this method and consider double locking
            static AuthenticationController getInstance(ServletConfig config) throws UnsupportedEncodingException {
                if (INSTANCE == null) {
                    String domain = config.getServletContext().getInitParameter("com.auth0.domain");
                    String clientId = config.getServletContext().getInitParameter("com.auth0.clientId");
                    String clientSecret = config.getServletContext().getInitParameter("com.auth0.clientSecret");

                    if (domain == null || clientId == null || clientSecret == null) {
                        throw new IllegalArgumentException("Missing domain, clientId, or clientSecret. Did you update src/main/webapp/WEB-INF/web.xml?");
                    }

                    // JwkProvider required for RS256 tokens. If using HS256, do not use.
                    JwkProvider jwkProvider = new JwkProviderBuilder(domain).build();
                    INSTANCE = AuthenticationController.newBuilder(domain, clientId, clientSecret)
                            .withJwkProvider(jwkProvider)
                            .build();
                }

                return INSTANCE;
            }
        }
        ```

        ```java CallbackServlet.java highlight={16-37} lines  theme={null}
        @WebServlet(urlPatterns = {"/callback"})
        public class CallbackServlet extends HttpServlet {

            private String redirectOnSuccess;
            private String redirectOnFail;
            private AuthenticationController authenticationController;

            @Override
            public void init(ServletConfig config) throws ServletException {
                super.init(config);
                redirectOnSuccess = "/portal/home";
                redirectOnFail = "/login";
                authenticationController = AuthenticationControllerProvider.getInstance(config);
            }

            @Override
            public void doGet(HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException {
                handle(req, res);
            }

            @Override
            public void doPost(HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException {
                handle(req, res);
            }

            private void handle(HttpServletRequest req, HttpServletResponse res) throws IOException {
                try {
                    // Parse the request
                    Tokens tokens = authenticationController.handle(req, res);
                    SessionUtils.set(req, "accessToken", tokens.getAccessToken());
                    SessionUtils.set(req, "idToken", tokens.getIdToken());
                    res.sendRedirect(redirectOnSuccess);
                } catch (IdentityVerificationException e) {
                    e.printStackTrace();
                    res.sendRedirect(redirectOnFail);
                }
            }
        }
        ```

        ```java HomeServlet.java highlight={4-14} lines theme={null}
        @WebServlet(urlPatterns = {"/portal/home"})
        public class HomeServlet extends HttpServlet {

            @Override
            protected void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
                final String accessToken = (String) SessionUtils.get(req, "accessToken");
                final String idToken = (String) SessionUtils.get(req, "idToken");
                if (accessToken != null) {
                    req.setAttribute("userId", accessToken);
                } else if (idToken != null) {
                    req.setAttribute("userId", idToken);
                }
                req.getRequestDispatcher("/WEB-INF/jsp/home.jsp").forward(req, res);
            }
        }
        ```

        ```java LogoutServlet.java highlight={13-30} lines  theme={null}
        @WebServlet(urlPatterns = {"/logout"})
        public class LogoutServlet extends HttpServlet {

            private String domain;
            private String clientId;

            @Override
            public void init(ServletConfig config) {
                domain = config.getServletContext().getInitParameter("com.auth0.domain");
                clientId = config.getServletContext().getInitParameter("com.auth0.clientId");
            }

            @Override
            protected void doGet(final HttpServletRequest request, final HttpServletResponse response) throws ServletException, IOException {
                if (request.getSession() != null) {
                    request.getSession().invalidate();
                }
                String returnUrl = String.format("%s://%s", request.getScheme(), request.getServerName());
                if ((request.getScheme().equals("http") && request.getServerPort() != 80) || (request.getScheme().equals("https") && request.getServerPort() != 443)) {
                    returnUrl += ":" + request.getServerPort();
                }
                returnUrl += "/login";
                String logoutUrl = String.format(
                        "https://%s/v2/logout?client_id=%s&returnTo=%s",
                        domain,
                        clientId,
                        returnUrl
                );
                response.sendRedirect(logoutUrl);
            }

        }
        ```
      </AuthCodeGroup>
    </SideMenuSectionItem>

    <SideMenuSectionItem id={sections[5].id}>
      <AuthCodeGroup>
        ```java CallbackServlet.java highlight={16-37} lines  theme={null}
        @WebServlet(urlPatterns = {"/callback"})
        public class CallbackServlet extends HttpServlet {

            private String redirectOnSuccess;
            private String redirectOnFail;
            private AuthenticationController authenticationController;

            @Override
            public void init(ServletConfig config) throws ServletException {
                super.init(config);
                redirectOnSuccess = "/portal/home";
                redirectOnFail = "/login";
                authenticationController = AuthenticationControllerProvider.getInstance(config);
            }

            @Override
            public void doGet(HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException {
                handle(req, res);
            }

            @Override
            public void doPost(HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException {
                handle(req, res);
            }

            private void handle(HttpServletRequest req, HttpServletResponse res) throws IOException {
                try {
                    // Parse the request
                    Tokens tokens = authenticationController.handle(req, res);
                    SessionUtils.set(req, "accessToken", tokens.getAccessToken());
                    SessionUtils.set(req, "idToken", tokens.getIdToken());
                    res.sendRedirect(redirectOnSuccess);
                } catch (IdentityVerificationException e) {
                    e.printStackTrace();
                    res.sendRedirect(redirectOnFail);
                }
            }
        }
        ```

        ```xml web.xml lines theme={null}
        <context-param>
            <param-name>com.auth0.domain</param-name>
            <param-value>{yourDomain}</param-value>
        </context-param>

        <context-param>
            <param-name>com.auth0.clientId</param-name>
            <param-value>{yourClientId}</param-value>
        </context-param>

        <context-param>
            <param-name>com.auth0.clientSecret</param-name>
            <param-value>{yourClientSecret}</param-value>
        </context-param>
        ```

        ```java AuthenticationControllerProvider.java highlight={5-26} lines  theme={null}
        class AuthenticationControllerProvider {

            private AuthenticationControllerProvider() {}

            private static AuthenticationController INSTANCE;

            // if multiple threads may call this, synchronize this method and consider double locking
            static AuthenticationController getInstance(ServletConfig config) throws UnsupportedEncodingException {
                if (INSTANCE == null) {
                    String domain = config.getServletContext().getInitParameter("com.auth0.domain");
                    String clientId = config.getServletContext().getInitParameter("com.auth0.clientId");
                    String clientSecret = config.getServletContext().getInitParameter("com.auth0.clientSecret");

                    if (domain == null || clientId == null || clientSecret == null) {
                        throw new IllegalArgumentException("Missing domain, clientId, or clientSecret. Did you update src/main/webapp/WEB-INF/web.xml?");
                    }

                    // JwkProvider required for RS256 tokens. If using HS256, do not use.
                    JwkProvider jwkProvider = new JwkProviderBuilder(domain).build();
                    INSTANCE = AuthenticationController.newBuilder(domain, clientId, clientSecret)
                            .withJwkProvider(jwkProvider)
                            .build();
                }

                return INSTANCE;
            }
        }
        ```

        ```java LoginServlet.java highlight={21-23} lines theme={null}
        @WebServlet(urlPatterns = {"/login"})
        public class LoginServlet extends HttpServlet {
            private AuthenticationController authenticationController;
            private String domain;

            @Override
            public void init(ServletConfig config) throws ServletException {
                super.init(config);
                domain = config.getServletContext().getInitParameter("com.auth0.domain");
                authenticationController = AuthenticationControllerProvider.getInstance(config);
            }

            @Override
            protected void doGet(final HttpServletRequest req, final HttpServletResponse res) throws ServletException, IOException {
                String redirectUri = req.getScheme() + "://" + req.getServerName();
                if ((req.getScheme().equals("http") && req.getServerPort() != 80) || (req.getScheme().equals("https") && req.getServerPort() != 443)) {
                    redirectUri += ":" + req.getServerPort();
                }
                redirectUri += "/callback";

                String authorizeUrl = authenticationController.buildAuthorizeUrl(req, res, redirectUri)
                        .build();
                res.sendRedirect(authorizeUrl);
            }
        }
        ```

        ```java HomeServlet.java highlight={4-14} lines theme={null}
        @WebServlet(urlPatterns = {"/portal/home"})
        public class HomeServlet extends HttpServlet {

            @Override
            protected void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
                final String accessToken = (String) SessionUtils.get(req, "accessToken");
                final String idToken = (String) SessionUtils.get(req, "idToken");
                if (accessToken != null) {
                    req.setAttribute("userId", accessToken);
                } else if (idToken != null) {
                    req.setAttribute("userId", idToken);
                }
                req.getRequestDispatcher("/WEB-INF/jsp/home.jsp").forward(req, res);
            }
        }
        ```

        ```java LogoutServlet.java highlight={13-30} lines  theme={null}
        @WebServlet(urlPatterns = {"/logout"})
        public class LogoutServlet extends HttpServlet {

            private String domain;
            private String clientId;

            @Override
            public void init(ServletConfig config) {
                domain = config.getServletContext().getInitParameter("com.auth0.domain");
                clientId = config.getServletContext().getInitParameter("com.auth0.clientId");
            }

            @Override
            protected void doGet(final HttpServletRequest request, final HttpServletResponse response) throws ServletException, IOException {
                if (request.getSession() != null) {
                    request.getSession().invalidate();
                }
                String returnUrl = String.format("%s://%s", request.getScheme(), request.getServerName());
                if ((request.getScheme().equals("http") && request.getServerPort() != 80) || (request.getScheme().equals("https") && request.getServerPort() != 443)) {
                    returnUrl += ":" + request.getServerPort();
                }
                returnUrl += "/login";
                String logoutUrl = String.format(
                        "https://%s/v2/logout?client_id=%s&returnTo=%s",
                        domain,
                        clientId,
                        returnUrl
                );
                response.sendRedirect(logoutUrl);
            }

        }
        ```
      </AuthCodeGroup>
    </SideMenuSectionItem>

    <SideMenuSectionItem id={sections[6].id}>
      <AuthCodeGroup>
        ```java HomeServlet.java highlight={4-14} lines theme={null}
        @WebServlet(urlPatterns = {"/portal/home"})
        public class HomeServlet extends HttpServlet {

            @Override
            protected void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
                final String accessToken = (String) SessionUtils.get(req, "accessToken");
                final String idToken = (String) SessionUtils.get(req, "idToken");
                if (accessToken != null) {
                    req.setAttribute("userId", accessToken);
                } else if (idToken != null) {
                    req.setAttribute("userId", idToken);
                }
                req.getRequestDispatcher("/WEB-INF/jsp/home.jsp").forward(req, res);
            }
        }
        ```

        ```xml web.xml lines theme={null}
        <context-param>
            <param-name>com.auth0.domain</param-name>
            <param-value>{yourDomain}</param-value>
        </context-param>

        <context-param>
            <param-name>com.auth0.clientId</param-name>
            <param-value>{yourClientId}</param-value>
        </context-param>

        <context-param>
            <param-name>com.auth0.clientSecret</param-name>
            <param-value>{yourClientSecret}</param-value>
        </context-param>
        ```

        ```java AuthenticationControllerProvider.java highlight={5-26} lines  theme={null}
        class AuthenticationControllerProvider {

            private AuthenticationControllerProvider() {}

            private static AuthenticationController INSTANCE;

            // if multiple threads may call this, synchronize this method and consider double locking
            static AuthenticationController getInstance(ServletConfig config) throws UnsupportedEncodingException {
                if (INSTANCE == null) {
                    String domain = config.getServletContext().getInitParameter("com.auth0.domain");
                    String clientId = config.getServletContext().getInitParameter("com.auth0.clientId");
                    String clientSecret = config.getServletContext().getInitParameter("com.auth0.clientSecret");

                    if (domain == null || clientId == null || clientSecret == null) {
                        throw new IllegalArgumentException("Missing domain, clientId, or clientSecret. Did you update src/main/webapp/WEB-INF/web.xml?");
                    }

                    // JwkProvider required for RS256 tokens. If using HS256, do not use.
                    JwkProvider jwkProvider = new JwkProviderBuilder(domain).build();
                    INSTANCE = AuthenticationController.newBuilder(domain, clientId, clientSecret)
                            .withJwkProvider(jwkProvider)
                            .build();
                }

                return INSTANCE;
            }
        }
        ```

        ```java LoginServlet.java highlight={21-23} lines theme={null}
        @WebServlet(urlPatterns = {"/login"})
        public class LoginServlet extends HttpServlet {
            private AuthenticationController authenticationController;
            private String domain;

            @Override
            public void init(ServletConfig config) throws ServletException {
                super.init(config);
                domain = config.getServletContext().getInitParameter("com.auth0.domain");
                authenticationController = AuthenticationControllerProvider.getInstance(config);
            }

            @Override
            protected void doGet(final HttpServletRequest req, final HttpServletResponse res) throws ServletException, IOException {
                String redirectUri = req.getScheme() + "://" + req.getServerName();
                if ((req.getScheme().equals("http") && req.getServerPort() != 80) || (req.getScheme().equals("https") && req.getServerPort() != 443)) {
                    redirectUri += ":" + req.getServerPort();
                }
                redirectUri += "/callback";

                String authorizeUrl = authenticationController.buildAuthorizeUrl(req, res, redirectUri)
                        .build();
                res.sendRedirect(authorizeUrl);
            }
        }
        ```

        ```java CallbackServlet.java highlight={16-37} lines  theme={null}
        @WebServlet(urlPatterns = {"/callback"})
        public class CallbackServlet extends HttpServlet {

            private String redirectOnSuccess;
            private String redirectOnFail;
            private AuthenticationController authenticationController;

            @Override
            public void init(ServletConfig config) throws ServletException {
                super.init(config);
                redirectOnSuccess = "/portal/home";
                redirectOnFail = "/login";
                authenticationController = AuthenticationControllerProvider.getInstance(config);
            }

            @Override
            public void doGet(HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException {
                handle(req, res);
            }

            @Override
            public void doPost(HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException {
                handle(req, res);
            }

            private void handle(HttpServletRequest req, HttpServletResponse res) throws IOException {
                try {
                    // Parse the request
                    Tokens tokens = authenticationController.handle(req, res);
                    SessionUtils.set(req, "accessToken", tokens.getAccessToken());
                    SessionUtils.set(req, "idToken", tokens.getIdToken());
                    res.sendRedirect(redirectOnSuccess);
                } catch (IdentityVerificationException e) {
                    e.printStackTrace();
                    res.sendRedirect(redirectOnFail);
                }
            }
        }
        ```

        ```java LogoutServlet.java highlight={13-30} lines  theme={null}
        @WebServlet(urlPatterns = {"/logout"})
        public class LogoutServlet extends HttpServlet {

            private String domain;
            private String clientId;

            @Override
            public void init(ServletConfig config) {
                domain = config.getServletContext().getInitParameter("com.auth0.domain");
                clientId = config.getServletContext().getInitParameter("com.auth0.clientId");
            }

            @Override
            protected void doGet(final HttpServletRequest request, final HttpServletResponse response) throws ServletException, IOException {
                if (request.getSession() != null) {
                    request.getSession().invalidate();
                }
                String returnUrl = String.format("%s://%s", request.getScheme(), request.getServerName());
                if ((request.getScheme().equals("http") && request.getServerPort() != 80) || (request.getScheme().equals("https") && request.getServerPort() != 443)) {
                    returnUrl += ":" + request.getServerPort();
                }
                returnUrl += "/login";
                String logoutUrl = String.format(
                        "https://%s/v2/logout?client_id=%s&returnTo=%s",
                        domain,
                        clientId,
                        returnUrl
                );
                response.sendRedirect(logoutUrl);
            }

        }
        ```
      </AuthCodeGroup>
    </SideMenuSectionItem>

    <SideMenuSectionItem id={sections[7].id}>
      <AuthCodeGroup>
        ```java LogoutServlet.java highlight={13-30} lines  theme={null}
        @WebServlet(urlPatterns = {"/logout"})
        public class LogoutServlet extends HttpServlet {

            private String domain;
            private String clientId;

            @Override
            public void init(ServletConfig config) {
                domain = config.getServletContext().getInitParameter("com.auth0.domain");
                clientId = config.getServletContext().getInitParameter("com.auth0.clientId");
            }

            @Override
            protected void doGet(final HttpServletRequest request, final HttpServletResponse response) throws ServletException, IOException {
                if (request.getSession() != null) {
                    request.getSession().invalidate();
                }
                String returnUrl = String.format("%s://%s", request.getScheme(), request.getServerName());
                if ((request.getScheme().equals("http") && request.getServerPort() != 80) || (request.getScheme().equals("https") && request.getServerPort() != 443)) {
                    returnUrl += ":" + request.getServerPort();
                }
                returnUrl += "/login";
                String logoutUrl = String.format(
                        "https://%s/v2/logout?client_id=%s&returnTo=%s",
                        domain,
                        clientId,
                        returnUrl
                );
                response.sendRedirect(logoutUrl);
            }

        }
        ```

        ```xml web.xml lines theme={null}
        <context-param>
            <param-name>com.auth0.domain</param-name>
            <param-value>{yourDomain}</param-value>
        </context-param>

        <context-param>
            <param-name>com.auth0.clientId</param-name>
            <param-value>{yourClientId}</param-value>
        </context-param>

        <context-param>
            <param-name>com.auth0.clientSecret</param-name>
            <param-value>{yourClientSecret}</param-value>
        </context-param>
        ```

        ```java AuthenticationControllerProvider.java highlight={5-26} lines  theme={null}
        class AuthenticationControllerProvider {

            private AuthenticationControllerProvider() {}

            private static AuthenticationController INSTANCE;

            // if multiple threads may call this, synchronize this method and consider double locking
            static AuthenticationController getInstance(ServletConfig config) throws UnsupportedEncodingException {
                if (INSTANCE == null) {
                    String domain = config.getServletContext().getInitParameter("com.auth0.domain");
                    String clientId = config.getServletContext().getInitParameter("com.auth0.clientId");
                    String clientSecret = config.getServletContext().getInitParameter("com.auth0.clientSecret");

                    if (domain == null || clientId == null || clientSecret == null) {
                        throw new IllegalArgumentException("Missing domain, clientId, or clientSecret. Did you update src/main/webapp/WEB-INF/web.xml?");
                    }

                    // JwkProvider required for RS256 tokens. If using HS256, do not use.
                    JwkProvider jwkProvider = new JwkProviderBuilder(domain).build();
                    INSTANCE = AuthenticationController.newBuilder(domain, clientId, clientSecret)
                            .withJwkProvider(jwkProvider)
                            .build();
                }

                return INSTANCE;
            }
        }
        ```

        ```java LoginServlet.java highlight={21-23} lines theme={null}
        @WebServlet(urlPatterns = {"/login"})
        public class LoginServlet extends HttpServlet {
            private AuthenticationController authenticationController;
            private String domain;

            @Override
            public void init(ServletConfig config) throws ServletException {
                super.init(config);
                domain = config.getServletContext().getInitParameter("com.auth0.domain");
                authenticationController = AuthenticationControllerProvider.getInstance(config);
            }

            @Override
            protected void doGet(final HttpServletRequest req, final HttpServletResponse res) throws ServletException, IOException {
                String redirectUri = req.getScheme() + "://" + req.getServerName();
                if ((req.getScheme().equals("http") && req.getServerPort() != 80) || (req.getScheme().equals("https") && req.getServerPort() != 443)) {
                    redirectUri += ":" + req.getServerPort();
                }
                redirectUri += "/callback";

                String authorizeUrl = authenticationController.buildAuthorizeUrl(req, res, redirectUri)
                        .build();
                res.sendRedirect(authorizeUrl);
            }
        }
        ```

        ```java CallbackServlet.java highlight={16-37} lines  theme={null}
        @WebServlet(urlPatterns = {"/callback"})
        public class CallbackServlet extends HttpServlet {

            private String redirectOnSuccess;
            private String redirectOnFail;
            private AuthenticationController authenticationController;

            @Override
            public void init(ServletConfig config) throws ServletException {
                super.init(config);
                redirectOnSuccess = "/portal/home";
                redirectOnFail = "/login";
                authenticationController = AuthenticationControllerProvider.getInstance(config);
            }

            @Override
            public void doGet(HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException {
                handle(req, res);
            }

            @Override
            public void doPost(HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException {
                handle(req, res);
            }

            private void handle(HttpServletRequest req, HttpServletResponse res) throws IOException {
                try {
                    // Parse the request
                    Tokens tokens = authenticationController.handle(req, res);
                    SessionUtils.set(req, "accessToken", tokens.getAccessToken());
                    SessionUtils.set(req, "idToken", tokens.getIdToken());
                    res.sendRedirect(redirectOnSuccess);
                } catch (IdentityVerificationException e) {
                    e.printStackTrace();
                    res.sendRedirect(redirectOnFail);
                }
            }
        }
        ```

        ```java HomeServlet.java highlight={4-14} lines theme={null}
        @WebServlet(urlPatterns = {"/portal/home"})
        public class HomeServlet extends HttpServlet {

            @Override
            protected void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
                final String accessToken = (String) SessionUtils.get(req, "accessToken");
                final String idToken = (String) SessionUtils.get(req, "idToken");
                if (accessToken != null) {
                    req.setAttribute("userId", accessToken);
                } else if (idToken != null) {
                    req.setAttribute("userId", idToken);
                }
                req.getRequestDispatcher("/WEB-INF/jsp/home.jsp").forward(req, res);
            }
        }
        ```
      </AuthCodeGroup>
    </SideMenuSectionItem>

    <SideMenuSectionItem id={sections[8].id}>
      <SignUpForm />
    </SideMenuSectionItem>
  </SideMenu>
</Recipe>
