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

如何在Arquillian功能测试中创建Payara用户账户?

嵌入式Payara + Arquillian 测试@RolesAllowed保护的REST接口方案

你好,针对你目前在嵌入式Payara(4.1.2.174)上用Arquillian+Graphene测试带@RolesAllowed注解的REST接口认证功能的困境,我整理了几个无需切换到远程实例的可行方案:

方案1:通过Payara嵌入式编程API直接创建用户/角色

嵌入式Payara其实暴露了内部管理API,你可以在测试启动阶段通过编程方式操作安全域,添加测试用户和角色。步骤如下:

  1. 确保依赖正确:在你的测试构建脚本(比如Maven的pom.xml)中引入Payara嵌入式全量依赖,版本对应4.1.2.174,scope设为test:
<dependency>
    <groupId>fish.payara.extras</groupId>
    <artifactId>payara-embedded-all</artifactId>
    <version>4.1.2.174</version>
    <scope>test</scope>
</dependency>
  1. 编写测试前置逻辑:在测试类中添加@BeforeClass注解的方法,或者结合Arquillian的部署钩子,获取嵌入式容器的内部实例来操作安全域:
import org.glassfish.api.admin.ServerEnvironment;
import org.glassfish.internal.api.Globals;
import com.sun.enterprise.security.auth.realm.Realm;
import com.sun.enterprise.security.auth.realm.file.FileRealm;

@BeforeClass
public static void setupTestUsers() throws Exception {
    // 获取Payara默认的文件型安全域
    Realm realm = Realm.getInstance("file");
    if (realm instanceof FileRealm) {
        FileRealm fileRealm = (FileRealm) realm;
        // 添加测试用户:用户名、加密前密码、关联角色数组
        fileRealm.addUser("testAdmin", "adminPass".toCharArray(), new String[]{"ADMIN"});
        fileRealm.addUser("testUser", "userPass".toCharArray(), new String[]{"USER"});
    }
}

注意:如果默认的file安全域不符合你的测试需求,也可以通过API创建自定义安全域,不过大部分场景下默认域足够覆盖认证测试。

方案2:在WAR包中嵌入预配置的安全域数据

你可以把用户、角色的预配置文件打包到WAR中,配合glassfish-web.xml(或payara-web.xml)指定安全域路径,让嵌入式Payara启动时自动加载这些数据:

  1. 生成用户数据文件:

    • 先通过本地Payara的asadmin命令生成加密后的用户密码:asadmin create-file-user --userpassword yourPass testUser,然后复制输出的加密字符串
    • 在项目资源目录创建users.properties:testUser={SSHA}xxxxxxxxx(替换成刚才生成的加密密码)
    • 创建groups.properties:testUser=USER,ADMIN
  2. 配置安全域映射:在WEB-INF/glassfish-web.xml中添加配置,指定安全域和数据文件路径:

<glassfish-web-app>
    <security-role-mapping>
        <role-name>ADMIN</role-name>
        <group-name>ADMIN</group-name>
    </security-role-mapping>
    <security-role-mapping>
        <role-name>USER</role-name>
        <group-name>USER</group-name>
    </security-role-mapping>
    <realm>file</realm>
    <property name="fileRealm.users" value="${com.sun.aas.instanceRoot}/config/users.properties"/>
    <property name="fileRealm.groups" value="${com.sun.aas.instanceRoot}/config/groups.properties"/>
</glassfish-web-app>
  1. 打包到部署包:在Arquillian的@Deployment方法中,把配置文件添加到WAR的对应路径:
@Deployment
public static WebArchive createDeployment() {
    return ShrinkWrap.create(WebArchive.class)
            // 添加你的应用类、REST接口等资源
            .addAsResource("users.properties", "config/users.properties")
            .addAsResource("groups.properties", "config/groups.properties")
            .addAsWebInfResource("glassfish-web.xml");
}

方案3:利用Arquillian容器配置传递启动命令

你可以在arquillian.xml中配置嵌入式Payara的启动参数,模拟执行asadmin创建用户的命令——虽然嵌入式模式没有独立的asadmin进程,但Payara支持通过启动参数直接执行管理命令:

<container qualifier="payara-embedded" default="true">
    <configuration>
        <property name="glassFishHome">${payara.embedded.home}</property>
        <property name="asadminCommands">
            create-file-user --userpassword adminPass --groups ADMIN testAdmin;
            create-file-user --userpassword userPass --groups USER testUser;
        </property>
    </configuration>
</container>

注意:这个方案依赖Payara嵌入式容器的实现细节,你可以针对4.1.2.174版本测试是否生效,如果参数格式不兼容,可调整命令的写法。

关于旧方案失效的说明

你提到的早期方案(比如注入CommandRunner)失效,是因为Payara 4.x对GlassFish的管理API做了重构,CommandRunner的包路径和调用逻辑都发生了变化;而找不到对应的Server类,是因为嵌入式Payara的类路径中没有暴露该公开API,需要直接使用内部的GlassFish/Payara类(比如方案1中的Realm相关实现)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 06:39:42