You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

AEM 6.2中基于Token的外部用户认证实现方案咨询

Step-by-Step Implementation for JWT Authentication in AEM

I’ve implemented similar flows in AEM before—here’s a practical breakdown of how to build this:

1. Create an OSGi Servlet to Handle Authentication Requests

This servlet will accept the form submission, process credentials, call your legacy API, and manage the JWT token.

Servlet Code Example

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.servlets.SlingAllMethodsServlet;
import org.osgi.service.component.annotations.Component;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.json.JSONObject;

import javax.servlet.Servlet;
import javax.servlet.ServletException;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Base64;

@Component(
        service = Servlet.class,
        property = {
                "sling.servlet.paths=/bin/legacy-auth/login",
                "sling.servlet.methods=POST",
                "sling.servlet.extensions=json"
        }
)
public class LegacyAuthServlet extends SlingAllMethodsServlet {

    private static final Logger LOG = LoggerFactory.getLogger(LegacyAuthServlet.class);
    private static final String LEGACY_API_AUTH_URL = "https://your-legacy-api-domain.com/auth/token"; // Replace with your API URL

    @Override
    protected void doPost(SlingHttpServletRequest request, SlingHttpServletResponse response) throws ServletException, IOException {
        // 1. Grab form credentials
        String username = request.getParameter("username");
        String password = request.getParameter("password");

        if (username == null || password == null || username.isBlank() || password.isBlank()) {
            response.setStatus(SlingHttpServletResponse.SC_BAD_REQUEST);
            response.getWriter().write("{\"error\": \"Username or password cannot be empty\"}");
            return;
        }

        try {
            // 2. Encode credentials (adjust based on your API's requirements)
            // Example: Basic Auth encoding
            String rawCreds = username + ":" + password;
            String encodedCreds = Base64.getEncoder().encodeToString(rawCreds.getBytes(StandardCharsets.UTF_8));

            // 3. Call legacy authentication API
            HttpClient httpClient = HttpClients.createDefault();
            HttpPost authPost = new HttpPost(LEGACY_API_AUTH_URL);

            // Set headers per your API specs
            authPost.setHeader("Authorization", "Basic " + encodedCreds);
            authPost.setHeader("Content-Type", "application/json");

            // If your API expects a JSON payload instead of Basic Auth:
            // JSONObject payload = new JSONObject();
            // payload.put("username", username);
            // payload.put("password", password);
            // authPost.setEntity(new StringEntity(payload.toString()));

            HttpResponse apiResponse = httpClient.execute(authPost);
            int statusCode = apiResponse.getStatusLine().getStatusCode();

            if (statusCode == SlingHttpServletResponse.SC_OK) {
                // 4. Extract JWT from API response
                HttpEntity responseEntity = apiResponse.getEntity();
                String responseBody = EntityUtils.toString(responseEntity);
                JSONObject jsonResponse = new JSONObject(responseBody);
                String jwtToken = jsonResponse.getString("token"); // Adjust field name to match your API

                // 5. Store JWT securely in an HttpOnly cookie
                setSecureAuthCookie(response, jwtToken);

                // Return success response to frontend
                response.setStatus(SlingHttpServletResponse.SC_OK);
                response.getWriter().write("{\"success\": true, \"message\": \"Login successful\"}");
            } else {
                // Handle failed authentication
                response.setStatus(statusCode);
                response.getWriter().write("{\"error\": \"Invalid credentials or API error\"}");
            }
        } catch (Exception e) {
            LOG.error("Authentication failed due to internal error", e);
            response.setStatus(SlingHttpServletResponse.SC_INTERNAL_SERVER_ERROR);
            response.getWriter().write("{\"error\": \"Server encountered an issue during login\"}");
        }
    }

    private void setSecureAuthCookie(SlingHttpServletResponse response, String jwtToken) {
        javax.servlet.http.Cookie authCookie = new javax.servlet.http.Cookie("legacy_auth_token", jwtToken);
        authCookie.setHttpOnly(true); // Block JS access to prevent XSS
        authCookie.setSecure(true); // Only send over HTTPS
        authCookie.setSameSite(javax.servlet.http.Cookie.SameSite.STRICT); // Mitigate CSRF
        authCookie.setPath("/"); // Make cookie available across the entire site
        authCookie.setMaxAge(86400); // Expire after 1 day (adjust as needed)
        response.addCookie(authCookie);
    }
}

2. Project Dependencies

Add these to your pom.xml to enable HTTP calls and JSON parsing:

<!-- Apache HttpClient for API calls -->
<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
    <version>4.5.14</version>
    <scope>provided</scope>
</dependency>

<!-- JSON parsing library -->
<dependency>
    <groupId>org.json</groupId>
    <artifactId>json</artifactId>
    <version>20230227</version>
    <scope>provided</scope>
</dependency>

3. Frontend Form Integration

Your public site’s login form should submit to the servlet path:

<form action="/bin/legacy-auth/login.json" method="POST">
    <div>
        <label for="username">Username:</label>
        <input type="text" id="username" name="username" required>
    </div>
    <div>
        <label for="password">Password:</label>
        <input type="password" id="password" name="password" required>
    </div>
    <button type="submit">Login</button>
</form>

4. Key Security Practices

  • Avoid Hardcoding: Move the legacy API URL to an OSGi configuration so you can update it without redeploying code.
  • Input Sanitization: Sanitize username/password inputs to prevent injection attacks.
  • Rate Limiting: Add rate limiting to the servlet (via AEM Dispatcher or custom code) to block brute-force attempts.
  • Token Validation: For protected resources, create a filter that checks the JWT cookie, validates the token (either via the legacy API or signature verification), and allows/blocks access.

内容的提问来源于stack exchange,提问作者isystems_uk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 06:28:24