Java 安全地从 WildFly 调用 EJB

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21217561/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 07:23:42  来源:igfitidea点击:

Invoke EJB from WildFly safely

javasslejbwildfly

提问by Kaskader



I'm trying to re-write my old application in enterprise, "business" way.
So, I've got a Swing client with login module and my own server created from scratch. The client use ssl certificate to encrypt TCP connection to the server (I check client certificate on server and server certificate on client) and then server use database to authenticate and authorize the user.

我正在尝试以企业“业务”方式重写我的旧应用程序。
所以,我有一个带有登录模块的 Swing 客户端和我自己从头开始创建的服务器。客户端使用 ssl 证书加密到服务器的 TCP 连接(我检查服务器上的客户端证书和客户端上的服务器证书),然后服务器使用数据库对用户进行身份验证和授权。

Now I'm trying to get it working with ejb hosted by WildFly 8 CR1. I want to use the same client-server keys pair to connect Swing client to WildFly server and then authenticate user with name and credentials stored in MySQL datasource. I have also roles stored in database and I want to use them to configure client principals.

现在我试图让它与 WildFly 8 CR1 托管的 ejb 一起工作。我想使用相同的客户端-服务器密钥对将 Swing 客户端连接到 WildFly 服务器,然后使用存储在 MySQL 数据源中的名称和凭据对用户进行身份验证。我还有存储在数据库中的角色,我想用它们来配置客户端主体。

I have simple, basic EJB invocation:

我有简单的基本 EJB 调用:

Context ctx = new InitialContext();
MyBeanRemote bean = (MyBeanRemote)ctx.lookup("AppName/module-0.0.1-SNAPSHOT/MyBean!my.app.MyBeanRemote");
ResultType result = bean.doSomething();

I have jndi.properties file

我有 jndi.properties 文件

java.naming.factory.initial=org.jboss.naming.remote.client.InitialContextFactory
java.naming.provider.url=http-remoting://myServer:8080
jboss.naming.client.ejb.context=true
java.naming.security.principal=app-user-name
java.naming.security.credentials=password@123

And I have basic datasource configuration

我有基本的数据源配置

<datasource jta="false" jndi-name="java:jboss/datasources/MyDB" pool-name="MyDB" enabled="true" use-ccm="false">
<connection-url>jdbc:mysql://localhost:3306/Mydb</connection-url>
<driver-class>com.mysql.jdbc.Driver</driver-class>
<driver>mysql-connector-java-5.1.28-bin.jar</driver>
<security>
  <user-name>mysqlUser</user-name>
  <password>mysqlPass</password>
</security>
<validation>
  <validate-on-match>false</validate-on-match>
  <background-validation>false</background-validation>
</validation>
<statement>
  <share-prepared-statements>false</share-prepared-statements>
</statement>
</datasource>

Everything above works fine.

以上一切正常。

I have read some guides but still haven't find the one describes how to use composite of: EJB (not web) + WildFly 8 (not JBoss 7) + encryption by SSL + authenticate and authorization via datasource with login client module

我已经阅读了一些指南,但仍然没有找到描述如何使用以下组合的指南:EJB(非 Web)+ WildFly 8(非 JBoss 7)+ SSL 加密 + 通过数据源与登录客户端模块进行身份验证和授权

Any help will be appreciated.

任何帮助将不胜感激。

Sorry for my english, I often use this language for reading, not writing:)

对不起我的英语,我经常使用这种语言来阅读,而不是写作:)

回答by mcmil

You would neet to create a security realm mapped to your remoting connector in the standalone.xml file, like such:

您需要在 standalone.xml 文件中创建一个映射到远程连接器的安全领域,如下所示:

<management>  
   <security-realms>  
    <security-realm name="MyRealm">  
      <authentication>  
        <jaas name="my-domain"/>  
      </authentication>  
    </security-realm>  
</management>  

<subsystem xmlns="urn:jboss:domain:remoting:1.1">
  <connector name="remoting-connector" socket-binding="remoting" security-realm="MyRealm"/>
</subsystem>

Then you should enable the security domain with a proper LoginModule (a built-in one, or a your own):

然后,您应该使用适当的 LoginModule(内置的或您自己的)启用安全域:

<security-domains>
    <security-domain name="my-domain" cache-type="default">
        <authentication>
            <login-module code="org.jboss.security.auth.spi.DatabaseServerLoginModule" flag="required">
                <module-option name="dsJndiName" value="java:jboss/datasources/serviceDS"/>
                <module-option name="principalsQuery" value="SELECT identificationCode FROM devices WHERE name=?"/>
                <module-option name="rolesQuery" value="SELECT 'device', 'Roles' FROM devices WHERE name=?"/>
            </login-module>
        </authentication>
    </security-domain>
</security-realms>

Of course the datasource should point to a database in which the queries would find proper principals (users) and their roles. Be sure to check out two articles about remoting: https://docs.jboss.org/author/display/AS71/Remote+EJB+invocations+via+JNDI+-+EJB+client+API+or+remote-naming+projectand https://docs.jboss.org/author/display/AS71/EJB+invocations+from+a+remote+client+using+JNDI. It seems like you are using the "old" remoting - the client login module is no longer supported from JBoss 7. The bottom line is that your ejb remoting config should look more like (notice the local users which are disallowed!):

当然,数据源应该指向一个数据库,在该数据库中查询会找到合适的主体(用户)及其角色。一定要查看两篇关于远程处理的文章:https: //docs.jboss.org/author/display/AS71/Remote+EJB+invocations+via+JNDI+-+EJB+client+API+or+remote-naming+projecthttps://docs.jboss.org/author/display/AS71/EJB+invocations+from+a+remote+client+using+JNDI。看起来您正在使用“旧”远程处理 - JBoss 7 不再支持客户端登录模块。底线是您的 ejb 远程处理配置应该看起来更像(注意不允许使用的本地用户!):

remote.connections=default
remote.connection.default.host=localhost
remote.connection.default.port=8080
remote.connection.default.username=userName
remote.connection.default.password=password
remote.connection.default.connect.options.org.xnio.Options.SASL_DISALLOWED_MECHANISMS=JBOSS-LOCAL-USER
remote.connection.default.connect.options.org.xnio.Options.SASL_POLICY_NOPLAINTEXT=false

Be sure to check out https://github.com/wildfly/quickstart/tree/master/ejb-remote

请务必查看https://github.com/wildfly/quickstart/tree/master/ejb-remote

Finally, remember to add your security domain mapping in your jboss-ejb3.xml:

最后,记得在你的 jboss-ejb3.xml 添加你的安全域映射:

<jboss:ejb-jar>
  <assembly-descriptor>  
    <s:security>     
      <ejb-name>*</ejb-name>    
      <s:security-domain>my-domain</s:security-domain>       
    </s:security>  
   </assembly-descriptor>
</jboss:ejb-jar