userRepository insecure as userDetailsService needs to look up user

99 Views Asked by At

I have implemented a custom UserDetailsService that looks up a user and allows them to get a oauth 2 token using password grant. The service indicates to use a JPA userRepository to look up the user.

This all works, except that now I have a /users endpoint publicly available pulling in all users and passwords to any authenticated user. Ideally I would like to not have this endpoint available at all, but if I put a preAuthorize on it with admin role, then all users are denied while trying to obtain a login token too, so this doesn't work either. How do people get around this issue? I can add a matcher to resource server to only allow admin users, this seems to work, but I don't want the endpoint available at all, it's quite scary to have it there just so UserDetailsService can use it to get access tokens?

Any input on what you guys do would be greatly appreciated.

//Example code:
// Bad public facing endpoint returning all users and passwords

public interface UserRepository extends JpaRepository<User, Long> {
    User findOneByUsername(String username);
}

// Custom user details service used by oauth 2 to get access tokens
// uses userRepo above
@Service("userDetailsService")
public class UserService implements UserDetailsService {

    @Autowired
    private UserRepository userRepository;

    @Override
     public UserDetails loadUserByUsername(String username) throws     UsernameNotFoundException {
        return userRepository.findOneByUsername(username);
    }
}

// class using user details service
@Configuration
@EnableAuthorizationServer
public class OAuth2Config extends AuthorizationServerConfigurerAdapter {

    @Qualifier("userDetailsService")
    private UserDetailsService userDetailsService;

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer configurer) throws Exception {
         configurer.userDetailsService(userDetailsService);
    }


}
1

There are 1 best solutions below

2
On

I presume that you are using Spring Data?

In that case, you need to tell Spring not to export the endpoint:

@RepositoryRestResource(exported = false)

https://docs.spring.io/spring-data/rest/docs/current/api/org/springframework/data/rest/core/annotation/RepositoryRestResource.html