我为我的网页和Web服务实现了数据库身份验证.
它对两者都很好,现在我必须添加Ldap身份验证.
我必须通过远程Ldap服务器进行身份验证(使用用户名和密码),如果用户存在我必须使用我的数据库为用户角色(在我的数据库用户名是相同的用户名Ldap).
所以我必须从我的实际代码切换到Ldap和数据库认证,如上所述.我的代码是:
SecurityConfig类
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled = true,prePostEnabled = true,proxyTargetClass = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    @Qualifier("userDetailsService")
    UserDetailsService userDetailsService;

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
    }

    @Bean
    public PasswordEncoder passwordEncoder(){
        PasswordEncoder encoder = new BCryptPasswordEncoder();
        return encoder;
    }

    @Configuration
    @Order(1)
    public static class ApiWebSecurityConfig extends WebSecurityConfigurerAdapter{
        @Override
        protected void configure(HttpSecurity http) throws Exception {
             http.csrf().disable()
             .antMatcher("/client/**")
             .authorizeRequests()
             .anyRequest().authenticated()
             .and()
             .httpBasic();
        }
    }

    @Configuration
    @Order(2)
    public static class FormWebSecurityConfig extends WebSecurityConfigurerAdapter{

        @Override
        public void configure(WebSecurity web) throws Exception {
            web
            //Spring Security ignores request to static resources such as CSS or JS files.
            .ignoring()
            .antMatchers("/static/**");
        }

        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http
            .authorizeRequests() //Authorize Request Configuration
                //the / and /register path are accepted without login
                //.antMatchers("/","/register").permitAll()
                //the /acquisition/** need admin role
                //.antMatchers("/acquisition/**").hasRole("ADMIN")
                //.and().exceptionHandling().accessDeniedPage("/Access_Denied");
                //all the path need authentication
                .anyRequest().authenticated()
                .and() //Login Form configuration for all others
            .formLogin()
                .loginPage("/login")
                //important because otherwise it goes in a loop because login page require authentication and authentication require login page
                    .permitAll()
            .and()
            .logout()
                .logoutSuccessUrl("/login?logout")
                .permitAll();
             // CSRF tokens handling
        }
    }

MyUserDetailsS​​ervice类

@Service("userDetailsService")
public class MyUserDetailsService implements UserDetailsService {

    @Autowired
    private UserServices userServices;
    static final Logger LOG = LoggerFactory.getLogger(MyUserDetailsService.class);

    @Transactional(readOnly=true)
    @Override
    public UserDetails loadUserByUsername(final String username){
        try{
            com.domain.User user = userServices.findById(username);
            if (user==null)
                LOG.error("Threw exception in MyUserDetailsService::loadUserByUsername : User doesn't exist" ); 
            else{
                List<GrantedAuthority> authorities = buildUserAuthority(user.getUserRole());
                return buildUserForAuthentication(user,authorities);
            }
        }catch(Exception e){
            LOG.error("Threw exception in MyUserDetailsService::loadUserByUsername : " + ErrorExceptionBuilder.buildErrorResponse(e));  }
        return null;
    }

    // Converts com.users.model.User user to
    // org.springframework.security.core.userdetails.User
    private User buildUserForAuthentication(com.domain.User user,List<GrantedAuthority> authorities) {
        return new User(user.getUsername(),user.getpassword(),user.isEnabled(),true,authorities);
    }

    private List<GrantedAuthority> buildUserAuthority(Set<UserRole> userRoles) {

        Set<GrantedAuthority> setAuths = new HashSet<GrantedAuthority>();

        // Build user's authorities
        for (UserRole userRole : userRoles) {
            setAuths.add(new SimpleGrantedAuthority(userRole.getUserRoleKeys().getRole()));
        }

        List<GrantedAuthority> Result = new ArrayList<GrantedAuthority>(setAuths);

        return Result;
    }

所以我必须要:

1)用户从网页的登录页面以及Web服务的用户名和密码访问用户.这必须通过Ldap完成.

2)用户需要用户名进行数据库查询来认证用户.
你有什么想法可以实现吗?
谢谢

使用正确的代码更新:遵循@M. Deinum建议我创建MyAuthoritiesPopulator类而不是MyUserDetailsS​​ervice,并使用数据库和Ldap进行身份验证:

@Service("myAuthPopulator")
public class MyAuthoritiesPopulator implements LdapAuthoritiesPopulator {

    @Autowired
    private UserServices userServices;
    static final Logger LOG = LoggerFactory.getLogger(MyAuthoritiesPopulator.class);

    @Transactional(readOnly=true)
    @Override
    public Collection<? extends GrantedAuthority> getGrantedAuthorities(DirContextOperations userData,String username) {
        Set<GrantedAuthority> authorities = new HashSet<GrantedAuthority>();
        try{
            com.domain.User user = userServices.findById(username);
            if (user==null)
                LOG.error("Threw exception in MyAuthoritiesPopulator::getGrantedAuthorities : User doesn't exist into ATS database" );  
            else{
                for(UserRole userRole : user.getUserRole()) {
                    authorities.add(new SimpleGrantedAuthority(userRole.getUserRoleKeys().getRole()));
                }
                return authorities;
            }
        }catch(Exception e){
            LOG.error("Threw exception in MyAuthoritiesPopulator::getGrantedAuthorities : " + ErrorExceptionBuilder.buildErrorResponse(e)); }
        return authorities;
    }
}

