AEM 6.3无法获取登录用户唯一会话ID,寻求技术解决方案
Hey there, let's break down how to solve this session ID problem you're hitting in AEM 6.3. First, let's clarify why the JCR session ID isn't working for you:
The Repository/JCR session ID changes on every page refresh because AEM ties these sessions directly to individual requests or resource resolutions—they're designed to be short-lived and aren't meant to represent a user's persistent login session. That's why you need the HTTP session's
JSESSIONIDinstead.
Here's how to get and use that stable JSESSIONID for your SOAP service, tailored to your requirements:
1. Get JSESSIONID from the HTTP Request Context
If your SOAP service is implemented as a Sling Servlet or tied to a request (which it should be, since you're dealing with a logged-in user), you can directly pull the JSESSIONID from the SlingHttpServletRequest:
import javax.servlet.http.HttpSession; import org.apache.sling.api.SlingHttpServletRequest; import org.apache.sling.settings.SlingSettingsService; import org.osgi.service.component.annotations.Reference; // Inject SlingSettingsService via OSGi @Reference private SlingSettingsService slingSettingsService; public UserSessionDto getAuthorUserSessionInfo(SlingHttpServletRequest request) { // First, verify we're on an Author instance if (!slingSettingsService.getRunModes().contains("author")) { throw new IllegalStateException("This method is only available on Author instances"); } // Get existing HTTP session (false = don't create a new session if none exists) HttpSession userSession = request.getSession(false); if (userSession == null || userSession.isNew()) { throw new UnauthorizedException("No active user session found"); } // Extract the stable JSESSIONID String jsessionId = userSession.getId(); // Pull user info and session expiration details String userId = (String) userSession.getAttribute("user.name"); // Calculate absolute expiration timestamp (max inactive interval in seconds * 1000 + last accessed time) long expiryTimestamp = userSession.getMaxInactiveInterval() * 1000L + userSession.getLastAccessedTime(); // Package into your required response format (e.g., a DTO for the SOAP method) UserSessionDto sessionDto = new UserSessionDto(); sessionDto.setSessionId(jsessionId); sessionDto.setUserId(userId); sessionDto.setExpiryTime(expiryTimestamp); return sessionDto; } // Example DTO class for SOAP response class UserSessionDto { private String sessionId; private String userId; private long expiryTime; // Getters and setters }
Key Notes:
- The
JSESSIONIDstays consistent for the user's entire login session (until they log out, the session expires, or the server invalidates it). - You must ensure the third-party app includes the
JSESSIONIDcookie in its SOAP requests—this is how AEM associates the request with the user's active session.
2. Handling Non-Request Contexts (If Needed)
If your SOAP method runs outside a request context (e.g., a background service), you'll need the third-party app to first authenticate against AEM's author instance (using the standard login form or Sling Authentication API) to retrieve the JSESSIONID cookie. They can then pass this cookie in subsequent SOAP calls, allowing your service to validate and use the session.
3. Validate Session & Expiration
To confirm the JSESSIONID is valid and hasn't expired, use the HttpSession object to check:
userSession.isNew(): Ensures the session isn't a fresh, unauthenticated one.userSession.getMaxInactiveInterval(): Gets the remaining time until expiration (calculated from the last access time).
4. Restrict to Author Instance
As you specified, this functionality should only work on the author instance. Using SlingSettingsService to check for the "author" run mode ensures you don't expose this on publish instances accidentally.
内容的提问来源于stack exchange,提问作者Prashasti

