Programmatic Login With Wildfly Elytron Security

1.4k views Asked by At

I'm in the process of migrating some legacy applications from Jboss AS 6 to Wildfly. Since the legacy (picketbox) security system is deprecated, I want to switch over to using elytron. I followed along with the quickstart examples and I think I have my configuration set up correctly, but I'm running into a problem with migrating my actual code.

There are time where we want to authorize a user directly rather than relying on a call from the client or a servlet. This is especially important in integration tests where we want to test ejb methods that require a certain permission. Currently, my login method for doing a manual authorization looks like this:

public boolean login(String domain, Credentials credentials)
    {
        try
        {
            lc = new javax.security.auth.login.LoginContext(domain,
                    new PassiveCallbackHandler(credentials.getUsername(), credentials.getPassword()));
            lc.login();
            Subject subject = lc.getSubject();
            pushSubjectContext(credentials.getUsername(), credentials.getPassword());
            if (sessionActivityService != null)
            {
                sessionActivityId = sessionActivityService.activateSession(applicationName, "127.0.0.1");
            }
            return true;
        }
        catch (LoginException e)
        {
            e.printStackTrace();
            return false;
        }
    }

When I try to call that method using the security domain defined in the elytron subsystem it fails. Debugging through the code, I can see that the LoginContext doesn't see any of the security domains from elytron. Only the legacy (jboss.as:security) domains are visible, so it defaults to a security domain of 'other'.

Is there any way to do what I want using elytron?

FYI, here are some snippets from my configuration:

standalone.xml:

<subsystem xmlns="urn:wildfly:elytron:8.0" final-providers="combined-providers" disallowed-providers="OracleUcrypto">         
            <security-domains>
                ...           
                <security-domain name="TestOptics" default-realm="testRealm" permission-mapper="default-permission-mapper">
                    <realm name="testRealm" role-decoder="groups-to-roles"/>
                </security-domain>
            </security-domains>
            <security-realms>
                <identity-realm name="local" identity="$local"/>              
                <jdbc-realm name="testRealm">
                    <principal-query sql="SELECT password FROM&#x9;persons WHERE username=?" data-source="TestOpticsDS">
                        <clear-password-mapper password-index="1"/>
                    </principal-query>
                    <principal-query sql="select roles.name,'Roles' from persons join persons_to_roles on persons_to_roles.person_id=persons.id join roles on roles.id=persons_to_roles.role_id where persons.username=? and persons.enabled=1 and persons.password is not null union select 'authenticated','Roles'" data-source="OpticsDS">
                        <attribute-mapping>
                            <attribute to="Roles" index="1"/>
                        </attribute-mapping>
                    </principal-query>
                </jdbc-realm>
                ...
            </security-realms>
           ...
            <http>
                ...
                <http-authentication-factory name="test-http-auth" security-domain="TestOptics" http-server-mechanism-factory="global">
                    <mechanism-configuration>
                        <mechanism mechanism-name="BASIC">
                            <mechanism-realm realm-name="testRealm"/>
                        </mechanism>
                    </mechanism-configuration>
                </http-authentication-factory>
                <provider-http-server-mechanism-factory name="global"/>
            </http>
            <sasl>
               ...
                <sasl-authentication-factory name="test-app-sasl-auth" sasl-server-factory="configured" security-domain="TestOptics">
                    <mechanism-configuration>
                        <mechanism mechanism-name="JBOSS-LOCAL-USER" realm-mapper="local"/>
                        <mechanism mechanism-name="BASIC">
                            <mechanism-realm realm-name="testRealm"/>
                        </mechanism>
                    </mechanism-configuration>
                </sasl-authentication-factory>
                ...
            </sasl>
        </subsystem>
        <subsystem xmlns="urn:jboss:domain:ejb3:6.0">
            ...
            <default-security-domain value="other"/>
            <application-security-domains>
                <application-security-domain name="TestOptics" security-domain="TestOptics"/>
            </application-security-domains>
            <default-missing-method-permissions-deny-access value="true"/>
            <statistics enabled="${wildfly.ejb3.statistics-enabled:${wildfly.statistics-enabled:false}}"/>
            <log-system-exceptions value="true"/>
        </subsystem>

jboss-web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE jboss-web>
<jboss-web xmlns="http://www.jboss.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.jboss.com/xml/ns/javaee http://www.jboss.org/schema/jbossas/jboss-web_14_0.xsd" version="14.0">
    <!-- <context-root>person/test</context-root> -->
    <security-domain>TestOptics</security-domain>
</jboss-web>

web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://java.sun.com/xml/ns/javaee  http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
      version="3.0"> 
    
    <login-config>
    <auth-method>BASIC</auth-method>
    <realm-name>TestOptics</realm-name>
    </login-config>
</web-app>
1

There are 1 answers

0
Vithun Venugopalan On

I found this here developer.jboss.org/thread/277957

SecurityDomain currentSecurityDomain = SecurityDomain.getCurrent();

            Evidence evidence = new PasswordGuessEvidence(runWith.password().toCharArray());

            SecurityIdentity identity = currentSecurityDomain.authenticate(runWith.username(), evidence);

            return identity.runAs(new Callable(){

                @Override
                public Object call() throws Exception {

                    LOG.warn("This should be runWith#username()? " + sessionCtx.getCallerPrincipal().getName());

                    return context.proceed();

                }

            });