配置安全性以通过 WS 访问 EJB -- WFLYEJB0364 连接被拒绝
Configuring security to access EJB through WS -- WFLYEJB0364 Connection rejected
我已按照 this tutorial 配置用户 ejbuser
,密码 12345678
和角色 appCitas
。我遵循的说明是:
C:\wildfly-14.0.1.Final\bin>jboss-cli.bat
You are disconnected at the moment. Type 'connect' to connect to the server or 'help' for the list of supported commands.
[disconnected /] connect
[standalone@localhost:9990 /] /subsystem=elytron/filesystem-realm=proxyRealm:add(path=proxy-realm-users,relative-to=jboss.server.config.dir)
{"outcome" => "success"}
[standalone@localhost:9990 /] /subsystem=elytron/filesystem-realm=proxyRealm:add-identity(identity=ejbuser)
{"outcome" => "success"}
[standalone@localhost:9990 /] /subsystem=elytron/filesystem-realm=proxyRealm:set-password(identity=ejbuser,clear={password=12345678})
{"outcome" => "success"}
[standalone@localhost:9990 /] /subsystem=elytron/filesystem-realm=proxyRealm:add-identity-attribute(identity=ejbuser,name=Roles,value=["guest", "appCitas"])
{"outcome" => "success"}
[standalone@localhost:9990 /] /subsystem=elytron/simple-role-decoder=from-roles-attribute:add(attribute=Roles)
{"outcome" => "success"}
[standalone@localhost:9990 /] /subsystem=elytron/security-domain=proxySD:add(default-realm=proxyRealm,permission-mapper=default-permission-mapper,realms=[{realm=proxyRealm,role-decoder=from-roles-attribute},{realm=local}])
{"outcome" => "success"}
[standalone@localhost:9990 /] /subsystem=elytron/sasl-authentication-factory=proxy-application-sasl-autentication:add(mechanism-configurations=[{mechanism-name=JBOSS-LOCAL-USER,realm-mapper=local},{mechanism-name=DIGEST-MD5,mechanism-realm-configurations=[{realm-name=proxyRealm}]},{mechanism-name=BASIC,mechanism-realm-configurations=[{realm-name=proxyRealm}]}],sasl-server-factory=configured,security-domain=proxySD)
{"outcome" => "success"}
[standalone@localhost:9990 /] /subsystem=ejb3/application-security-domain=other:add(security-domain=proxySD)
{"outcome" => "success"}
[standalone@localhost:9990 /] /subsystem=remoting/http-connector=http-remoting-connector:write-attribute(name=sasl-authentication-factory,value=proxy-application-sasl-autentication)
{
"outcome" => "success",
"response-headers" => {
"operation-requires-reload" => true,
"process-state" => "reload-required"
}
}
在mi EJB中,我有
@WebService(
endpointInterface = "es.ssib.otic.test.prototipoEjbCitas.ApiCitasPublico",
name = "ApiCitasEjb")
@RolesAllowed("apiCitas")
@Stateless
public class ApiCitasPublicoImpl
implements ApiCitasPublico {
@Override
public @XmlElement(name = "pacienteCitaResponse", required = true) PacienteCitaResponse getPacienteCita(
@WebParam(name = "datosSolicitante") @XmlElement(required = true) IdPeticion idPaciente) {
...
}
我的jboss-app.xml
是
<?xml version="1.0" encoding="UTF-8"?>
<jboss-app>
<security-domain>other</security-domain>
</jboss-app>
ear 正确部署并且没有显示任何日志问题,但我尝试从 SoapUI 访问方法并添加基本身份验证,其中:
- 用户名:ejbuser
- 密码:12345678
- 域:我尝试过使用其他的 proxySD、proxyRealm 并将其留空
- 先发制人的身份验证:我将 "Domain" 的所有上述值与 "Use-global-preference" 和 "Authenticate pre-emptively".
组合在一起
在所有情况下,我得到一个
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<soap:Fault>
<faultcode>soap:Server</faultcode>
<faultstring>WFLYEJB0364: Invocation on method: public es.ssib.otic.test.prototipoEjbCitas.beans.PacienteCitaResponse es.ssib.otic.test.prototipoEjbCitas.impl.ApiCitasPublicoImpl.getPacienteCita(es.ssib.otic.test.prototipoEjbCitas.beans.IdPeticion) of bean: ApiCitasPublicoImpl is not allowed</faultstring>
</soap:Fault>
</soap:Body>
</soap:Envelope>
如果我删除安全配置,我可以毫无问题地通过 SoapUI 访问。
使用 WildFly 14.0.0.1 Final。
注意:这个问题和my previous one有些关系,但是由于我已经重装了wildfly并且按照上面的教程一步一步来,我觉得还是post比较好作为一个单独的问题。
更新
根据@fjuma 的回答,我配置了以下内容:
[standalone@localhost:9990 /] /subsystem=elytron/http-authentication-factory=proxy-application-http-authentication:add(http-server-mechanism-factory=global,security-domain=proxySD,mechanism-configurations=[{mechanism-name=BASIC,mechanims-realm-configuration=[{realm-name=proxyAD}]}])
{"outcome" => "success"}
[standalone@localhost:9990 /] /subsystem=undertow/application-security-domain=proxyAD:add(http-authentication-factory=proxy-application-http-authentication)
{"outcome" => "success"}
并将 jboss-app.xml
中的 security-domain
的值更改为 proxyAD
,部署 ear 时出现错误:
{
"WFLYCTL0412: Required services that are not installed:" => ["jboss.security.security-domain.proxyAD"],
"WFLYCTL0180: Services with missing/unavailable dependencies" => [
"jboss.deployment.subunit.\"prototipoEarCitas-0.0.1-SNAPSHOT.ear\".\"prototipoEjbCitas-0.0.1-SNAPSHOT.jar\".component.ApiCitasPublicoImpl.CREATE is missing [jboss.security.security-domain.proxyAD]",
"jboss.ws.endpoint.\"prototipoEarCitas-0.0.1-SNAPSHOT.ear\".\"prototipoEjbCitas-0.0.1-SNAPSHOT.jar\".ApiCitasPublicoImpl is missing [jboss.security.security-domain.proxyAD]"
]
}
有几点需要注意:
要使用 HTTP 基本身份验证,需要 Elytron http-authentication-factory
。可以找到有关如何配置它的文档 here。
使用HTTP Basic认证时,还需要在Undertow子系统中添加一个application-security-domain
映射。有关使用网络服务时与此相关的更多详细信息,请参阅 https://developer.jboss.org/thread/276445。
###OP更新:
这是通过 WS 配置 EJB 访问的最后一组最小命令(在干净、全新的 Wildfly 14.0.1 上测试。Final):
C:\wildfly-14.0.1.Final\bin>jboss-cli.bat
You are disconnected at the moment. Type 'connect' to connect to the server or '
help' for the list of supported commands.
[disconnected /] connect
[standalone@localhost:9990 /] /subsystem=elytron/properties-realm=proxyRealm:add(groups-attribute=groups,groups-properties={path=proxy-roles.properties,relative-to=jboss.server.config.dir},users-properties={path=proxy-users.properties,relative-to=jboss.server.config.dir,plain-text=true})
{"outcome" => "success"}
[standalone@localhost:9990 /] /subsystem=elytron/security-domain=proxySD:add(realms=[{realm=proxyRealm,role-decoder=groups-to-roles}],default-realm=proxyRealm,permission-mapper=default-permission-mapper)
{"outcome" => "success"}
[standalone@localhost:9990 /] /subsystem=elytron/http-authentication-factory=proxy-http-auth:add(http-server-mechanism-factory=global,security-domain=proxySD,mechanism-configurations=[{mechanism-name=BASIC,mechanism-realm-configurations=[{realm-name=proxyRealm}]}]
{"outcome" => "success"}
[standalone@localhost:9990 /] /subsystem=undertow/application-security-domain=proxySD:add(http-authentication-factory=proxy-http-auth)
{"outcome" => "success"}
[standalone@localhost:9990 /] /subsystem=elytron/sasl-authentication-factory=proxy-app-sasl-auth:add(mechanism-configurations=[{mechanism-name=JBOSS-LOCAL-USER,realm-mapper=local},{mechanism-name=BASIC,mechanism-realm-configurations=[{realm-name=proxyRealm}]}],sasl-server-factory=configured,security-domain=proxySD)
{"outcome" => "success"}
[standalone@localhost:9990 /] /subsystem=ejb3/application-security-domain=proxySD:add(security-domain=proxySD)
{"outcome" => "success"}
备注:
您可能已经注意到,我从文件系统领域切换到属性领域。这与问题无关,只是它更容易调试。
Elytron的security域(第3条命令定义)、Undertow的application安全域(第4条命令定义)和EJB的application-security-domain(第6条命令定义)都一样姓名 proxySD
。 名称在所有三个子系统中都相同很重要,如果它们的名称不同(我还没有尝试过所有组合),就会发生不好的事情。
基于 EJB 的 WS 必须使用“先发制人验证”调用,在服务器不提示的情况下在第一个请求中发送验证数据。 war基于POJOs的WS使用网页认证系统,无需抢先认证。
我已按照 this tutorial 配置用户 ejbuser
,密码 12345678
和角色 appCitas
。我遵循的说明是:
C:\wildfly-14.0.1.Final\bin>jboss-cli.bat
You are disconnected at the moment. Type 'connect' to connect to the server or 'help' for the list of supported commands.
[disconnected /] connect[standalone@localhost:9990 /] /subsystem=elytron/filesystem-realm=proxyRealm:add(path=proxy-realm-users,relative-to=jboss.server.config.dir)
{"outcome" => "success"}[standalone@localhost:9990 /] /subsystem=elytron/filesystem-realm=proxyRealm:add-identity(identity=ejbuser)
{"outcome" => "success"}[standalone@localhost:9990 /] /subsystem=elytron/filesystem-realm=proxyRealm:set-password(identity=ejbuser,clear={password=12345678})
{"outcome" => "success"}[standalone@localhost:9990 /] /subsystem=elytron/filesystem-realm=proxyRealm:add-identity-attribute(identity=ejbuser,name=Roles,value=["guest", "appCitas"])
{"outcome" => "success"}[standalone@localhost:9990 /] /subsystem=elytron/simple-role-decoder=from-roles-attribute:add(attribute=Roles)
{"outcome" => "success"}[standalone@localhost:9990 /] /subsystem=elytron/security-domain=proxySD:add(default-realm=proxyRealm,permission-mapper=default-permission-mapper,realms=[{realm=proxyRealm,role-decoder=from-roles-attribute},{realm=local}])
{"outcome" => "success"}[standalone@localhost:9990 /] /subsystem=elytron/sasl-authentication-factory=proxy-application-sasl-autentication:add(mechanism-configurations=[{mechanism-name=JBOSS-LOCAL-USER,realm-mapper=local},{mechanism-name=DIGEST-MD5,mechanism-realm-configurations=[{realm-name=proxyRealm}]},{mechanism-name=BASIC,mechanism-realm-configurations=[{realm-name=proxyRealm}]}],sasl-server-factory=configured,security-domain=proxySD)
{"outcome" => "success"}[standalone@localhost:9990 /] /subsystem=ejb3/application-security-domain=other:add(security-domain=proxySD)
{"outcome" => "success"}[standalone@localhost:9990 /] /subsystem=remoting/http-connector=http-remoting-connector:write-attribute(name=sasl-authentication-factory,value=proxy-application-sasl-autentication)
{ "outcome" => "success", "response-headers" => { "operation-requires-reload" => true, "process-state" => "reload-required" } }
在mi EJB中,我有
@WebService(
endpointInterface = "es.ssib.otic.test.prototipoEjbCitas.ApiCitasPublico",
name = "ApiCitasEjb")
@RolesAllowed("apiCitas")
@Stateless
public class ApiCitasPublicoImpl
implements ApiCitasPublico {
@Override
public @XmlElement(name = "pacienteCitaResponse", required = true) PacienteCitaResponse getPacienteCita(
@WebParam(name = "datosSolicitante") @XmlElement(required = true) IdPeticion idPaciente) {
...
}
我的jboss-app.xml
是
<?xml version="1.0" encoding="UTF-8"?>
<jboss-app>
<security-domain>other</security-domain>
</jboss-app>
ear 正确部署并且没有显示任何日志问题,但我尝试从 SoapUI 访问方法并添加基本身份验证,其中:
- 用户名:ejbuser
- 密码:12345678
- 域:我尝试过使用其他的 proxySD、proxyRealm 并将其留空
- 先发制人的身份验证:我将 "Domain" 的所有上述值与 "Use-global-preference" 和 "Authenticate pre-emptively". 组合在一起
在所有情况下,我得到一个
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<soap:Fault>
<faultcode>soap:Server</faultcode>
<faultstring>WFLYEJB0364: Invocation on method: public es.ssib.otic.test.prototipoEjbCitas.beans.PacienteCitaResponse es.ssib.otic.test.prototipoEjbCitas.impl.ApiCitasPublicoImpl.getPacienteCita(es.ssib.otic.test.prototipoEjbCitas.beans.IdPeticion) of bean: ApiCitasPublicoImpl is not allowed</faultstring>
</soap:Fault>
</soap:Body>
</soap:Envelope>
如果我删除安全配置,我可以毫无问题地通过 SoapUI 访问。
使用 WildFly 14.0.0.1 Final。
注意:这个问题和my previous one有些关系,但是由于我已经重装了wildfly并且按照上面的教程一步一步来,我觉得还是post比较好作为一个单独的问题。
更新
根据@fjuma 的回答,我配置了以下内容:
[standalone@localhost:9990 /] /subsystem=elytron/http-authentication-factory=proxy-application-http-authentication:add(http-server-mechanism-factory=global,security-domain=proxySD,mechanism-configurations=[{mechanism-name=BASIC,mechanims-realm-configuration=[{realm-name=proxyAD}]}])
{"outcome" => "success"}[standalone@localhost:9990 /] /subsystem=undertow/application-security-domain=proxyAD:add(http-authentication-factory=proxy-application-http-authentication)
{"outcome" => "success"}
并将 jboss-app.xml
中的 security-domain
的值更改为 proxyAD
,部署 ear 时出现错误:
{
"WFLYCTL0412: Required services that are not installed:" => ["jboss.security.security-domain.proxyAD"],
"WFLYCTL0180: Services with missing/unavailable dependencies" => [
"jboss.deployment.subunit.\"prototipoEarCitas-0.0.1-SNAPSHOT.ear\".\"prototipoEjbCitas-0.0.1-SNAPSHOT.jar\".component.ApiCitasPublicoImpl.CREATE is missing [jboss.security.security-domain.proxyAD]",
"jboss.ws.endpoint.\"prototipoEarCitas-0.0.1-SNAPSHOT.ear\".\"prototipoEjbCitas-0.0.1-SNAPSHOT.jar\".ApiCitasPublicoImpl is missing [jboss.security.security-domain.proxyAD]"
]
}
有几点需要注意:
要使用 HTTP 基本身份验证,需要 Elytron
http-authentication-factory
。可以找到有关如何配置它的文档 here。使用HTTP Basic认证时,还需要在Undertow子系统中添加一个
application-security-domain
映射。有关使用网络服务时与此相关的更多详细信息,请参阅 https://developer.jboss.org/thread/276445。
###OP更新:
这是通过 WS 配置 EJB 访问的最后一组最小命令(在干净、全新的 Wildfly 14.0.1 上测试。Final):
C:\wildfly-14.0.1.Final\bin>jboss-cli.bat
You are disconnected at the moment. Type 'connect' to connect to the server or ' help' for the list of supported commands.
[disconnected /] connect[standalone@localhost:9990 /] /subsystem=elytron/properties-realm=proxyRealm:add(groups-attribute=groups,groups-properties={path=proxy-roles.properties,relative-to=jboss.server.config.dir},users-properties={path=proxy-users.properties,relative-to=jboss.server.config.dir,plain-text=true})
{"outcome" => "success"}[standalone@localhost:9990 /] /subsystem=elytron/security-domain=proxySD:add(realms=[{realm=proxyRealm,role-decoder=groups-to-roles}],default-realm=proxyRealm,permission-mapper=default-permission-mapper)
{"outcome" => "success"}[standalone@localhost:9990 /] /subsystem=elytron/http-authentication-factory=proxy-http-auth:add(http-server-mechanism-factory=global,security-domain=proxySD,mechanism-configurations=[{mechanism-name=BASIC,mechanism-realm-configurations=[{realm-name=proxyRealm}]}]
{"outcome" => "success"}[standalone@localhost:9990 /] /subsystem=undertow/application-security-domain=proxySD:add(http-authentication-factory=proxy-http-auth)
{"outcome" => "success"}[standalone@localhost:9990 /] /subsystem=elytron/sasl-authentication-factory=proxy-app-sasl-auth:add(mechanism-configurations=[{mechanism-name=JBOSS-LOCAL-USER,realm-mapper=local},{mechanism-name=BASIC,mechanism-realm-configurations=[{realm-name=proxyRealm}]}],sasl-server-factory=configured,security-domain=proxySD)
{"outcome" => "success"}[standalone@localhost:9990 /] /subsystem=ejb3/application-security-domain=proxySD:add(security-domain=proxySD)
{"outcome" => "success"}
备注:
您可能已经注意到,我从文件系统领域切换到属性领域。这与问题无关,只是它更容易调试。
Elytron的security域(第3条命令定义)、Undertow的application安全域(第4条命令定义)和EJB的application-security-domain(第6条命令定义)都一样姓名
proxySD
。 名称在所有三个子系统中都相同很重要,如果它们的名称不同(我还没有尝试过所有组合),就会发生不好的事情。基于 EJB 的 WS 必须使用“先发制人验证”调用,在服务器不提示的情况下在第一个请求中发送验证数据。 war基于POJOs的WS使用网页认证系统,无需抢先认证。