1

I'm using Vaadin 7.5.6, Vaadins Spring 1.0.0, the Vaadin4Spring Managed Security Extension 0.0.7-SNAPSHOT and Tomcat8.

Currently, I got a configuration class which implements the AuthenticationManagerConfigurer interface:

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.vaadin.spring.security.annotation.EnableVaadinManagedSecurity;
import org.vaadin.spring.security.config.AuthenticationManagerConfigurer;

import com.vaadin.server.CustomizedSystemMessages;
import com.vaadin.server.SystemMessages;
import com.vaadin.server.SystemMessagesInfo;
import com.vaadin.server.SystemMessagesProvider;

import de.blume2000.kiss.hibernate.dto.User;
import de.blume2000.kiss.hibernate.services.UserService;
import de.blume2000.kiss.utils.EncryptionUtil;

@Configuration
@EnableVaadinManagedSecurity
public class SecurityConfiguration implements AuthenticationManagerConfigurer
{

    @Autowired
    UserService userService;

    @Override
    public void configure(AuthenticationManagerBuilder auth) throws Exception
    {
        List<User> users = userService.findAll();

        if (users == null)
            return;

        for (User user : users)
        {
            String encryptedPassword = EncryptionUtil.decryptPassword(user.getPassword(), user.getSalt());
            auth.inMemoryAuthentication().withUser(user.getUsername()).password(encryptedPassword).roles(user.getRole());
        }

    }

    /**
     * Provide custom system messages to make sure the application is reloaded when the session expires.
     */
    @SuppressWarnings("serial")
    @Bean
    SystemMessagesProvider systemMessagesProvider()
    {
        return new SystemMessagesProvider()
        {
            @Override
            public SystemMessages getSystemMessages(SystemMessagesInfo systemMessagesInfo)
            {
                CustomizedSystemMessages systemMessages = new CustomizedSystemMessages();
                systemMessages.setSessionExpiredNotificationEnabled(false);
                return systemMessages;
            }
        };
    }

}

Now if the user did a login he has the option to edit his user account settings. This changes the user object in the database (e.g. the username for login). Now if he does a logout, i want the application to reload the userlist, so the user can use his new username. How is this possible?

Regards shinchillahh

shinchillahh
  • 515
  • 1
  • 4
  • 22

1 Answers1

2

In short, replace your in-memory authentication with DAO authentication.

Please note that in the example below UserDetailsService userService is the Spring core interface, and UserRepository userRepository is the DAO for your users (aka UserService userService in your example).

1. Configuration

@Configuration
public class Authorization extends GlobalAuthenticationConfigurerAdapter {

    @Autowired
    private UserDetailsService userService;

    @Override
    public void init(AuthenticationManagerBuilder auth) throws Exception {
       auth.userDetailsService(userService).passwordEncoder(passwordEncoder());
    }

    @Bean
    public PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }
}

2. Service providing user details

@Service
public class UserService implements UserDetailsService {

    @Autowired
    private UserRepository userRepository;

    @Override
    @Transactional(readOnly = true)
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        User user = userRepository.findByUsername(username);
        if (user == null) {
            throw new UsernameNotFoundException(username);
        }
        return user;
    }
}
Morfic
  • 15,178
  • 3
  • 51
  • 61
  • Thank you for your answer. Is this method compatible with the Vaadin4Spring Security extension? So I can handle login and logout via vaadinSecurity.login(...) and vaadinSecurity.logout()? – shinchillahh Oct 15 '15 at 11:16
  • @shinchillahh I haven't really tried the add-on, but you're simply switching the `InMemoryUserDetailsManagerConfigurer` with a `DaoAuthenticationConfigurer` which should be transparent – Morfic Oct 15 '15 at 11:31
  • Okay I got it. Do I have to notice something special about the User DTO class? Because the loadUserByUsername(String username) method returns the UserDetails interface... – shinchillahh Oct 15 '15 at 11:48
  • @shinchillahh For simplicity I made my `User` bean implement the `org.springframework.security.core.userdetails.UserDetails` interface. A nicer and cleaner code would probably create a `org.springframework.security.core.userdetails.User` (or a custom implementation) from your own `User`model bean. – Morfic Oct 15 '15 at 11:56
  • Im so thankful for your help. I think I know how to do it. Last question: Because I have my own password encryption util I have to define my own password encoder, right? How should I do that? – shinchillahh Oct 15 '15 at 12:06
  • @shinchillahh You can either implement yourself the [PasswordEncoder interface](http://stackoverflow.com/questions/17444258/how-to-use-new-passwordencoder-from-spring-security) or use one of the encoders already provided such as `BCryptPasswordEncoder`. The main idea is to always [generate the same hash](http://stackoverflow.com/questions/26811885/getting-same-hashed-value-while-using-bcryptpasswordencoder) for the same password, otherwise you'll never be able to login. – Morfic Oct 15 '15 at 12:43