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

Posted

技术标签:

【中文标题】针对不同端点的多个用户详细信息服务【英文标题】:Multiple user details services for different endpoints 【发布时间】:2018-09-02 04:24:03 【问题描述】:

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

@Override
protected void configure(HttpSecurity http) throws Exception 
    http.authorizeRequests().anyRequest().authenticated().and().httpBasic();

我还设置了一个DaoAuthenticationProvider 来使用我的用户详细信息服务并使用它来配置全局安全性。

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

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

【问题讨论】:

【参考方案1】:

您可以做的一件事是拥有两个WebSecurityConfigurerAdapters:

@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() 用于将springSecurityFilterChains 定位到特定端点。

编辑:Mahmoud Odeh 提出了一个很好的观点,即如果用户群相同,那么您可能不需要多个 UserDetailsService 实例。相反,您可以使用一项更改,通过用户帐户上的权限来隔离您的特殊端点:

http
    .authorizeRequests()
        .antMatchers("/specialendpoint").hasAuthority("SPECIAL")
        .anyRequest().authenticated()
        .and()
    .httpBasic();

然后,您的单个 UserDetailsService 将查找所有用户。对于有权访问/specialendpoint 的用户,它将在UserDetails 实例中包含SPECIAL GrantedAuthority

【讨论】:

您能否看看这个问题:***.com/questions/57686645/… 我遇到了同样的问题,并且在每个 spring 安全配置中指定不同的 userDetailService 对我不起作用。谢谢 谢谢我知道了...我已经分享了@98​​7654322@ @surajbahl,很乐意提供帮助,但听起来您应该提出自己的问题 @surajbahl,我建议你开始一个新问题。在另一个人的问题中提出你自己独特的问题,尤其是作为答案,可能会让未来的访问者非常困惑。 谢谢@MahmoudOdeh,我根据您的反馈添加了替代解决方案。由于问题是如何支持两个UserDetailsServices,我认为将其作为第一个答案仍然是有意义的;但是,正如您所说,在许多情况下,用户群的重叠和单独的UserDetailsServices 是不必要的。【参考方案2】:

我正在尝试遵循 M. Deinum 给出的解决方案,但在我的情况下,无论执行哪个 URL /v3/authorize/login 或 /v2/authorize/login,它总是转到相同的用户服务 (v2userDetailsS​​ervice)。这是我的代码:

@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();
    

  

【讨论】:

你能解决这个问题吗?我有点陷入同样的​​境地。 我也是。卡了几个小时:(

以上是关于针对不同端点的多个用户详细信息服务的主要内容,如果未能解决你的问题,请参考以下文章

具有多个grant_type的Spring Oauth2授权服务器用户信息端点不起作用

spring-security-oauth2 JwkTokenStore 与自定义用户详细信息服务

如何自定义Spring 授权服务器的 UserInfo 端点

Spring boot actuator:当其他执行器的端点受到保护时,健康端点未显示详细信息

用于复合 API 调用的 Spring Cloud Zuul?

Spring 安全客户端详细信息将作为 DaoAuthenticationProvider 中的用户详细信息