Spring Security OAuth2 和 Ldap 对同一资源的身份验证

Posted

技术标签:

【中文标题】Spring Security OAuth2 和 Ldap 对同一资源的身份验证【英文标题】:Spring Security OAuth2 and Ldap authentication to the same resourse 【发布时间】:2019-10-02 07:18:45 【问题描述】:

我有 Spring Boot 2 REST 应用程序,并且我想配置 Spring Security 以支持对相同资源的 Google 登录或 LDAP 身份验证(例如 /employees)

我已经通过 httpBasic(连接到 Apache AD LDAP 服务器)完成了身份验证。

我还设置了通过 Google OAuth2 登录的身份验证。 这两种配置都可以单独工作(我可以通过 Google 登录进行身份验证,但不能同时使用 LDAP,因为我必须重新设置 spring 安全性),现在我需要能够通过这两种方式进行身份验证同时。

我的 LDAP 身份验证的 Spring Security 配置

@Override
    protected void configure(HttpSecurity http) throws Exception 
        http
            .csrf()
            .disable()
            .authorizeRequests()
            .antMatchers("/", "/login**","/callback/", "/webjars/**", "/error**")
            .permitAll()
            .anyRequest()
            .authenticated()
            .and()
            .httpBasic()
            .and()
            .sessionManagement()
            .sessionCreationPolicy(SessionCreationPolicy.STATELESS);
    


    @Override
    public void configure(AuthenticationManagerBuilder auth) throws Exception 
        auth
                .ldapAuthentication()
                .ldapAuthoritiesPopulator(customLdapAuthoritiesPopulator)
                .userDnPatterns("uid=0,ou=people")
                .groupSearchBase("ou=groups")
                .contextSource()
                .url(env.getProperty("spring.ldap.urls") + env.getProperty("spring.ldap.base"))
                .and()
                .passwordCompare()
                .passwordAttribute("userPassword")
                .passwordEncoder(new LdapShaPasswordEncoder());
    

当我为 Google OAuth2 登录重新配置 Spring Security 时它的外观

@Override
    protected void configure(HttpSecurity http) throws Exception 
        http
            .csrf()
            .disable()
            .authorizeRequests()
            .antMatchers("/", "/login**","/callback/", "/webjars/**", "/error**")
            .permitAll()
            .anyRequest()
            .authenticated()
            .and()
            .oauth2Login()
            .userInfoEndpoint().oidcUserService(customOAuth2UserService);
    

我需要的结果:用户有两种选择:使用 Oauth2 进行身份验证,或者,如果他愿意,使用 httpBasic LDAP,无论哪种方式。

我认为有一种方法可以配置 Spring Security,以便 OAuth2 和 httpBasic LDAP 一起工作,但我不知道该怎么做。

【问题讨论】:

【参考方案1】:

有可能。

基本身份验证使用基本身份验证,而 oauth 使用承载作为标头授权标头的一部分。

我们可以使用自定义请求匹配器来检测基本身份验证并使用 ldap 进行身份验证。如果不是,它将通过oauth流动。

首先,将WebSecurityConfigurerAdapter排序高于Oauth认证服务器,

@Configuration
@Order(2)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter 

使用我们的自定义请求映射器,

http
            .csrf()
            .disable()
            .requestMatcher(new BasicRequestMatcher())
            .authorizeRequests()
            .antMatchers("/", "/login**","/callback/", "/webjars/**", "/error**")
            .permitAll()
            .anyRequest()
            .authenticated()
            .and()
            .httpBasic()
            .and()
            .sessionManagement()
            .sessionCreationPolicy(SessionCreationPolicy.STATELESS);

自定义请求匹配器,

 private static class BasicRequestMatcher implements RequestMatcher 
    @Override
    public boolean matches(HttpServletRequest request) 
        String auth = request.getHeader("Authorization");
        return (auth != null && auth.startsWith("Basic"));
    

【讨论】:

以上是关于Spring Security OAuth2 和 Ldap 对同一资源的身份验证的主要内容,如果未能解决你的问题,请参考以下文章

使用 spring-session 和 spring-cloud-security 时,OAuth2ClientContext (spring-security-oauth2) 不会保留在 Redis

针对授权标头的Spring Security OAuth2 CORS问题

微服务和 Spring Security OAuth2

Spring Security 解析 —— Spring Security Oauth2 源码解析

带有 Jersey 和 Spring Security OAuth2 的 Spring Boot

Spring Cloud Security[微服务安全](一)初识Spring Cloud Security和OAuth2.0