|
|
@ -33,6 +33,7 @@ import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
|
|
|
import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties;
|
|
|
|
import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties;
|
|
|
|
import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
|
|
|
|
import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
|
|
|
|
import org.springframework.boot.actuate.endpoint.web.PathMappedEndpoints;
|
|
|
|
import org.springframework.boot.actuate.endpoint.web.PathMappedEndpoints;
|
|
|
|
|
|
|
|
import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletPathProvider;
|
|
|
|
import org.springframework.boot.security.servlet.ApplicationContextRequestMatcher;
|
|
|
|
import org.springframework.boot.security.servlet.ApplicationContextRequestMatcher;
|
|
|
|
import org.springframework.core.annotation.AnnotationUtils;
|
|
|
|
import org.springframework.core.annotation.AnnotationUtils;
|
|
|
|
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
|
|
|
|
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
|
|
|
@ -40,6 +41,7 @@ import org.springframework.security.web.util.matcher.OrRequestMatcher;
|
|
|
|
import org.springframework.security.web.util.matcher.RequestMatcher;
|
|
|
|
import org.springframework.security.web.util.matcher.RequestMatcher;
|
|
|
|
import org.springframework.util.Assert;
|
|
|
|
import org.springframework.util.Assert;
|
|
|
|
import org.springframework.util.StringUtils;
|
|
|
|
import org.springframework.util.StringUtils;
|
|
|
|
|
|
|
|
import org.springframework.web.context.WebApplicationContext;
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* Factory that can be used to create a {@link RequestMatcher} for actuator endpoint
|
|
|
|
* Factory that can be used to create a {@link RequestMatcher} for actuator endpoint
|
|
|
@ -114,7 +116,7 @@ public final class EndpointRequest {
|
|
|
|
* The request matcher used to match against {@link Endpoint actuator endpoints}.
|
|
|
|
* The request matcher used to match against {@link Endpoint actuator endpoints}.
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
public static final class EndpointRequestMatcher
|
|
|
|
public static final class EndpointRequestMatcher
|
|
|
|
extends ApplicationContextRequestMatcher<PathMappedEndpoints> {
|
|
|
|
extends ApplicationContextRequestMatcher<WebApplicationContext> {
|
|
|
|
|
|
|
|
|
|
|
|
private final List<Object> includes;
|
|
|
|
private final List<Object> includes;
|
|
|
|
|
|
|
|
|
|
|
@ -140,7 +142,7 @@ public final class EndpointRequest {
|
|
|
|
|
|
|
|
|
|
|
|
private EndpointRequestMatcher(List<Object> includes, List<Object> excludes,
|
|
|
|
private EndpointRequestMatcher(List<Object> includes, List<Object> excludes,
|
|
|
|
boolean includeLinks) {
|
|
|
|
boolean includeLinks) {
|
|
|
|
super(PathMappedEndpoints.class);
|
|
|
|
super(WebApplicationContext.class);
|
|
|
|
this.includes = includes;
|
|
|
|
this.includes = includes;
|
|
|
|
this.excludes = excludes;
|
|
|
|
this.excludes = excludes;
|
|
|
|
this.includeLinks = includeLinks;
|
|
|
|
this.includeLinks = includeLinks;
|
|
|
@ -163,32 +165,40 @@ public final class EndpointRequest {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
@Override
|
|
|
|
protected void initialized(Supplier<PathMappedEndpoints> pathMappedEndpoints) {
|
|
|
|
protected void initialized(
|
|
|
|
this.delegate = createDelegate(pathMappedEndpoints);
|
|
|
|
Supplier<WebApplicationContext> webApplicationContext) {
|
|
|
|
|
|
|
|
this.delegate = createDelegate(webApplicationContext);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private RequestMatcher createDelegate(
|
|
|
|
private RequestMatcher createDelegate(
|
|
|
|
Supplier<PathMappedEndpoints> pathMappedEndpoints) {
|
|
|
|
Supplier<WebApplicationContext> webApplicationContext) {
|
|
|
|
try {
|
|
|
|
try {
|
|
|
|
return createDelegate(pathMappedEndpoints.get());
|
|
|
|
WebApplicationContext context = webApplicationContext.get();
|
|
|
|
|
|
|
|
PathMappedEndpoints pathMappedEndpoints = context
|
|
|
|
|
|
|
|
.getBean(PathMappedEndpoints.class);
|
|
|
|
|
|
|
|
DispatcherServletPathProvider pathProvider = context
|
|
|
|
|
|
|
|
.getBean(DispatcherServletPathProvider.class);
|
|
|
|
|
|
|
|
return createDelegate(pathMappedEndpoints, pathProvider.getServletPath());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
catch (NoSuchBeanDefinitionException ex) {
|
|
|
|
catch (NoSuchBeanDefinitionException ex) {
|
|
|
|
return EMPTY_MATCHER;
|
|
|
|
return EMPTY_MATCHER;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private RequestMatcher createDelegate(PathMappedEndpoints pathMappedEndpoints) {
|
|
|
|
private RequestMatcher createDelegate(PathMappedEndpoints pathMappedEndpoints,
|
|
|
|
|
|
|
|
String servletPath) {
|
|
|
|
Set<String> paths = new LinkedHashSet<>();
|
|
|
|
Set<String> paths = new LinkedHashSet<>();
|
|
|
|
if (this.includes.isEmpty()) {
|
|
|
|
if (this.includes.isEmpty()) {
|
|
|
|
paths.addAll(pathMappedEndpoints.getAllPaths());
|
|
|
|
paths.addAll(pathMappedEndpoints.getAllPaths());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
streamPaths(this.includes, pathMappedEndpoints).forEach(paths::add);
|
|
|
|
streamPaths(this.includes, pathMappedEndpoints).forEach(paths::add);
|
|
|
|
streamPaths(this.excludes, pathMappedEndpoints).forEach(paths::remove);
|
|
|
|
streamPaths(this.excludes, pathMappedEndpoints).forEach(paths::remove);
|
|
|
|
List<RequestMatcher> delegateMatchers = getDelegateMatchers(paths);
|
|
|
|
List<RequestMatcher> delegateMatchers = getDelegateMatchers(servletPath,
|
|
|
|
|
|
|
|
paths);
|
|
|
|
if (this.includeLinks
|
|
|
|
if (this.includeLinks
|
|
|
|
&& StringUtils.hasText(pathMappedEndpoints.getBasePath())) {
|
|
|
|
&& StringUtils.hasText(pathMappedEndpoints.getBasePath())) {
|
|
|
|
delegateMatchers.add(
|
|
|
|
delegateMatchers.add(new AntPathRequestMatcher(
|
|
|
|
new AntPathRequestMatcher(pathMappedEndpoints.getBasePath()));
|
|
|
|
servletPath + pathMappedEndpoints.getBasePath()));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return new OrRequestMatcher(delegateMatchers);
|
|
|
|
return new OrRequestMatcher(delegateMatchers);
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -216,14 +226,16 @@ public final class EndpointRequest {
|
|
|
|
return annotation.id();
|
|
|
|
return annotation.id();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private List<RequestMatcher> getDelegateMatchers(Set<String> paths) {
|
|
|
|
private List<RequestMatcher> getDelegateMatchers(String servletPath,
|
|
|
|
return paths.stream().map((path) -> new AntPathRequestMatcher(path + "/**"))
|
|
|
|
Set<String> paths) {
|
|
|
|
|
|
|
|
return paths.stream()
|
|
|
|
|
|
|
|
.map((path) -> new AntPathRequestMatcher(servletPath + path + "/**"))
|
|
|
|
.collect(Collectors.toList());
|
|
|
|
.collect(Collectors.toList());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
@Override
|
|
|
|
protected boolean matches(HttpServletRequest request,
|
|
|
|
protected boolean matches(HttpServletRequest request,
|
|
|
|
Supplier<PathMappedEndpoints> context) {
|
|
|
|
Supplier<WebApplicationContext> context) {
|
|
|
|
return this.delegate.matches(request);
|
|
|
|
return this.delegate.matches(request);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -233,29 +245,41 @@ public final class EndpointRequest {
|
|
|
|
* The request matcher used to match against the links endpoint.
|
|
|
|
* The request matcher used to match against the links endpoint.
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
public static final class LinksRequestMatcher
|
|
|
|
public static final class LinksRequestMatcher
|
|
|
|
extends ApplicationContextRequestMatcher<WebEndpointProperties> {
|
|
|
|
extends ApplicationContextRequestMatcher<WebApplicationContext> {
|
|
|
|
|
|
|
|
|
|
|
|
private RequestMatcher delegate;
|
|
|
|
private RequestMatcher delegate;
|
|
|
|
|
|
|
|
|
|
|
|
private LinksRequestMatcher() {
|
|
|
|
private LinksRequestMatcher() {
|
|
|
|
super(WebEndpointProperties.class);
|
|
|
|
super(WebApplicationContext.class);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
@Override
|
|
|
|
protected void initialized(Supplier<WebEndpointProperties> properties) {
|
|
|
|
protected void initialized(
|
|
|
|
this.delegate = createDelegate(properties.get());
|
|
|
|
Supplier<WebApplicationContext> webApplicationContext) {
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
|
|
WebApplicationContext context = webApplicationContext.get();
|
|
|
|
|
|
|
|
WebEndpointProperties properties = context
|
|
|
|
|
|
|
|
.getBean(WebEndpointProperties.class);
|
|
|
|
|
|
|
|
DispatcherServletPathProvider pathProvider = context
|
|
|
|
|
|
|
|
.getBean(DispatcherServletPathProvider.class);
|
|
|
|
|
|
|
|
this.delegate = createDelegate(pathProvider.getServletPath(), properties);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
catch (NoSuchBeanDefinitionException ex) {
|
|
|
|
|
|
|
|
this.delegate = EMPTY_MATCHER;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private RequestMatcher createDelegate(WebEndpointProperties properties) {
|
|
|
|
private RequestMatcher createDelegate(String path,
|
|
|
|
|
|
|
|
WebEndpointProperties properties) {
|
|
|
|
if (StringUtils.hasText(properties.getBasePath())) {
|
|
|
|
if (StringUtils.hasText(properties.getBasePath())) {
|
|
|
|
return new AntPathRequestMatcher(properties.getBasePath());
|
|
|
|
return new AntPathRequestMatcher(path + properties.getBasePath());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return EMPTY_MATCHER;
|
|
|
|
return EMPTY_MATCHER;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
@Override
|
|
|
|
protected boolean matches(HttpServletRequest request,
|
|
|
|
protected boolean matches(HttpServletRequest request,
|
|
|
|
Supplier<WebEndpointProperties> context) {
|
|
|
|
Supplier<WebApplicationContext> context) {
|
|
|
|
return this.delegate.matches(request);
|
|
|
|
return this.delegate.matches(request);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|