Spring Security Ldap 登录认证实现

一、了解LDAP的组织结构

1.User:用户,包含基础的用户信息,用户可以创建到Organizational Unit内部,并且可以关联不同的Group。

2.Organizational unit :组织单元,也类似于文件的目录,其下可以包含各种对象。

3.Group:组,可以将用户关联到group。

二、构建Spring Security Ldap项目的pom文件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.2</version>
        <relativePath/>
    </parent>
    <groupId>com.framework</groupId>
    <artifactId>ldap</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>ldap</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>11</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-ldap</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-ldap</artifactId>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.2</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

三、构建项目的application-work.yml文件配置

spring:
    ldap:
        urls: ldap://192.168.31.240:389
        base: dc=houpu,dc=com
        username: cn=Manager,dc=houpu,dc=com
        password: houpu123
server:
    port: 19001

四、通过配置类继承WebSecurityConfigurerAdapter类

package com.framework.security.config;

/**
 * @Author: LongGE
 * @Date: 2023-3-30
 * @Description: springboot security ldap integration
 */
@Configuration
@EnableWebSecurity
public class SecurityLdapConfig extends WebSecurityConfigurerAdapter {

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

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

    @Value("${spring.ldap.username}")
    private String username;

    @Value("${spring.ldap.password}")
    private String password;

    @Bean
    public PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }


    @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception {
        AuthenticationManager authenticationManager = super.authenticationManagerBean();
        return authenticationManager;
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.ldapAuthentication()
                //.userDnPatterns("uid={0},ou=rppwebapp,ou=application")
                .userSearchBase("ou=People")
                .userSearchFilter("uid={0}")
                .contextSource()
                .url(url + "/" + base)
                .managerDn(username)
                .managerPassword(password);
    }

    @Override
    protected void configure(HttpSecurity httpSecurity) throws Exception {
        httpSecurity.cors().and().csrf().disable();
        httpSecurity
                .authorizeRequests()
                .antMatchers("/AuthLdapController/**")
                .permitAll()
                .anyRequest().authenticated();
    }

    @Override
    public void configure(WebSecurity webSecurity) {
        webSecurity
                .ignoring()
                .antMatchers("/resources/**", "/static/**", "/css/**",
                        "/js/**", "/images/**","/vendor/**","/fonts/**", "/pages/**", "/assets/**", "/dist/**");
    }

    @Bean
    public AuthenticationFailureHandler authenticationFailureHandler() {
        return new CustomAuthenticationFailureHandler();
    }

}

1.继承WebSecurityConfigurerAdapter类,通过父类的构造器构造WebSecurityConfigurerAdapter。

2.通过@Bean构建AuthenticationManager,构建登录认证器,在登录的时候我们需要使用。

 @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception {
        AuthenticationManager authenticationManager = super.authenticationManagerBean();
        return authenticationManager;
    }

上面代码实现中我们他通过父类去实现的构建AuthenticationManager类。

3.通过@EnableWebSecurity第一优先级去调用configure(AuthenticationManagerBuilder auth)方法,来完成对AuthenticationManager接口的实现类ProviderManager封装对应的List<AuthenticationProvider> providers = Collections.emptyList();

protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        //构建一个providerconfigurer
        auth.ldapAuthentication()
                //第一种登录认证方式,我们通过userDnPatterns通过用户所属的组织单直接认证用户信息
                //.userDnPatterns("uid={0},ou=rppwebapp,ou=application")
                //第二种登录热恩正方式,在第一行不存在或者查询不到user信息时候会执行第二种方式
                //第二种方式是通过userSearchBase就是用户所属的组织单元,userSearchFilter用户名
                .userSearchBase("ou=People")
                .userSearchFilter("uid={0}")
                //构建Ldap的数据源,这里通过我们的管理员用户去连接Ldap。
                //后面登录认证会重复使用这个contextSource但是每次登录都会重置账号密码和组织单元
                .contextSource()
                .url(url + "/" + base)
                .managerDn(username)
                .managerPassword(password);
    }

4.通过@EnableWebSecurity第二优先级去调用configure(HttpSecurity httpSecurity)方法。

@Override
    protected void configure(HttpSecurity httpSecurity) throws Exception {
        //关闭csrf开启cors
        httpSecurity.cors().and().csrf().disable();
        httpSecurity
                //开启配置
                .authorizeRequests()
                .antMatchers("/AuthLdapController/login")
                //开放上面端口,不需要登录认证也可访问
                .permitAll()
                //剩下所有接口登录认证后可以访问
                .anyRequest().authenticated();
    }

5.通过@EnableWebSecurity第三优先级去调用configure(WebSecurity webSecurity)方法,来完成对一些静态页面的授权访问。

 @Override
    public void configure(WebSecurity webSecurity) {
        webSecurity
                .ignoring()
                .antMatchers("/resources/**", "/static/**", "/css/**",
                        "/js/**", "/images/**","/vendor/**","/fonts/**", "/pages/**", "/assets/**", "/dist/**");
    }

 

登录接口代码如下。


/**
 * @Author: LongGE
 * @Date: 2023-03-27
 * @Description:
 */
@Slf4j
@RestController
@RequestMapping("/AuthLdapController")
public class AuthLdapController {

    @Autowired
    private AuthenticationManager authenticationManager;

    @PostMapping(value = "/login")
    public String login(String username, String password) {
        System.out.println("登录请求!");

        log.info("start spring security login to!");

        Authentication authentication = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(username, password));

        log.info("登录返回信息:{}", authentication);
        return "login to success!";
    }
}

1.注入AuthenticationManager authenticationManager;

2.创建new UsernamePasswordAuthenticationToken(username, password);token是封装登录用户的账号和密码。

3.登录成功会返回Authentication authentication,这里会包含用户基本信息。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值