当前位置: 首页 > 知识库问答 >
问题:

使用Spring Boot(Spring Security)和LDAP自动登录站点

江凯风
2023-03-14

一旦用户点击登录页面,我需要根据Spring Security中提供的LDAP组中的角色自动登录。

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

我已经连续搜索了2天,为任何在线文档或一个例子,但徒劳无功。我所能找到的就是使用jdbcDataSource或在控制器中硬编码用户名和密码,然后在登录时或通过Spring使用web.xml对其进行验证。但不是通过LDAP。任何帮助都会很有帮助。

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

}

共有1个答案

卓胜
2023-03-14

为了方便起见,这个答案附带了一个完整的工作示例,包括一个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。

    @Test
    @DisplayName("ldap login works")
    void doLogin() throws Exception {
        mvc.perform(
            MockMvcRequestBuilders.post("/login")
                .param("username", "marissa")
                .param("password", "koala")
                .with(csrf())
        )
            .andExpect(status().is3xxRedirection())
            .andExpect(authenticated())
        ;
    }
    null

因此,让我们使用Java配置来配置Spring Boot应用程序

经典示例文件securityconfig.java

@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

安全配置不会改变。

    null
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .anyRequest()
                .fullyAuthenticated()
                .and()
            .formLogin()
        ;
    }
    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth
            .ldapAuthentication()
                .contextSource()
                    .url("ldap://localhost:389")
                    .managerDn("cn=admin,dc=test,dc=com")
                    .managerPassword("password")
                    .and()
                .userSearchBase("ou=Users,dc=test,dc=com")
                .userSearchFilter("cn={0}")
                .groupSearchBase("dc=test,dc=com")
                .groupSearchFilter("member={0}")
        ;
    }

就这样了。现在,我使用从Cloud Foundry UAA项目中编写的一些代码来为集成测试创建内存中的LDAP服务器。

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

真的就是这么简单。现在可以展开此示例,将LDAP组映射到Spring Security授权。

 类似资料:
  • 本文向大家介绍SpringBoot 配合 SpringSecurity 实现自动登录功能的代码,包括了SpringBoot 配合 SpringSecurity 实现自动登录功能的代码的使用技巧和注意事项,需要的朋友参考一下 自动登录是我们在软件开发时一个非常常见的功能,例如我们登录 QQ 邮箱: 很多网站我们在登录的时候都会看到类似的选项,毕竟总让用户输入用户名密码是一件很麻烦的事。 自动登录功能

  • 当我尝试使用Selenium(Python)登录Chase网站时,我遇到以下错误消息: 然而,使用“人类”登录工作良好。看来,当硒找到一种元素时,就会引发问题。 我是不是漏掉了什么?我试图在stackoverflow上找到答案,但没有结果。

  • 本文向大家介绍Springboot+SpringSecurity+JWT实现用户登录和权限认证示例,包括了Springboot+SpringSecurity+JWT实现用户登录和权限认证示例的使用技巧和注意事项,需要的朋友参考一下 如今,互联网项目对于安全的要求越来越严格,这就是对后端开发提出了更多的要求,目前比较成熟的几种大家比较熟悉的模式,像RBAC 基于角色权限的验证,shiro框架专门用于

  • 问题内容: 不仅仅是一个问题,我需要使用jsf执行身份验证。我开发了一个登录名,该登录名接收存储在MySQL中的用户名和密码。从Active Directory登录后,它应该使用AD的用户名和密码,我想应该与MySQL的用户名和密码相同。 然后,要进入系统,您将不再看到登录名,而是直接看到主页或主页。 希望您的帮助和预先感谢。 问候。 问题答案: 这是我的解决方案,对我有用:编辑faces-con

  • 我有一个批处理文件,其中有用户名和密码登录以下格式的网站在第16行第5个字是用户名,第7个字是密码。 启动VPNGUI-c-用户1000-pwd 123456 我需要一个关于JavaScript的帮助,它应该打开网站主页,阅读批量文件收集用户名和密码,自动填写用户名和密码在主页上,并使用发送键登录。我已经尝试过使用vbscript,下面是我的代码,但我需要Java版本,它应该允许用户一次点击就自动

  • 我是(IdP)和漏洞(SSO)架构的新手。 今天,我们有一个SharePoint 2010应用程序,它已经进行了声明身份验证。登录的环境或流程如下: 这可以正常工作,SSO也可以正常工作。现在,我们希望通过从其他源(而不是Shibboleth)获取安全断言标记语言(SAML)响应来自动登录用户。 我们将以标题或纯文本形式接收SAML。 我现在要做的是,根据代表性状态传输(REST)服务的响应,在A