代码之家  ›  专栏  ›  技术社区  ›  PatPanda

Spring Security-指定哪个X509可以访问哪个特定端点

  •  0
  • PatPanda  · 技术社区  · 5 年前

    关于如何使用Spring Security指定哪个客户端证书可以访问哪个特定的预定义端点的小问题,请。

    预定义端点是指web应用程序具有默认端点(不是我通过@RestController定义的端点),如执行器端点 /actuator/health , /actuator/prometheus ,或Spring Cloud Config端点,例如 /config/myservice/ 不可能 @PreAuthorize .

    我只想指定哪个客户端证书可以访问哪个端点,例如:

    • 客户端证书 UID=Alice 可以访问 /执行器/健康状况 /config/myservice .
    • 客户端证书 UID=Bob 可以访问 /执行器/普罗米修斯

    网上有很多例子, How to extract X509 certificate :

    但是如何在应用程序中配置它,即哪种证书可以访问什么的映射?

    非常感谢。

    0 回复  |  直到 5 年前
        1
  •  0
  •   jccampanero    5 年前

    @塞图给了你解决问题的基本信息。

    请考虑以下代码,该代码改编自 one of the articles 你引用了:

    @SpringBootApplication
    @EnableWebSecurity
    @EnableGlobalMethodSecurity(prePostEnabled = true)
    public class X509AuthenticationServer extends WebSecurityConfigurerAdapter {
      ...
    
      @Override
      protected void configure(HttpSecurity http) throws Exception {
        http
          .authorizeRequests()
            // Define the mapping between the different endpoints
            // and the corresponding user roles
            .antMatchers("/actuator/health").hasRole("ACTUATOR_HEALTH")
            .antMatchers("/actuator/prometheus").hasRole("ACTUATOR_PROMETEUS")
            .antMatchers("/config/myservice").hasRole("CONFIG_MYSERVICE")
            // Please, adjust the fallback as appropriate
            .anyRequest().authenticated()
          .and()
            // Configure X509Configurer (https://docs.spring.io/spring-security/site/docs/current/api/org/springframework/security/config/annotation/web/configurers/X509Configurer.html)
            .x509()
              .subjectPrincipalRegex("CN=(.*?)(?:,|$)")
              .userDetailsService(userDetailsService())
        ;
      }
    
      @Bean
      public UserDetailsService userDetailsService() {
        // Ideally this information will be obtained from a database or some
        // configuration information
        return new UserDetailsService() {
    
          @Override
          public UserDetails loadUserByUsername(String username) {
    
            Objects.requireNonNull(username);
    
            List<GrantedAuthority> authorities = null;
            switch (username) {
              // Match the different X509 certificate CNs. Maybe you can use the
              // X509 certificate subject distinguished name to include the role in
              // some way and obtain it directly with the subjectPrincipalRegex
              case "Alice":
                authorities = AuthorityUtils
                  .commaSeparatedStringToAuthorityList("ROLE_ACTUATOR_HEALTH, ROLE_CONFIG_MYSERVICE");
                break;
    
              case "Bob":
                authorities = AuthorityUtils
                  .commaSeparatedStringToAuthorityList("ROLE_ACTUATOR_PROMETHEUS");
                break;
    
              default:
                throw new UsernameNotFoundException(String.format("User '%s' not found!", username));
            }
    
            return new User(username, "", authorities);
          }
        };
      }
    }
    

    请根据需要调整代码,以满足您的实际端点和用户。