Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/161.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用SpringBoot(SpringSecurity)和LDAP自动登录站点_Spring_Spring Boot_Spring Security_Ldap - Fatal编程技术网

使用SpringBoot(SpringSecurity)和LDAP自动登录站点

使用SpringBoot(SpringSecurity)和LDAP自动登录站点,spring,spring-boot,spring-security,ldap,Spring,Spring Boot,Spring Security,Ldap,我正在从事一个SpringBoot项目,该项目在SpringSecurity中使用LDAP进行身份验证 我需要根据SpringSecurity中提供的LDAP组中的角色,在用户点击登录页面后自动登录 如果用户在LDAP中提到的组中有任何角色,则必须在登录后重定向到相应的页面。(即我的示例中的第1页) 我已经连续两天在此搜索任何在线文档或示例,但都是徒劳的。我所能找到的就是使用jdbcDataSource,或者在Controller中硬编码用户名和密码,然后在登录时或通过Spring使用web.x

我正在从事一个SpringBoot项目,该项目在SpringSecurity中使用LDAP进行身份验证

我需要根据SpringSecurity中提供的LDAP组中的角色,在用户点击登录页面后自动登录

如果用户在LDAP中提到的组中有任何角色,则必须在登录后重定向到相应的页面。(即我的示例中的第1页)

我已经连续两天在此搜索任何在线文档或示例,但都是徒劳的。我所能找到的就是使用jdbcDataSource,或者在Controller中硬编码用户名和密码,然后在登录时或通过Spring使用web.xml对其进行验证。但不是通过LDAP。任何帮助都会大有帮助

这就是我的Spring安全XML的外观:

<?xml version="1.0" encoding="UTF-8" ?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:beans="http://www.springframework.org/schema/beans"
    xsi:schemaLocation="http://www.springframework.org/schema/security
                                 http://www.springframework.org/schema/security/spring-security.xsd
                                 http://www.springframework.org/schema/beans
                                 http://www.springframework.org/schema/beans/spring-beans.xsd">

    <http auto-config="true" use-expressions="true">
        <intercept-url pattern="/login" access="permitAll" />
        <intercept-url pattern="/logout" access="permitAll" />
        <intercept-url pattern="/webjars/**" access="permitAll" />
        <intercept-url pattern="/page1" access="hasAnyRole('GP1','GP2')" />
        <intercept-url pattern="/page2" access="hasAnyRole('GP1','GP2')" />
        <intercept-url pattern="/page3" access="hasAnyRole('GP1','GP2')" />
        <intercept-url pattern="/**" access="permitAll" />

        <form-login default-target-url="/page1" login-page="/login"
            always-use-default-target="true" />
        <access-denied-handler error-page="/403.html" />
        <csrf disabled="true" />
        <logout logout-url="/logout" />
    </http>

    <authentication-manager alias="authenticationManager"
        erase-credentials="false">
        <authentication-provider ref="ldapAuthProvider" />
    </authentication-manager>

    <ldap-server id="contextSource" url="ldap://url"
        manager-dn="mymanagerdn" manager-password="mymanagerpswd" />

    <beans:bean id="ldapAuthProvider"
        class="org.springframework.security.ldap.authentication.LdapAuthenticationProvider">
        <beans:constructor-arg>
            <beans:bean id="bindAuthenticator"
                class="org.springframework.security.ldap.authentication.BindAuthenticator">
                <beans:constructor-arg ref="contextSource" />
                <beans:property name="userSearch" ref="userSearch" />
            </beans:bean>
        </beans:constructor-arg>
        <beans:constructor-arg>
            <beans:bean
                class="org.springframework.security.ldap.userdetails.DefaultLdapAuthoritiesPopulator">
                <beans:constructor-arg ref="contextSource" />
                <beans:constructor-arg value="myDCvalues" />
                <beans:property name="searchSubtree" value="true" />
                <beans:property name="ignorePartialResultException"
                    value="true" />
                <beans:property name="groupSearchFilter" value="(member={0})" />
            </beans:bean>
        </beans:constructor-arg>
    </beans:bean>

    <beans:bean id="userSearch"
        class="org.springframework.security.ldap.search.FilterBasedLdapUserSearch">
        <beans:constructor-arg index="0"
            value="myDCvalues" />
        <beans:constructor-arg index="1"
            value="(sAMAccountName={0})" />
        <beans:constructor-arg index="2" ref="contextSource" />
        <beans:property name="searchSubtree" value="true" />
    </beans:bean>

</beans:beans>
package com.myPackage;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.springframework.context.annotation.Bean;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.InternalResourceViewResolver;

@Controller
public class WebController extends WebMvcConfigurerAdapter {

    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/page1").setViewName("page1");
        registry.addViewController("/page2").setViewName("page2");
        registry.addViewController("/page3").setViewName("page3");
        registry.addViewController("/login").setViewName("login");
        registry.addViewController("/403").setViewName("error/403");
    }

    @GetMapping("/page1")
    public String page1(HttpSession session) {
        return "page1";
    }

    @GetMapping("/page2")
    public String page2(HttpSession session) {
        return "page2";
    }

    @GetMapping("/page3")
    public String page3(HttpSession session) {
        return "page3";
    }

    @GetMapping("/login")
    public String login() {
        return "login";
    }

    @GetMapping("/403")
    public String error403() {
        return "error/403";
    }

    @Bean
    public ViewResolver getViewResolver() {
        InternalResourceViewResolver resolver = new InternalResourceViewResolver();
        resolver.setPrefix("templates/");
        return resolver;
    }

    @Override
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
        configurer.enable();
    }

    private String getCredentials() {
        String credential = null;

        UserDetails userDetails = (UserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        credential = userDetails.getUsername().toString();

        return credential;
    }

}

