1 2 Previous Next 23 Replies Latest reply on Nov 14, 2018 11:18 AM by pmm

    Wildfly 13 and custom (legacy) login module

    djapal

      Hello all.

      I'm trying to migrate our application from Wildfly 10.1 and picketbox to Wildfly 13 and elytron.

      We have a security-domain like the following

       

      <security-domain name="default-domain" cache-type="infinispan">

      <authentication>

      <login-module code="com.test.SecurityLoginV2" flag="sufficient">

      <module-option name="java.naming.provider.url" value="ldap://ldap.internal.net/"/>

      <module-option name="java.naming.security.authentication" value="simple"/>

      <module-option name="java.naming.factory.initial" value="com.sun.jndi.ldap.LdapCtxFactory"/>

      <module-option name="principalDNPrefix" value="uid="/>

      <module-option name="uidAttributeID" value="memberOf"/>

      <module-option name="roleNameAttributeID" value="cn"/>

      <module-option name="roleAttributeID" value="memberOf"/>

      <module-option name="principalDNSuffix" value=",cn=users,cn=accounts,dc=internal,dc=net"/>

      <module-option name="userSrchBase" value="dc=internal,dc=net"/>

      <module-option name="rolesCtxDN" value="cn=groups,cn=accounts,dc=internal,dc=net"/>

      <module-option name="matchOnUserDN" value="true"/>

      <module-option name="unauthendicatedIdentity" value="foousr"/>

      <module-option name="com.sun.jndi.ldap.connect.timeout" value="5000"/>

      </login-module>

      </authentication>

      </security-domain>

       

      How can we migrate a custom login module to Elytron?

       

      I found this guide but it is for standard LDAP, not for a custom login module.

       

      Any help would be appreciated.

       

      Thank you

        • 1. Re: Wildfly 13 and custom (legacy) login module
          pmm

          We're in a similar situation. Here's what we understand so far:

          • Find out why you need a custom login module and the default LDAP realm does not work in your case.
            • If the default LDAP realm works for you, use that.
            • If the default LDAP realm almost works for you, check if you can still use it which a custom class that does your custom things.
            • If the default LDAP realm categorically does not work for you then you need to implement org.wildfly.security.auth.server.SecurityRealm
          • 2. Re: Wildfly 13 and custom (legacy) login module
            djapal

            Hi Philippe.

            Thank you for your answer.

            Right now I'm trying to make it work at least with the default LDAP authentication mechanism but I still have problems.

            I have downloaded the wildfly-elytron source and I'm debugging the code, in order to find the error.

            As we found out yesterday, legacy security-domain can also be used in Wildfly 13. I had the impression that this was not supported anymore beginning with version 12.

            But still, this is sth that we need to find out if we can fix.

            I'll keep this post updated with any new findings.

            • 3. Re: Wildfly 13 and custom (legacy) login module
              djapal

              Ok so what I have managed so far is that I had to use the Directory Manager credentials (not what we want, but let's bypass this step for the moment) because

              this was the only way of reading the userPassword property of the ldap user.

              This works.

              User is authenticated and authorized. Roles are retrieved successfully.

               

               

              When I login though and call SessionContext.getCallerPrincipal() "anonymous" is returned though request.getUserPrincipal().toString() returns the correct name.

              What needs to be changed? Why anonymous is returned since i have disabled it through the equivalent mapper?

               

                                  <permission-mapping>

                                      <principal name="anonymous"/>

                                  </permission-mapping>

                                  <permission-mapping match-all="true">

                                      <permission class-name="org.wildfly.security.auth.permission.LoginPermission"/>

                                      <permission class-name="org.wildfly.extension.batch.jberet.deployment.BatchPermission" module="org.wildfly.extension.batch.jberet" target-name="*"/>

                                      <permission class-name="org.wildfly.transaction.client.RemoteTransactionPermission" module="org.wildfly.transaction.client"/>

                                      <permission class-name="org.jboss.ejb.client.RemoteEJBPermission" module="org.jboss.ejb-client"/>

                                  </permission-mapping>

              • 4. Re: Wildfly 13 and custom (legacy) login module
                pmm

                Is that with the legacy or the Elytron configuration?

                • 5. Re: Wildfly 13 and custom (legacy) login module
                  djapal

                  With the Elytron.

                  Same application deployed as is on Wildfly 10.1 with picketbox and no such weird stuff.

                  Also I didnt have to declare the Directory Manager and his password in order to use the ldap authentication login module.

                  • 6. Re: Wildfly 13 and custom (legacy) login module
                    mchoma

                    What is the package of SessionContext? Can you describe your solution. E.g. you are using BASIC http authentication to servlet and then servlet is calling EJB? And in EJB there is called SessionContext.getCallerPrincipal()?

                    • 7. Re: Wildfly 13 and custom (legacy) login module
                      djapal

                      Hi Martin.

                      It is a FORM authentication.

                      It is the normal javax.ejb.SessionContext class.

                      I have the following class with the following snippet.

                       

                      import javax.annotation.Resource;

                      import javax.ejb.SessionContext;

                      import javax.ejb.Stateless;

                       

                      @Stateless
                      public class UtilityService {

                       

                        @Resource
                        private SessionContext securityContext;

                       

                        public boolean isInAnyOfRoles(List<String> roles) {

                        System.out.println(securityContext.getCallerPrincipal().getName());

                         return roles.stream().anyMatch(securityContext::isCallerInRole);

                        }

                       

                      I inject this service in some places where I want to hide/show some links/menus.

                      In picketbox this works fine. principal name is correct and of course roles are found.

                      In Elytron this does not work. it displays anonymous.

                      • 8. Re: Wildfly 13 and custom (legacy) login module
                        mchoma

                        In general that should work We test that.

                         

                        There must be some difference in your case. Can you show us logs. With FORM do you use programmatic login? Can you show us how you call EJB from servlet? What application domain do you use in case of Undertow and EJB subsystems.

                        • 9. Re: Wildfly 13 and custom (legacy) login module
                          djapal

                          I have jsf pages where i use the rendered attribute in order to show/hide elements.

                          e.g. <ui:fragment rendered="#{utils.isInAnyOfRoles(['it'])}">

                          utils is an ApplicationScoped bean which injects the Utility service that i posted in my previous reply.

                           

                          @Named(value = "utils")

                          @ApplicationScoped
                          public class UtilityBean extends GenericBean {

                           

                            private UtilityService utilityService;

                           

                            @Inject
                            public UtilityBean(UtilityService utilityService) {

                             this.utilityService = utilityService;

                            }

                           

                          These work

                          value="#{request.getUserPrincipal().toString()}"

                          value="#{request.isUserInRole('it')}"

                           

                          My snippet from standalone.xml

                           

                                  <subsystem xmlns="urn:jboss:domain:ejb3:5.0">

                          .

                          .

                          .

                                      <default-security-domain value="lotusAD"/>

                                      <application-security-domains>

                                          <application-security-domain name="lotusAD" security-domain="lotusSD"/>

                                      </application-security-domains>

                                      <default-missing-method-permissions-deny-access value="true"/>

                                      <log-system-exceptions value="true"/>

                                  </subsystem>

                           

                           

                           

                                    <subsystem xmlns="urn:jboss:domain:undertow:6.0" default-server="default-server" default-virtual-host="default-host" default-servlet-container="default" default-security-domain="lotusAD">

                           

                                      <application-security-domains>

                                          <application-security-domain name="lotusAD" http-authentication-factory="lotus-ldap-http-auth"/>

                                      </application-security-domains>

                           

                           

                                          <http-authentication-factory name="lotus-ldap-http-auth" security-domain="lotusSD" http-server-mechanism-factory="global">

                                              <mechanism-configuration>

                                                  <mechanism mechanism-name="FORM">

                                                      <mechanism-realm realm-name="lotusAD"/>

                                                  </mechanism>

                                              </mechanism-configuration>

                                          </http-authentication-factory>

                           

                           

                                          <security-domain name="lotusSD" default-realm="lotusLR" permission-mapper="custom-permission-mapper">

                                              <realm name="lotusLR" role-decoder="from-roles-attribute"/>

                                          </security-domain>

                           

                           

                           

                                          <ldap-realm name="lotusLR" dir-context="lotusDC">

                                              <identity-mapping rdn-identifier="uid" search-base-dn="cn=users,cn=accounts,dc=internal,dc=net">

                                                  <attribute-mapping>

                                                      <attribute from="cn" to="Roles" filter="(member={1})" filter-base-dn="cn=groups,cn=accounts,dc=internal,dc=net"/>

                                                  </attribute-mapping>

                                                  <user-password-mapper from="userPassword"/>

                                              </identity-mapping>

                                          </ldap-realm>

                           

                           

                                          <simple-permission-mapper name="custom-permission-mapper">

                                              <permission-mapping>

                                                  <principal name="anonymous"/>

                                              </permission-mapping>

                                              <permission-mapping match-all="true">

                                                  <permission class-name="org.wildfly.security.auth.permission.LoginPermission"/>

                                                  <permission class-name="org.wildfly.extension.batch.jberet.deployment.BatchPermission" module="org.wildfly.extension.batch.jberet" target-name="*"/>

                                                  <permission class-name="org.wildfly.transaction.client.RemoteTransactionPermission" module="org.wildfly.transaction.client"/>

                                                  <permission class-name="org.jboss.ejb.client.RemoteEJBPermission" module="org.jboss.ejb-client"/>

                                              </permission-mapping>

                                          </simple-permission-mapper>

                           

                          web.xml

                           

                          <login-config>

                            <auth-method>FORM</auth-method>

                            <realm-name>lotusAD</realm-name>

                            <form-login-config>

                             <form-login-page>/pages/login.jsf</form-login-page>

                             <form-error-page>/pages/login.jsf?failLogin=true</form-error-page>

                            </form-login-config>

                          </login-config>

                           

                           

                          jboss-ejb3.xml (not needed I guess since I have declared a default SD)

                           

                          <?xml version="1.0"?>
                          <jboss:ejb-jar xmlns:jboss="http://www.jboss.com/xml/ns/javaee"
                             xmlns="http://java.sun.com/xml/ns/javaee"
                             xmlns:s="urn:security"
                             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                             xsi:schemaLocation="http://www.jboss.com/xml/ns/javaee
                            http://www.jboss.org/j2ee/schema/jboss-ejb3-2_0.xsd
                            http://java.sun.com/xml/ns/javaee
                            http://java.sun.com/xml/ns/javaee/ejb-jar_3_1.xsd"
                             version="3.1"
                             impl-version="2.0">

                            <assembly-descriptor>

                             <s:security>

                             <ejb-name>*</ejb-name>

                             <s:security-domain>lotusAD</s:security-domain>

                             </s:security>

                            </assembly-descriptor>

                          </jboss:ejb-jar>

                          • 10. Re: Wildfly 13 and custom (legacy) login module
                            mchoma

                            Any logs?

                            Are you calling request.login yourself in login.jsf ? Or are you relying on j_security_check?

                            • 11. Re: Wildfly 13 and custom (legacy) login module
                              djapal

                              I;m reyling on j_security_check.

                              I need to filter the log and post it here.

                              I'm also trying to create a simple senario with a demo app to see If I can reproduce it.

                              • 12. Re: Wildfly 13 and custom (legacy) login module
                                djapal

                                Martin, I just reproduced the issue with a test project.

                                What i did is that i created a demo local ldap with the info from this section

                                 

                                https://docs.jboss.org/author/display/WFLY/WildFly+Elytron+Security#WildFlyElytronSecurity-ConfigureAuthenticationwithanLDAPBasedIdentityStore

                                 

                                I followed the steps and made the required changes also to web.xml, jboss-web and jboss-ejb3.

                                Finally i had to add the new <application-security-domain> for ejb3 subsystem.

                                If i leave the security domain in jboss-ejb3, anonymous user is shown.

                                If I annotate my EJB3 bean, execution of method is not permitted and exceptions are thrown.

                                Please find the demo project here.

                                 

                                https://www.dropbox.com/s/zcoei4j2xzpjih2/ldapwildfly13test.zip?dl=0

                                • 13. Re: Wildfly 13 and custom (legacy) login module
                                  mchoma

                                  Can you try to use EJBContext instead of SessionContext? I found similar discussion in case of EJBContext [1]

                                  What is the exception when you secure EJB?

                                   

                                  [1] [JBEAP-9744] EJBContext.getCallerPrincipal behaves differently in Elytron and legacy security - JBoss Issue Tracker

                                  • 14. Re: Wildfly 13 and custom (legacy) login module
                                    djapal

                                    EJBContext didn;t work.

                                    I'll try again on Monday and I will post the logs. Thank you

                                    1 2 Previous Next