【问题标题】:How to get LDAP Username in Springboot如何在 Spring Boot 中获取 LDAP 用户名
【发布时间】:2018-08-23 09:55:48
【问题描述】:

当用户在 Springboot 中尝试通过 LDAP 使用 Active Directory 进行身份验证时如何获取用户名。

正如我尝试使用下面的代码但得到如下所示的错误:

LDAP 配置:

#ldap.url=ldap://localhost:389

#ldap.base.dn=dc=springframework,dc=org
#ldap.user.dn.pattern=(&(objectClass=user)(userPrincipalName={0})(memberof=CN=GroupACCESS,OU=people, DC=springframework,DC=org))

WebSecurityConfig.java

    @Configuration
    @EnableWebSecurity
    public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

        private final static Logger log = LogManager.getLogger(WebSecurityConfig.class);

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

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

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


        @Override
        protected void configure(HttpSecurity http) throws Exception {

          http.addFilterBefore(
                  new CustomFilter(), UsernamePasswordAuthenticationFilter.class);

            http.authorizeRequests().anyRequest().fullyAuthenticated().and().httpBasic();
        }

        @Override
        protected void configure(AuthenticationManagerBuilder auth) throws Exception {

            ActiveDirectoryLdapAuthenticationProvider adProvider = new ActiveDirectoryLdapAuthenticationProvider(
                    this.ldapDomain, this.ldapUrl);

            adProvider.setConvertSubErrorCodesToExceptions(true);
            adProvider.setUseAuthenticationRequestCredentials(true);


            // Checks with the Distinguished Name pattern provided
            if (this.ldapUserDnPattern != null && this.ldapUserDnPattern.trim().length() > 0) {

                adProvider.setSearchFilter(this.ldapUserDnPattern);

                Authentication auth1 = SecurityContextHolder.getContext().getAuthentication();
                String userName = auth1.getName();
                String password = (String)auth1.getCredentials();

                log.info("userName:"+userName);
            }


            auth.authenticationProvider(adProvider);

        }
    }

请找到如下所示的错误日志:

 [ERROR] 2018-08-23 15:13:53.376 [restartedMain] SpringApplication - Application run failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'springSecurityFilterChain' defined in class path resource [org/springframework/security/config/annotation/web/configuration/WebSecurityConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [javax.servlet.Filter]: Factory method 'springSecurityFilterChain' threw exception; nested exception is java.lang.NullPointerException
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:587) ~[spring-beans-5.0.4.RELEASE.jar:5.0.4.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1250) ~[spring-beans-5.0.4.RELEASE.jar:5.0.4.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1099) ~[spring-beans-5.0.4.RELEASE.jar:5.0.4.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:545) ~[spring-beans-5.0.4.RELEASE.jar:5.0.4.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:502) ~[spring-beans-5.0.4.RELEASE.jar:5.0.4.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:312) ~[spring-beans-5.0.4.RELEASE.jar:5.0.4.RELEASE]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228) ~[spring-beans-5.0.4.RELEASE.jar:5.0.4.RELEASE]

任何人都可以看看这个并帮助我。

【问题讨论】:

  • 发布您的完整堆栈跟踪,因为有一个NullPointerException
  • 请立即查看@mrkernelpanic
  • 如果您不想完整发布,请检查您的堆栈跟踪,您发布的那个并没有真正的帮助。
  • 我猜 nullPointer 来自您在配置方法Authentication auth1 = SecurityContextHolder.getContext().getAuthentication(); String userName = auth1.getName(); // <-- here auth1 is null ! 中的行。为什么你试图从 SpringBoot 服务器初始化期间执行的代码访问 SecurityContextHolder(所以那里没有可用的 User SecurityContext)?
  • 实际上,我在使用 LDAP AD 对用户进行身份验证时尝试获取用户名。如果用户无法登录,则需要存储,所以请告诉我我必须将那段代码放在哪里才能获取用户名。谢谢@M.Ricciuti

标签: java spring spring-boot active-directory ldap


【解决方案1】:

将以下过滤器添加到您的 WebSecurityConfigurerAdapter 以从请求中读取用户名参数:

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests().anyRequest().authenticated().and().formLogin().and().addFilterBefore(new Filter() {

            public void init(FilterConfig filterConfig) throws ServletException {

            }

            public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
                    throws IOException, ServletException {
                if (request.getParameter("username")!=null) System.out.println(request.getParameter("username"));
                chain.doFilter(request, response);
            }

            public void destroy() {

            }
        }, UsernamePasswordAuthenticationFilter.class);
    }

【讨论】:

  • 我添加了过滤器,并在帖子中更新了代码,如上所示。并将获取用户代码保留在该过滤器中,但之前没有执行。你能检查一下吗?谢谢@TomB
猜你喜欢
  • 1970-01-01
  • 2018-01-14
  • 2015-04-15
  • 1970-01-01
  • 2023-03-11
  • 2022-01-02
  • 2019-11-11
  • 2018-10-25
  • 2014-07-18
相关资源
最近更新 更多