Java Spring Security/Spring Boot - 如何为用户设置角色

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/37615034/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 19:29:26  来源:igfitidea点击:

Spring Security/Spring Boot - How to set ROLES for users

javaspringspring-mvcspring-securityspring-boot

提问by Lester

When I logged in using security, I cannot use the request.isUserInRole()method. I think the roles of the users was not set.

当我使用安全登录时,我无法使用该request.isUserInRole()方法。我认为用户的角色没有设置。

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 Userentity:

这是我的User实体:

 @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:

这是我的枚举Role

public enum Role {

Fleet_Company, Service_Center, Admin

}

This is my UserDetailsServiceImplementation:

这是我的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:

这是实现的类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'.

所以基本上,我们可以看到我的 MySQL 数据库上只有一张表,它有四列,其中之一是“角色”。

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.

但是就像我说的那样,当我使用 时request.isUserInRole("Service_Center"),它返回 FALSE。而且.antMatchers("/first").hasAuthority("Service_Center")也不起作用。

采纳答案by DiveInto

You should fill in the content of role by yourself when creating your UserDetails:

在创建 UserDetails 时,您应该自己填写角色的内容:

public class SecurityUser implements UserDetails{
    String ROLE_PREFIX = "ROLE_";

    String userName;
    String password;
    String role;

    public SecurityUser(String username, String password, String role){
        this.userName = username;
        this.password = password;
        this.role = role;
    }

    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        List<GrantedAuthority> list = new ArrayList<GrantedAuthority>();

        list.add(new SimpleGrantedAuthority(ROLE_PREFIX + role));

        return list;
    }

Basically, what you need to do is override method: getAuthorities, and fill in the content of your role field into the GrantedAuthoritylist.

基本上,您需要做的是 override method: getAuthorities,并将您的角色字段的内容填写到GrantedAuthority列表中。

回答by Ajay Kumar

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:

Divelnto、zapl 和 thorinkor 说的是对的。但问题应该是关于“角色”而不是“角色”。或者,如果您将用户和角色放在一个表中,这是一个糟糕的设计。您可能想重新审视您的设计方法。您应该有一个单独的角色实体。在您的 UserService 中,您可以执行以下操作:

AppUser user = userRepository.findByUsername(username);

Set<GrantedAuthority> grantedAuthorities = new HashSet<>(); // use list if you wish
for (AppRole role : user.getRoles()) {
    grantedAuthorities.add(new SimpleGrantedAuthority(role.getName()));
}
return new org.springframework.security.core.userdetails.User(
        user.getUsername(),
        user.getPassword(),
        grantedAuthorities
);

Samples: sample1sample2sample3

样品: SAMPLE1 SAMPLE2样品3

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.

在数据库中,您可以将角色名称存储为 - (例如)数据库中的 ADMIN/EDITOR/VIEWER 或将角色存储为 ROLE_ADMIN/ROLE_... 那么您可能想要使用 hasRole/hasAuthoriy。希望能帮助到你。

For reference, take a look at here:

作为参考,请看这里:

Spring Security Related 1

Spring 安全相关 1

Spring Security Related 2

Spring 安全相关 2

回答by Siddhey Sankhe

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

要添加角色,您需要有一个包含用户名及其相应角色的表。
假设一个用户有两个角色,即 ADMIN 和 USER

One User can have multiple roles.

一个用户可以有多个角色。

@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
    final List<SimpleGrantedAuthority> authorities = new LinkedList<>();
    if (enabled) {
        if (this.getUser().isAdmin()) {
            authorities.add(new SimpleGrantedAuthority("ROLE_ADMIN"));
        }
        authorities.add(new SimpleGrantedAuthority("ROLE_USER"));
    }
        return authorities;
}

This can be called as,

这可以称为,

private UsernamePasswordAuthenticationToken getAuthentication(
final String token, final HttpServletRequest req,
final HttpServletResponse res){
    return new UsernamePasswordAuthenticationToken(userAccount, null,
    userAccount.getAuthorities());
}