-
1. Re: WildFly Elytron security client programatic login
dlofthouse Jul 20, 2018 6:56 AM (in response to sergiu_pienar)Are you executing this within a deployment associated with an Elyton security domain?
-
2. Re: WildFly Elytron security client programatic login
sergiu_pienar Jul 20, 2018 7:30 AM (in response to dlofthouse)Yes. This is from within a jar (containing EJB's and startup classes) that is packed into an EAR. The jboss-app.xml of the EAR defines a security domain based on elytron. Found the below approach:
SecurityDomain currentSecurityDomain = SecurityDomain.getCurrent(); Evidence evidence = new PasswordGuessEvidence(User.SYSTEM_USER_PASSWORD.toCharArray()); try { SecurityIdentity identity = currentSecurityDomain.authenticate(User.SYSTEM_USER_NAME, evidence); } catch (RealmUnavailableException e) { // TODO write your own catch code! } catch (SecurityException e) { // TODO write your own catch code! }
Is this the correct way of doing it ?
-
3. Re: WildFly Elytron security client programatic login
dlofthouse Jul 20, 2018 7:37 AM (in response to sergiu_pienar)1 of 1 people found this helpfulThat code sample is almost there, a big difference here is you know once you have a SecurityIdentity the authentication was successful - the old SecurityClient API didn't actually perform an authentication it just stored the credentials on a ThreadLocal for future use.
Now that you have the SecurityIdentity from the authentication you need to use it for the ongoing request by using one of the various runAs methods it exposes: -
SecurityIdentity (WildFly Elytron 1.4.0.Final API)
The identity will then be automatically in place for the duration of the RunAs call and automatically cleaned up once the call returns.
-
4. Re: WildFly Elytron security client programatic login
sergiu_pienar Jul 20, 2018 7:46 AM (in response to dlofthouse)Unfortunately this doesn't work when trying to authenticate:
ERROR [stderr] (Thread-291) org.wildfly.security.authz.AuthorizationFailureException: ELY01088: Attempting to run as "SYSTEM" authorization operation failed 14:37:42,308 ERROR [stderr] (Thread-291) at org.wildfly.security.auth.server.SecurityIdentity.createRunAsIdentity(SecurityIdentity.java:639) 14:37:42,309 ERROR [stderr] (Thread-291) at org.wildfly.security.auth.server.SecurityIdentity.createRunAsIdentity(SecurityIdentity.java:614) 14:37:42,314 ERROR [stderr] (Thread-291) at org.wildfly.security.auth.server.SecurityIdentity.createRunAsIdentity(SecurityIdentity.java:598) 14:37:42,314 ERROR [stderr] (Thread-291) at com.util.security.SecurityClient.doLogin(SecurityClient.java:85)
In the above snippet I added
SecurityIdentity runAs = identity.createRunAsIdentity(User.SYSTEM_USER_NAME);
after calling authenticate on the security domain.
The Elytron domain that I'm using is linked to a jdbc-realm.
-
5. Re: WildFly Elytron security client programatic login
dlofthouse Jul 20, 2018 7:47 AM (in response to sergiu_pienar)That stack trace does not appear to match the code you posted? The stack trace appears to be calling createRunAsIdentity instead - that method performs an authorization check to check if the current identity is authorized to run as the Principal requested.
-
6. Re: WildFly Elytron security client programatic login
sergiu_pienar Jul 20, 2018 8:23 AM (in response to dlofthouse)Here's a more complete image of what I'm trying to achieve:
Old code:
@Startup @Singleton @DependsOn({ "HibernateService", "CACDatasourceBean", "CACJobScheduleBean", "CACClientBean" }) public class ViSessionFactoryService implements ViSessionFactoryServiceMBean { private static final Logger LOGGER = Logger.getLogger(SessionFactoryService.class); @Override @PostConstruct public void start() { String startSessionFactories = PlatformConfig.getInstance().getClientSessionFactoriesStart(); boolean start = new Boolean(startSessionFactories).booleanValue(); org.jboss.security.client.SecurityClient client = SecurityClientFactory.getSecurityClient(); client.setSimple(User.SYSTEM_USER_NAME, User.SYSTEM_USER_PASSWORD); client.login(); if (start) { ViSessionFactoryService.LOGGER.info("start the client session factories, this can take while"); try { CACDatasourceFactory.getLocal().recreateSessionFactories(); } catch (CACException e) { ViSessionFactoryService.LOGGER.error(e); } catch (NamingException e) { ViSessionFactoryService.LOGGER.error(e); }
.............
The above would only work because when calling the CACDatasourceFactory.getLocal().recreateSessionFactories(); the SYSTEM use would have been already logged in and was allowed to call the recreateSessionFactories method, which has a @RolesAllowed annotation.
The new code would be something like:
@Startup @Singleton @DependsOn({ "HibernateService", "CACDatasourceBean", "CACJobScheduleBean", "CACClientBean" }) public class ViSessionFactoryService implements ViSessionFactoryServiceMBean { private static final Logger LOGGER = Logger.getLogger(ViSessionFactoryService.class); @Override @PostConstruct public void start() { String startSessionFactories = PlatformConfig.getInstance().getClientSessionFactoriesStart(); boolean start = new Boolean(startSessionFactories).booleanValue(); SecurityDomain currentSecurityDomain = SecurityDomain.getCurrent(); Evidence evidence = new PasswordGuessEvidence(User.SYSTEM_USER_PASSWORD.toCharArray()); currentSecurityDomain.authenticate(User.SYSTEM_USER_NAME, evidence);
How can I use the SecurityIdentity to call my EJB's method (CACDatasourceBean) ?
Later edit: If I'm doing identity.getRoles() I'm getting the correct roles for that user so this seems to be working correctly... what I now need would be to understand how to call the EJB's method from within the identities' runAs method.
Would this do :
identity.runAs(() -> { try { CACDatasourceFactory.getLocal().recreateSessionFactories(); } catch (CACException | NamingException e2) { // TODO write your own catch code! } });
?
Later-later edit: It worked fine !
Thanks.