【问题标题】:Logging user info and update operations from REST / EJB service从 REST / EJB 服务记录用户信息和更新操作
【发布时间】:2019-11-13 10:46:55
【问题描述】:

我需要从我的剩余资源中记录所有更新操作并存储到数据库日志表中。

这个想法是存储如下信息:

  • 登录用户
  • 关于更新/保存实体的操作说明
  • 更新的字段和引用键

我的应用程序与 Java EE8 兼容,它使用 REST / EJB 和 CDI 的东西。

起初我想在 EJB 端处理所有这些东西,但是暴露的服务不需要在方法签名上登录用户,所以添加它会导致强制..

有什么方法可以发送用户信息,一般是通过webrequest检索(我们使用会话令牌模型认证)并通过EJB注入?

【问题讨论】:

  • “通过 ejb 注入”是什么意思?也许 entitylisteners 帮助(我们也使用它们)stackoverflow.com/questions/10765508/…
  • entitylistener 可能确实有帮助,但主要问题是:如何从 EJB 获取记录的用户信息,这些信息实际上是从 REST 端的 HttpServletRequest 检索的?

标签: authentication ejb cdi java-ee-8


【解决方案1】:

如果您的会话管理设置正确,您可以通过以下方式注入会话上下文:

@Resource
SessionContext sessionContext;

然后:

sessionContext.getCallerPrincipal().getName()

是您的登录用户。

【讨论】:

  • callerprincipal 是匿名的,可能是因为系统认证有自己的机制
【解决方案2】:

如前所述,SessionContext.getCallerPrincipal().getName() 不起作用,因为身份验证机制不提供它。

经过一些尝试,我发现了这个:

在 EJB 方面

@RequestScoped
public class UserInfo {

    private String userId;

    public String getUserId() {
        return userId;
    }

    public void setUserId(String userId) {
        if (this.userId != null) throw new UncheckedException("cannot infer userid twice");
        this.userId = userId;
    }
}

在 REST 方面

@Inject
UserInfo userInfo;

void userAuthenticated(...) {

    String userId = ... // get userid from access token through **WebRequest** object

    userInfo.setUserId(userId);

}

旁注

老实说,我更愿意在 UserInfo 构造函数上注入 userid,但我不允许这样做,因为 WebRequest 对象不属于 EJB上下文

另一种方式

使用响应过滤器将所有日志记录过程移至 REST 端。

示例代码:

@Provider
public class LoggingFilter implements ContainerResponseFilter {


    @Context
    HttpServletRequest webRequest;

    @Context
    ResourceInfo resinfo;

    @Inject
    LoggingService loggingService;


    @Override
    public void filter(ContainerRequestContext containerRequestContext, ContainerResponseContext containerResponseContext) {

        final Method resourceMethod = resinfo.getResourceMethod();

        if (resourceMethod.isAnnotationPresent(Loggable.class) && containerResponseContext.getStatusInfo().getFamily() == Response.Status.Family.SUCCESSFUL) {

            // get all method's info and log to database ...

        }
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-02-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多