我更改了SecurityConfig如下:

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled = true,proxyTargetClass = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    @Qualifier("myAuthPopulator")
    LdapAuthoritiesPopulator myAuthPopulator;

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {

         auth.ldapAuthentication()
          .contextSource()
            .url("ldap://127.0.0.1:10389/dc=example,dc=com")
//          .managerDn("")
//          .managerPassword("")
          .and()   
            .userSearchBase("ou=people")
            .userSearchFilter("(uid={0})")
            .ldapAuthoritiesPopulator(myAuthPopulator);     
    }

    @Configuration
    @Order(1)
    public static class ApiWebSecurityConfig extends WebSecurityConfigurerAdapter{
        @Override
        protected void configure(HttpSecurity http) throws Exception {
             http.csrf().disable()
             .antMatcher("/client/**")
             .authorizeRequests()
             //Excluede send file from authentication because it doesn't work with spring authentication
             //Todo add java authentication to send method
             .antMatchers(HttpMethod.POST,"/client/file").permitAll()
             .anyRequest().authenticated()
             .and()
             .httpBasic();
        }
    }

    @Configuration
    @Order(2)
    public static class FormWebSecurityConfig extends WebSecurityConfigurerAdapter{

        @Override
        public void configure(WebSecurity web) throws Exception {
            web
            //Spring Security ignores request to static resources such as CSS or JS files.
            .ignoring()
            .antMatchers("/static/**");
        }

        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http
            .authorizeRequests() //Authorize Request Configuration
                //the "/" and "/register" path are accepted without login
                //.antMatchers("/","/register").permitAll()
                //the /acquisition/** need admin role
                //.antMatchers("/acquisition/**").hasRole("ADMIN")
                //.and().exceptionHandling().accessDeniedPage("/Access_Denied");
                //all the path need authentication
                .anyRequest().authenticated()
                .and() //Login Form configuration for all others
            .formLogin()
                .loginPage("/login")
                //important because otherwise it goes in a loop because login page require authentication and authentication require login page
                    .permitAll()
            .and()
            .logout()
                .logoutSuccessUrl("/login?logout")
                .permitAll();
        }
    }
}

我的LDAP开发环境在Apache目录工作室中创建

解决方法

Spring Security已经支持LDAP开箱即用.它实际上有一个 whole chapter这个.

要使用和配置LDAP,请添加spring-security-ldap依赖项,接下来使用AuthenticationManagerBuilder.ldapAuthentication进行配置. LdapAuthenticationProviderConfigurer允许您设置所需的东西.

@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
    auth.ldapAuthentication()
      .contextSource()
        .url(...)
        .port(...)
        .managerDn(...)
        .managerPassword(...)
      .and()
        .passwordEncoder(passwordEncoder())
        .userSearchBase(...)        
        .ldapAuthoritiesPopulator(new UserServiceLdapAuthoritiesPopulater(this.userService));      
}

这样的东西(它应该给你至少一个关于什么/如何配置事情的想法)有更多的选择,但检查javadocs.如果您不能使用UserService来检索角色(因为只有角色在数据库中),那么可以实现自己的LdapAuthoritiesPopulator.

