简体   繁体   English

Spring Boot LDAP 认证和匹配数据库用户

[英]Spring Boot LDAP authentication and matching with database users

I have a Spring Boot MVC application which uses LDAP for authentication.我有一个使用 LDAP 进行身份验证的 Spring Boot MVC 应用程序。 This works fine, but now I have to match authenticated user (from LDAP repository) with users from my database.这工作正常,但现在我必须将经过身份验证的用户(来自 LDAP 存储库)与我的数据库中的用户匹配。 I created LDAPUser:我创建了 LDAPUser:

import java.util.jar.Attributes.Name;

import org.springframework.ldap.odm.annotations.Attribute;
import org.springframework.ldap.odm.annotations.Entry;
import org.springframework.ldap.odm.annotations.Id;

@Entry(
    base="ou=users",
    objectClasses = { "person", "inetOrgPerson", "top" })
public class LDAPUser {

    @Id
    private Name id;

    private @Attribute(name = "cn") String username;
    private @Attribute(name = "sn") String password;
    private boolean rememberme;
}

And LDAPUserRepository:和 LDAPUserRepository:

import org.springframework.data.ldap.repository.LdapRepository;
import org.springframework.stereotype.Repository;

import com.licensewatcher.model.LDAPUser;

@Repository("ldapUserRespository")
public interface LDAPUserRepository extends LdapRepository<LDAPUser>{

    LDAPUser findByUsername(String username);
    LDAPUser findByUsernameAndPassword(String username, String password);
    /*List<LDAPUser> findByUsernameLikeIgnoreCase(String username);*/
}

and AuthUserService:和 AuthUserService:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.licensewatcher.repository.LDAPUserRepository;

@Service("authUserService")
public class AuthUserService {

    @Autowired LDAPUserRepository ldapUserRespository;

    public boolean authenticate(LDAPUser ldapUser) {
        //TODO: implement this!!!

        return false;
    }

    public boolean authorize(LDAPUser ldapUser) {
        //TODO: implement this!!!

        return false;
    }
}

Class WebSecurityConfig (extends WebSecurityConfigurerAdapte) configures application to submit login controller action: WebSecurityConfig 类(扩展 WebSecurityConfigurerAdapte)配置应用程序以提交登录控制器操作:

@PostMapping("/login/check")
public String login(Model model, LDAPUser ldapUser, RedirectAttributes redirectAttr) {

    //TODO: call authUserService.authenticate(LDAPUser ldapUser);
    return "redirect:/login";
}

I want to implement authUserService.authenticate(LDAPUser ldapUser) to check LDAPUserRepository first and if user exists, check up the User from my database.我想实现 authUserService.authenticate(LDAPUser ldapUser) 首先检查 LDAPUserRepository 如果用户存在,请从我的数据库中检查用户。 If they match, add user to a session and redirect to the requested page.如果它们匹配,则将用户添加到会话并重定向到请求的页面。 Is this a good approach?这是一个好方法吗? Do you have any suggestions how this could be implemented in a more elegant way?您对如何以更优雅的方式实现这一点有什么建议吗? Thanks in advance!提前致谢!

Here is my answer based on the link I provided in the comment.这是我根据我在评论中提供的链接的答案。 This work using the latest Spring boot version 2.7.1 and Spring security 5.7.2这项工作使用最新的 Spring boot 版本 2.7.1 和 Spring security 5.7.2

I'm using Custom Spring Authentication Provider.我正在使用自定义 Spring 身份验证提供程序。

class CustomAuthProvider类 CustomAuthProvider

 @Component
 public class CustomAuthProvider implements AuthenticationProvider {

    @Autowired
    RfaUserService rfaUserService;

    @Autowired
    AuthenticationManager ldapAuthenticationManager;

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {

        Optional<RfaUser> rfaUser = rfaUserService.findByUsername((String) authentication.getPrincipal());
        if (rfaUser.isPresent()) {
            return ldapAuthenticationManager.authenticate(authentication);
        }

        return null;
    }

    @Override
    public boolean supports(Class<?> authentication) {
        return authentication.equals(UsernamePasswordAuthenticationToken.class);
    }
}

class WebSecurityConfig类 WebSecurityConfig

@Configuration
public class WebSecurityConfig {

@Autowired
private CustomAuthProvider customAuthProvider;

@Bean
public SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception {
    httpSecurity
            .httpBasic()
            .and()
            .authorizeRequests()
            .anyRequest()
            .authenticated()
            .and()
            .cors()
            .and()
            .csrf()
            .disable().logout();

    // here is the important part
    httpSecurity.authenticationProvider(customAuthProvider);

    return httpSecurity.build();
}

LDAP configuration class LDAP 配置类

@Configuration
public class LdapSecurityConfig {

    @Value("${ldap.urls}")
    private String ldapUrls;

    @Value("${ldap.base.dn}")
    private String ldapBaseDn;

    @Value("${ldap.username}")
    private String ldapSecurityPrincipal;

    @Value("${ldap.password}")
    private String ldapPrincipalPassword;

    @Value("${ldap.user.dn.pattern}")
    private String ldapUserDnPattern;

    @Autowired
    private CustomAuthoritiesPopulator customAuthoritiesPopulator;
    @Autowired
    private CustomUserDetailsMapper customUserDetailsMapper;


    @Bean
    public AuthenticationManager ldapAuthenticationManager(BaseLdapPathContextSource contextSource) {
        LdapBindAuthenticationManagerFactory managerFactory = new LdapBindAuthenticationManagerFactory(contextSource);
        managerFactory.setUserDnPatterns(ldapUserDnPattern);
        managerFactory.setUserDetailsContextMapper(customUserDetailsMapper);
        managerFactory.setLdapAuthoritiesPopulator(customAuthoritiesPopulator);
        managerFactory.setUserSearchFilter("sAMAccountName={0}");

        return managerFactory.createAuthenticationManager();
    }

    @Bean
    public LdapContextSource contextSource() {
        LdapContextSource ldapContextSource = new LdapContextSource();
        ldapContextSource.setUrl(ldapUrls);
        ldapContextSource.setBase(ldapBaseDn);
        ldapContextSource.setUserDn(ldapSecurityPrincipal);
        ldapContextSource.setPassword(ldapPrincipalPassword);
        return ldapContextSource;
    }
}

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM