0

I am doing my B.Tech project and everything was going well but now I am stuck in configuring authentication for two different types of users i.e Customers and Service Providers. I am using MongoDB.

I have two different databases for each user. I am trying to create multiple login pages that would authenticate the user from their respective databases. I am using order(1) and order(2) for configuration but only order(1) is working.

This is my configuration code.

       @Configuration
       @EnableWebSecurity
       public class MultiLoginConfig {

@Configuration
@Order(1)
public static class DearHelpUserSecConfig extends WebSecurityConfigurerAdapter{

      @Override
        @Bean
        protected UserDetailsService userDetailsService() {
            return new CustomUserDetailsService();
        }

      @Bean
        public static NoOpPasswordEncoder passwordEncoder() {
         return (NoOpPasswordEncoder) NoOpPasswordEncoder.getInstance();
        }

        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http
            .authorizeRequests()
                .antMatchers( "/home").permitAll()
                .antMatchers("/hellouser").access("hasRole('USER')")

                .and()
            .formLogin()

                .loginPage("/login1")
                .permitAll()
                .and()
            .logout()
              .permitAll()
            .logoutUrl("/logout"). 
            logoutSuccessUrl("/home")
                .and()
                    .userDetailsService(userDetailsService());
        }

}

@Configuration
@Order(2)
public static class DearHelpSPSecConfig extends WebSecurityConfigurerAdapter{

     @Override
        @Bean
        protected UserDetailsService userDetailsService() {
            return new SPUserDetailsService();
        }

        @Bean
        public static NoOpPasswordEncoder passwordEncoder() {
         return (NoOpPasswordEncoder) NoOpPasswordEncoder.getInstance();
        }

        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http
            .authorizeRequests()
                .antMatchers( "/home").permitAll()
                .antMatchers("/hellosp").access("hasRole('SP')")

               .and()
            .formLogin()

                .loginPage("/login2")
                .permitAll()
                .and()
            .logout()
                .permitAll()
            .logoutUrl("/logout"). 
            logoutSuccessUrl("/home")
                .and()
                    .userDetailsService(userDetailsService());
        }


}   

  }

I am implementing Custom UserDetailsService for each user.

Custom implementation for Customers UserDetailsServices is..

   public class CustomUserDetailsService implements UserDetailsService {

@Autowired
private MongoTemplate mongoTemplate;

@Override
public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {
    Query query = new Query();
    query.addCriteria(Criteria.where("email").is(email));
    DearHelpUsers user =
            mongoTemplate.findOne(query, DearHelpUsers.class);
    if (user == null) {
        throw new UsernameNotFoundException(String.format("email %s not found", email));
    }



    return new User(user.getEmail(), user.getPassword(),
         AuthorityUtils.createAuthorityList(user.getRole()));

   }
 }                  

Custom implementation for Service Providers UserDetailsServices is..

   public class SPUserDetailsService implements UserDetailsService {

@Autowired
private MongoTemplate mongoTemplate;

@Override
public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {
    Query query = new Query();
    query.addCriteria(Criteria.where("email").is(email));
    ServiceProviders user =
            mongoTemplate.findOne(query, ServiceProviders.class);
    System.out.println(user);
    if (user == null) {
        throw new UsernameNotFoundException(String.format("email %s not found", email));
    }



    return new User(user.getEmail(), user.getPassword(),
         AuthorityUtils.createAuthorityList(user.getRole()));

   }
}

When I am trying to access Customers page i.e "/hellouser", the login page is popping out and authentication is working fine. But When I am trying to access Service provider page i.e "/hellosp", it is accessible without logging in the user. Authorization for Service providers is not working. I tried changing the order and observed that authorization for only order(1) code is working but order(2) is not working. Where am I doing wrong? Any help would be highly appreciated. Thank you

2
  • This is going to be exceedingly complex to manage. It would generally be simpler to write a UserDetailsService that distinguishes them internally somehow. Commented Mar 27, 2019 at 5:52
  • I don't any idea about what you are suggesting. I would be more clear to me if you write some code samples Commented Mar 27, 2019 at 7:09

1 Answer 1

1
@Configuration
@EnableMongoRepositories(basePackages = {"com.sbr.platform.services.repository.primary"},
        mongoTemplateRef = "primaryMongoTemplate")
@EntityScan(basePackages = "com.sbr.platform.services.model")
@EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class})
public class PrimaryMongodbConfig {

}

Create Secondary db configuration

@Configuration
@EnableMongoRepositories(basePackages = {"com.sbr.platform.services.repository.secondary"}, mongoTemplateRef = "secondaryMongoTemplate")
@EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class})
public class SecondaryMongodbConfig {

}
@Data
@Configuration
@RequiredArgsConstructor
@EnableConfigurationProperties(MongoConfigProperties.class)
@Slf4j
public class MultipleMongoConfig {

    private final MongoConfigProperties mongoConfigProperties;

    @Primary
    @Bean(name = "primaryMongoTemplate")
    public MongoTemplate primaryMongoTemplate() throws Exception {
        return new MongoTemplate(mongoFactory(this.mongoConfigProperties.getPrimary()), this.mongoConfigProperties.getPrimary().getDatabase());
    }

    @Primary
    @Bean(name = "secondaryMongoTemplate")
    public MongoTemplate secondaryMongoTemplate() throws Exception {
        return new MongoTemplate(mongoFactory(this.mongoConfigProperties.getSecondary()), this.mongoConfigProperties.getSecondary().getDatabase());
    }

    private MongoClient mongoFactory(final MongoProperties mongo) {
        StringBuffer sb = new StringBuffer();
        sb.append("mongodb://");
        sb.append(mongo.getUsername());
        sb.append(":");
        sb.append(mongo.getPassword());
        sb.append("@");
        sb.append(mongo.getHost());
        sb.append(":");
        sb.append(mongo.getPort());
        sb.append("/");
        sb.append(mongo.getDatabase());
        sb.append("?authSource=");
        sb.append(mongo.getAuthenticationDatabase());
        log.info("Connection String : {} ",sb.toString());
        MongoCredential credential = MongoCredential.createCredential(mongo.getUsername(), mongo.getDatabase(), mongo.getPassword());
        log.info("mongoFactory : {} : credential: {} ", mongo, credential);
        MongoClientSettings mongoClientSettings = MongoClientSettings.builder()
                .applyConnectionString(new ConnectionString(sb.toString()))
                .build();
        return MongoClients.create(mongoClientSettings);
    }

}

application.yml

sbr:
  service:
    mongodb: # MongoDB configuration
      config:
        primary:
          host: localhost
          port: 27017
          database: primary-profiles-collections
          authentication-database: admin
          username: root
          password: example
          repositories:
            enable: true
        secondary:
          host: localhost
          port: 27017
          database: secondary-profiles-collections
          authentication-database: admin
          username: root
          password: example
          repositories:
            enable: true

Create 2 repositories and in different package

@Repository
public interface ProfilePrimaryRepository extends MongoRepository<Profile, String> {
}

@Repository
public interface ProfileSecondaryRepository extends MongoRepository<Profile, String> {
}

Add below code springboot main class

@Configuration
@Slf4j
public class ProfileApplicationConfig implements CommandLineRunner {

    @Autowired
    private ProfilePrimaryRepository profilePrimaryRepository;
    @Autowired
    private ProfileSecondaryRepository profileSecondaryRepository;

    /**
     * Callback used to run the bean.
     *
     * @param args incoming main method arguments
     * @throws Exception on error
     */
    @Override
    public void run(String... args) throws Exception {
        Profile profile = new Profile();
        profile.setProfileType(ProfileType.USER);
        User userProfile = new User();
        userProfile.setPassword("testPWD");
        userProfile.setUserName("test user");
        profile.setBaseProfile(userProfile);
        profile = profilePrimaryRepository.save(profile);
        log.info("Create Profile: {} ", profilePrimaryRepository.findAll());
    }
}

Result

ProfileApplicationConfig  : Create Profile: [Profile(profileType=USER, baseProfile=User(userName=test user, password=testPWD))] 
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.