gpt4 book ai didi

java - 如何使用 Java EE 安全性从 HttpSessionListener 访问登录主体?

转载 作者:行者123 更新时间:2023-12-02 03:37:07 25 4
gpt4 key购买 nike

我有一个带有 @CustomFormAuthenticationMechanismDefinition 的应用程序,我想在登录和注销时记录用户名、 session ID、IP 地址等。应用此注释的 HttpAuthMechanism 将给定 session 与主体相关联,我可以通过 SecurityContext 访问该主体。通过直接注销,我的日志记录没有问题,但我还想在 session 超时时进行日志记录。因此,我创建了一个 HttpSessionListener,并在其 sessionDestroyed() 方法中尝试通过 SecurityContext 访问登录用户,但它返回一个空集,可能是因为 securityContext 已失效已经。

我想到的一个解决方案是将用户主体存储在 session 参数中(这可能发生在 HttpAuthMechanism 实现中),并从 HttpSessionEvent 从那里访问它> 对象,但这感觉不是最干净的解决方案。我可以使用另一个监听器或其他解决方案吗?

最佳答案

我使用了自定义的 HttpAuthenticationMechanism,如果有人需要它的话,这里就是它(尽管我很高兴收到一些关于它是否有任何安全缺陷或改进的反馈) .

在实现 HttpAuthenticationMechanism@ApplicationScoped 类中:

@Override
public AuthenticationStatus validateRequest(HttpServletRequest request, HttpServletResponse response, HttpMessageContext httpMessageContext) throws AuthenticationException {
if (!httpMessageContext.isProtected()) {
return httpMessageContext.doNothing();
}
HttpSession session = request.getSession(false);

Credential credential = httpMessageContext.getAuthParameters().getCredential();

// If we already have a session, we get the user from it, unless it's a new login
if (session != null && !(credential instanceof UsernamePasswordCredential)) {
User user = (User) session.getAttribute("user");
if (user != null) {
return httpMessageContext.notifyContainerAboutLogin(user, user.getRoles());
}
}

// If we either don't have a session or it has no user attribute, we redirect/forward to login page
if (!(credential instanceof UsernamePasswordCredential)) {
return redirect(request, response, httpMessageContext);
}

// Here we have a Credential, so we validate it with the registered IdentityStoreHandler (injected as idStoreHandler)
CredentialValidationResult validate = idStoreHandler.validate(credential);

Context context = new Context();
context.setIp(request.getRemoteAddr());

if (validate.getStatus() == CredentialValidationResult.Status.VALID) {
session = request.getSession(true);
CallerPrincipal callerPrincipal = validate.getCallerPrincipal();
session.setAttribute("user", callerPrincipal);


context.setUser(callerPrincipal);
context.setSessionId(session.getId());

Logger log = new Logger(logger, "validateRequest", context);

log.debug("Logged in user: " + callerPrincipal.getName());

String redirectPage = "whatYouWant.xhtml";

redirect(request, response, httpMessageContext, redirectPage);

return httpMessageContext.notifyContainerAboutLogin(validate);
} else if (validate.getStatus() == CredentialValidationResult.Status.NOT_VALIDATED) {
return redirect(request, response, httpMessageContext);
} else {
// Logging
return httpMessageContext.responseUnauthorized();
}
}

在实现的HttpSessionListener中:

 @Override
public void sessionDestroyed(HttpSessionEvent se) {
User user = (User) se.getSession().getAttribute("user");

if (user != null) {
// logging
}
}

关于java - 如何使用 Java EE 安全性从 HttpSessionListener 访问登录主体?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56853513/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com