Spring 不同端点的多个用户详细信息服务

Spring 不同端点的多个用户详细信息服务,spring,spring-boot,spring-security,basic-authentication,Spring,Spring Boot,Spring Security,Basic Authentication,我正在使用Spring构建REST API,目前正在使用自定义用户详细信息服务和以下配置代码验证我的所有请求: @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests().anyRequest().authenticated().and().httpBasic(); } 我还设置了一个DaoAuthenticationProvider来使用“我的用户详

我正在使用Spring构建REST API,目前正在使用自定义用户详细信息服务和以下配置代码验证我的所有请求:

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.authorizeRequests().anyRequest().authenticated().and().httpBasic();
}
我还设置了一个
DaoAuthenticationProvider
来使用“我的用户详细信息”服务,并使用它来配置全局安全性

现在,我想提供一个端点(尽管仍然使用HTTP基本身份验证进行保护),该端点使用不同的用户详细信息服务来检查是否允许用户访问给定的资源


如何为不同的端点使用两个不同的用户详细信息服务?

您可以做的一件事是使用两个
websecurityConfigureAdapter
s:

@EnableWebSecurity
@Order(Ordered.HIGHEST_PRECEDENCE)
class FirstEndpointConfiguration extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) {
        http
            .requestMatchers()
                .antMatchers("/specialendpoint")
                .and()
            .authorizeRequests()
                .anyRequest().authenticated()
                .and()
            .httpBasic();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) {
        auth.userDetailsService(/* first of your userDetailsServices */);
    }
}


@Configuration
class SecondEndpointConfiguration extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) {
        http // all other requests handled here
            .authorizeRequests()
                .anyRequest().authenticated()
                .and()
            .httpBasic();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) {
        auth.userDetailsService(/* second of your userDetailsServices */);
    }
}
requestMatchers()
用于将
springSecurityFilterChain
s定位到特定端点

编辑:马哈茂德·奥德(Mahmoud Odeh)指出,如果用户基础相同,则可能不需要多个
userdetails服务
实例。相反,您可以使用一个更改,通过用户帐户上的权限隔离您的特殊端点:

http
.授权请求()
.antMatchers(“/specialendpoint”).hasAuthority(“特殊”)
.anyRequest().authenticated()
.及()
.httpBasic();

然后,您的单个
userdetails服务将查找所有用户。它将在
UserDetails
实例中包含
SPECIAL
,供有权访问
/specialendpoint

的用户使用。我试图遵循M.Deinum给出的解决方案,但在我的情况下,它总是指向同一个用户服务(v2userDetailsService)无论执行哪个URL/v3/authorize/login或/v2/authorize/login。这是我的密码:

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class SecurityConfiguration {


  @Configuration
  @Order(2)
  public static class V2Configuration extends WebSecurityConfigurerAdapter {

    @Autowired
    @Qualifier("v2userDetailsService")
    private UserDetailsService v2userDetailsService;

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

    @Override
    public void configure(AuthenticationManagerBuilder auth) throws Exception {
      ShaPasswordEncoder passwordEncoder = new ShaPasswordEncoder(256);
      auth
              .userDetailsService(v2userDetailsService)
              .passwordEncoder(passwordEncoder);
    }


    @Override
    protected void configure(HttpSecurity http) throws Exception {
      http.exceptionHandling().authenticationEntryPoint(authenticationEntryPoint).and().csrf().disable().headers()
              .frameOptions().disable().and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
              .authorizeRequests()
              .antMatchers("/app").permitAll()
              .antMatchers("/v2/authorize/login").permitAll()
              .antMatchers("/v2/authorize/reLogin").permitAll()
              .antMatchers("/v2/authorize/logout").permitAll();
    }

  }



  @Configuration
  @Order(1)
  public static class V3Configuration extends WebSecurityConfigurerAdapter {
    @Autowired
    @Qualifier("v3UserDetailsService")
    private UserDetailsService v3UserDetailsService;

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

    @Override
    public void configure(AuthenticationManagerBuilder auth) throws Exception {
      ShaPasswordEncoder passwordEncoder = new ShaPasswordEncoder(256);
      auth
              .userDetailsService(v3UserDetailsService)
              .passwordEncoder(passwordEncoder);
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
      http.exceptionHandling().authenticationEntryPoint(authenticationEntryPoint).and().csrf().disable().headers()
              .frameOptions().disable().and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
              .authorizeRequests()
                          .antMatchers("/v3/authorize/login").permitAll()
                          .antMatchers("/v3/authorize/reLogin").permitAll()
                          .antMatchers("/v3/authorize/logout").permitAll();
    }

  }
}

你能看看这个问题吗:我有同样的问题,在每个spring安全配置中指定不同的userDetailService对我不起作用。谢谢汉克斯,伙计,我明白了。。。我已经分享了@surajbahl,很乐意帮忙,但听起来你应该打开自己的大门question@surajbahl,我建议你开始一个新问题。在别人的问题中问你自己独特的问题,尤其是作为回答,可能会让未来的访问者很困惑。谢谢,@MahmoudOdeh,我根据你的反馈添加了一个替代解决方案。既然问题是如何支持两个
UserDetailsService
s,我认为将其作为第一个答案仍然是有意义的;但是,正如您所说,在许多情况下,用户群重叠,因此不需要单独的
UserDetailsService
s。您能解决这个问题吗?我也陷入了同样的境地。