我已经配置了自己的内存中身份验证配置,并且我的应用程序可以在Spring Boot Admin Server上注册自己,并且服务器获得了正确的凭据,但是仍然会从我的应用程序获得未经授权的响应。如果我在浏览器中输入凭据,那么它将起作用。
@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();
}
}
有效的浏览器请求与导致401的Spring-Boot-Admin请求之间的区别在于,“ BasicAuthenticationFilter”在brwoser尝试中获得了标头,但是在Spring-Boot-Admin尝试中,“ BasicAuthenticationFilter”却不读任何标头,并且导致匿名用户。有什么想法吗?
答案 0 :(得分:1)
我遇到了类似的问题,并使用下面的示例(来自文档)解决了该问题。
@Bean
public HttpHeadersProvider customHttpHeadersProvider() {
return instance -> {
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.add("Authorization", "My Custom Value");
return httpHeaders;
};
}
如果您需要将自定义HTTP标头注入到对受监视应用程序的执行器端点的请求中,则可以轻松添加
HttpHeadersProvider
答案 1 :(得分:0)
一种解决方法是,使用自定义标头为/ 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;
};
}
}