Quantcast
Channel: Baeldung
Viewing all articles
Browse latest Browse all 4536

Spring Security: Authentication with a Database-backed UserDetailsService

$
0
0

The Master Class of "Learn Spring Security" is out:

>> CHECK OUT THE COURSE

1. Overview

In this article, we will show how to create a custom database-backed UserDetailsService for authentication with Spring Security.

2. UserDetailsService

The UserDetailsService interface is used to retrieve user-related data. It has one method named loadUserByUsername() which finds a user entity based on the username and can be overridden to customize the process of finding the user.

It is used by the DaoAuthenticationProvider to load details about the user during authentication.

3. The User Model

For storing users, we will create a User entity that is mapped to a database table, with the following attributes:

@Entity
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @Column(nullable = false, unique = true)
    private String username;

    private String password;

    //standard getters and setters
}

4. Retrieving a User

For the purpose of retrieving a user associated with a username, we will create a DAO class using Spring Data by extending the JpaRepository interface:

public interface UserRepository extends JpaRepository<User, Long> {

    User findByUsername(String username);
}

5. The UserDetailsService

In order to provide our own user service, we will need to implement the UserDetailsService interface.

We’ll create a class called MyUserDetailsService that overrides the method loadUserByUsername() of the interface.

In this method, we retrieve the User object using the DAO, and if it exists, wrap it into a MyUserPrincipal object, which implements UserDetails, and returns it:

@Service
public class MyUserDetailsService implements UserDetailsService {

    @Autowired
    private UserRepository userRepository;

    @Override
    public UserDetails loadUserByUsername(String username) {
        User user = userRepository.findByUsername(username);
        if (user == null) {
            throw new UsernameNotFoundException(username);
        }
        return new MyUserPrincipal(user);
    }
}

The MyUserPrincipal class is defined as follows:

public class MyUserPrincipal implements UserDetails {
    private User user;

    public MyUserPrincipal(User user) {
        this.user = user;
    }
    //...
}

6. Spring Configuration

We will demonstrate both types of Spring configurations: XML and annotation-based, which are necessary in order to use our custom UserDetailsService implementation.

6.1. Annotation Configuration

Using Spring annotations, we will define the UserDetailsService bean, and set it as a property of the authenticationProvider bean, which we inject into the authenticationManager:

@Override
protected void configure(AuthenticationManagerBuilder auth)
  throws Exception {
    auth.userDetailsService(userDetailsService);
}

@Bean
public DaoAuthenticationProvider authenticationProvider() {
    DaoAuthenticationProvider authProvider
      = new DaoAuthenticationProvider();
    authProvider.setUserDetailsService(userDetailsService);
    authProvider.setPasswordEncoder(encoder());
    return authProvider;
}

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

6.2. XML Configuration

For the XML configuration, we need to define a bean with type MyUserDetailsService, and inject it into Spring’s authentication-provider bean:

<bean id="myUserDetailsService" 
  class="org.baeldung.security.MyUserDetailsService"/>

<security:authentication-manager>
    <security:authentication-provider 
      user-service-ref="myUserDetailsService" >
        <security:password-encoder ref="passwordEncoder">
        </security:password-encoder>
    </security:authentication-provider>
</security:authentication-manager>
    
<bean id="passwordEncoder" 
  class="org.springframework.security
  .crypto.bcrypt.BCryptPasswordEncoder">
    <constructor-arg value="11"/>
</bean>

7. Conclusion

In this article, we’ve shown how to create a custom Spring-based UserDetailsService backed by persistent data.

The implementation can be found in the GitHub project – this is a Maven based project, so it should be easy to import and run as it is.

The Master Class "Learn Spring Security" is out:

>> CHECK OUT THE COURSE


Viewing all articles
Browse latest Browse all 4536

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>