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



我编写了UserDetails的实现,以便更改登录和用户角色。登录后,一切都变得很简单,但我在角色方面遇到了问题。我不明白我需要做什么才能将默认的客户角色更改为另一个卖方角色

@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;
}
}

如果您还没有将CustomUserDetails实体存储到DB:中的服务

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);}
}

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

**实体**

@Entity
@Table(name="users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String name;
private String roles;
//getter and setters

也许我应该更具体地回答我的问题。但是我自己找到了解决这个问题的办法。也许我的方法能帮助到别人。

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

@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:/";
}

因此,我设法实现了用户角色的动态更改。如果你对如何改进我的方法有任何建议,我很乐意听到。

相关内容

  • 没有找到相关文章

最新更新