View Javadoc
1   package cn.home1.cloud.config.server.security;
2   
3   import static cn.home1.cloud.config.server.security.Role.ACTUATOR;
4   import static cn.home1.cloud.config.server.security.Role.ADMIN;
5   import static cn.home1.cloud.config.server.security.Role.HOOK;
6   import static org.springframework.security.config.http.SessionCreationPolicy.STATELESS;
7   
8   import org.springframework.beans.factory.annotation.Autowired;
9   import org.springframework.beans.factory.annotation.Value;
10  import org.springframework.boot.actuate.autoconfigure.security.servlet.EndpointRequest;
11  import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
12  import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
13  import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
14  import org.springframework.boot.autoconfigure.security.SecurityDataConfiguration;
15  import org.springframework.boot.autoconfigure.security.SecurityProperties;
16  import org.springframework.boot.autoconfigure.security.servlet.PathRequest;
17  import org.springframework.boot.autoconfigure.security.servlet.SpringBootWebSecurityConfiguration;
18  import org.springframework.boot.autoconfigure.security.servlet.WebSecurityEnablerConfiguration;
19  import org.springframework.boot.context.properties.EnableConfigurationProperties;
20  import org.springframework.cloud.config.server.config.ConfigServerProperties;
21  import org.springframework.cloud.config.server.environment.EnvironmentController;
22  import org.springframework.context.ApplicationEventPublisher;
23  import org.springframework.context.annotation.Bean;
24  import org.springframework.context.annotation.Configuration;
25  import org.springframework.context.annotation.Import;
26  import org.springframework.core.annotation.Order;
27  import org.springframework.security.authentication.AuthenticationEventPublisher;
28  import org.springframework.security.authentication.DefaultAuthenticationEventPublisher;
29  import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
30  import org.springframework.security.config.annotation.web.builders.HttpSecurity;
31  import org.springframework.security.config.annotation.web.builders.WebSecurity;
32  import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
33  import org.springframework.security.crypto.password.NoOpPasswordEncoder;
34  
35  /**
36   * see: https://github.com/spring-projects/spring-boot/issues/12323
37   * see: {@link org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration}
38   * see: https://spring.io/blog/2017/09/15/security-changes-in-spring-boot-2-0-m4
39   */
40  @Configuration
41  @ConditionalOnClass(DefaultAuthenticationEventPublisher.class)
42  @ConditionalOnProperty(prefix = "spring.security", name = "enabled", havingValue = "true")
43  @EnableConfigurationProperties(SecurityProperties.class)
44  @Import({SpringBootWebSecurityConfiguration.class, WebSecurityEnablerConfiguration.class,
45      SecurityDataConfiguration.class})
46  public class ApplicationSecurityAutoConfiguration {
47  
48      @Bean
49      @ConditionalOnMissingBean(AuthenticationEventPublisher.class)
50      public DefaultAuthenticationEventPublisher authenticationEventPublisher(
51          ApplicationEventPublisher publisher) {
52          return new DefaultAuthenticationEventPublisher(publisher);
53      }
54  
55      @ConditionalOnProperty(prefix = "spring.security", name = "enabled", havingValue = "true")
56      @Configuration
57      @Order(SecurityProperties.BASIC_AUTH_ORDER)
58      //@Order(ApplicationSecurityAutoConfiguration.ACCESS_OVERRIDE_ORDER)
59      static class ApplicationWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {
60  
61  //  /**
62  //   * org.springframework.boot.autoconfigure.security.SecurityProperties.ACCESS_OVERRIDE_ORDER
63  //   *
64  //   * TODO deprecated in spring-boot 2.x
65  //   */
66  //  public static final int ACCESS_OVERRIDE_ORDER = 2147483640;
67  
68          @Autowired
69          private ConfigSecurity configSecurity;
70  
71          @Autowired
72          private ConfigServerProperties configServerProperties;
73  
74          @Autowired
75          private EnvironmentController environmentController;
76  
77          /**
78           * TODO rename
79           */
80          @Value("${management.endpoints.web.base-path:}")
81          private String managementContextPath;
82  
83          @Override
84          public void init(final WebSecurity web) throws Exception {
85              super.init(web);
86          }
87  
88          @Override
89          protected void configure(final AuthenticationManagerBuilder auth) throws Exception {
90              auth.userDetailsService(this.userDetailsService()).passwordEncoder(NoOpPasswordEncoder.getInstance());
91          }
92  
93          @Override
94          protected void configure(final HttpSecurity http) throws Exception {
95              final String configServerPrefix = this.configServerProperties.getPrefix();
96              //final String loginEndpoint = configServerPrefix + "/users/login";
97              final String monitorEndpoint = configServerPrefix + "/monitor";
98  
99              //super.configure(http); // default config
100             http //
101                 .authorizeRequests() //
102                 .requestMatchers(EndpointRequest.to("health", "info")).permitAll() //
103                 .requestMatchers(EndpointRequest.toAnyEndpoint()).hasRole(ACTUATOR.toString()) //
104                 .requestMatchers(PathRequest.toStaticResources().atCommonLocations()).permitAll() //
105                 .antMatchers(configServerPrefix + "/").permitAll() //
106                 .antMatchers(configServerPrefix + "/deployKeyPublic").permitAll() //
107                 .antMatchers(configServerPrefix + "/decrypt").hasRole(ADMIN.toString()) //
108                 .antMatchers(configServerPrefix + "/encrypt", monitorEndpoint).permitAll() //
109                 .antMatchers(configServerPrefix + "/encryptParentPassword").hasRole(ADMIN.toString()) //
110                 .antMatchers(configServerPrefix + "/monitor").hasAnyRole(ADMIN.toString(), HOOK.toString()) //
111                 .antMatchers(new String[]{ //
112                     configServerPrefix + "/{application}/{profiles:.*[^-].*}", //
113                     configServerPrefix + "/{application}/{profiles}/{label:.*}", //
114                     configServerPrefix + "/{application}-{profiles}.json", //
115                     configServerPrefix + "/{label}/{application}-{profiles}.json", //
116                     configServerPrefix + "/{application}-{profiles}.properties", //
117                     configServerPrefix + "/{application}/{name}-{profiles}.properties", //
118                     configServerPrefix + "/{application}-{profiles}.yml", //
119                     configServerPrefix + "/{application}-{profiles}.yaml", //
120                     configServerPrefix + "/{label}/{application}-{profiles}.yml", //
121                     configServerPrefix + "/{label}/{application}-{profiles}.yaml", //
122                     configServerPrefix + "/{application}/{profiles}/{label}/**", //
123                 }).access("@applicationConfigSecurity.checkAuthentication(#application,#profiles)")//
124                 .anyRequest().hasRole(ADMIN.toString()) //
125                 //.antMatchers("/**").hasRole(USER.toString()) //
126                 .and() //
127                 .csrf().disable() //
128                 .formLogin().disable() //
129                 .httpBasic().and() //
130                 .sessionManagement().sessionCreationPolicy(STATELESS).and() //
131             ;
132         }
133 
134         @Bean
135         public ApplicationConfigSecurity applicationConfigSecurity() {
136             return new ApplicationConfigSecurity();
137         }
138 
139         @Bean
140         public PrivilegedUserProperties privilegedUserProperties() {
141             return new PrivilegedUserProperties();
142         }
143 
144         @Bean
145         public GitFileConfigUserDetailsService userDetailsService() {
146             final GitFileConfigUserDetailsService userDetailsService = new GitFileConfigUserDetailsService();
147             userDetailsService.setConfigSecurity(this.configSecurity);
148             userDetailsService.setDefaultLabel(this.configServerProperties.getDefaultLabel());
149             userDetailsService.setPrivilegedUserProperties(this.privilegedUserProperties());
150             userDetailsService.setEnvironmentController(this.environmentController);
151             return userDetailsService;
152         }
153     }
154 }