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

> This tutorial demonstrates how to configure Apache to add authentication and authorization to your web app.

# Apache

export const SignUpForm = () => {
  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 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>;
};

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>;
};

export const sections = [{
  id: "system-requirements",
  title: "System Requirements"
}, {
  id: "install-and-enable-mod-auth-openidc-module",
  title: "Install and Enable mod_auth_openidc Module"
}, {
  id: "configure-the-module-with-your-auth0-account-information",
  title: "Configure the Module with Your Auth0 Account Information"
}, {
  id: "configure-auth0",
  title: "Configure Auth0"
}, {
  id: "authorization",
  title: "Authorization"
}];

<Recipe>
  <Content>
    This tutorial demonstrates how to configure Apache to add authentication and authorization to your web app. We recommend that you log in to follow this quickstart with examples configured for your account.

    <Section id={sections[0].id} title={sections[0].title} stepNumber="1">
      This tutorial and sample project have been tested with the following:

      * Apache 2.4
    </Section>

    <Section id={sections[1].id} title={sections[1].title} stepNumber="2">
      First, install the `mod_auth_openidc` module for Apache.

      You can get the binaries from [GitHub](https://github.com/zmartzone/mod_auth_openidc/releases) and install them for your OS. If your OS isn't compatible with any of the binaries, you can still [build it from source](https://github.com/zmartzone/mod_auth_openidc/blob/master/INSTALL).

      Once you've installed the module, enable it for Apache with the `a2enmod` command. To learn more, read [a2enmod on Ubuntu Manpage](https://manpages.ubuntu.com/manpages/focal/man8/a2enmod.8.html):

      ```text lines
      a2enmod auth_openidc
      ```

      <Info>
        For Windows, you can use [this Powershell script](https://github.com/enderandpeter/win-a2enmod#installation) to get `a2enmod` working on your system.
      </Info>
    </Section>

    <Section id={sections[2].id} title={sections[2].title} stepNumber="3">
      Update your new configuration file (`auth_openidc.conf`), located in the `/etc/apache2/mods-available` folder.

      <Info>
        For Windows, you must use the `/apache/conf/httpd.conf` file.
      </Info>
    </Section>

    <Section id={sections[3].id} title={sections[3].title} stepNumber="4">
      In the Auth0 Dashboard:

      1. Go to **Applications** > **Applications**, and then select your application from the list.
      2. Switch to the **Settings** view, and then locate the **Application URIs** section.
      3. Add the value of `OIDCRedirectURI` to **Allowed Callback URLs**.
      4. Locate **Advanced Settings** at the bottom of the page.
      5. Switch to the **OAuth** view.
      6. Set **JSON Web Token (JWT) Signature Algorithm** to `RS256`.
    </Section>

    <Section id={sections[4].id} title={sections[4].title} stepNumber="5">
      You can configure Apache to protect a specific location based on the value of a claim in the user’s ID token by adding a `Location` block to your `auth_openidc.conf` file.

      For example, you could create an Action that reads the user’s roles, and then adds a claim that grants access to a protected location:

      ```js lines
      exports.onExecutePostLogin = async (event, api) => {
        const roles = event.authorization.roles; // ['user', 'admin']
          if (roles.includes('admin')) {
          api.idToken.setCustomClaim('folder', 'admin');
        }
      };
      ```
    </Section>

    ## Next Steps

    Excellent work! If you made it this far, you should now have login, logout, and user profile information running in your application.

    This concludes our quickstart tutorial, but there is so much more to explore. To learn more about what you can do with Auth0, check out:

    * [Auth0 Dashboard](https://manage.auth0.com/) - Learn how to configure and manage your Auth0 tenant and applications

    * [Auth0 Marketplace](https://marketplace.auth0.com/) - Discover integrations you can enable to extend Auth0’s functionality
  </Content>

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

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

    <SideMenuSectionItem id={sections[2].id}>
      <CodeGroup>
        ```conf auth_openidc.conf highlight={1-12} lines
        OIDCProviderMetadataURL https://{yourDomain}/.well-known/openid-configuration OIDCClientID {yourClientId} 
        OIDCClientSecret {yourClientSecret}
        OIDCScope "openid name email" 
        OIDCRedirectURI https://your_apache_server/your_path/redirect_uri/ OIDCCryptoPassphrase <passwordToEncryptTheSessionInformationOnTheCookie> 

        <Location /your_path> 
          AuthType openid-connect 
          Require valid-user 
          LogLevel debug 
        </Location>

        <Location /admin> 
          AuthType openid-connect 
          #Require valid-user 
          Require claim folder:admin 
        </Location>
        ```
      </CodeGroup>
    </SideMenuSectionItem>

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

    <SideMenuSectionItem id={sections[4].id}>
      <CodeGroup>
        ```conf auth_openidc.conf highlight={13-16} lines
        OIDCProviderMetadataURL https://{yourDomain}/.well-known/openid-configuration OIDCClientID {yourClientId} 
        OIDCClientSecret {yourClientSecret}
        OIDCScope "openid name email" 
        OIDCRedirectURI https://your_apache_server/your_path/redirect_uri/ OIDCCryptoPassphrase <passwordToEncryptTheSessionInformationOnTheCookie> 

        <Location /your_path> 
          AuthType openid-connect 
          Require valid-user 
          LogLevel debug 
        </Location>

        <Location /admin> 
          AuthType openid-connect 
          #Require valid-user 
          Require claim folder:admin 
        </Location>
        ```
      </CodeGroup>
    </SideMenuSectionItem>
  </SideMenu>
</Recipe>
