Authentication With Spring Security and MongoDB – 用Spring Security和MongoDB进行认证

最后修改: 2022年 3月 11日

1. Overview


Spring Security offers different authentication systems, such as via a database and UserDetailService.

Spring Security提供不同的认证系统。如通过数据库和UserDetailService

Instead of using a JPA persistence layer, we may also want to use, for example, a MongoDB repository. In this tutorial, we’ll see how to authenticate a user using Spring Security and MongoDB.

不要使用JPA持久化层。我们可能还想使用,例如, MongoDB 存储库。在本教程中,我们将看到如何使用 Spring Security 和 MongoDB 对用户进行认证。

2. Spring Security Authentication with MongoDB


Similar to using a JPA repository, we can use a MongoDB repository. However, we need to set a different configuration in order to use it.


2.1. Maven Dependencies


For this tutorial, we’re going to use Embedded MongoDB. However, a MongoDB instance and Testcontainer could be valid options for a production environment. First, let’s add the spring-boot-starter-data-mongodb and de.flapdoodle.embed.mongo dependencies:

在本教程中,我们将使用Embedded MongoDB然而,MongoDB实例和Testcontainer可以成为生产环境的有效选择。首先,让我们添加spring-boot-starter-data-mongodbde.flapdoodle.embed.mongo依赖项:


2.2. Configuration


Once we set dependencies, we can create our configuration:


public class MongoConfig {

    private static final String CONNECTION_STRING = "mongodb://%s:%d";
    private static final String HOST = "localhost";

    public MongoTemplate mongoTemplate() throws Exception {

        int randomPort = SocketUtils.findAvailableTcpPort();

        ImmutableMongodConfig mongoDbConfig = MongodConfig.builder()
          .net(new Net(HOST, randomPort, Network.localhostIsIPv6()))

        MongodStarter starter = MongodStarter.getDefaultInstance();
        MongodExecutable mongodExecutable = starter.prepare(mongoDbConfig);
        return new MongoTemplate(MongoClients.create(String.format(CONNECTION_STRING, HOST, randomPort)), "mongo_auth");

We also need to configure our AuthenticationManager with, for example, an HTTP basic authentication:


@EnableGlobalMethodSecurity(securedEnabled = true, jsr250Enabled = true)
public class SecurityConfig {

    public SecurityConfig(UserDetailsService userDetailsService) {
        this.userDetailsService = userDetailsService;

    public AuthenticationManager customAuthenticationManager(HttpSecurity http) throws Exception {
        AuthenticationManagerBuilder authenticationManagerBuilder = http.getSharedObject

    public BCryptPasswordEncoder bCryptPasswordEncoder() {
        return new BCryptPasswordEncoder();

    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {


2.3. User Domain and Repository


First, let’s define a simple user with roles for our authentication. We’ll have it implement the UserDetails interface to reuse commons methods of a Principal object:


public class User implements UserDetails {
    private @MongoId ObjectId id;
    private String username;
    private String password;
    private Set<UserRole> userRoles;
    // getters and setters

Now that we have our user, let’s define a simple repository:


public interface UserRepository extends MongoRepository<User, String> {

    User findUserByUsername(String username);

2.4. Authentication Service


Finally, let’s implement our UserDetailService in order to retrieve a user and check if it’s authenticated:


public class MongoAuthUserDetailService implements UserDetailsService {
    // ...
    public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException {

        com.baeldung.mongoauth.domain.User user = userRepository.findUserByUsername(userName);

        Set<GrantedAuthority> grantedAuthorities = new HashSet<>();

          .forEach(role -> {
              grantedAuthorities.add(new SimpleGrantedAuthority(role.getRole()

        return new User(user.getUsername(), user.getPassword(), grantedAuthorities);


2.5. Test Authentication


To test our application, let’s define a simple controller. As an example, we’ve defined two different roles to test authentication and authorization for specific endpoints:


public class ResourceController {

    public String admin() {
        return "Hello Admin!";

    @RolesAllowed({ "ROLE_ADMIN", "ROLE_USER" })
    public String user() {
        return "Hello User!";


Let’s wrap it all up in a Spring Boot Test to check if our authentication works. As we can see, we’re expecting a 401 code for someone providing invalid credentials or who doesn’t exist in our system:

让我们用Spring Boot测试来总结这一切,检查我们的认证是否有效。正如我们所看到的,如果有人提供无效的凭证或不存在于我们的系统中,我们将期待一个401代码

class MongoAuthApplicationTest {

    // set up

    void givenUserCredentials_whenInvokeUserAuthorizedEndPoint_thenReturn200() throws Exception {
        mvc.perform(get("/user").with(httpBasic(USER_NAME, PASSWORD)))

    void givenUserNotExists_whenInvokeEndPoint_thenReturn401() throws Exception {
        mvc.perform(get("/user").with(httpBasic("not_existing_user", "password")))

    void givenUserExistsAndWrongPassword_whenInvokeEndPoint_thenReturn401() throws Exception {
        mvc.perform(get("/user").with(httpBasic(USER_NAME, "wrong_password")))

    void givenUserCredentials_whenInvokeAdminAuthorizedEndPoint_thenReturn403() throws Exception {
        mvc.perform(get("/admin").with(httpBasic(USER_NAME, PASSWORD)))

    void givenAdminCredentials_whenInvokeAdminAuthorizedEndPoint_thenReturn200() throws Exception {
        mvc.perform(get("/admin").with(httpBasic(ADMIN_NAME, PASSWORD)))

        mvc.perform(get("/user").with(httpBasic(ADMIN_NAME, PASSWORD)))

3. Conclusion


In this article, we looked at MongoDB for authentication with Spring Security.

在这篇文章中,我们研究了MongoDB与Spring Security的认证。

We’ve seen how to create a working configuration and implement our custom UserDetailService. We have also seen how to mock an MVC context and test authentication and authorization.


As always, the code for these examples is available over on GitHub.