Spring Security Custom User Detail Service: Difference between revisions

From NovaOrdis Knowledge Base
Jump to navigation Jump to search
 
(11 intermediate revisions by the same user not shown)
Line 9: Line 9:
Combining application authentication and authorization with domain model user information largely consists in the following steps:
Combining application authentication and authorization with domain model user information largely consists in the following steps:
* Declare a User entity that should implement the Spring [https://docs.spring.io/spring-security/site/docs/current/api/org/springframework/security/core/userdetails/UserDetails.html UserDetails] interface. Implementation of UserDetails provides essential user information to the framework, in a standard fashion (whether the account is enabled or not, [[Spring_Security_Concepts#Authority|authorities]], etc.). Implementing UserInterface on a generic user domain model entity is the programmatic way of modifying the generic user entity to make it useful for authentication.
* Declare a User entity that should implement the Spring [https://docs.spring.io/spring-security/site/docs/current/api/org/springframework/security/core/userdetails/UserDetails.html UserDetails] interface. Implementation of UserDetails provides essential user information to the framework, in a standard fashion (whether the account is enabled or not, [[Spring_Security_Concepts#Authority|authorities]], etc.). Implementing UserInterface on a generic user domain model entity is the programmatic way of modifying the generic user entity to make it useful for authentication.
* Declare the corresponding repository interface:
<syntaxhighlight lang='java'>
public interface UserRepository extends CrudRepository<User, Long> {
    User findByUsername(String username);
}
</syntaxhighlight>
* Implement a Spring [[@Service]] that implements [https://docs.spring.io/spring-security/site/docs/current/api/org/springframework/security/core/userdetails/UserDetailsService.html UserDetailsService]:
<syntaxhighlight lang='java'>
@Service
public class UserRepositoryUserDetailsService implements UserDetailsService {
  private UserRepository userRepository;
  @Autowired
  public UserRepositoryUserDetailsService(UserRepository userRepository) {
    this.userRepository = userRepository;
  }
  @Override
  public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
    User user = userRepository.findByUsername(username);
    if (user == null) {
      throw new UsernameNotFoundException("\"" + username + "\" not found");
    }
    return user;
  }
}
</syntaxhighlight>
* Make Spring Security aware of the custom user details service:
<syntaxhighlight lang='java'>
@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
  @Autowired
  private UserDetailsService userDetailsService;
  @Override
  protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth.userDetailsService(userDetailsService);
  }
}
</syntaxhighlight>
* Configure a password encoder and configure the UserDetailsService with it, using the passwordEncoder() builder method. For more details about password encoders see [[Spring_Security_Concepts#User_Stores_and_Password_Encoder|User Stores and Password Encoder]].
* Provide a way to register users via a dedicated controller or similar.


=Playground Example=
=Playground Example=


{{External|[https://github.com/ovidiuf/playground/tree/master/spring/spring-in-action/cap4-security-user-detail-service Playground - Spring Security - User Detail Service]}}
{{External|[https://github.com/ovidiuf/playground/tree/master/spring/spring-in-action/cap4-security-user-detail-service Playground - Spring Security - User Detail Service]}}

Latest revision as of 21:08, 10 November 2018

Internal

Overview

This approach is useful for the situation in which the user information should be part of the application's domain model.

Combining application authentication and authorization with domain model user information largely consists in the following steps:

  • Declare a User entity that should implement the Spring UserDetails interface. Implementation of UserDetails provides essential user information to the framework, in a standard fashion (whether the account is enabled or not, authorities, etc.). Implementing UserInterface on a generic user domain model entity is the programmatic way of modifying the generic user entity to make it useful for authentication.
  • Declare the corresponding repository interface:
public interface UserRepository extends CrudRepository<User, Long> {
    User findByUsername(String username);
}
@Service
public class UserRepositoryUserDetailsService implements UserDetailsService {

  private UserRepository userRepository;

  @Autowired
  public UserRepositoryUserDetailsService(UserRepository userRepository) {
    this.userRepository = userRepository;
  }

  @Override
  public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
    User user = userRepository.findByUsername(username);
    if (user == null) {
      throw new UsernameNotFoundException("\"" + username + "\" not found");
    }
    return user;
  }
}
  • Make Spring Security aware of the custom user details service:
@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

  @Autowired
  private UserDetailsService userDetailsService;

  @Override
  protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth.userDetailsService(userDetailsService);
  }
}
  • Configure a password encoder and configure the UserDetailsService with it, using the passwordEncoder() builder method. For more details about password encoders see User Stores and Password Encoder.
  • Provide a way to register users via a dedicated controller or similar.

Playground Example

Playground - Spring Security - User Detail Service