#java #spring #security
#java #spring #Безопасность
Вопрос:
Я использую SpringSecurity в своем веб-проекте. У меня есть объект User, который сохранен в БД. Мне нужно выполнять запросы в BD с идентификатором пользователя, чтобы получить любую информацию из других таблиц в этом BD. Как я могу получить своего пользователя из SecurityContextHolder вместо стандартного пользователя Spring (у этого пользователя нет идентификатора) после аутентификации в Spring Security?
@Entity
@Table(name = "users")
public class User{
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private int id;
@Column(name = "name")
private String name;
@Column(name = "login")
private String login;
@Column(name = "password")
private String password;
getters and setters
PS. Извините за мой английский 🙂
Ответ №1:
Вы должны реализовать интерфейс UserDetailsService и интерфейс UserDetails в другом классе. Например:
CustomUserDetailsService:
@Service("customUserDetailsService")
public class CustomUserDetailsService implements UserDetailsService {
// your UserRepository for your user
private final UserRepository userRepository;
@Autowired
public CustomUserDetailsService(UserRepository userRepository) {
this.userRepository = userRepository;
}
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userRepository.findByUsername(username);
if (null == user || ! user.getUsername().equals(username)) {
throw new UsernameNotFoundException("No user present with username: " username);
} else {
return new CustomUserDetails(user);
}
}
}
Пользовательские пользовательские данные:
// You want to extend your User class here
public class CustomUserDetails extends User implements UserDetails {
private static final long serialVersionUID = 1L;
private Users user;
public CustomUserDetails(User user) {
super(user);
this.user = user;
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
// You don't talk about UserRoles, so return ADMIN for everybody or implement roles.
return AuthorityUtils.commaSeparatedStringToAuthorityList("ROLE_ADMIN");
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
// just for example
return this.user.getActive() == true;
}
@Override
public String getUsername() {
return this.user.getUsername();
}
@Override
public String getPassword() {
return this.user.getPassword();
}
// Just an example to put some addititional Data to your logged in user
public String getUserDatabase() {
return "usertable" Integer.toString(1 this.user.getUserId());
}
}
В вашем User
классе создайте пустой конструктор для гибернации и тот, который принимает экземпляр пользователя:
@Entity
@Table(name = "users")
public class User{
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private int id;
@Column(name = "name")
private String name;
@Column(name = "login")
private String login;
@Column(name = "password")
private String password;
public User() {}
public User(User user) {
this.id = user.getId();
this.name = user.getName();
// … the same for all properties.
}
}
В вашем WebSecurityConfig @Autowire
CustomUserDetailsService
и введите его в поток аутентификации:
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
private final
UserDetailsService service;
@Autowired
public WebSecurityConfig(UserDetailsService service) {
this.service = service;
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(service).passwordEncoder(passwordEncoder());
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
//left out because not related here
}
}
И это все. Теперь вы можете передать аутентифицированного участника своим пользовательским пользовательским данным в каждом контроллере или у поставщика с:
CustomUserDetails userDetails =
(CustomUserDetails) SecurityContextHolder
.getContext()
.getAuthentication()
.getPrincipal();
Комментарии:
1. Что такое «private final UserRepository UserRepository»?
2. Это ваш пользовательский репозиторий, интерфейс, с помощью которого вы получаете запрос к своей базе данных
3. Пожалуйста, посмотрите на мои классы.