Spring защита получить объект пользователя
Я реализовал аутентификацию пользователя через Spring Security Framework, и все работает нормально. Я могу войти в систему и выйти из системы, я могу получить имя зарегистрированного пользователя, например:
String userName = ((UserDetails) auth.getPrincipal()).getUsername();
Теперь я хочу получить пользователя как объект из базы данных (мне нужен идентификатор пользователя и другие пользовательские свойства).
Как я уже пробовал:
User user = (User)SecurityContextHolder.getContext().getAuthentication().getPrincipal();
После этого я получил следующее исключение:
Request processing failed; nested exception is java.lang.ClassCastException: org.springframework.security.core.userdetails.User cannot be cast to net.viralpatel.contact.model.User
Вот вопрос: как я могу получить User как объект, как мне изменить мои классы UserDetailsServiceImpl и UserAssembler, любые идеи?
@Component
@Transactional
public class UserDetailsServiceImpl implements UserDetailsService{
@Autowired
private UserDAO userDAO;
@Autowired
private UserAssembler userAssembler;
private static final Logger logger = LoggerFactory.getLogger(UserDetailsServiceImpl.class);
@Transactional(readOnly = true)
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException {
User user = userDAO.findByEmail(username);
if(null == user) throw new UsernameNotFoundException("User not found");
return userAssembler.buildUserFromUser(user);
}
}
И еще один:
@Service("assembler")
public class UserAssembler {
@Autowired
private UserDAO userDAO;
@Transactional(readOnly = true)
public User buildUserFromUser(net.viralpatel.contact.model.User user) {
String role = "ROLE_USER";//userEntityDAO.getRoleFromUserEntity(userEntity);
Collection<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
authorities.add(new GrantedAuthorityImpl(role));
return new User(user.getLogin(), user.getPassword(), true, true, true, true, authorities);
}
}
Ответы
Ответ 1
По существу, вам нужно вернуть реализацию UserDetails
, которая обеспечивает доступ к вашему User
.
У вас есть два варианта:
-
Добавьте свой User
в качестве поля (вы можете расширить его org.springframework.security.core.userdetails.User
):
public class UserPrincipal extends org.springframework.security.core.userdetails.User {
private final User user;
...
}
и получим a User
из этого поля:
Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
User user = ((UserPrincipal) principal).getUser();
-
Создайте класс, который расширяет ваш User
и реализует UserDetails
:
public class UserPrincipal extends User implements UserDetails {
...
public UserPrincipal(User user) {
// copy fields from user
}
}
Этот подход позволяет напрямую передать принципалу в User
:
User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
Ответ 2
Похоже, ваш класс User не расширяет Spring org.springframework.security.core.userdetails.User класс.
Вот пример кода для ссылки, я назвал класс с именем "AuthenticUser":
public class AuthenticUser extends User {
public AuthenticUser(String username, String password, boolean enabled,
boolean accountNonExpired, boolean credentialsNonExpired,
boolean accountNonLocked,
Collection<? extends GrantedAuthority> authorities) {
super(username, password, enabled, accountNonExpired, credentialsNonExpired,
accountNonLocked, authorities);
}
.....
.....
}
Теперь вы можете создать объект этого класса в своем коде и установить его как часть Spring Контекст аутентификации, например
AuthenticUser user = new AuthenticUser(username, password, .... rest of the parameters);
Authentication authentication = new UsernamePasswordAuthenticationToken(user, null,
user.getAuthorities());
SecurityContextHolder.getContext().setAuthentication(authentication);
Это приведет к аутентификации вашего пользователя и настройке пользователя в контексте безопасности.
Ответ 3
Вам необходимо реализовать свой собственный UserDetailsService и свой собственный объект UserDetails (согласно вашему желанию):
public class CustomService implements UserDetailsService {
@Transactional(readOnly = true)
public UserDetails loadUserByUsername(String userId) {
Account account = accountDAO.findAccountByName(userId);
// validation of the account
if (account == null) {
throw new UsernameNotFoundException("not found");
}
return buildUserFromAccount(account);
}
@SuppressWarnings("unchecked")
@Transactional(readOnly = true)
private User buildUserFromAccount(Account account) {
// take whatever info you need
String username = account.getUsername();
String password = account.getPassword();
boolean enabled = account.getEnabled();
boolean accountNonExpired = account.getAccountNonExpired();
boolean credentialsNonExpired = account.getCredentialsNonExpired();
boolean accountNonLocked = account.getAccountNonLocked();
// additional information goes here
String companyName = companyDAO.getCompanyName(account);
Collection<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
for (Role role : account.getRoles()) {
authorities.add(new SimpleGrantedAuthority(role.getName()));
}
CustomUserDetails user = new CustomUserDetails (username, password, enabled, accountNonExpired, credentialsNonExpired, accountNonLocked,
authorities, company);
return user;
}
public class CustomUserDetails extends User{
// ...
public CustomUserDetails(..., String company){
super(...);
this.company = company;
}
private String company;
public String getCompany() { return company;}
public void setCompany(String company) { this.company = company;}
}
Примечание:
Это стандартная реализация класса User, в которой у вас есть какая-то пользовательская информация, которую вы можете создать пользовательский класс и расширить класс User