Difference UserDetailsService and UserDetail
In Spring Security, `UserDetailsService` and `UserDetails` are two key interfaces used for user authentication. They serve different but complementary roles in the security authentication process.
`UserDetailsService`
- Â This interface is responsible for retrieving user-related data. It has a single method, `loadUserByUsername(String username)`, which is used to fetch the user’s details from a data source (like a database) based on the provided username.
- Â Implementing this interface allows you to define how the user is retrieved, whether from a database, in-memory storage, or another source.
Table of Contents
`UserDetails`
- This interface represents the core user information. Implementations are used to store user credentials and account status. It provides methods to get the username, password, and authorities granted to the user.
- Implementing this interface allows you to encapsulate the user’s details and provide Spring Security with the necessary data for authentication and authorization.
Example Implementation:
1. `UserDetails` Implementation:
```java
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import java.util.Collection;
public class MyUserDetails implements UserDetails {
private String username;
private String password;
private boolean enabled;
private Collection<? extends GrantedAuthority> authorities;
public MyUserDetails(String username, String password, boolean enabled, Collection<? extends GrantedAuthority> authorities) {
this.username = username;
this.password = password;
this.enabled = enabled;
this.authorities = authorities;
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return authorities;
}
@Override
public String getPassword() {
return password;
}
@Override
public String getUsername() {
return username;
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return enabled;
}
}
Example
2. `UserDetails-Service` Implementation:
```java
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
@Service
public class MyUserDetailsService implements UserDetailsService {
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
// Normally, here you would fetch user details from a database or another source
if ("user".equals(username)) {
return new MyUserDetails("user", "{noop}password", true, List.of(() -> "ROLE_USER"));
} else {
throw new UsernameNotFoundException("User not found");
}
}
}
```
Key Points:
UserDetailsService
: Responsible for fetching user details based on the username.UserDetails
: Encapsulates the user’s core information, such as username, password, and roles.
Conclusion
The UserDetails-Service
interface is a service layer that handles the retrieval of user details, while UserDetails
represents the user’s information. They work together in Spring Security to authenticate users and determine their roles and permissions.