![](/img/trans.png)
[英]How to create a list type View to fetch all the records from DB using spring boot?
[英]How to fetch user role from DB using LDAP login using Spring Boot
嗨,我是 Spring Boot 和 LDAP 的新手。 我面臨問題!
我可以通過 LDAP 登錄,但我無法獲取存儲在我的數據庫中的用戶角色。 我確實收到以下錯誤:
org.springframework.security.ldap.userdetails.LdapUserDetailsImpl cannot be cast to com.test.rnd.geo.web.dto.CustomUser
我試過這個:
private CustomUser getUserDetails() {
CustomUser userDetails = (CustomUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
LOGGER.info("Deatils: "+userDetails);
LOGGER.info("UserName: " + userDetails.getUsername());
LOGGER.info("Auth Token: " + userDetails.getAuthToken());
LOGGER.info("User Role size: " + userDetails.getAuthorities().size());
LOGGER.info("User Role : " + userDetails.getAuthorities());
return userDetails;
}
獲取此 getUserDetails() 函數時出現錯誤。
CustomUser customUser = getUserDetails();
這是我的 CustomUser 類:
@Component
@Scope("session")
public class CustomUser implements UserDetails {
private String username;
private String password;
private List<RoleEntity> authorities;
private String authToken;
public String getAuthToken() {
return authToken;
}
public void setAuthToken(String authToken) {
this.authToken = authToken;
}
public void setAuthorities(List<RoleEntity> authorities) {
this.authorities = authorities;
}
public String getUsername() {
return username;
}
@Override
public boolean isAccountNonExpired() {
return false;
}
@Override
public boolean isAccountNonLocked() {
return false;
}
@Override
public boolean isCredentialsNonExpired() {
return false;
}
@Override
public boolean isEnabled() {
return false;
}
public void setUsername(String username) {
this.username = username;
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return authorities;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String toString() {
return "CustomUser{" +
"username='" + username + '\'' +
", password='****" + '\'' +
", authorities=" + authorities +
", AuthToken='" + authToken + '\'' +
'}';
}
}
這是我的 WebSecurityConfig:
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth
.authenticationProvider(customAuthenticationProvider)
.ldapAuthentication()
.userSearchFilter("(&(mail={0})(memberOf=CN=aa,OU=Security Group,OU=aa,DC=aa,DC=com))")
.contextSource()
.url("ldap://www.domain.com:3268/dc=v,dc=com")
.managerDn("aaa")
.managerPassword("aaa");
}
存儲庫類:
@Repository
public class UserAuthRepository {
@Autowired
private InterServiceConnector serviceConnector;
@Autowired
private httpsServiceConnector httpsServiceConnector;
private static final org.slf4j.Logger LOG
= LoggerFactory.getLogger(CustomAuthenticationProvider.class);
@Value("${dmzAddress}")
private String host;
public CustomUser authenticateUser(String userName, String password) {
CustomUser customUser = null;
try {
customUser = null;
LOG.info("UserAuthRepository::authenticateUser:: userName" + userName);
// LOG.info("UserAuthRepository::authenticateUser:: password ********");
Request request = new Request();
request.setUsername(userName);
request.setPassword(password);
Gson gson = new GsonBuilder().create();
String jsonInput = gson.toJson(request);
// LOG.info("UserAuthRepository::authenticateUser:: Authentication Token :: " + request.getAuthToken());
String user = null;
if (host.contains("http://")){
user = serviceConnector.serviceCall(jsonInput, "portalLogin", "post", request.getAuthToken());
}
else{
user = httpsServiceConnector.serviceCall(jsonInput, "portalLogin", "post");
}
// String user = serviceConnector.serviceCall(jsonInput, "portalLogin", "post", request.getAuthToken());
// String user = httpsServiceConnector.serviceCall(jsonInput, "portalLogin", "post");
// LOG.info("UserAuthRepository::authenticateUser:: user---->>> " + user);
customUser = gson.fromJson(user, CustomUser.class);
LOG.info("UserAuthRepository:: Custom User:: {}", customUser);
} catch (JsonSyntaxException e) {
LOG.error("UserAuthRepository :: authenticateUser :: Parse Exception", e);
}
return customUser;
}
}
首先,您的 CustomUser 應該實現LdapUserDetails
而不是UserDetails
您還需要將LdapUserDetailsMapper
子類化,因為 Spring 將調用mapUserFromContext
,您可以在此處從數據庫中獲取所需的任何數據並創建 CustomUser 的實例。
@Component
public class CustomLdapUserDetailsMapper extends LdapUserDetailsMapper {
@Autowired
private IUserRepository userRepository;
@Autowired
private IUserRoleRepository userRoleRepository;
@Override
public UserDetails mapUserFromContext(DirContextOperations ctx, String username,
Collection<? extends GrantedAuthority> authorities) {
User user = userRepository.findOneByUsername(username);
if (user == null) {
throw new UsernameNotFoundException("Username not found");
}
UserDetails userDetails = super.mapUserFromContext(ctx, username, getAuthorities(user));
//add a constructor for your CustomUser
return new CustomUser(user.getEmail(), user.getFullName(), (LdapUserDetails) userDetails);
}
}
private Set<GrantedAuthority> getAuthorities(User user) {
Set<GrantedAuthority> authorities = new HashSet<>();
//populate authorities/user roles from User (db entity) and UserRole entities
for (UserRole userRole : userRoleRepository.findAllByUserId(user.getId())) {
authorities.add(new SimpleGrantedAuthority(userRole.getRole.getName()));
}
return authorities;
}
}
最后,告訴你的身份驗證提供者使用這個 ldap 映射器類(把它放在你的網絡安全代碼中)
@Autowired
private CustomLdapUserDetailsMapper customLdapUserDetailsMapper;
....
customAuthenticationProvider.setUserDetailsContextMapper(customLdapUserDetailsMapper);
更新:CustomUser 代碼可能看起來像這樣
public class CustomUser implements LdapUserDetails{
private String email;
private String fullName;
private String username;
private LdapUserDetails ldapUserDetails;
public CustomUser(String email, String fullName, LdapUserDetails ldapUserDetails) {
super();
this.email = email;
this.fullName = fullName;
this.ldapUserDetails = ldapUserDetails;
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return ldapUserDetails.getAuthorities();
}
@Override
public String getPassword() {
return ldapUserDetails.getPassword();
}
@Override
public String getUsername() {
return ldapUserDetails.getUsername();
}
//add all the other overrides and getter/setter methods
}
存儲庫類可能看起來像
public interface IUserRepository extends JpaRepository<User, Integer> {
public User findOneByUsername(String username);
public User findOneById(Integer id);
public User findOneByEmail(String email);
}
public interface IUserRoleRepository extends JpaRepository<UserRole, Integer> {
UserRole findOneByRoleName(String rolename);//role name like admin, user, mod etc
UserRole findOneById(Integer id);//role id
}
@dsp_user 提供了很好的解決方案。
現在根據您的上述代碼,我假設您正在使用您的存儲庫類中的一個函數,該函數將用戶名和密碼作為參數。
做類似的另一個函數,只接受用戶名作為參數。 在您的 CustomLdapUserDetailsMapper 類中調用該函數。
試試這個代碼:
@Component
public class CustomLdapUserDetailsMapper extends LdapUserDetailsMapper {
@Autowired
private UserRepository userRepository;
@Override
public UserDetails mapUserFromContext(DirContextOperations ctx, String username, Collection<? extends GrantedAuthority> authorities) {
CustomUser user = userRepository.authenticationMethod(username);
if (user == null) {
throw new UsernameNotFoundException("User is not found!");
}
return user;
}
}
我希望這能解決問題。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.