绑定用户实体和 GlassFish 主体

2024-04-20

我有一个实体类User其中包含用户名、名字、姓氏和密码等信息,我有 GlassFish 3.1 服务器设置来执行身份验证。到目前为止,一切都很好。在容器对用户进行身份验证后,我需要某种方法将主体绑定到实际的用户实体。毕竟,GlassFish 告诉我用户“laurens”已通过身份验证,但它没有给我相应的信息User entity.

为此我编写了一个 JSF 托管 beanUserController。我想知道的是,这是否是查找实际实体的正确方法,以及是否存在我没​​有看到的明显陷阱。

UserController具有以下字段:

@EJB
private UserFacade userFacade;

private User user;

The userFacade是一个需要持久化和查找的无状态会话 beanUser实例。这userJSF 页面使用 field 来获取和设置用户的属性。

我使用以下方法来执行绑定并附带两个辅助方法:

@PostConstruct
private void init() {
    try {
        user = userFacade.find(getUserPrincipal().getName());
    } catch (NullPointerException ex) {
        // Intentionally left empty -- User is not logged in.
    }
}

private HttpServletRequest getHttpServletRequest() {
    return (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest();
}

private Principal getUserPrincipal() {
    return getHttpServletRequest().getUserPrincipal();
}

JSF 页面使用以下方法来确定要显示哪些组件(如果用户已经通过身份验证,则无需显示登录表单)、在单击“登录”按钮时对用户进行身份验证,或者注册为单击“注册”按钮后将成为新用户。

public boolean isAuthenticated() {
    return getUserPrincipal() != null;
}

public void authenticate() {
    try {
        getHttpServletRequest().login(user.getEmailAddress(), user.getPassword());
    } catch (Exception ex) {
        // TODO: Handle failed login attempt
    }
}

public void register() {
    userFacade.create(user);
}

这是正确的做法吗?

Thanks!

Edit:

感谢您的投入!我想了一会儿,虽然我认为将密码移动到不同的表对我来说目前处理起来有点太多,但我确实认为我可以通过分离密码来解决一些问题UserController in a @RequestScoped AuthenticationController和一个脱光的@SessionScoped UserController.

The AuthenticationController将有emailAddress and password字段,由网页的电子邮件地址和密码字段绑定。它还将包含public void authenticate()对用户进行身份验证并随后丢弃凭据。这@SessionScoped UserController然后可以绑定到适当的User实体而无需知道密码。事实上,我相信我能够从中删除密码字段User共。


您提出的方法有一些粗糙的地方,但在大多数情况下它是相当好的。

如果您打算存储对User实体,那么最好是在SessionScoped托管 bean。这有它的优点和缺点。明显的优点是

  • the User实体在整个应用程序流程中的所有页面上都可用。这意味着您需要绑定Principal to a User实体在一个会话中只能使用一次。如果需要,您可以在所有页面中重复使用绑定值。

不太明显的缺点是

  • the password字段将在内存中存储相当长的一段时间。最好的情况是,您应该在尝试身份验证后尝试使实体的密码字段无效(无论是否成功,无论该字段包含明文密码还是散列密码)。此外,定义password字段作为延迟获取(FetchType of LAZY) 与默认的 eager fetch (FetchType of EAGER)。如果您实现此操作(特别是密码字段无效),您需要注意涉及在User实体;在这种情况下,最好有一个单独的实体来存储用户的密码(非常不幸,但这就是您必须在某些应用程序中保护密码及其哈希值的程度)。

话虽如此,还需要确保以下几点:

  • 应谨慎处理匿名用户主体。如果您没有编写一个强制访问控制机制来保护应用程序的“私有”页面的过滤器,那么您应该更多地担心页面中授权逻辑的构建方式,而不是您不必担心当您使用过滤器时。匿名主体与任何其他主体一样,只是它不受领域中身份的支持。如果主体到用户实体绑定方案由于某种原因失败,您必须使会话无效并再次将用户重定向到登录页面,特别是如果您的页面依赖于User实体而不是Principal对象强制执行访问控制检查。
  • 确保您有一个单独的应用程序登录页面。这对于大多数接受登录页面中存在的表单形式的用户凭据的应用程序来说是更可取的;如果表单位于对话框或其他一些装置中,则通常不需要单独的登录页面。这是可取的,原因很简单,您希望登录过程实现 POST-REDIRECT-GET 模式 - 成功登录到您的应用程序的用户必须重定向到应用程序的主页。如果不这样做,将导致浏览器刷新(由有权访问终端的任何人执行)将重新提交凭据;很明显,使用模式对话框或类似内容的应用程序不太容易受到此问题的影响。

Update

这是基于编辑的问题。如果您实施authenticate方法建议,你可以实现你的绑定方案User实体到Principal仅在身份验证成功后。

以下是我的应用程序中类似实现的复制:

public String authenticate()
{
    String result = null;
    ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext();
    HttpServletRequest request = (HttpServletRequest) externalContext.getRequest();
    try
    {
        request.login(userId, password);
        result = "/private/MainPage.xhtml?faces-redirect=true";
    }
    catch (ServletException ex)
    {
        logger.error("Failed to authenticate user.", ex);
        FacesMessage facesMessage = new FacesMessage(FacesMessage.SEVERITY_ERROR, Messages.getString("Login.InvalidIdOrPasswordMessage"), null);
        FacesContext.getCurrentInstance().addMessage(null, facesMessage);
    }
    return result;
}

这是从 Facelet 调用的:

<h:form id="LoginForm" acceptcharset="UTF-8">
    <p>
        <h:outputLabel for="userid" value="#{msg['Login.userid.label']}" />
        <h:inputText id="userid" value="#{loginBean.userId}" />
    </p>
    <p>
        <h:outputLabel for="password" value="#{msg['Login.password.label']}" />
        <h:inputSecret id="password" value="#{loginBean.password}" />
    </p>
        <h:commandButton id="submit" value="#{msg['Login.submit.label']}"
            action="#{loginBean.authenticate}" />
</h:form>

请注意在身份验证成功的情况下使用 POST-REDIRECT-GET 模式。我留下了一些与重定向前当前会话失效相关的代码,以防止会话固定攻击。的绑定User实体到Principal只要是在会话范围的 bean 中完成,就会在新会话中完成。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

绑定用户实体和 GlassFish 主体 的相关文章

  • 用 @DataJpaTest 注释的测试不是用 @Autowired 注释的自动装配字段

    我有一个 Spring Boot 应用程序 其中包含 Spring Data Jpa 存储库 我需要围绕这个存储库运行单元 或组件 测试 我对 Spring Data Jpa 没有太多经验 这是我的测试 这很简单 我无法让它通过 impor
  • MP3:一种以毫秒为单位获取任何给定字节位置的位置的方法?

    我创建了一个 servlet 它返回从客户端请求的任何给定字节位置开始的流 来自 MP3 文件 这允许客户端在任何给定字节位置立即开始播放 而无需进行任何本地查找 现在 我有一个滑块可以直观地显示进度 我正在使用当前字节位置来更新滑块 但是
  • Java 创建浮雕(红/蓝图像)

    我正在编写一个 Java 游戏引擎 http victoryengine org http victoryengine org 并且我一直在尝试生成具有深度的 3D 图像 您可以使用那些红色 蓝色眼镜看到 我正在使用 Java2D 进行图形
  • 由于连接超时,无法通过 ImageIO.read(url) 获取图像

    下面的代码似乎总是失败 URL url new URL http userserve ak last fm serve 126 8636005 jpg Image img ImageIO read url System out printl
  • JTree 节点不会被直观地选择

    不知何故 我无法为我的 JTree 节点启用 选择突出显示 我正在我的项目中使用自定义单元格渲染器 这很可能导致此问题 这是完整的渲染器类代码 protected class ProfessionTreeCellRenderer exten
  • 无法加载 jar 文件的主类

    我使用 Eclipse IDE 开发了一个应用程序 创建应用程序后 我以 jar 格式导出项目 当我尝试运行此 jar 文件时 出现错误 无法加载主类 请帮忙 当您将项目导出为 jar 时 请参阅此所以问题 https stackoverf
  • 有没有好的方法来解析用户代理字符串?

    我有一个Java接收模块User Agent来自最终用户浏览器的字符串的行为需要略有不同 具体取决于浏览器类型 浏览器版本甚至操作系统 例如 FireFox 7 0 Win7 Safari 3 2 iOS9 我明白了User Agent由于
  • Java:从元素创建 DOM 元素,而不是文档

    如您所知 在 Java 中创建 Dom 元素的正确方法是执行以下操作 import org w3c dom Document import org w3c dom Element Document d Element e e d creat
  • 如何将 Spotlight for Help 插入本地化的 macOS 应用程序?

    我正在 macOS 上使用 Swing GUI 框架实现 Java 应用程序 当使用system外观和感觉以及screen菜单栏 Swing 自动插入一个搜索栏 called 聚光灯寻求帮助 https developer apple co
  • Java 变量的作用域

    我不明白为什么这段代码的输出是10 package uno public class A int x 10 A int x 12 new B public static void main String args int x 11 new
  • spring - 强制 @Autowired 字段的 cglib 代理

    我有混合堆栈 EJB 和 Spring 为了将 Spring 自动装配到 EJB 我使用SpringBeanAutowiringInterceptor 不确定这是否会影响我遇到的问题 在尝试通过以下方式自动装配 bean 时 Scope p
  • 所有junit测试后的清理

    在我的项目中 我必须在所有测试之前进行一些存储库设置 这是使用一些棘手的静态规则来完成的 然而 在所有测试之后我不知道如何进行清理 我不想保留一些神奇的静态数字来引用所有测试方法的数量 我应该一直维护它 最受赞赏的方法是添加一些侦听器 该侦
  • 为什么我在 Mac 上看到“java.lang.reflect.InaccessibleObjectException: Unable to make private java.nio.DirectByteBuffer(long,int)accessibl

    我已经在工作中愉快地构建代码好几天了 但突然我的一个项目 不是全部 失败并出现此错误消息 看看下面的答案吧 我是如何修复它的 起初我用谷歌搜索 看到很多有这个问题的人正在使用 Java 16 但我认为 错误 我正在使用 Java 11 因为
  • 具有多种值类型的 Java 枚举

    基本上我所做的是为国家编写一个枚举 我希望不仅能够像国家一样访问它们 而且还能够访问它们的缩写以及它们是否是原始殖民地 public enum States MASSACHUSETTS Massachusetts MA true MICHI
  • jmap - 组织和堆操作会给 jvm 带来开销吗?

    正如标题所述 需要多少开销jmap histo and jmap heap分别带到jvm 如果一个内存敏感的 Java 进程处于OutOfMemory 例如 大约 96 的堆已满 并且无法通过 full gc 清除 其中一项操作是否有可能将
  • 使用 Java 从 S3 上的文件在 S3 上创建 zip 文件

    我在 S3 上有很多文件 需要对其进行压缩 然后通过 S3 提供压缩文件 目前 我将它们从流压缩到本地文件 然后再次上传该文件 这会占用大量磁盘空间 因为每个文件大约有 3 10MB 而且我必须压缩多达 100 000 个文件 所以一个 z
  • 从java中的字符串数组中删除空值

    java中如何从字符串数组中删除空值 String firstArray test1 test2 test4 我需要像这样没有 null 空 值的 firstArray String firstArray test1 test2 test4
  • Path2D 上的鼠标指针检测

    我构建了一个Path2D http docs oracle com javase 7 docs api java awt geom Path2D html表示由直线组成的未闭合形状 我希望能够检测何时单击鼠标并且鼠标指针靠近路径 在几个像素
  • 如何将实例变量传递到 Quartz 作业中?

    我想知道如何在 Quartz 中外部传递实例变量 下面是我想写的伪代码 如何将 externalInstance 传递到此作业中 public class SimpleJob implements Job Override public v
  • 使用 eclipse IDE 配置 angularjs

    我想开始使用 AngularJs 和 Java Spring 进行开发 我使用 Eclipse 作为 IDE 我想配置我的 Eclipse 以使这些框架无缝工作 我知道我可能要求太多 但相信我 我已经做了很多研究 你们是我最后的选择 任何帮

随机推荐

  • 为什么有些对象属性是 UnaryExpression,而另一些对象属性是 MemberExpression?

    根据我的答案采取行动使用 lambda 而不是字符串属性名称选择模型属性 https stackoverflow com questions 3558974 select a model property using a lambda an
  • 删除记录时找不到元素

    JqG rid 4 6 一切正常 唯一的问题是 当我打开 Firefox 调试器并转到控制台时 如果我删除一条记录 单击垃圾桶图标 然后弹出删除对话框 单击删除按钮并刷新页面等 调试器会警告我 没有找到元素 可能的脚本是 gridSelec
  • Python 中 Comet 的最新推荐? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 对 numpy 屏蔽数组的操作给出屏蔽的无效值

    来自 numpy 中屏蔽数组的文档numpy 数组上的操作 https docs scipy org doc numpy reference maskedarray generic html operations on masked arr
  • Java 中的内存管理

    如何在Java中手动删除对象 有没有类似的方法obj delete or obj kill 没有真正的办法 Java有一个特殊的垃圾收集器这会为你做到这一点 一旦您的对象没有任何对它的引用 它就会在某个时候被垃圾收集器拾取并销毁 From
  • 带有多个 webapp 的 tomcat ajp 连接器

    我有一个 tomcat 服务器 带有 webapps ROOT 应用程序 以 Apache 为前端 LoadModule proxy ajp module modules mod proxy ajp so and ProxyPass ajp
  • 如何在 Swift 中返回序列?

    我正在尝试编写一个扩展Matrix书中的例子 稍微调整为通用的 https stackoverflow com q 24136604 458193 我正在尝试编写一个名为的方法getRow返回给定行的值序列 在 C 中 我会这样写 IEnu
  • 迭代 JSON 数据? [关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 我有一个如下所示的 JSON 数据
  • 数据源中 String 类型的给定值无法转换为指定目标列的 bigint 类型

    这是我的代码 protected void SendToServer Click object sender EventArgs e DataTable Values Session valuesdt as DataTable if Val
  • 必须在创建 QCoreApplication 之前设置属性 Qt::AA_UseSoftwareOpenGL

    所以我的环境是 Windows 10 截至 2019 年 11 月 8 日更新 通过 miniconda 安装了 Python 3 6 Spyder 4 运行 miniconda shell 激活虚拟环境 运行 Spyder 我得到以下信息
  • .PO 到 .MO - 程序转换 (PHP)

    我计划允许用户通过 PHP 用户界面生成 POT 文件 PO 文件 作为 CMS 解决方案的一部分 一旦生成这些文件 简单一点 我希望允许我的系统自动将这些文件转换为 MO 文件以响应用户 POST 请求 我在SO上看到了以下问题 php
  • InvalidArgumentError:ConcatOp:输入的维度应该匹配

    Tensorflow 1 7使用dynamic rnn时 一开始运行良好 但在第32步 当我运行代码时它发生变化 时 出现错误 当我使用较小的批次时 代码似乎可以运行更长时间 但是错误仍然弹出 只是无法弄清楚出了什么问题 from mapp
  • 一个带有一个等号的 php if 语句...?这是什么意思?

    我正在尝试解决问题 并且需要理解这个 if 语句的含义 if confirmation payment modules gt confirmation 我能找到的所有资源只显示带有双等号的 if 语句 而不是单等号 这是 php if 的简
  • 错误:没有运算符 << 与这些操作数匹配?

    我正在练习一些 C 试图离开 Java 我偶然发现了这个恼人的错误 错误 没有操作符 这个错误在我的 cpp 文件中 还有其他错误 但我现在不关心它们 void NamedStorm displayOutput NamedStorm sto
  • 是否可以在 Android Wear 上显示 Google 地图视图?

    是否可以在 Android Wear 上显示 Google 地图视图 我想在地图上向用户显示特定位置 您可以设法在您的 Activity 中嵌入 MapView 但是这是行不通的因为 Android Wear 无法直接访问网络 然而 你能做
  • 使用 ImageIO 发送图像流?

    我设置了一个 ServerSocket 和一个 Socket 因此 ServerSocket 使用 ImageIO write 发送图像流 并且 Socket 尝试读取它们并用它们更新 JFrame 所以我想知道 ImageIO 是否可以检
  • 使用 Bash 下载并在 wordpress wp-config.php 中插入盐字符串

    如何插入变量 SALT 的内容在特定点 线或串 使用 Bash 脚本从 WordPress 获取像 wp contet php 这样的文件 SALT curl L https api wordpress org secret key 1 1
  • 应用 CSS 过滤器时,内联 SVG 在 iOS 和 Safari 中消失

    情况是我有一个内联 SVG 生成的格伦蒂康 https github com filamentgroup grunticon并插入到 DOM 中 它是灰色背景上的白色 带有阴影 我对阴影使用了以下 CSS svg webkit filter
  • 在 Python 中注释函数的正确方法是什么?

    Python 中是否有一种普遍接受的注释函数的方法 以下情况可以接受吗 Create a new user def add self 正确的方法是提供文档字符串 那样 help add 也会吐出你的评论 def add self Creat
  • 绑定用户实体和 GlassFish 主体

    我有一个实体类User其中包含用户名 名字 姓氏和密码等信息 我有 GlassFish 3 1 服务器设置来执行身份验证 到目前为止 一切都很好 在容器对用户进行身份验证后 我需要某种方法将主体绑定到实际的用户实体 毕竟 GlassFish