spring 如何在CustomUserDetails中更改用户的角色?

sqxo8psd  于 2022-10-30  发布在  Spring
关注(0)|答案(3)|浏览(160)

我编写了UserDetails的实现,以便更改登录和用户角色。使用登录,一切都变得非常简单,但是我在角色方面遇到了问题。我不明白我需要做什么来将默认的CUSTOMER角色更改为另一个SELLER角色

@ToString
public class CustomUserDetails implements UserDetails {
    @ToString.Exclude
    private Account account;

    private final long serialVersionUID = 1L;

    public CustomUserDetails(Account account) {
        this.account = account;
    }

    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        List<GrantedAuthority> authorities = new ArrayList<>();
        authorities.add(new SimpleGrantedAuthority("ROLE_" + this.account.getRole().getAuthority()));

        return authorities;
    }

    public void setRole(Role role) {
        this.account.setRole(role);
    }

    @Override
    public String getPassword() {
        return this.account.getPassword();
    }

    @Override
    public String getUsername() {
        return this.account.getLogin();
    }

    public void setUsername(String username) {
        this.account.setLogin(username);
    }

    @Override
    public boolean isAccountNonExpired() {
        return true;
    }

    @Override
    public boolean isAccountNonLocked() {
        return true;
    }

    @Override
    public boolean isCredentialsNonExpired() {
        return true;
    }

    @Override
    public boolean isEnabled() {
        return true;
    }
}
y1aodyip

y1aodyip1#

如果您还没有将CustomUserDetails实体存储到数据库中的服务:
你的CustomUserDetails.class必须有注解@Entity,因为它应该被存储为关系数据库中的表。因此,它必须有一个用@Id注解的id字段。下一步:

public interface CustomUserRepo extends 
CrudRepository<CustomUserDetails, ID_TYPE> {

CustomUserDetails loadUserByArgThatYouWant (String ARG_THAT_YOU_WANT);

@Transactional
@Modifying
@Query("update CustomUserDetails c set c.role = ?1 where c.id = ?2")
void updatRoleById(String role, ID_TYPE);
}

public class UserService implements UserDetailsService {
@Autowired
private final CustomUserRepo repo;
@Override
CustomUserDetails loadUserByUsername (String arg) {
return repo.loadUserByArgThatYouWant(arg);
}
// down below method that you need

public void updateRoleById (String role, ID_TYPE id){
repo.updateRoleById(role,id);}

}
7fyelxc5

7fyelxc52#

如果你想分配一个角色,那么你可以在你的数据库中有一个列角色,你可以在提交你的数据的时候给予它,你也可以在你的控制器中有一个方法来更新它

实体

@Entity
@Table(name="users")
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;
    private String name;
    private String roles;

    //getter and setters
wribegjk

wribegjk3#

也许我应该把我的问题说得更具体一些。但是。我自己找到了解决这个问题的方法。也许我的方法会帮助到别人。
我的自定义用户详细信息服务:

@Service("userDetailsService")
public class CustomUserDetailsService implements UserDetailsService {

    @Autowired
    private AccountRepository accountRepository;

    @Override
    public UserDetails loadUserByUsername(String login) throws UsernameNotFoundException {
        Account account = accountRepository.findByLogin(login);
        if (account == null) {
            throw new UsernameNotFoundException(login);
        }

        return new CustomUserDetails(account, mapRolesToAuthority(account.getRole()));
    }

    private Collection<? extends GrantedAuthority> mapRolesToAuthority(Role role) {
        List<GrantedAuthority> authorities = new ArrayList<>();
        authorities.add(new SimpleGrantedAuthority("ROLE_" + role.getAuthority()));
        authorities.add(new SimpleGrantedAuthority(role.getAuthority()));

        return authorities;
    }
}

我的自定义用户详细信息:

@ToString
public class CustomUserDetails implements UserDetails {
    @ToString.Exclude
    private Account account;
    private Collection<? extends GrantedAuthority> authorities;

    private final long serialVersionUID = 1L;

    public CustomUserDetails(Account account, Collection<? extends GrantedAuthority> authorities) {
        this.account = account;
        this.authorities = authorities;
    }

    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        return authorities;
    }

    public void setAuthorities(Collection<? extends GrantedAuthority> authorities) {
        this.authorities = authorities;
    }

    @Override
    public String getPassword() {
        return this.account.getPassword();
    }

    @Override
    public String getUsername() {
        return this.account.getLogin();
    }

    public void setUsername(String username) {
        this.account.setLogin(username);
    }

    @Override
    public boolean isAccountNonExpired() {
        return true;
    }

    @Override
    public boolean isAccountNonLocked() {
        return true;
    }

    @Override
    public boolean isCredentialsNonExpired() {
        return true;
    }

    @Override
    public boolean isEnabled() {
        return true;
    }
}

控制器中更改用户会话中的数据的方法(需要重构):

@PostMapping("/trade")
    public String updateAccountRole(Principal principal) {
        Account account = accountRepository.findByLogin(principal.getName());
        account.setRole(Role.SELLER);

        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        CustomUserDetails userDetails = (CustomUserDetails) authentication.getPrincipal();
        List<GrantedAuthority> authorities = new ArrayList<>();
        authorities.add(new SimpleGrantedAuthority("ROLE_" + account.getRole().getAuthority()));
        authorities.add(new SimpleGrantedAuthority(account.getRole().getAuthority()));
        userDetails.setAuthorities(authorities);

        System.out.println("BEFORE -> " + SecurityContextHolder.getContext().getAuthentication());
        UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(
                SecurityContextHolder.getContext().getAuthentication().getPrincipal(),
                SecurityContextHolder.getContext().getAuthentication().getCredentials(),
                userDetails.getAuthorities()
        );
        token.setDetails(SecurityContextHolder.getContext().getAuthentication().getDetails());
        SecurityContextHolder.getContext().setAuthentication(token);
        System.out.println("AFTER -> " + SecurityContextHolder.getContext().getAuthentication());

        accountRepository.save(account);

        return "redirect:/";
    }

因此,我成功地实现了用户角色的动态变化。如果你对我的方法有什么改进的建议,我很乐意听听。

相关问题