简体   繁体   English

如何使用 Spring Boot 使用 LDAP 登录从数据库中获取用户角色

[英]How to fetch user role from DB using LDAP login using Spring Boot

Hi I am novice to Spring Boot and LDAP.嗨,我是 Spring Boot 和 LDAP 的新手。 I am facing problems!我面临问题!

I could login via LDAP but I cant fetch user role which is stored in my Database.我可以通过 LDAP 登录,但我无法获取存储在我的数据库中的用户角色。 I do get the following error:我确实收到以下错误:

org.springframework.security.ldap.userdetails.LdapUserDetailsImpl cannot be cast to com.test.rnd.geo.web.dto.CustomUser

I had tried this:我试过这个:

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

I am getting error to fetch this getUserDetails() function.获取此 getUserDetails() 函数时出现错误。

        CustomUser customUser = getUserDetails();

Here is my CustomUser Class:这是我的 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 + '\'' +
                '}';
    }
}

Here's my WebSecurityConfig:这是我的 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 Class:存储库类:

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



}

First, your CustomUser should implement LdapUserDetails and not UserDetails首先,您的 CustomUser 应该实现LdapUserDetails而不是UserDetails

You also need to subclass LdapUserDetailsMapper because Spring will call mapUserFromContext and this is where you can fetch whatever data you need from your database and create an instance of CustomUser.您还需要将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;
}
}

And finally, tell your authentication provider to use this ldap mapper class (put this in your web security code)最后,告诉你的身份验证提供者使用这个 ldap 映射器类(把它放在你的网络安全代码中)

@Autowired
private CustomLdapUserDetailsMapper customLdapUserDetailsMapper;     
.... 

customAuthenticationProvider.setUserDetailsContextMapper(customLdapUserDetailsMapper);

UPDATE: The CustomUser code might look something like this更新: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

}

And the repository classes might look something like存储库类可能看起来像

   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 gave great solutions. @dsp_user 提供了很好的解决方案。

Now Based on your above codes I assume that your are using a function in your Repository Class that takes username and password as the params.现在根据您的上述代码,我假设您正在使用您的存储库类中的一个函数,该函数将用户名和密码作为参数。

Do make similar another function that takes only username as param.做类似的另一个函数,只接受用户名作为参数。 Call that function in your CustomLdapUserDetailsMapper Class.在您的 CustomLdapUserDetailsMapper 类中调用该函数。

Try this code:试试这个代码:

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

}

I hope this would solve the problem.我希望这能解决问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何创建列表类型视图以使用 spring boot 从数据库中获取所有记录? - How to create a list type View to fetch all the records from DB using spring boot? 如何使用spring security(spring boot)实现Ldap身份验证 - how to achieve Ldap Authentication using spring security(spring boot) 如何在 Spring 启动时使用 Date 从数据库中获取数据? - How to fetch data from database by using Date in Spring boot? 如何使用 Spring Boot 的 JPA 存储库中的映射从 spring 引导中的多个表中获取数据 - How to fetch data from multiple tables in spring boot using mapping in Spring Boot's JPA repository 如何使用REST和Spring安全性通过ldap使用Angular登录 - How to Login with Angular by ldap with using Rest and Spring security 使用Spring Boot和LDAP的REST API中的权限 - Permisions in REST API using Spring Boot and LDAP 在 Spring Boot 中使用 ldap 时凭据错误 - Bad credentials when using ldap in spring boot 使用 LDAP 身份验证的 Spring Boot REST API - Spring Boot REST API using LDAP authentication 如何在 spring 引导中验证具有特定角色的用户? - How to authenticate user with specific role in spring boot? 为什么新用户使用Spring Boot注册后无法登录? - Why the new user cannot login after registration using Spring Boot?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM