【问题标题】:how to achieve Ldap Authentication using spring security(spring boot)如何使用spring security(spring boot)实现Ldap Authentication
【发布时间】:2015-12-21 19:49:12
【问题描述】:

我有以下代码 我正在尝试实现 ldap 身份验证,但我认为它没有发生。

我的安全配置

@EnableWebSecurity
@Configuration
@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
public class Config extends WebSecurityConfigurerAdapter {

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

        http.httpBasic().and().authorizeRequests().antMatchers("/*")
                .permitAll().anyRequest().authenticated().and().csrf()
                .disable().httpBasic().and().csrf()
                .csrfTokenRepository(csrfTokenRepository()).and()
                .addFilterAfter(csrfHeaderFilter(), CsrfFilter.class);

    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth)
            throws Exception {
        auth.ldapAuthentication()
                .userSearchFilter("(uid={0})")
                .userSearchBase("dc=intern,dc=xyz,dc=com")
                .contextSource()
                .url("ldap://192.168.11.11:1234/dc=intern,dc=xyz,dc=com")
                .managerDn("username")
                .managerPassword("password!")
                .and()
                .groupSearchFilter("(&(objectClass=user)(sAMAccountName=" + "username" + "))");

    }

    private Filter csrfHeaderFilter() {
        return new OncePerRequestFilter() {
            @Override
            protected void doFilterInternal(HttpServletRequest request,
                    HttpServletResponse response, FilterChain filterChain)
                    throws ServletException, IOException {
                CsrfToken csrf = (CsrfToken) request
                        .getAttribute(CsrfToken.class.getName());
                if (csrf != null) {
                    Cookie cookie = WebUtils.getCookie(request, "XSRF-TOKEN");
                    String token = csrf.getToken();
                    if (cookie == null || token != null
                            && !token.equals(cookie.getValue())) {
                        cookie = new Cookie("XSRF-TOKEN", token);
                        cookie.setPath("/");
                        response.addCookie(cookie);
                        response.sendRedirect("/notAllowed");
                    }
                }
                filterChain.doFilter(request, response);
            }
        };
    }

    private CsrfTokenRepository csrfTokenRepository() {
        HttpSessionCsrfTokenRepository repository = new HttpSessionCsrfTokenRepository();
        repository.setHeaderName("X-XSRF-TOKEN");
        return repository;
    }
}

我的控制器

    @RequestMapping(value = { "/test" }, method = RequestMethod.GET)
public @ResponseBody String retrieve() {
    System.out.println("line 1");
    System.out.println("line 2");
    return "hello";

}

@RequestMapping(value = { "/notAllowed" }, method = RequestMethod.GET)
public @ResponseBody HttpStatus login() {

    return HttpStatus.FORBIDDEN;

}

我的目标是:

我想实现 ldap 身份验证。 U用户名和密码将来自浏览器,尽管我也尝试过使用硬编码的用户名和密码。

如果用户是真实的,那么过滤器将通过检查令牌来检查授权

如果这是第一次请求,则将生成新令牌并发送。 如果它未找到,那么它将发送HTTP 状态禁止

我有以下问题:

  1. 当我第一次从浏览器运行时,它返回禁止,但它还在控制台中打印“第 1 行和第 2 行”,尽管它不返回 hello 但禁止。

  2. 我的 htpSecurity 和 ldap 配置是否正常?

  3. 从第二个请求它总是返回你好,我试图打开新标签,新请求但它仍然工作正常。如果我 重新启动服务器然后只有 它生成令牌 并将其与 cookie 令牌进行比较。如果两个人使用相同的系统(不同时间)会怎样。

  4. 我究竟如何测试 ldap 身份验证?我正在使用 POSTMAN 作为客户端。

如果我缺少某些信息,请告诉我。 我会感谢你的回答。

【问题讨论】:

  • 您还有问题吗?如果我的回答没有帮助,请告诉我。
  • 如何从邮递员那里测试?

标签: java spring spring-mvc spring-security spring-boot


【解决方案1】:

首先,我认为您的 HttpSecurity 配置是错误的。您想保护所有端点。不是吗?

所以改成下面这样:

http.httpBasic()
        .and()
        .authorizeRequests()
        .anyRequest()
        .authenticated()
        .and()
        .csrf()
        .csrfTokenRepository(csrfTokenRepository())
        .and()
        .addFilterAfter(csrfHeaderFilter(), CsrfFilter.class);

此外,我不确定您的 ldap 配置是否正确。我认为您可以将其简化为以下内容:

auth.ldapAuthentication()
        .userSearchFilter("uid={0}")
        .contextSource()
        .url("ldap://192.168.11.11:1234/dc=intern,dc=xyz,dc=com");

确定您的 userSearchBase 是否正确。它没有“ou”。

如果您没有任何不同的组织单位,您可以简单地删除 userSearchBase

为了提供更好的帮助,我需要了解您的 ldap 的结构。

如果您想检查您的 HttpSecurity 配置,您可能一开始就不要使用 ldap 而是使用 inMemoryAuthentication:

auth.inMemoryAuthentication().withUser("user").password("password").authorities("ROLE_USER");

【讨论】:

  • 嗨,Yannic,请您帮忙解决一下 ldap 配置问题。 auth.ldapAuthentication 应该如何查找这个 ldap_user_search_base = OU=People,DC=mgmt,DC=abcd,DC=net ldap_group_search_base = OU=Groups,DC=mgmt,DC=abcd,DC=net ldap_default_bind_dn = uid=proxy, ou=特殊用户,dc=mgmt,dc=abcd,dc=net ldap_default_authtok_type = 密码 ldap_default_authtok = 这是密码 ldap_group_member = memberUid
  • 请在 stackoverflow 上创建一个问题并将其链接到我。我去看看。
  • 有什么方法可以同时使用auth.inMemoryAuthentication()auth.ldapAuthentication() 吗?比方说,我有一个测试环境,对非 ldap 进行测试,然后添加 ldap 测试。
  • 这将适合弹簧“轮廓”机制。创建两个配置,一个使用@Profile("nonLdapOrWhateverNameYouPrefer") 一个使用@Profile("...")。现在在测试中指定您想要的配置文件。
猜你喜欢
  • 2015-07-12
  • 2017-08-15
  • 2011-03-06
  • 2020-01-03
  • 1970-01-01
  • 2019-01-17
  • 2021-11-05
  • 2014-07-02
  • 1970-01-01
相关资源
最近更新 更多