ARTICLE AD BOX
I have an EJB client application using WildFly 38 as the server.
User authentication already works correctly: Elytron is configured with a jdbc-realm, and users can log in successfully using username/password. So far, so good. Now I need to fetch some non-sensitive configuration data from the server before the user logs in. This data does not require any security protection. My idea was to use an anonymous user for this initial access.
Problem summary:
I want to allow anonymous remote EJB access to exactly one stateless EJB (before user login), while all other EJBs require authentication. However:
If ANONYMOUS is not granted login-permission, the server rejects the connection with "Server rejected authentication".
If ANONYMOUS is granted login-permission, all callers (including authenticated users) are treated as "anonymous".
I would like to understand whether this approach is correct and how to configure it properly with Elytron.
This is my server configuration (standalone.xml):
Remoting subsystem:
<subsystem xmlns="urn:jboss:domain:remoting:8.0"> <endpoint worker="default"/> <http-connector name="https-remoting-connector" connector-ref="https" sasl-authentication-factory="example-ejb-sasl-auth"/> </subsystem>Elytron subsystem (relevant parts):
<security-domains> <security-domain name="ApplicationDomain" default-realm="ApplicationRealm" permission-mapper="default-permission-mapper"> <realm name="ApplicationRealm" role-decoder="groups-to-roles"/> <realm name="local"/> </security-domain> <security-domain name="ManagementDomain" default-realm="ManagementRealm" permission-mapper="default-permission-mapper"> <realm name="ManagementRealm" role-decoder="groups-to-roles"/> <realm name="local" role-mapper="super-user-mapper"/> </security-domain> <security-domain name="Example-security" default-realm="Example-JdbcRealm" permission-mapper="default-permission-mapper"> <realm name="Example-JdbcRealm"/> </security-domain> </security-domains> <mappers> <simple-permission-mapper name="default-permission-mapper" mapping-mode="first"> <permission-mapping> <principal name="anonymous"/> <permission-set name="default-permissions"/> </permission-mapping> <permission-mapping match-all="true"> <permission-set name="login-permission"/> <permission-set name="default-permissions"/> </permission-mapping> </simple-permission-mapper> <simple-permission-mapper name="login-permission-mapper" mapping-mode="first"> <permission-mapping match-all="true"> <permission-set name="login-permission"/> <permission-set name="default-permissions"/> </permission-mapping> </simple-permission-mapper> <constant-realm-mapper name="local" realm-name="local"/> <simple-role-decoder name="groups-to-roles" attribute="groups"/> <constant-role-mapper name="super-user-mapper"> <role name="SuperUser"/> </constant-role-mapper> </mappers> <sasl-authentication-factory name="example-ejb-sasl-auth" sasl-server-factory="configured" security-domain="Example-security"> <mechanism-configuration> <mechanism mechanism-name="ANONYMOUS"/> <mechanism mechanism-name="PLAIN"> <mechanism-realm realm-name="Example-JdbcRealm"/> </mechanism> </mechanism-configuration> </sasl-authentication-factory>EJB subsystem:
<default-security-domain value="ejb-jdbc-mapping"/> <application-security-domains> <application-security-domain name="ejb-jdbc-mapping" security-domain="Example-security"/> </application-security-domains> <default-missing-method-permissions-deny-access value="true"/>The deployed EAR contains a JAR with a jboss-ejb3.xml that references this application-security-domain.
What I tried:
Creating a separate JAR with a dedicated EJB (and different application-security-domain) for anonymous access -> did not work (I think because the same sasl-authentication-factory was used)
Granting the login-permission to the anonymous principal (in the permission-mapping) -> this allows login without username/password, but then sessionContext.getCallerPrincipal() is always "anonymous", even for authenticated users.
Client-side lookup:
Properties props = new Properties(); props.put( Context.INITIAL_CONTEXT_FACTORY, WildFlyInitialContextFactory.class.getName() ); props.put( Context.PROVIDER_URL, "https-remoting://localhost:8443" ); Context ctx = new InitialContext( props ); ctx.lookup("...");When performing a remote EJB lookup without credentials, the client always fails with:
Authentication failed: all available authentication mechanisms failed: ANONYMOUS: javax.security.sasl.SaslException: ANONYMOUS: Server rejected authenticationQuestions:
Is it supported in WildFly/Elytron to expose a single remote EJB to anonymous clients while protecting all other EJBs?
If yes, which part of the configuration is wrong or missing here:
- SASL authentication factory
- security-domain / permission-mapper
- EJB application-security-domain
- or client-side configuration?
Is using SASL ANONYMOUS the correct mechanism for this use case, or is a different approach recommended? I know I could use a REST endpoint but I don't like to mix EJBs and HTTP.
Thanks!
