如何使用 WildFly 执行 EJB DB RBAC?
How to perform EJB DB RBAC with WildFly?
我正在尝试创建一个执行 EJB RMI 以与 server/DB 交互的富客户端。以前,我与远程系统进行通信以验证用户身份。然后我使用密钥库和集群将 HTTPS 通信添加到环境中。那时一切正常。
基于文件的身份验证是迈向数据库身份验证和授权的过渡步骤。我可能仍然有来自那个挥之不去并影响这个新步骤的配置,我不确定。
以下是尝试通过客户端进行身份验证时的失败消息:
Jan 19, 2017 12:51:52 PM org.jboss.ejb.client.EJBClient <clinit>
INFO: JBoss EJB Client version 2.1.4.Final
Jan 19, 2017 12:51:52 PM org.xnio.Xnio <clinit>
INFO: XNIO version 3.4.0.Final
Jan 19, 2017 12:51:52 PM org.xnio.nio.NioXnio <clinit>
INFO: XNIO NIO Implementation Version 3.4.0.Final
Jan 19, 2017 12:51:52 PM org.jboss.remoting3.EndpointImpl <clinit>
INFO: JBoss Remoting version 4.0.21.Final
Jan 19, 2017 12:51:53 PM org.jboss.ejb.client.remoting.ConfigBasedEJBClientContextSelector setupEJBReceivers
WARN: Could not register a EJB receiver for connection to 10.0.0.1:8443
javax.security.sasl.SaslException: Authentication failed: all available authentication mechanisms failed:
JBOSS-LOCAL-USER: javax.security.sasl.SaslException: Failed to read server challenge [Caused by java.io.FileNotFoundException: /home/appsrv/wildfly-10.1.0.Final/domain/tmp/auth/local4807198060994958453.challenge (No such file or directory)]
DIGEST-MD5: Server rejected authentication
at org.jboss.remoting3.remote.ClientConnectionOpenListener.allMechanismsFailed(ClientConnectionOpenListener.java:114)
at org.jboss.remoting3.remote.ClientConnectionOpenListener$Capabilities.handleEvent(ClientConnectionOpenListener.java:389)
at org.jboss.remoting3.remote.ClientConnectionOpenListener$Capabilities.handleEvent(ClientConnectionOpenListener.java:241)
at org.xnio.ChannelListeners.invokeChannelListener(ChannelListeners.java:92)
at org.xnio.channels.TranslatingSuspendableChannel.handleReadable(TranslatingSuspendableChannel.java:198)
at org.xnio.channels.TranslatingSuspendableChannel.handleEvent(TranslatingSuspendableChannel.java:112)
at org.xnio.ChannelListeners.invokeChannelListener(ChannelListeners.java:92)
at org.xnio.ChannelListeners$DelegatingChannelListener.handleEvent(ChannelListeners.java:1092)
at org.xnio.ChannelListeners.invokeChannelListener(ChannelListeners.java:92)
at org.xnio.conduits.ReadReadyHandler$ChannelListenerHandler.readReady(ReadReadyHandler.java:66)
at org.xnio.ssl.JsseStreamConduit.run(JsseStreamConduit.java:446)
at org.xnio.ssl.JsseStreamConduit.readReady(JsseStreamConduit.java:547)
at org.xnio.ssl.JsseStreamConduit.readReady(JsseStreamConduit.java:319)
at org.xnio.nio.NioSocketConduit.handleReady(NioSocketConduit.java:89)
at org.xnio.nio.WorkerThread.run(WorkerThread.java:567)
at ...asynchronous invocation...(Unknown Source)
at org.jboss.remoting3.EndpointImpl.doConnect(EndpointImpl.java:294)
at org.jboss.remoting3.EndpointImpl.connect(EndpointImpl.java:430)
at org.jboss.ejb.client.remoting.EndpointPool$PooledEndpoint.connect(EndpointPool.java:192)
at org.jboss.ejb.client.remoting.NetworkUtil.connect(NetworkUtil.java:153)
at org.jboss.ejb.client.remoting.NetworkUtil.connect(NetworkUtil.java:133)
at org.jboss.ejb.client.remoting.ConnectionPool.getConnection(ConnectionPool.java:78)
at org.jboss.ejb.client.remoting.RemotingConnectionManager.getConnection(RemotingConnectionManager.java:51)
at org.jboss.ejb.client.remoting.ConfigBasedEJBClientContextSelector.setupEJBReceivers(ConfigBasedEJBClientContextSelector.java:161)
at org.jboss.ejb.client.remoting.ConfigBasedEJBClientContextSelector.getCurrent(ConfigBasedEJBClientContextSelector.java:118)
at org.jboss.ejb.client.remoting.ConfigBasedEJBClientContextSelector.getCurrent(ConfigBasedEJBClientContextSelector.java:47)
at org.jboss.ejb.client.EJBClientContext.getCurrent(EJBClientContext.java:281)
at org.jboss.ejb.client.EJBClientContext.requireCurrent(EJBClientContext.java:291)
at org.jboss.ejb.client.EJBInvocationHandler.doInvoke(EJBInvocationHandler.java:178)
at org.jboss.ejb.client.EJBInvocationHandler.invoke(EJBInvocationHandler.java:146)
at com.sun.proxy.$Proxy6.getVer(Unknown Source)
at com.test.clientapp.TestClient.authenticate(TestClient.java:208)
at com.test.clientapp.BackgroundServiceEngine.run(BackgroundServiceEngine.java:136)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
在我的 WildFly 域配置中,我通过 GUI 在 -> 安全 -> MySecurityDomain 中的 "ha" 配置文件(分配给我的主机控制器的配置文件)中添加了以下身份验证模块:
name: testds01
code: Database
flag: required
module options:
dsJndiName = java:/TestDS01
principalsQuery = SELECT password FROM users WHERE username=?
password-stacking = useFirstPass
hashAlgorithm = MD5
hashEncoding = BASE64
hashCharset = utf-8
我还在同一区域添加了以下授权模块:
name: testds01
code: Delegating
flag: required
module options:
dsJndiName = java:/TestDS01
rolesQuery = SELECT role, 'Roles' FROM roles INNER JOIN users ON users.role_id = roles.role_id WHERE users.username =?
老实说,我不知道标志 "required" 是什么意思。也不是代码 "Delegating"。我刚刚在我读的一本书中找到这些。
我的 WildFly 设置包括:1 个域控制器、2 个主机控制器 w/1 每个服务器、2 个 SQL 数据库。所有这 5 个都是单独的虚拟机。因此,除了上面添加的 testds01 模块外,我还添加了指向 "java:/TestDS02".
的 testds02 模块
如果需要更多信息,请告诉我。我不确定我是否涵盖了所有内容。
更新:拥有我用来设置和执行 RMI 的客户端属性可能很有用:
// Set TLS Properties
System.setProperty("javax.net.ssl.keyStore", "test.keystore");
System.setProperty("javax.net.ssl.trustStore", "test.truststore");
System.setProperty("javax.net.ssl.keyStorePassword", "testpass1");
System.setProperty("javax.net.ssl.trustStorePassword", "testpass2");
// Set Application Server Properties
properties = new Properties();
properties.put("remote.connectionprovider.create.options.org.xnio.Options.SSL_ENABLED", "true");
properties.put("remote.connections", "hcl01,hcl02");
// Host Controller
properties.put("remote.connection.hcl01.port", "8443");
properties.put("remote.connection.hcl01.host", "10.0.0.1");
properties.put("remote.connection.hcl01.protocol", "https-remoting");
properties.put("remote.connection.hcl01.connect.options.org.xnio.Options.SSL_STARTTLS", "true");
properties.put("remote.connection.hrl01.connect.options.org.xnio.Options.SASL_POLICY_NOPLAINTEXT", "false");
properties.put("remote.connection.hcl01.connect.options.org.xnio.Options.SASL_POLICY_NOANONYMOUS", "true");
properties.put("remote.connection.hrl01.connect.options.org.xnio.Options.SASL_DISALLOWED_MECHANISMS", "JBOSS-LOCAL-USER");
properties.put("remote.connection.hcl02.port", "8443");
properties.put("remote.connection.hcl02.host", "10.0.0.2");
properties.put("remote.connection.hcl02.protocol", "https-remoting");
properties.put("remote.connection.hcl02.connect.options.org.xnio.Options.SSL_STARTTLS", "true");
properties.put("remote.connection.hrl02.connect.options.org.xnio.Options.SASL_POLICY_NOPLAINTEXT", "false");
properties.put("remote.connection.hcl02.connect.options.org.xnio.Options.SASL_POLICY_NOANONYMOUS", "true");
properties.put("remote.connection.hrl02.connect.options.org.xnio.Options.SASL_DISALLOWED_MECHANISMS", "JBOSS-LOCAL-USER");
// Build SLSB Lookup String
String appName = "/"; //name of ear containg ejb
String moduleName = "testapp/"; //name of ejb jar w/o extension
String distinctName = "/"; //any distinct name set within jboss for this deployment
String beanName = Login.class.getSimpleName(); //name of the bean we're looking up
String viewClassName = LoginRemote.class.getName(); //name of the bean interface
System.out.println("beanName=" + beanName + " viewClassName=" + viewClassName);
lookupSLSB = "ejb:" + appName + moduleName + distinctName + beanName + "!" + viewClassName;
// Configure EJB Lookup
Properties props = new Properties();
props.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
context = new InitialContext(props);
properties.put("remote.connection.hcl01.username", au.getUsername());
properties.put("remote.connection.hcl01.password", au.getPassword());
properties.put("remote.connection.hcl02.username", au.getUsername());
properties.put("remote.connection.hcl02.password", au.getPassword());
// JBoss Cluster Setup (using properties above)
EJBClientConfiguration cc = new PropertiesBasedEJBClientConfiguration(properties);
ContextSelector<EJBClientContext> selector = new ConfigBasedEJBClientContextSelector(cc);
EJBClientContext.setSelector(selector);
LoginRemote bean = (LoginRemote)context.lookup(lookupSLSB);
System.out.println("NIC [From bean]: Class=\"" + bean.getStr() + "\"");
我解决了这个问题。转储流量后,查询似乎被发送到数据库。我在数据库上启用了查询日志记录,发现正在接收它们,但是数据库用户存在权限问题。给查询的表赋权后,通信成功
我正在尝试创建一个执行 EJB RMI 以与 server/DB 交互的富客户端。以前,我与远程系统进行通信以验证用户身份。然后我使用密钥库和集群将 HTTPS 通信添加到环境中。那时一切正常。
基于文件的身份验证是迈向数据库身份验证和授权的过渡步骤。我可能仍然有来自那个挥之不去并影响这个新步骤的配置,我不确定。
以下是尝试通过客户端进行身份验证时的失败消息:
Jan 19, 2017 12:51:52 PM org.jboss.ejb.client.EJBClient <clinit>
INFO: JBoss EJB Client version 2.1.4.Final
Jan 19, 2017 12:51:52 PM org.xnio.Xnio <clinit>
INFO: XNIO version 3.4.0.Final
Jan 19, 2017 12:51:52 PM org.xnio.nio.NioXnio <clinit>
INFO: XNIO NIO Implementation Version 3.4.0.Final
Jan 19, 2017 12:51:52 PM org.jboss.remoting3.EndpointImpl <clinit>
INFO: JBoss Remoting version 4.0.21.Final
Jan 19, 2017 12:51:53 PM org.jboss.ejb.client.remoting.ConfigBasedEJBClientContextSelector setupEJBReceivers
WARN: Could not register a EJB receiver for connection to 10.0.0.1:8443
javax.security.sasl.SaslException: Authentication failed: all available authentication mechanisms failed:
JBOSS-LOCAL-USER: javax.security.sasl.SaslException: Failed to read server challenge [Caused by java.io.FileNotFoundException: /home/appsrv/wildfly-10.1.0.Final/domain/tmp/auth/local4807198060994958453.challenge (No such file or directory)]
DIGEST-MD5: Server rejected authentication
at org.jboss.remoting3.remote.ClientConnectionOpenListener.allMechanismsFailed(ClientConnectionOpenListener.java:114)
at org.jboss.remoting3.remote.ClientConnectionOpenListener$Capabilities.handleEvent(ClientConnectionOpenListener.java:389)
at org.jboss.remoting3.remote.ClientConnectionOpenListener$Capabilities.handleEvent(ClientConnectionOpenListener.java:241)
at org.xnio.ChannelListeners.invokeChannelListener(ChannelListeners.java:92)
at org.xnio.channels.TranslatingSuspendableChannel.handleReadable(TranslatingSuspendableChannel.java:198)
at org.xnio.channels.TranslatingSuspendableChannel.handleEvent(TranslatingSuspendableChannel.java:112)
at org.xnio.ChannelListeners.invokeChannelListener(ChannelListeners.java:92)
at org.xnio.ChannelListeners$DelegatingChannelListener.handleEvent(ChannelListeners.java:1092)
at org.xnio.ChannelListeners.invokeChannelListener(ChannelListeners.java:92)
at org.xnio.conduits.ReadReadyHandler$ChannelListenerHandler.readReady(ReadReadyHandler.java:66)
at org.xnio.ssl.JsseStreamConduit.run(JsseStreamConduit.java:446)
at org.xnio.ssl.JsseStreamConduit.readReady(JsseStreamConduit.java:547)
at org.xnio.ssl.JsseStreamConduit.readReady(JsseStreamConduit.java:319)
at org.xnio.nio.NioSocketConduit.handleReady(NioSocketConduit.java:89)
at org.xnio.nio.WorkerThread.run(WorkerThread.java:567)
at ...asynchronous invocation...(Unknown Source)
at org.jboss.remoting3.EndpointImpl.doConnect(EndpointImpl.java:294)
at org.jboss.remoting3.EndpointImpl.connect(EndpointImpl.java:430)
at org.jboss.ejb.client.remoting.EndpointPool$PooledEndpoint.connect(EndpointPool.java:192)
at org.jboss.ejb.client.remoting.NetworkUtil.connect(NetworkUtil.java:153)
at org.jboss.ejb.client.remoting.NetworkUtil.connect(NetworkUtil.java:133)
at org.jboss.ejb.client.remoting.ConnectionPool.getConnection(ConnectionPool.java:78)
at org.jboss.ejb.client.remoting.RemotingConnectionManager.getConnection(RemotingConnectionManager.java:51)
at org.jboss.ejb.client.remoting.ConfigBasedEJBClientContextSelector.setupEJBReceivers(ConfigBasedEJBClientContextSelector.java:161)
at org.jboss.ejb.client.remoting.ConfigBasedEJBClientContextSelector.getCurrent(ConfigBasedEJBClientContextSelector.java:118)
at org.jboss.ejb.client.remoting.ConfigBasedEJBClientContextSelector.getCurrent(ConfigBasedEJBClientContextSelector.java:47)
at org.jboss.ejb.client.EJBClientContext.getCurrent(EJBClientContext.java:281)
at org.jboss.ejb.client.EJBClientContext.requireCurrent(EJBClientContext.java:291)
at org.jboss.ejb.client.EJBInvocationHandler.doInvoke(EJBInvocationHandler.java:178)
at org.jboss.ejb.client.EJBInvocationHandler.invoke(EJBInvocationHandler.java:146)
at com.sun.proxy.$Proxy6.getVer(Unknown Source)
at com.test.clientapp.TestClient.authenticate(TestClient.java:208)
at com.test.clientapp.BackgroundServiceEngine.run(BackgroundServiceEngine.java:136)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
在我的 WildFly 域配置中,我通过 GUI 在 -> 安全 -> MySecurityDomain 中的 "ha" 配置文件(分配给我的主机控制器的配置文件)中添加了以下身份验证模块:
name: testds01
code: Database
flag: required
module options:
dsJndiName = java:/TestDS01
principalsQuery = SELECT password FROM users WHERE username=?
password-stacking = useFirstPass
hashAlgorithm = MD5
hashEncoding = BASE64
hashCharset = utf-8
我还在同一区域添加了以下授权模块:
name: testds01
code: Delegating
flag: required
module options:
dsJndiName = java:/TestDS01
rolesQuery = SELECT role, 'Roles' FROM roles INNER JOIN users ON users.role_id = roles.role_id WHERE users.username =?
老实说,我不知道标志 "required" 是什么意思。也不是代码 "Delegating"。我刚刚在我读的一本书中找到这些。
我的 WildFly 设置包括:1 个域控制器、2 个主机控制器 w/1 每个服务器、2 个 SQL 数据库。所有这 5 个都是单独的虚拟机。因此,除了上面添加的 testds01 模块外,我还添加了指向 "java:/TestDS02".
的 testds02 模块如果需要更多信息,请告诉我。我不确定我是否涵盖了所有内容。
更新:拥有我用来设置和执行 RMI 的客户端属性可能很有用:
// Set TLS Properties
System.setProperty("javax.net.ssl.keyStore", "test.keystore");
System.setProperty("javax.net.ssl.trustStore", "test.truststore");
System.setProperty("javax.net.ssl.keyStorePassword", "testpass1");
System.setProperty("javax.net.ssl.trustStorePassword", "testpass2");
// Set Application Server Properties
properties = new Properties();
properties.put("remote.connectionprovider.create.options.org.xnio.Options.SSL_ENABLED", "true");
properties.put("remote.connections", "hcl01,hcl02");
// Host Controller
properties.put("remote.connection.hcl01.port", "8443");
properties.put("remote.connection.hcl01.host", "10.0.0.1");
properties.put("remote.connection.hcl01.protocol", "https-remoting");
properties.put("remote.connection.hcl01.connect.options.org.xnio.Options.SSL_STARTTLS", "true");
properties.put("remote.connection.hrl01.connect.options.org.xnio.Options.SASL_POLICY_NOPLAINTEXT", "false");
properties.put("remote.connection.hcl01.connect.options.org.xnio.Options.SASL_POLICY_NOANONYMOUS", "true");
properties.put("remote.connection.hrl01.connect.options.org.xnio.Options.SASL_DISALLOWED_MECHANISMS", "JBOSS-LOCAL-USER");
properties.put("remote.connection.hcl02.port", "8443");
properties.put("remote.connection.hcl02.host", "10.0.0.2");
properties.put("remote.connection.hcl02.protocol", "https-remoting");
properties.put("remote.connection.hcl02.connect.options.org.xnio.Options.SSL_STARTTLS", "true");
properties.put("remote.connection.hrl02.connect.options.org.xnio.Options.SASL_POLICY_NOPLAINTEXT", "false");
properties.put("remote.connection.hcl02.connect.options.org.xnio.Options.SASL_POLICY_NOANONYMOUS", "true");
properties.put("remote.connection.hrl02.connect.options.org.xnio.Options.SASL_DISALLOWED_MECHANISMS", "JBOSS-LOCAL-USER");
// Build SLSB Lookup String
String appName = "/"; //name of ear containg ejb
String moduleName = "testapp/"; //name of ejb jar w/o extension
String distinctName = "/"; //any distinct name set within jboss for this deployment
String beanName = Login.class.getSimpleName(); //name of the bean we're looking up
String viewClassName = LoginRemote.class.getName(); //name of the bean interface
System.out.println("beanName=" + beanName + " viewClassName=" + viewClassName);
lookupSLSB = "ejb:" + appName + moduleName + distinctName + beanName + "!" + viewClassName;
// Configure EJB Lookup
Properties props = new Properties();
props.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
context = new InitialContext(props);
properties.put("remote.connection.hcl01.username", au.getUsername());
properties.put("remote.connection.hcl01.password", au.getPassword());
properties.put("remote.connection.hcl02.username", au.getUsername());
properties.put("remote.connection.hcl02.password", au.getPassword());
// JBoss Cluster Setup (using properties above)
EJBClientConfiguration cc = new PropertiesBasedEJBClientConfiguration(properties);
ContextSelector<EJBClientContext> selector = new ConfigBasedEJBClientContextSelector(cc);
EJBClientContext.setSelector(selector);
LoginRemote bean = (LoginRemote)context.lookup(lookupSLSB);
System.out.println("NIC [From bean]: Class=\"" + bean.getStr() + "\"");
我解决了这个问题。转储流量后,查询似乎被发送到数据库。我在数据库上启用了查询日志记录,发现正在接收它们,但是数据库用户存在权限问题。给查询的表赋权后,通信成功