Configuring security to access EJB through WS — WF

2019-08-26 10:37发布

问题:

I have followed this tutorial to configure an user ejbuser with password 12345678 and role appCitas. The instructions that I followed are:

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" } }

In mi EJB, I have

@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) {
   ...
}

And my jboss-app.xml is

<?xml version="1.0" encoding="UTF-8"?>
<jboss-app>
   <security-domain>other</security-domain>
</jboss-app>

The ear deploys correctly and it does not show any log problem, yet I try to access a method from SoapUI and I add a Basic Authentication, with:

  • username: ejbuser
  • password: 12345678
  • Domain: I have tried with other, proxySD, proxyRealm and leaving it blank
  • Pre-emptive auth: I have combined all of the above values of "Domain" with both "Use-global-preference" and "Authenticate pre-emptively".

In all cases, I get a

<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>

If I remove the security configuration, I can access through SoapUI with no problems.

Working with WildFly 14.0.0.1 Final.

Note: This question is somewhat related to my previous one, but since I have reinstalled the wildfly and I have followed step by step the above mentioned tutorial, I think it is better to post it as a separate question.


Update

Following the lead of @fjuma's answer, I have configured the following:

[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"}

And changed the value of security-domain in jboss-app.xml to proxyAD, I get an error deploying the 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]"
]
}

回答1:

A couple things to note:

  • To make use of HTTP Basic authentication, an Elytron http-authentication-factory is needed. Documentation on how to configure this can be found here.

  • When using HTTP Basic authentication, an application-security-domain mapping also needs to be added in the Undertow subsystem. See https://developer.jboss.org/thread/276445 for more details related to this when using webservices.


Update by the OP:

This is the final minimal set of commands to configure EJBs access through WS (tested on a clean, brand new 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"}

Notes:

  1. As you may have noticed, I switched from a FileSystem realm to a Properties realm. This is not related to the issue, it is just that it made easier to debug.

  2. Elytron's security domain (defined at the 3rd command), Undertow's application security domain (defined at the 4th command) and EJB's application-security-domain (defined at the 6th command) have all the same name proxySD. That the name is the same in all three subsystems is important, and bad things can happen if they have different names (I have not tried out all the combinations).

  3. WS based on EJBs must be invoked with "authenticate pre-emptively", sending the authentication data in the first request without being prompted by the server. WS based on POJOs in a war use the authentication system for web pages, so there is no need to authentica pre-emptively.