Wildfly setup using ejb remote access and custom login module
steffen.mall.exxeta Jul 22, 2017 3:05 PMWhen activating a custom login module for EJB remote authentification, the applicationrealm is additionally called for authentication. Unfortunately, I do not know why.
With the current variant the user is logged in the customlogin module and logged in the ejb. This is only successful as long as a user with same username and same password is registered in the application-users.properties. Change the user so the login does not work anymore. I am at this point not clear whether the authentication is running exclusively through application-users.properties (ApplicationRealm) or combined via application-users.properties and via custom login module. and why does it authenticate with application-users.properties.
The goal is to authenticate EJB remote access completely by custom login module.
Following the setup:
EJB remote client properties:
props.put("java.naming.factory.initial", "org.jboss.naming.remote.client.InitialContextFactory"); props.put(java.naming.factory.url.pkgs, "org.jboss.ejb.client.naming"); props.put("jboss.naming.client.ejb.context", false); props.put("org.jboss.ejb.client.scoped.context", true); props.put("endpoint.name", "client-endpoint"); props.put("remote.connections", "default"); props.put("remote.connectionprovider.create.options.org.xnio.Options.SSL_ENABLED", false); props.put("remote.connection.default.connect.options.org.xnio.Options.SASL_POLICY_NOANONYMOUS", false); props.put("remote.connection.default.connect.options.org.xnio.Options.SASL_POLICY_NOPLAINTEXT", "false"); props.put("java.naming.provider.url", "http-remoting://127.0.0.1:8080"); props.put("remote.connection.default.host", "127.0.0.1"); props.put("remote.connection.default.port", "8080"); props.put("remote.connection.default.username", "username"); props.put("remote.connection.default.password", "password");
ejb url:
ejb:/my-app/MyServiceImpl!com.some.MyServiceInterface
standalone.xml configuration based on normal standalone.xml (not full):
<security-realm name="MyRealm"> <authentication> <jaas name="com.some.MyCustomLoginModule"/> </authentication> </security-realm>
<security-domain name="MySecurityDomain" cache-type="default"> <authentication> <login-module code="com.some.MyCustomLoginModule" flag="required" module="login.my"> <module-option name="usersProperties" value="user.properties"/> <module-option name="rolesProperties" value="roles.properties"/> </login-module> </authentication> </security-domain>
<subsystem xmlns="urn:jboss:domain:remoting:3.0"> <endpoint/> <http-connector name="http-remoting-connector" connector-ref="default" security-realm="MyRealm"/> </subsystem>
Implementation:
@Stateless @SecurityDomain("MySecurityDomain") @DeclareRoles("user") public class MyServiceImpl implements MyService { private static final Logger logger = Logger.getLogger(MyServiceImpl .class); @Resource private EJBContext ejbContext; @PermitAll public String getPrincipalName() { logger.info("Principal: " + ejbContext.getCallerPrincipal().getName()); return ejbContext.getCallerPrincipal().getName(); } }
@Remote public interface MyService { public String getPrincipalName(); }
import java.security.Principal; import java.util.Map; import javax.security.auth.Subject; import javax.security.auth.callback.CallbackHandler; import javax.security.auth.login.LoginException; import org.jboss.logging.Logger; import org.jboss.security.auth.spi.UsersRolesLoginModule; public class CustomLoginModule extends UsersRolesLoginModule { private CustomPrincipal principal; private static final Logger logger = Logger.getLogger(CustomLoginModule.class); @Override public void initialize(Subject arg0, CallbackHandler arg1, Map<String, ?> arg2, Map<String, ?> arg3) { logger.info("init module from main class"); super.initialize(arg0, arg1, arg2, arg3); } public boolean login() throws LoginException { logger.info("Calling login()"); logger.info("User before: " + getUsername()); boolean login = super.login(); logger.info("User: " + getUsername()); logger.info("Password: " + getUsersPassword()); if (login) { principal = new CustomPrincipal(getUsername(), "An user description!"); } return login; } protected Principal getIdentity() { return principal != null ? principal : super.getIdentity(); } }