8
votes

I have a Spring MVC web app secured with Spring Security and I'm in the process of writing tests. I'm struggling with getting one of my (custom) user retrieved by Spring Security in its SecurityContextHolder. Once my user is "inserted" (java-configured) with :

auth.inMemoryAuthentication().getUserDetailsService().createUser(myCustomUser);

I can then create the related token (a UsernamePasswordAuthenticationToken) and ask for Spring to authenticate my user with this token. The problem is Spring doesn't retrieve a custom user instance but an instance of its User class. When Spring looks for such a user in the following method (from Spring's InMemoryUserDetailsManager) :

public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        UserDetails user = users.get(username.toLowerCase());

        if (user == null) {
            throw new UsernameNotFoundException(username);
        }

        return new User(user.getUsername(), user.getPassword(), user.isEnabled(), user.isAccountNonExpired(),
                user.isCredentialsNonExpired(), user.isAccountNonLocked(), user.getAuthorities());
    }

It instantiates a new User with the details provided by my configuration.

I don't see the problem with having the InMemoryUserDetailsManager directly returning what was sent to him via the "getUserDetailsService().createUser" call but there must be one probably... Anyway, I'm probably doing something wrong here, any idea ?

1
Well, looks like you can't do anything with that. Is it an issue for you to write the custom InMemoryUserDetailsManager ?Artem Bilan
Nope, that's indeed what I'm currently looking at but I can't believe the Spring guys didn't add the possibility to retrieve a custom user via the InMemoryAuth.m4rtin
The type of user you get depends on the UserDetailsService you use. So, I would fully expect the InMemoryUserDetailsService to return its' version of the User object. I believe, in most cases, people write their own UserDetailsService, or at least that has seemed to be the case in all the examples I have seen.CodeChimp
I fully agree with you for non-testing case but I thought the InMemoryAuth was made to be used as a lightweight solution for testing purposes and that it would act like a Map from which the principal could be casted in any type it was given.m4rtin

1 Answers

9
votes

Like suggested, I ended up writing a custom InMemoryUserDetailsManager which I feed my Spring Security configuration with.
To anyone wondering, it seems that it's the only way.