为了方便起见,这个答案附带了一个测试,包括一个LDAP服务器,其中填充了用户和组以及一个集成测试,这样您就可以自己运行这些测试了

假设LDAP中有以下用户

dn: cn=marissa,ou=Users,dc=test,dc=com
changetype: add
objectClass: person
objectClass: organizationalPerson
objectClass: inetOrgPerson
cn: marissa
userPassword: koala
uid: 20f459e0-e30b-4d1f-998c-3ded7f769db1
mail: marissa@test.com
sn: Marissa
用户名是marissa,密码是koala

让我们从测试用例开始:

@测试
@DisplayName(“ldap登录工作”)
void doLogin()引发异常{
mvc.perform(
MockMvcRequestBuilders.post(“/login”)
.param(“用户名”、“marissa”)
.param(“密码”、“考拉”)
.with(csrf())
)
.andExpect(状态().is3xx重定向())
.andExpect(已验证()
;
}
从这个测试中,我们可以推断

  • LDAP使用表单登录、用户名/密码
  • 表单具有CSRF保护
  • 因此,让我们使用Java配置配置Spring引导应用程序

    经典的示例文件,
    SecurityConfig.java

    @EnableWebSecurity
    公共类SecurityConfig扩展了WebSecurity配置适配器{
    
    安全配置不会更改

  • 我们希望用户得到完全认证
  • 我们想使用表单登录
  • @覆盖
    受保护的无效配置(HttpSecurity http)引发异常{
    http
    .授权请求()
    .anyRequest()
    .fullyaauthenticated()
    .及()
    .formLogin()
    ;
    }
    
    就这样,接下来我们配置LDAP,同样在
    SecurityConfig.java
    中,我们通过调用
    AuthenticationManagerBuilder
    来实现。这是Spring Security配置的bean。因此,我们可以使用
    @Autowired
    访问它

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth)引发异常{
    认证
    .lda身份验证()
    .contextSource()
    .url(“ldap://localhost:389")
    .managerDn(“cn=admin,dc=test,dc=com”)
    .managerPassword(“密码”)
    .及()
    .userSearchBase(“ou=Users,dc=test,dc=com”)
    .userSearchFilter(“cn={0}”)
    .groupSearchBase(“dc=test,dc=com”)
    .groupSearchFilter(“成员={0}”)
    ;
    }
    
    就是这样。现在,我使用我从CloudFoundry UAA项目中编写的一些代码为我的集成测试创建了一个in

    因此,当模拟MVC集成测试启动时,它会启动一个LDAP服务器来运行

    其实很简单,现在可以扩展这个示例,将LDAP组映射到Spring安全机构


    LDAP示例在my community repo中提供:

    为方便起见,此答案附带了一个示例,包括一个LDAP服务器,由用户和组填充,以及一个集成测试,以便您可以自己运行这些测试

    假设LDAP中有以下用户

    dn: cn=marissa,ou=Users,dc=test,dc=com
    changetype: add
    objectClass: person
    objectClass: organizationalPerson
    objectClass: inetOrgPerson
    cn: marissa
    userPassword: koala
    uid: 20f459e0-e30b-4d1f-998c-3ded7f769db1
    mail: marissa@test.com
    sn: Marissa
    
    用户名是marissa,密码是koala

    让我们从测试用例开始:

    @测试
    @DisplayName(“ldap登录工作”)
    void doLogin()引发异常{
    mvc.perform(
    MockMvcRequestBuilders.post(“/login”)
    .param(“用户名”、“marissa”)
    .param(“密码”、“考拉”)
    .with(csrf())
    )
    .andExpect(状态().is3xx重定向())
    .andExpect(已验证()
    ;
    }
    
    从这个测试中,我们可以推断

  • LDAP使用表单登录、用户名/密码
  • 表单具有CSRF保护
  • 因此,让我们使用Java配置配置Spring引导应用程序

    经典的示例文件,
    SecurityConfig.java

    @EnableWebSecurity
    公共类SecurityConfig扩展了WebSecurity配置适配器{
    
    安全配置不会更改

  • 我们希望用户得到完全认证
  • 我们想使用表单登录
  • @覆盖
    受保护的无效配置(HttpSecurity http)引发异常{
    http
    .授权请求()
    .anyRequest()
    .fullyaauthenticated()
    .及()
    .formLogin()
    ;
    }
    
    就这样,接下来我们配置LDAP,同样在
    SecurityConfig.java
    中,我们通过调用
    AuthenticationManagerBuilder
    来实现。这是Spring Security配置的bean。因此,我们可以使用
    @Autowired
    访问它

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth)引发异常{
    认证
    .lda身份验证()
    .contextSource()
    .url(“ldap://localhost:389")
    .managerDn(“cn=admin,dc=test,dc=com”)
    .managerPassword(“密码”)
    .及()
    .userSearchBase(“ou=Users,dc=test,dc=com”)
    .userSearchFilter(“cn={0}”)
    .groupSearchBase(“dc=test,dc=com”)
    .groupSearchFilter(“成员={0}”)
    ;
    }
    
    就这样,现在,我用