Announcement Announcement Module
Collapse
No announcement yet.
How to set authentication provider list for manager based on database record? Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • How to set authentication provider list for manager based on database record?

    Hi all,

    I am facing an issue to configure authentication manager by adding authentication providers according to database records.
    Our system will allow end user to configure external authentication system and will store this information in database.
    While our system start up, all configured external authentication systems should be loaded and be enable to provide authenticating for end users.

    I have tried following way but have no luck.
    In security relative configuration file security-context.xml
    Code:
        <http authentication-manager-ref="authenticationManager" use-expressions="true">
            <intercept-url pattern="/common/**" access="hasRole('ROLE_ADMINISTRATOR')" requires-channel="https" />
            <form-login login-page="/login.xhtml" default-target-url="/common/homePage.xhtml" always-use-default-target="true" />
            <logout logout-success-url="/login.xhtml" delete-cookies="JSESSIONID" />
        </http>
    
        <beans:bean id="internalAuthenticationProvider" class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
        </beans:bean>
    
        <beans:bean id="authenticationManager" class="org.springframework.security.authentication.ProviderManager">
            <beans:property name="providers" ref="authenticationProviderListFactoryBean" />    
        </beans:bean>
    
        <beans:bean id="authenticationProviderListFactoryBean" class="com.aaa.bbb.ccc.services.utilities.auth.MyAuthenticationProviderListFactoryBean">
            <beans:property name="internalAuthenticationProvider" ref="internalAuthenticationProvider" />
            <beans:property name="identitySystemRepository" ref="identitySystemRepositoryImpl" />
            <beans:property name="userGroupRepository" ref="userGroupRepositoryImpl" />
        </beans:bean>
    
        <security:global-method-security authentication-manager-ref="authenticationManager" pre-post-annotations="enabled">
        </security:global-method-security>
    After deploy project, I get following error.
    Code:
    java.lang.IllegalArgumentException: Internal Authentication Provider required
            at org.springframework.util.Assert.isNull(Assert.java:89)
            at com.aaa.bbb.ccc.services.utilities.auth.MyAuthenticationProviderListFactoryBean.addAuthenticationProviderForIdentitySystem(MyAuthenticationProviderListFactoryBean.java:49)
    In my MyAuthenticationProviderListFactoryBean.java
    Code:
    public class MyAuthenticationProviderListFactoryBean implements FactoryBean<List<AuthenticationProvider>>, InitializingBean {
    
        List<AuthenticationProvider> providers;
        private AuthenticationProvider internalAuthenticationProvider;
        private IdentitySystemRepositoryInterface identitySystemRepository;
        private UserGroupRepositoryInterface userGroupRepository;
    
        public void setInternalAuthenticationProvider(AuthenticationProvider internalAuthenticationProvider) {
            this.internalAuthenticationProvider = internalAuthenticationProvider;
        }
    
        public void setIdentitySystemRepository(IdentitySystemRepositoryInterface identitySystemRepository) {
            this.identitySystemRepository = identitySystemRepository;
        }
    
        public void setUserGroupRepository(UserGroupRepositoryInterface userGroupRepository) {
            this.userGroupRepository = userGroupRepository;
        }
    
        @Override
        public List<AuthenticationProvider> getObject() throws Exception {
            return this.providers;
        }
    
        @SuppressWarnings("unchecked")
        @Override
        public Class<List<?>> getObjectType() {
            return (Class<List<?>>) (null != providers ? providers.getClass() : (Class<?>) List.class);
        }
    
        @Override
        public boolean isSingleton() {
            return true;
        }
    
        @Override
        public void afterPropertiesSet() throws Exception {
            addAuthenticationProviderForIdentitySystem();
        }
    
        private void addAuthenticationProviderForIdentitySystem() {
    
            Assert.isNull(internalAuthenticationProvider, "Internal Authentication Provider required");
            Assert.isNull(identitySystemRepository, "Identity System Repository required");
            Assert.isNull(userGroupRepository, "User Group Repository required");
    
            List<IdentitySystemEntity> identitySystems = identitySystemRepository.findAll();
    
            providers = new ArrayList<AuthenticationProvider>(identitySystems.size() + 1);
    
            providers.add(internalAuthenticationProvider);
    
            for (IdentitySystemEntity identitySystem : identitySystems) {
                providers.add(new ActiveDirectoryLdapAuthenticationProvider(identitySystem.getUrl(), identitySystem.getDomain(), userGroupRepository));
            }
        }
    }
    Is there anything I did wrong?
    Thanks and best regards,
    Flik

  • #2
    Hi all,
    The root cause is method Assert.notNull should be used instead of Assert.isNull.
    Then everything works fine.
    Best regards,
    Flik

    Comment


    • #3
      Hi all,

      Although the factory bean could help build list of provider during boot up, it looks hard to update the list to reflect any change of database except invoking deprecated method "setProviders" of ProviderManager.
      Is there any way to allow changes of authentication system to take effects immediately?

      Thanks in advance.
      Flik

      Comment

      Working...
      X