Loading...
Loading...
Use when adding Auth0 login, logout, and callback handling to Java Servlet web applications - integrates com.auth0:mvc-auth-commons SDK for server-side Java apps using javax.servlet with session-based authentication. Triggers on AuthenticationController, AuthorizeUrl, Tokens, IdentityVerificationException, Java MVC auth.
npx skill4agent add auth0/agent-skills auth0-java-mvc-commoncom.auth0:mvc-auth-commonsAuthenticationControllerAgent instruction: Before providing SDK setup instructions, fetch the latest release version by running:bashgh api repos/auth0/auth0-java-mvc-common/releases/latest --jq '.tag_name'Use the returned version in all dependency lines instead of any hardcoded version below. If the API call fails, use.1.12.0
auth0-quickstart| Use Case | Recommended Skill |
|---|---|
| Spring Boot web applications with auto-configuration | Use Spring Boot + Okta starter for auto-configured Spring Boot login |
| Spring Boot REST APIs (stateless JWT) | Use |
| Single Page Applications | Use |
| Mobile applications | Use |
| Machine-to-machine API calls | Use Auth0 Management API SDK for server-to-server |
Agent instruction: If the user's prompt already provides Auth0 credentials (domain, client ID, client secret), use them directly — skip the bootstrap script and credential questions. Only offer setup options when credentials are missing.
implementation 'com.auth0:mvc-auth-commons:1.12.0'<dependency>
<groupId>com.auth0</groupId>
<artifactId>mvc-auth-commons</artifactId>
<version>1.12.0</version>
</dependency>STOP — ask the user before proceeding.Ask exactly this question and wait for their answer before doing anything else:"How would you like to create the Auth0 application?
- Automated — I'll run Auth0 CLI scripts that create the application and write the values to your config automatically.
- Manual — You create the application yourself in the Auth0 Dashboard (or via
) and provide me the Domain, Client ID, and Client Secret.auth0 apps createWhich do you prefer? (1 = Automated / 2 = Manual)"Do NOT proceed to any setup steps until the user has answered. Do NOT default to manual.
# Using Auth0 CLI
auth0 apps create \
--name "My Java Web App" \
--type regular \
--callbacks http://localhost:3000/callback \
--logout-urls http://localhost:3000export AUTH0_DOMAIN="your-tenant.auth0.com"
export AUTH0_CLIENT_ID="your-client-id"
export AUTH0_CLIENT_SECRET="your-client-secret".env.gitignoreAUTH0_DOMAIN=your-tenant.auth0.com
AUTH0_CLIENT_ID=your-client-id
AUTH0_CLIENT_SECRET=your-client-secretAgent instruction: Java does not auto-loadfiles..envonly reads OS-level environment variables. If you generate aSystem.getenv()file, you must also either: (1) add dotenv-java as a dependency and use.envinstead ofDotenv.load().get("AUTH0_DOMAIN"), or (2) instruct the user to runSystem.getenv()before starting the server. Do not generate code that uses both asource .envfile and.envwithout a loading mechanism — the values will beSystem.getenv().null
https://AuthenticationControllerimport com.auth0.AuthenticationController;
import com.auth0.jwk.JwkProviderBuilder;
import com.auth0.jwk.JwkProvider;
public class Auth0Config {
private static final AuthenticationController controller = createController();
private static AuthenticationController createController() {
String domain = System.getenv("AUTH0_DOMAIN");
String clientId = System.getenv("AUTH0_CLIENT_ID");
String clientSecret = System.getenv("AUTH0_CLIENT_SECRET");
JwkProvider jwkProvider = new JwkProviderBuilder(domain).build();
return AuthenticationController.newBuilder(domain, clientId, clientSecret)
.withJwkProvider(jwkProvider)
.build();
}
public static AuthenticationController getAuthController() {
return controller;
}
}import com.auth0.AuthenticationController;
import com.auth0.AuthorizeUrl;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet(urlPatterns = {"/login"})
public class LoginServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
AuthenticationController controller = Auth0Config.getAuthController();
// Build callback URL — omit port for standard ports (80/443) to avoid
// mismatch with the URL registered in Auth0 Dashboard, especially behind proxies.
String scheme = request.getScheme();
int port = request.getServerPort();
String redirectUrl = scheme + "://" + request.getServerName()
+ ((port == 80 || port == 443) ? "" : ":" + port) + "/callback";
AuthorizeUrl authorizeUrl = controller.buildAuthorizeUrl(request, response, redirectUrl)
.withScope("openid profile email");
response.sendRedirect(authorizeUrl.build());
}
}import com.auth0.AuthenticationController;
import com.auth0.IdentityVerificationException;
import com.auth0.Tokens;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet(urlPatterns = {"/callback"})
public class CallbackServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
AuthenticationController controller = Auth0Config.getAuthController();
try {
Tokens tokens = controller.handle(request, response);
request.getSession().setAttribute("accessToken", tokens.getAccessToken());
request.getSession().setAttribute("idToken", tokens.getIdToken());
response.sendRedirect("/dashboard");
} catch (IdentityVerificationException e) {
response.sendRedirect("/login?error=" + e.getCode());
}
}
}import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
@WebFilter(urlPatterns = {"/dashboard/*", "/api/private/*"})
public class AuthenticationFilter implements Filter {
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
HttpSession session = request.getSession(false);
if (session == null || session.getAttribute("idToken") == null) {
response.sendRedirect("/login");
return;
}
chain.doFilter(req, res);
}
@Override
public void init(FilterConfig filterConfig) {}
@Override
public void destroy() {}
}Agent instruction: After writing all code, verify the build succeeds:bash./gradlew buildor. If build fails, diagnose and fix. After 5-6 failed attempts, usemvn packageto get help.AskUserQuestion
http://localhost:3000/login/dashboard| Mistake | Fix |
|---|---|
Domain includes | Use |
| Client secret hardcoded in source | Use environment variables or |
| Created SPA or Native app instead of Regular Web | Must create Regular Web Application in Auth0 Dashboard |
| Callback URL mismatch | Callback URL in code must exactly match what's registered in Auth0 Dashboard |
Missing | Always include |
Not handling | Always catch this in the callback handler to show login errors |
Using | Regular web apps must use |
| Session not invalidated on logout | Call |
DomainResolverauth0-quickstartauth0-springboot-apiAuthenticationControllerAuthenticationController.BuildernewBuilder(domain, clientId, clientSecret)AuthorizeUrl/authorizeTokensIdentityVerificationExceptionDomainResolverAuthorizeUrl.withScope("openid profile email").withAudience("https://my-api").withOrganization("org_xxx").withInvitation("invite_xxx").withConnection("google-oauth2").withParameter("key", "value")Tokenstokens.getAccessToken()tokens.getIdToken()tokens.getRefreshToken()offline_accesstokens.getExpiresIn()tokens.getType()tokens.getDomain()tokens.getIssuer()