When I logged in using security, I cannot use the request.isUserInRole()
method. I think the roles of the users was not set.
This is my Security Configuration:
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled=true)
@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private DataSource dataSource;
@Autowired
private UserDetailsServiceImplementation userDetailsService;
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/signup").permitAll()
.antMatchers("/").permitAll()
//.antMatchers("/first").hasAuthority("Service_Center")
.antMatchers("/login").permitAll()
.anyRequest().fullyAuthenticated()
.and().formLogin()
.loginPage("/login")
.usernameParameter("email")
.passwordParameter("password")
.defaultSuccessUrl("/default")
.failureUrl("/login?error").permitAll()
.and().logout()
.logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
.logoutSuccessUrl("/login?logout")
.deleteCookies("JSESSIONID")
.invalidateHttpSession(true).permitAll();
}
@Autowired
public void configAuthentication(AuthenticationManagerBuilder auth)
throws Exception {
auth.userDetailsService(userDetailsService);
}
}
This is my User
entity:
@Entity
@Table(name="user")
public class User implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name="user_id")
private Long userID;
@Column(name="email_address", nullable = false, unique = true)
private String emailAddress;
@Column(name="password")
private String password;
@Column(name = "role", nullable = false)
@Enumerated(EnumType.STRING)
private Role role;
public User() {
super();
}
public User(String emailAddress, String password) {
this.emailAddress = emailAddress;
this.password = password;
}
public Long getUserID() {
return userID;
}
public void setUserID(Long userID) {
this.userID = userID;
}
public String getEmailAddress() {
return emailAddress;
}
public void setEmailAddress(String emailAddress) {
this.emailAddress = emailAddress;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Role getRole() {
return role;
}
public void setRole(Role role) {
this.role = role;
}
@Override
public String toString() {
return "User [userID=" + userID + ", emailAddress=" + emailAddress
+ ", password=" + password + ", role=" + role + "]";
}
public UserDetails toCurrentUserDetails() {
return CurrentUserDetails.create(this);
}
}
This is my enum Role
:
public enum Role {
Fleet_Company, Service_Center, Admin
}
This is my UserDetailsServiceImplementation
:
@Component
public class UserDetailsServiceImplementation implements UserDetailsService {
@Autowired
private UserRepository userRepository;
@Override
public UserDetails loadUserByUsername(String username)
throws UsernameNotFoundException {
if ( username == null || username.isEmpty() ){
throw new UsernameNotFoundException("username is empty");
}
User foundUser = userRepository.findByEmailAddress(username);
if( foundUser != null ){
System.out.println("FOUND");
return foundUser.toCurrentUserDetails();
}
throw new UsernameNotFoundException( username + "is not found");
}
}
This is the class that implements UserDetails
:
public class CurrentUserDetails implements UserDetails {
private Long userID;
private String emailAddress;
private String password;
private Role role;
public CurrentUserDetails(Long userID, String emailAddress, String password, Role role) {
super();
this.userID = userID;
this.emailAddress = emailAddress;
this.password = password;
this.role = role;
}
/* public static UserDetails create(Users entity) {
List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
for(Authorities auth: entity.getAuthorities()){
authorities.add(new SimpleGrantedAuthority(auth.getId().getAuthority()));
}
return new MyUserDetail(entity.getUserId(), entity.getLoginId(), entity.getPassword(), entity.getDisplayName(), authorities);
}*/
public Long getUserID(){
return this.userID;
}
public Role getRole(){
return this.role;
}
@Override
public String getPassword() {
return this.password;
}
public String getEmailAddress() {
return this.emailAddress;
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return true;
}
public static UserDetails create(User entity) {
System.out.println(entity.getUserID()+ entity.getEmailAddress()+ entity.getPassword()+ entity.getRole());
return new CurrentUserDetails(entity.getUserID(), entity.getEmailAddress(), entity.getPassword(), entity.getRole());
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
// TODO Auto-generated method stub
return null;
}
@Override
public String getUsername() {
// TODO Auto-generated method stub
return null;
}
}
So basically, we can see that I only have one table on my MySQL database, it has four columns and one of them is 'role'.
But like what I said, when I use request.isUserInRole("Service_Center")
, it returns FALSE. And .antMatchers("/first").hasAuthority("Service_Center")
doesn't work either.
You should fill in the content of role by yourself when creating your UserDetails:
Basically, what you need to do is override method:
getAuthorities
, and fill in the content of your role field into theGrantedAuthority
list.For adding Roles you need to have a table containing username and its corresponding role.
Suppose a user has two roles namely, ADMIN and USER
One User can have multiple roles.
This can be called as,
What Divelnto, zapl and thorinkor said is right. But the question should be about "Role" and NOT "Roles". OR, if you are having users and roles into one table, its a bad design. You might want to take a relook at your design approach. You should have a separate role entity. And in your UserService you can do something like:
Samples: sample1 sample2 sample3
In DB, you can store role name as - (e.g.) ADMIN/EDITOR/VIEWER in the database or store roles as ROLE_ADMIN/ROLE_... then you might wanna use hasRole/hasAuthoriy. Hope it helps.
For reference, take a look at here:
Spring Security Related 1
Spring Security Related 2