Fix management security when using different port

Update ManagementWebSecurityAutoConfiguration to reinstate lazy creation
of EndpointHandlerMapping from the EndpointPathRequestMatcher.

Fixes a regression introduced in eb2984781 and picked up my one of the
sample integration tests.

Fixes gh-4059
pull/4022/merge
Phillip Webb 9 years ago
parent 7801a3879e
commit 5cbb81c64f

@ -152,8 +152,8 @@ public class ManagementWebSecurityAutoConfiguration {
List<String> ignored = SpringBootWebSecurityConfiguration List<String> ignored = SpringBootWebSecurityConfiguration
.getIgnored(this.security); .getIgnored(this.security);
if (!this.management.getSecurity().isEnabled()) { if (!this.management.getSecurity().isEnabled()) {
ignored.addAll(Arrays.asList(EndpointPaths ignored.addAll(Arrays.asList(EndpointPaths.ALL
.get(this.endpointHandlerMapping))); .getPaths(this.endpointHandlerMapping)));
} }
if (ignored.contains("none")) { if (ignored.contains("none")) {
ignored.remove("none"); ignored.remove("none");
@ -230,7 +230,7 @@ public class ManagementWebSecurityAutoConfiguration {
this.endpointHandlerMapping = endpointHandlerMapping; this.endpointHandlerMapping = endpointHandlerMapping;
} }
protected final void deduceEndpointHandlerMappingIfMissing() { protected final EndpointHandlerMapping getRequiredEndpointHandlerMapping() {
if (this.endpointHandlerMapping == null) { if (this.endpointHandlerMapping == null) {
ApplicationContext context = (this.contextResolver == null ? null ApplicationContext context = (this.contextResolver == null ? null
: this.contextResolver.getApplicationContext()); : this.contextResolver.getApplicationContext());
@ -244,6 +244,7 @@ public class ManagementWebSecurityAutoConfiguration {
Collections.<MvcEndpoint>emptySet()); Collections.<MvcEndpoint>emptySet());
} }
} }
return this.endpointHandlerMapping;
} }
@Override @Override
@ -282,8 +283,7 @@ public class ManagementWebSecurityAutoConfiguration {
return matcher; return matcher;
} }
// Match everything, including the sensitive and non-sensitive paths // Match everything, including the sensitive and non-sensitive paths
return new EndpointPathRequestMatcher( return new EndpointPathRequestMatcher(EndpointPaths.ALL);
EndpointPaths.get(this.endpointHandlerMapping));
} }
private AuthenticationEntryPoint entryPoint() { private AuthenticationEntryPoint entryPoint() {
@ -296,26 +296,24 @@ public class ManagementWebSecurityAutoConfiguration {
ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry requests) { ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry requests) {
// Permit access to the non-sensitive endpoints // Permit access to the non-sensitive endpoints
requests.requestMatchers( requests.requestMatchers(
new EndpointPathRequestMatcher(EndpointPaths.get( new EndpointPathRequestMatcher(EndpointPaths.NON_SENSITIVE))
this.endpointHandlerMapping, false))).permitAll(); .permitAll();
// Restrict the rest to the configured role // Restrict the rest to the configured role
requests.anyRequest().hasRole(this.management.getSecurity().getRole()); requests.anyRequest().hasRole(this.management.getSecurity().getRole());
} }
private final class EndpointPathRequestMatcher implements RequestMatcher { private final class EndpointPathRequestMatcher implements RequestMatcher {
private RequestMatcher delegate; private final EndpointPaths endpointPaths;
private String[] paths; private RequestMatcher delegate;
EndpointPathRequestMatcher(String[] paths) { EndpointPathRequestMatcher(EndpointPaths endpointPaths) {
this.paths = paths; this.endpointPaths = endpointPaths;
} }
@Override @Override
public boolean matches(HttpServletRequest request) { public boolean matches(HttpServletRequest request) {
ManagementWebSecurityConfigurerAdapter.this
.deduceEndpointHandlerMappingIfMissing();
if (this.delegate == null) { if (this.delegate == null) {
this.delegate = createDelegate(); this.delegate = createDelegate();
} }
@ -325,7 +323,9 @@ public class ManagementWebSecurityAutoConfiguration {
private RequestMatcher createDelegate() { private RequestMatcher createDelegate() {
ServerProperties server = ManagementWebSecurityConfigurerAdapter.this.server; ServerProperties server = ManagementWebSecurityConfigurerAdapter.this.server;
List<RequestMatcher> matchers = new ArrayList<RequestMatcher>(); List<RequestMatcher> matchers = new ArrayList<RequestMatcher>();
for (String path : this.paths) { EndpointHandlerMapping endpointHandlerMapping = ManagementWebSecurityConfigurerAdapter.this
.getRequiredEndpointHandlerMapping();
for (String path : this.endpointPaths.getPaths(endpointHandlerMapping)) {
matchers.add(new AntPathRequestMatcher(server.getPath(path))); matchers.add(new AntPathRequestMatcher(server.getPath(path)));
} }
return (matchers.isEmpty() ? AnyRequestMatcher.INSTANCE return (matchers.isEmpty() ? AnyRequestMatcher.INSTANCE
@ -336,43 +336,29 @@ public class ManagementWebSecurityAutoConfiguration {
} }
/** private enum EndpointPaths {
* Helper class for extracting lists of paths from the EndpointHandlerMapping.
*/ ALL,
private static class EndpointPaths {
/**
* Get all the paths (sensitive and unsensitive).
*
* @param endpointHandlerMapping the mapping
* @return all paths
*/
public static String[] get(EndpointHandlerMapping endpointHandlerMapping) {
String[] insecure = get(endpointHandlerMapping, false);
String[] secure = get(endpointHandlerMapping, true);
return StringUtils.mergeStringArrays(insecure, secure);
}
/** NON_SENSITIVE {
* Get all the paths that are either sensitive or unsensitive. @Override
* protected boolean isIncluded(MvcEndpoint endpoint) {
* @param endpointHandlerMapping the mapping return !endpoint.isSensitive();
* @param secure flag to say if we want the secure ones }
* @return the relevant paths };
*/
public static String[] get(EndpointHandlerMapping endpointHandlerMapping, public String[] getPaths(EndpointHandlerMapping endpointHandlerMapping) {
boolean secure) {
if (endpointHandlerMapping == null) { if (endpointHandlerMapping == null) {
return NO_PATHS; return NO_PATHS;
} }
Set<? extends MvcEndpoint> endpoints = endpointHandlerMapping.getEndpoints(); Set<? extends MvcEndpoint> endpoints = endpointHandlerMapping.getEndpoints();
Set<String> paths = new LinkedHashSet<String>(endpoints.size()); Set<String> paths = new LinkedHashSet<String>(endpoints.size());
for (MvcEndpoint endpoint : endpoints) { for (MvcEndpoint endpoint : endpoints) {
if (endpoint.isSensitive() == secure) { if (isIncluded(endpoint)) {
String path = endpointHandlerMapping.getPath(endpoint.getPath()); String path = endpointHandlerMapping.getPath(endpoint.getPath());
paths.add(path); paths.add(path);
if (!path.equals("")) { if (!path.equals("")) {
if (secure) { if (endpoint.isSensitive()) {
// Ensure that nested paths are secured // Ensure that nested paths are secured
paths.add(path + "/**"); paths.add(path + "/**");
// Add Spring MVC-generated additional paths // Add Spring MVC-generated additional paths
@ -385,6 +371,10 @@ public class ManagementWebSecurityAutoConfiguration {
return paths.toArray(new String[paths.size()]); return paths.toArray(new String[paths.size()]);
} }
protected boolean isIncluded(MvcEndpoint endpoint) {
return true;
}
} }
} }

Loading…
Cancel
Save