【问题标题】:Spring Boot Admin Server can't get access to endpoints (Unauthorized 401)Spring Boot Admin Server 无法访问端点(未经授权的 401)
【发布时间】:2019-10-11 13:30:01
【问题描述】:

我已经配置了自己的内存中身份验证配置,并且我的应用程序可以在 Spring Boot 管理服务器上注册自己,并且服务器会获得正确的凭据,但它仍然会从我的应用程序中获得未经授权的响应。如果我在浏览器中输入凭据,它就会起作用。

@Configuration
@Order(2)
public class ActuatorSecurity extends WebSecurityConfigurerAdapter {
  @Value("${spring.boot.admin.client.instance.metadata.user.name:actuator}")
  private String actuatorName;
  @Value("${spring.boot.admin.client.instance.metadata.user.password:secret}")
  private String actuatorPassword;

  @Override
  protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth.inMemoryAuthentication().withUser(actuatorName).password("{noop}" + actuatorPassword).authorities("ACTUATOR");
  }

  @Override
  public void configure(HttpSecurity http) throws Exception {
    http
            .antMatcher("/actuator/**")
            .authorizeRequests()
            .anyRequest().hasAuthority("ACTUATOR")
            .and()
            .httpBasic();
  }
}

spring-boot-admin-dashboard

有效的浏览器请求和导致 401 的 Spring-Boot-Admin 请求之间的区别在于 BasicAuthenticationFilter 在浏览器尝试中获取标头,但在 Spring-Boot-Admin 尝试中 BasicAuthenticationFilter 不读取任何内容标头并导致匿名用户。

有什么想法吗?

【问题讨论】:

    标签: spring-boot spring-boot-admin


    【解决方案1】:

    我遇到了类似的问题,并使用以下示例(来自文档)解决了。

    @Bean
    public HttpHeadersProvider customHttpHeadersProvider() {
        return  instance -> {
            HttpHeaders httpHeaders = new HttpHeaders();
            httpHeaders.add("Authorization", "My Custom Value");
            return httpHeaders;
        };
    }
    

    如果您需要将自定义 HTTP 标头注入到向受监控应用程序的执行器端点发出的请求中,您可以轻松添加 HttpHeadersProvider

    参考: Injecting Custom HTTP Headers

    【讨论】:

      【解决方案2】:

      一种解决方法是您使用自定义标题为 /actuator/** 路径构建自己的过滤器,如下所示:

      在应用方面:

      @Configuration
      @Order(2)
      public class ActuatorSecurity extends WebSecurityConfigurerAdapter {
      
        public static String name = "actuator-admin";
        public static String pw = "actuator-pw";
      
        public static String headerName = "ACTUATOR_HEADER_NAME";
        public static String headerPw = "ACTUATOR_HEADER_PW";
      
      
        protected String getActuatorFilterUrl() {
          return "/actuator/" + "**";
        }
      
        @Override
        protected void configure(HttpSecurity httpSecurity) throws Exception {
          httpSecurity
                  .cors()
                  .and()
                  // we don't need CSRF because our token is invulnerable
                  .csrf().disable()
                  // All urls must be authenticated (filter for token always fires (/**)
                  .antMatcher(getActuatorFilterUrl())
      
                  .authorizeRequests()
                  .antMatchers(HttpMethod.OPTIONS).permitAll()
                  .antMatchers(getActuatorFilterUrl()).authenticated()
      
                  .and()
                  .addFilterBefore(new ActuatorSecurityFilter(getActuatorFilterUrl(), name, pw, headerName, headerPw),
                          UsernamePasswordAuthenticationFilter.class)
                  .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
        }
      }
      
      public class ActuatorSecurityFilter extends AbstractAuthenticationProcessingFilter {
      
        private String name;
        private String pw;
      
        private String headerName;
        private String headerPw;
      
        public ActuatorSecurityFilter(String filterUrl, String name, String pw, String headerName, String headerPw) {
          super(filterUrl);
          this.name = name;
          this.pw = pw;
      
          this.headerName = headerName;
          this.headerPw = headerPw;
        }
      
        @Override
        public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse httpServletResponse) throws AuthenticationException, IOException, ServletException {
          final String name = request.getHeader(headerName);
          final String pw = request.getHeader(headerPw);
      
          if (name.equals(this.name) && pw.equals(this.pw)) {
            return new Authentication() {
              @Override
              public Collection<? extends GrantedAuthority> getAuthorities() {
                return new ArrayList<>();
              }
      
              @Override
              public Object getCredentials() {
                return null;
              }
      
              @Override
              public Object getDetails() {
                return null;
              }
      
              @Override
              public Object getPrincipal() {
                return null;
              }
      
              @Override
              public boolean isAuthenticated() {
                return true;
              }
      
              @Override
              public void setAuthenticated(boolean b) throws IllegalArgumentException {
      
              }
      
              @Override
              public String getName() {
                return null;
              }
            };
          }
          throw new IllegalStateException("name or pw wrong");
        }
      
        @Override
        protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult)
                throws IOException, ServletException {
      
          SecurityContextHolder.getContext().setAuthentication(authResult);
      
          // As this authentication is in HTTP header, after success we need to continue the request normally
          // and return the response as if the resource was not secured at all
          chain.doFilter(request, response);
        }
      }
      

      在 Spring-Admin 方面:

      @Configuration
      public class CUstomHeaderConf {
      
        @Bean
        public HttpHeadersProvider customHttpHeadersProvider() {
          return  instance -> {
            HttpHeaders httpHeaders = new HttpHeaders();
            httpHeaders.add("ACTUATOR_HEADER_NAME", "actuator-admin");
            httpHeaders.add("ACTUATOR_HEADER_PW", "actuator-pw");
            return httpHeaders;
          };
        }
      }
      

      【讨论】:

        猜你喜欢
        • 2021-02-02
        • 2021-04-07
        • 2022-11-09
        • 2021-01-24
        • 2022-01-21
        • 2020-10-22
        • 1970-01-01
        • 2022-11-08
        • 1970-01-01
        相关资源
        最近更新 更多