UserDetail
Integrating Spring Security with Spring Framework is very easy, because we already have Spring Beans configuration file in previous chapter. All we need is to create spring security authentication related changes to get it working. Now we will look into how we can implement authentication in Spring application using in-memory, UserDetailsService DAO implementation and JDBC based authentication.
UserDetailDao.java
package dao;
import org.springframework.security.core.userdetails.UserDetailsService;
public interface UserDetailDao extends UserDetailsService {
}
UserDetailsService interface is used in order to lookup the username, password and GrantedAuthorities for any given user. This interface provide only one method which implementing class need to implement.
UserDetailServiceImpl.java
package service.impl;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import dao.UserSharedDao;
import entity.UserShared;
import security.UserDetail;
public class UserDetailServiceImpl implements UserDetailsService {
private UserSharedDao userDao;
public UserDetailServiceImpl(UserSharedDao userDao) {
this.userDao = userDao;
}
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
UserShared user = userDao.findByUsername(username);
if (null == user) {
throw new UsernameNotFoundException("The employee with username " + username + " was not found");
}
return new UserDetail(user);
}
}
Here UserDetails is container for core user information. According to docs, its implementations are not used directly by Spring Security for security purposes. They simply store user information which is later encapsulated into Authentication objects. This allows non-security related user information (such as username, password etc) to be stored in a convenient location. A very good sample implementation can be like UserShared class.
UserDetails.java
package security;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import javax.xml.bind.annotation.XmlTransient;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import entity.UserRole;
import entity.UserShared;
public class UserDetail implements UserDetails {
private static final long serialVersionUID = 1L;
private Long id;
private String username;
private String password;
private Set<GrantedAuthority> authorities = new HashSet<GrantedAuthority>(0);
public UserDetail() {
}
public UserDetail(UserShared user) {
username = user.getUsername();
password = user.getPassword();
id = user.getId();
Set<UserRole> roles = user.getUser().getUserRole();
for (UserRole userRole : roles) {
authorities.add(new SimpleGrantedAuthority(userRole.getRole()
.getValue().name()));
}
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return authorities;
}
@Override
@XmlTransient
public String getPassword() {
return password;
}
@Override
@XmlTransient
public String getUsername() {
return username;
}
@Override
@XmlTransient
public boolean isAccountNonExpired() {
return true;
}
@Override
@XmlTransient
public boolean isAccountNonLocked() {
return true;
}
@Override
@XmlTransient
public boolean isCredentialsNonExpired() {
return true;
}
@Override
@XmlTransient
public boolean isEnabled() {
return true;
}
public Long getId() {
return id;
}
@Override
public String toString() {
return "UserDetail [id=" + id + ", username=" + username
+ ", password=" + password + ", authorities=" + authorities
+ "]";
}
}