Reputation: 307
I am making a project in Spring MVC 4 with Hibernate and Spring Security. In this project I have 3 roles: ROLE_USER
, ROLE_COMPANY
and ROLE_ADMIN
.
User will register like regular registration site, but I am confused on how to save a new user in database through registration process, that how to save the new user and database defined by Spring Security and how to fetch that information using hibernate.
Thank you.
Upvotes: 1
Views: 2538
Reputation: 3176
You would have your User
class that implements UserDetails
which has either one or many authorities. For example:
User
@Entity
@Table(name = "User")
public class User implements UserDetails {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@NotNull
private String username;
@NotNull
private String password;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "user", fetch = FetchType.EAGER, orphanRemoval = true)
private Set<UserAuthority> authorities;
//helper method to set roles for this user
public void grantRole(UserRole role) {
if (authorities == null) {
authorities = new HashSet<UserAuthority>();
}
authorities.add(role.asAuthorityFor(this));
}
//overrides, getters, setters
}
UserAuthority
@Entity
@IdClass(UserAuthority.class)
public class UserAuthority implements GrantedAuthority {
@NotNull
@ManyToOne(fetch = FetchType.LAZY)
@JsonIgnore
@Id
private User user;
@NotNull
@Id
private String authority;
//overrides, getters, setters
}
UserRole
public enum UserRole {
USER, COMPANY, ADMIN;
}
While creating user just:
User user = new User();
user.grantRole(UserRole.USER);
repository.save(user);
As for authenticating you need to implement UserDetailsService
that loads the user from the repository
UserDetailsService implementation
@Service
public class UserDetailsService implements org.springframework.security.core.userdetails.UserDetailsService {
@Autowired
private UserRepository repository;
private final AccountStatusUserDetailsChecker detailsChecker = new AccountStatusUserDetailsChecker();
@Override
public final User loadUserByUsername(String username) throws UsernameNotFoundException {
final User user = repository.findByUsername(username);
if (user == null) {
throw new UsernameNotFoundException("User not found");
}
detailsChecker.check(user);
return user;
}
}
Now in your Security configuration you just use that UserDetailsService
@Autowired
private UserDetailsService userDetailsService;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(new BCryptPasswordEncoder());
}
@Override
protected UserDetailsService userDetailsService() {
return userDetailsService;
}
How you fetch the data is up to you, I would be using Spring Data JPA for that.
Upvotes: 6