java – Spring安全切换到Ldap认证和数据库权限的更多相关文章

  1. .net – 用于Windows 8上的开发目的的LDAP服务器

    例如,快速搜索给出了OpenLDAP.如果您使用的是Windows8Pro,则包含ADLDS.转到打开或关闭Windows功能,选择ActiveDirectory轻量级目录服务.您也可以使用powershell

  2. centos – pam_ldap和ldaps无法联系ldap服务器

    我正在尝试通过CentOS主机系统上的LDAP进行身份验证.但我总是得到一个无法联系pam_ldap的LDAP服务器错误.LDAP服务器是可ping的,身份验证与ldap://完美配合,但与ldaps://无关.它也适用于debianOS上的ldaps://,但不适用于CentOS.我的$ldapsearch也得到了无法联系的错误….尝试通过pam,/var/log/secure进行身份验证运行$ldapsearch-v-Hldaps://10.1.1.42/-Dcn=admin,dc=sub,dc=ex

  3. centos – 当名称冲突时,如何使本地/ etc / group优先于LDAP?

    .另外,在/etc/nsswitch.conf中我们有和其余的正常位和bobs.因此,如果LDAP和本地文件中都存在名称,是否有办法确保本地文件中的ID优先于LDAP中的ID?

  4. ldap_modify:更改密码时访问不足(50)

    为什么根标识为LDAP管理员无权更改密码?

  5. Centos 6 Linux和nss-pam-ldapd

    我正在尝试使用centos6来对ldap进行身份验证我有点困惑,因为在安装nss-pam-ldapd后,我看到几个文件似乎是相同的配置.例如,我有/etc/pam_ldap.conf和/etc/nslcd.conf.这两个文件似乎都具有相同的配置选项.似乎没有工作.任何指导将不胜感激.

  6. 在Windows 7上安装和配置LDAP(AD LDS)

    如何在Windows7上安装Ldap并进行配置?做了一些谷歌搜索..无法找到任何确切的文章..有什么建议??displaylang=en&FamilyID=a45059af-47a8-4c96-afe3-93dab7b5b658,您可以找到ADLDS的安装.它实际上是Win7的某种更新.安装完成后,要安装ADLDS,您需要在控制面板/管理工具中安装向导.此外,在同一窗口中,您可以使用ADSIEdit来接近ADLDS实例.

  7. 如何判断CentOS上是否安装了OpenLDAP,并测试它是否正常工作?

    这样做的简单方法是什么?

  8. 我在哪里可以找到有关Centos / RHEL 6上LDAP身份验证的USEFUL官方文档?

    是否存在任何关于如何设置LDAP服务器的官方安装文档,我可以将客户端连接到authconfig.我将是Centos6和RHEL6.1.我能找到的是this.但是我不需要学习如何重新启动服务,我更想知道我需要在LDIF文件中输入什么样的东西,任何需要完成的SELinux事情,如何执行authconfig工具和stuf,人们在他们的博客如何写.这样的事情是否存在?

  9. centos – FreeRADIUS2和LDAP身份验证

    我目前正在运行带有FreeRADIUS2的CentOS5.5盒子.我现在打开了简单的身份验证.我想通过我当前的OpenLDAP服务器让FreeRADIUS对用户进行身份验证.有人能指出我正确的方向吗?

  10. sssd – 刷新ldap客户端配置Centos

    最近我们更改了我们的LDAP服务器的ip地址(并添加了一些组)(在SuseEnterprise中运行),因此也应该更改我们拥有的所有服务器的ldap验证配置.大多数服务器都在Centos上.我们将/etc/sssd/sssd.conf中的ldap_uri参数修改为新服务器,但是当我们登录到服务器并创建一个:我们获取旧服务器的用户信息,而不是新服务器的用户信息.实际上,如果我们更改sssd.conf

随机推荐

  1. 基于EJB技术的商务预订系统的开发

    用EJB结构开发的应用程序是可伸缩的、事务型的、多用户安全的。总的来说,EJB是一个组件事务监控的标准服务器端的组件模型。基于EJB技术的系统结构模型EJB结构是一个服务端组件结构,是一个层次性结构,其结构模型如图1所示。图2:商务预订系统的构架EntityBean是为了现实世界的对象建造的模型,这些对象通常是数据库的一些持久记录。

  2. Java利用POI实现导入导出Excel表格

    这篇文章主要为大家详细介绍了Java利用POI实现导入导出Excel表格,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  3. Mybatis分页插件PageHelper手写实现示例

    这篇文章主要为大家介绍了Mybatis分页插件PageHelper手写实现示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

  4. (jsp/html)网页上嵌入播放器(常用播放器代码整理)

    网页上嵌入播放器,只要在HTML上添加以上代码就OK了,下面整理了一些常用的播放器代码,总有一款适合你,感兴趣的朋友可以参考下哈,希望对你有所帮助

  5. Java 阻塞队列BlockingQueue详解

    本文详细介绍了BlockingQueue家庭中的所有成员,包括他们各自的功能以及常见使用场景,通过实例代码介绍了Java 阻塞队列BlockingQueue的相关知识,需要的朋友可以参考下

  6. Java异常Exception详细讲解

    异常就是不正常,比如当我们身体出现了异常我们会根据身体情况选择喝开水、吃药、看病、等 异常处理方法。 java异常处理机制是我们java语言使用异常处理机制为程序提供了错误处理的能力,程序出现的错误,程序可以安全的退出,以保证程序正常的运行等

  7. Java Bean 作用域及它的几种类型介绍

    这篇文章主要介绍了Java Bean作用域及它的几种类型介绍,Spring框架作为一个管理Bean的IoC容器,那么Bean自然是Spring中的重要资源了,那Bean的作用域又是什么,接下来我们一起进入文章详细学习吧

  8. 面试突击之跨域问题的解决方案详解

    跨域问题本质是浏览器的一种保护机制,它的初衷是为了保证用户的安全,防止恶意网站窃取数据。那怎么解决这个问题呢?接下来我们一起来看

  9. Mybatis-Plus接口BaseMapper与Services使用详解

    这篇文章主要为大家介绍了Mybatis-Plus接口BaseMapper与Services使用详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

  10. mybatis-plus雪花算法增强idworker的实现

    今天聊聊在mybatis-plus中引入分布式ID生成框架idworker,进一步增强实现生成分布式唯一ID,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

返回
顶部