java 如何使用spring security(spring boot)实现LDAP认证

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/32757440/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 20:43:48  来源:igfitidea点击:

how to achieve Ldap Authentication using spring security(spring boot)

javaspringspring-mvcspring-securityspring-boot

提问by lesnar

I have following code with me I am trying to achieve ldap Authentication but i think it is not happening.

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

My Security Configuration

我的安全配置

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

My Controller

我的控制器

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

}

i am aiming for :

我的目标是:

i want to achieve ldap authentication. Username and password will come from browserthough i have tried with hardcoded username and password as well.

我想实现 ldap 身份验证。ü sername和密码将来自浏览器,虽然我有硬编码的用户名和密码尝试为好。

if user is authenticthen filter will check the authorizátion by checking the token.

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

if this is first requestthen new token will be generatedand sent. if its not foundthen it will send the HTTP Status forbidden.

如果这是第一个请求,则将生成并发送新令牌。如果未找到,它将发送HTTP Status forbidden

I have following problems :

我有以下问题:

  1. when i run first time from browser it returns forbidden but it also prints "line 1 and line 2" in console though it do not return hello but forbidden.

  2. are my htpSecurity and ldap Configuration fine?.

  3. from 2nd request it always return hello , i have tried to open new tab ,new request but still it works fine .If i restart serverthen only it generates tokenand compare it with cookies token.what if two people are using same system (different times).

  4. how exactly i can test ldap authentication ? i am using POSTMAN as a client .

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

  2. 我的 htpSecurity 和 ldap 配置好吗?。

  3. 从第二个请求开始,它总是返回 hello ,我尝试打开新选项卡,新请求,但仍然可以正常工作。如果我重新启动服务器,那么只会生成令牌并将其与 cookie令牌进行比较。如果两个人使用相同的系统(不同次)。

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

If some information is missing from my end please let me know . And i will be thankful for your answers.

如果我最后遗漏了某些信息,请告诉我。我将感谢您的回答。

回答by Yannic Klem

First of all, I think your HttpSecurity config is wrong. You want to protect ALL the endpoints. Don't you?

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

So change it to the following:

因此将其更改为以下内容:

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

Furthermore, I'm not sure whether your ldap config is right. I think you can reduce it to the following:

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

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

Make sure if your userSearchBase is right. It doesn't have an "ou".

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

If you don't have any different organizational units, you can simply remove the userSearchBase

如果您没有任何不同的组织单位,则只需删除 userSearchBase

To provide better help i need to know the structure of your ldap.

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

If you want to check your HttpSecurity config you may not use ldap in the first place and use inMemoryAuthentication instead:

如果你想检查你的 HttpSecurity 配置,你可能不会首先使用 ldap 而是使用 inMemoryAuthentication :

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