我撰寫了 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;
}
}
uj5u.com熱心網友回復:
萬一,您還沒有將您的 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);}
}
uj5u.com熱心網友回復:
如果你想分配一個角色,那么你可以在你的資料庫角色中有一個列,你可以在提交資料時給出,你也可以在控制器中有一個方法來更新它
**物體 **
@Entity
@Table(name="users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String name;
private String roles;
//getter and setters
uj5u.com熱心網友回復:
也許我應該更具體地說明我的問題。但。我為自己找到了解決這個問題的方法。也許我的方法會對某人有所幫助。
我的 CustomUserDetailsS??ervice:
@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:/";
}
因此,我設法為用戶實作了角色的動態變化。如果您對如何改進我的方法有任何建議,我很想聽聽。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/515525.html
標籤:爪哇春天安全主要的
