This commit is contained in:
Phillip Webb 2017-08-28 15:29:36 -07:00
parent b02edd2e81
commit 2c97d3a5e9
143 changed files with 689 additions and 655 deletions

View File

@ -26,6 +26,8 @@ import org.springframework.context.annotation.Conditional;
/**
* {@link Conditional} that matches based on the configuration of the management port.
*
* @since 2.0.0
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.TYPE, ElementType.METHOD })

View File

@ -35,6 +35,10 @@ import org.springframework.context.annotation.Import;
@Import(ManagementContextConfigurationImportSelector.class)
@interface EnableManagementContext {
/**
* The management context type that should be enabled.
* @return the management context type
*/
ManagementContextType value();
}

View File

@ -37,6 +37,7 @@ import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.Environment;
import org.springframework.core.env.PropertySource;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.util.Assert;
import org.springframework.web.context.ConfigurableWebApplicationContext;
/**
@ -58,7 +59,7 @@ public class ManagementContextAutoConfiguration {
@Bean
public ManagementServletContext managementServletContext(
final ManagementServerProperties properties) {
ManagementServerProperties properties) {
return () -> properties.getContextPath();
}
@ -86,12 +87,11 @@ public class ManagementContextAutoConfiguration {
}
private void verifySslConfiguration() {
if (this.environment.getProperty("management.ssl.enabled", Boolean.class,
false)) {
throw new IllegalStateException(
"Management-specific SSL cannot be configured as the management "
+ "server is not listening on a separate port");
}
Boolean enabled = this.environment.getProperty("management.ssl.enabled",
Boolean.class, false);
Assert.state(!enabled,
"Management-specific SSL cannot be configured as the management "
+ "server is not listening on a separate port");
}
private void verifyContextPathConfiguration() {
@ -112,6 +112,7 @@ public class ManagementContextAutoConfiguration {
ConfigurableEnvironment environment) {
environment.getPropertySources()
.addLast(new PropertySource<Object>("Management Server") {
@Override
public Object getProperty(String name) {
if ("local.management.port".equals(name)) {
@ -119,6 +120,7 @@ public class ManagementContextAutoConfiguration {
}
return null;
}
});
}

View File

@ -122,8 +122,8 @@ class ManagementContextConfigurationImportSelector
Map<String, Object> annotationAttributes = annotationMetadata
.getAnnotationAttributes(
ManagementContextConfiguration.class.getName());
return annotationAttributes == null ? ManagementContextType.ANY
: (ManagementContextType) annotationAttributes.get("value");
return (annotationAttributes == null ? ManagementContextType.ANY
: (ManagementContextType) annotationAttributes.get("value"));
}
private int readOrder(AnnotationMetadata annotationMetadata) {

View File

@ -27,7 +27,13 @@ import org.springframework.context.ConfigurableApplicationContext;
*/
interface ManagementContextFactory {
/**
* Create the management application context.
* @param parent the parent context
* @param configurationClasses the configuration classes
* @return a configured application context
*/
ConfigurableApplicationContext createManagementContext(ApplicationContext parent,
Class<?>... configClasses);
Class<?>... configurationClasses);
}

View File

@ -18,6 +18,12 @@ package org.springframework.boot.actuate.autoconfigure;
import org.springframework.core.env.Environment;
/**
* Port types that can be used to control how the management server is started.
*
* @author Andy Wilkinson
* @since 2.0.0
*/
public enum ManagementPortType {
/**

View File

@ -78,8 +78,8 @@ import org.springframework.web.servlet.handler.AbstractHandlerMethodMapping;
* @author Eddú Meléndez
* @author Meang Akira Tanaka
* @author Ben Hale
* @since 2.0.0
* @author Andy Wilkinson
* @since 2.0.0
*/
@Configuration
@AutoConfigureAfter({ FlywayAutoConfiguration.class, LiquibaseAutoConfiguration.class })

View File

@ -20,8 +20,8 @@ import org.springframework.boot.actuate.autoconfigure.web.ManagementServerProper
import org.springframework.boot.endpoint.EndpointPathResolver;
/**
* {@link EndpointPathResolver} implementation for resolving
* actuator endpoint paths based on the endpoint id and management.context-path.
* {@link EndpointPathResolver} implementation for resolving actuator endpoint paths based
* on the endpoint id and management.context-path.
*
* @author Madhura Bhave
* @since 2.0.0
@ -38,5 +38,5 @@ public class ManagementEndpointPathResolver implements EndpointPathResolver {
public String resolvePath(String endpointId) {
return this.contextPath + "/" + endpointId;
}
}
}

View File

@ -51,9 +51,8 @@ class DefaultEndpointObjectNameFactory implements EndpointObjectNameFactory {
@Override
public ObjectName generate(EndpointMBean mBean) throws MalformedObjectNameException {
String baseObjectName = this.properties.getDomain() +
":type=Endpoint" +
",name=" + StringUtils.capitalize(mBean.getEndpointId());
String baseObjectName = this.properties.getDomain() + ":type=Endpoint" + ",name="
+ StringUtils.capitalize(mBean.getEndpointId());
StringBuilder builder = new StringBuilder(baseObjectName);
if (this.mBeanServer != null && hasMBean(baseObjectName)) {
builder.append(",context=").append(this.contextId);
@ -76,7 +75,8 @@ class DefaultEndpointObjectNameFactory implements EndpointObjectNameFactory {
}
StringBuilder builder = new StringBuilder();
for (Map.Entry<Object, Object> name : this.properties.getStaticNames().entrySet()) {
for (Map.Entry<Object, Object> name : this.properties.getStaticNames()
.entrySet()) {
builder.append(",").append(name.getKey()).append("=").append(name.getValue());
}
return builder.toString();

View File

@ -71,17 +71,20 @@ public class EndpointInfrastructureAutoConfiguration {
@Bean
public OperationParameterMapper operationParameterMapper() {
DefaultConversionService conversionService = new DefaultConversionService();
conversionService.addConverter(String.class, Date.class, (string) -> {
if (StringUtils.hasLength(string)) {
OffsetDateTime offsetDateTime = OffsetDateTime.parse(string,
DateTimeFormatter.ISO_OFFSET_DATE_TIME);
return new Date(offsetDateTime.toEpochSecond() * 1000);
}
return null;
});
conversionService.addConverter(String.class, Date.class, this::convertToDate);
return new ConversionServiceOperationParameterMapper(conversionService);
}
private Date convertToDate(String value) {
if (StringUtils.hasLength(value)) {
OffsetDateTime offsetDateTime = OffsetDateTime.parse(value,
DateTimeFormatter.ISO_OFFSET_DATE_TIME);
return new Date(offsetDateTime.toEpochSecond() * 1000);
}
return null;
}
@Bean
public CachingConfigurationFactory cacheConfigurationFactory() {
return new CachingConfigurationFactory(this.applicationContext.getEnvironment());

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2015 the original author or authors.
* Copyright 2012-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2015 the original author or authors.
* Copyright 2012-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@ -61,8 +61,9 @@ public class EndpointEnablementProvider {
public EndpointEnablement getEndpointEnablement(String endpointId,
boolean enabledByDefault, EndpointExposure exposure) {
Assert.hasText(endpointId, "Endpoint id must have a value");
Assert.isTrue(!endpointId.equals("default"), "Endpoint id 'default' is a reserved "
+ "value and cannot be used by an endpoint");
Assert.isTrue(!endpointId.equals("default"),
"Endpoint id 'default' is a reserved "
+ "value and cannot be used by an endpoint");
EndpointEnablement result = findEnablement(endpointId, exposure);
if (result != null) {
return result;
@ -76,8 +77,7 @@ public class EndpointEnablementProvider {
if (!enabledByDefault) {
return getDefaultEndpointEnablement(endpointId, false, exposure);
}
return getGlobalEndpointEnablement(endpointId, enabledByDefault,
exposure);
return getGlobalEndpointEnablement(endpointId, enabledByDefault, exposure);
}
private EndpointEnablement findEnablement(String endpointId,
@ -98,12 +98,10 @@ public class EndpointEnablementProvider {
if (result != null) {
return result;
}
return getDefaultEndpointEnablement(endpointId, enabledByDefault,
exposure);
return getDefaultEndpointEnablement(endpointId, enabledByDefault, exposure);
}
private EndpointEnablement findGlobalEndpointEnablement(
EndpointExposure exposure) {
private EndpointEnablement findGlobalEndpointEnablement(EndpointExposure exposure) {
if (exposure != null) {
EndpointEnablement result = findEnablement(getKey("default", exposure));
if (result != null) {
@ -136,8 +134,8 @@ public class EndpointEnablementProvider {
private EndpointEnablement getDefaultEndpointEnablement(String endpointId,
boolean enabledByDefault, EndpointExposure exposure) {
return new EndpointEnablement(enabledByDefault, createDefaultEnablementMessage(
endpointId, enabledByDefault, exposure));
return new EndpointEnablement(enabledByDefault,
createDefaultEnablementMessage(endpointId, enabledByDefault, exposure));
}
private String createDefaultEnablementMessage(String endpointId,
@ -145,8 +143,7 @@ public class EndpointEnablementProvider {
StringBuilder message = new StringBuilder();
message.append(String.format("endpoint '%s' ", endpointId));
if (exposure != null) {
message.append(
String.format("(%s) ", exposure.name().toLowerCase()));
message.append(String.format("(%s) ", exposure.name().toLowerCase()));
}
message.append(String.format("is %s by default",
(enabledByDefault ? "enabled" : "disabled")));

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2015 the original author or authors.
* Copyright 2012-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2015 the original author or authors.
* Copyright 2012-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@ -32,12 +32,10 @@ import org.springframework.web.servlet.mvc.ServletWrappingController;
/**
* {@link ManagementContextConfiguration} for embedding Jolokia, a JMX-HTTP bridge giving
* an alternative to JSR-160 connectors.
*
* <p>
* This configuration will get automatically enabled as soon as the Jolokia
* {@link AgentServlet} is on the classpath. To disable it set
* {@code management.jolokia.enabled=false}.
*
* <p>
* Additional configuration parameters for Jolokia can be provided by specifying
* {@code management.jolokia.config.*} properties. See the

View File

@ -31,6 +31,7 @@ import org.springframework.security.config.annotation.web.configuration.EnableWe
* Security configuration for management endpoints.
*
* @author Madhura Bhave
* @since 2.0.0
*/
@Configuration
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
@ -39,9 +40,9 @@ import org.springframework.security.config.annotation.web.configuration.EnableWe
public class ManagementWebSecurityAutoConfiguration {
@Bean
public EndpointPathResolver managementEndpointPathResolver(ManagementServerProperties properties) {
public EndpointPathResolver managementEndpointPathResolver(
ManagementServerProperties properties) {
return new ManagementEndpointPathResolver(properties);
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2016 the original author or authors.
* Copyright 2012-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@ -66,32 +66,33 @@ public class CloudFoundryActuatorAutoConfiguration {
@Bean
public CloudFoundryWebEndpointServletHandlerMapping cloudFoundryWebEndpointServletHandlerMapping(
EndpointProvider<WebEndpointOperation> provider,
Environment environment, RestTemplateBuilder builder) {
CloudFoundryWebEndpointServletHandlerMapping handlerMapping = new CloudFoundryWebEndpointServletHandlerMapping(
EndpointProvider<WebEndpointOperation> provider, Environment environment,
RestTemplateBuilder builder) {
return new CloudFoundryWebEndpointServletHandlerMapping(
"/cloudfoundryapplication", provider.getEndpoints(),
getCorsConfiguration(), getSecurityInterceptor(builder, environment));
return handlerMapping;
}
private CloudFoundrySecurityInterceptor getSecurityInterceptor(
RestTemplateBuilder restTemplateBuilder, Environment environment) {
CloudFoundrySecurityService cloudfoundrySecurityService = getCloudFoundrySecurityService(
restTemplateBuilder, environment);
TokenValidator tokenValidator = new TokenValidator(cloudfoundrySecurityService);
return new CloudFoundrySecurityInterceptor(
tokenValidator, cloudfoundrySecurityService,
TokenValidator tokenValidator = new TokenValidator(
cloudfoundrySecurityService);
return new CloudFoundrySecurityInterceptor(tokenValidator,
cloudfoundrySecurityService,
environment.getProperty("vcap.application.application_id"));
}
private CloudFoundrySecurityService getCloudFoundrySecurityService(
RestTemplateBuilder restTemplateBuilder, Environment environment) {
String cloudControllerUrl = environment.getProperty("vcap.application.cf_api");
String cloudControllerUrl = environment
.getProperty("vcap.application.cf_api");
boolean skipSslValidation = environment.getProperty(
"management.cloudfoundry.skip-ssl-validation", Boolean.class, false);
return cloudControllerUrl == null ? null
: new CloudFoundrySecurityService(restTemplateBuilder, cloudControllerUrl,
skipSslValidation);
return (cloudControllerUrl == null ? null
: new CloudFoundrySecurityService(restTemplateBuilder,
cloudControllerUrl, skipSslValidation));
}
private CorsConfiguration getCorsConfiguration() {
@ -107,9 +108,9 @@ public class CloudFoundryActuatorAutoConfiguration {
}
/**
* {@link WebSecurityConfigurer} to tell Spring Security to
* ignore cloudfoundry specific paths. The Cloud foundry endpoints
* are protected by their own security interceptor.
* {@link WebSecurityConfigurer} to tell Spring Security to ignore cloudfoundry
* specific paths. The Cloud foundry endpoints are protected by their own security
* interceptor.
*/
@ConditionalOnClass(WebSecurity.class)
@Order(SecurityProperties.IGNORED_ORDER)
@ -119,7 +120,8 @@ public class CloudFoundryActuatorAutoConfiguration {
@Override
public void init(WebSecurity builder) throws Exception {
builder.ignoring().requestMatchers(new AntPathRequestMatcher("/cloudfoundryapplication/**"));
builder.ignoring().requestMatchers(
new AntPathRequestMatcher("/cloudfoundryapplication/**"));
}
@Override

View File

@ -52,18 +52,19 @@ class CloudFoundrySecurityInterceptor {
this.applicationId = applicationId;
}
SecurityResponse preHandle(HttpServletRequest request,
String endpointId) {
SecurityResponse preHandle(HttpServletRequest request, String endpointId) {
if (CorsUtils.isPreFlightRequest(request)) {
return SecurityResponse.success();
}
try {
if (!StringUtils.hasText(this.applicationId)) {
throw new CloudFoundryAuthorizationException(CloudFoundryAuthorizationException.Reason.SERVICE_UNAVAILABLE,
throw new CloudFoundryAuthorizationException(
CloudFoundryAuthorizationException.Reason.SERVICE_UNAVAILABLE,
"Application id is not available");
}
if (this.cloudFoundrySecurityService == null) {
throw new CloudFoundryAuthorizationException(CloudFoundryAuthorizationException.Reason.SERVICE_UNAVAILABLE,
throw new CloudFoundryAuthorizationException(
CloudFoundryAuthorizationException.Reason.SERVICE_UNAVAILABLE,
"Cloud controller URL is not available");
}
if (HttpMethod.OPTIONS.matches(request.getMethod())) {
@ -75,21 +76,23 @@ class CloudFoundrySecurityInterceptor {
logger.error(ex);
if (ex instanceof CloudFoundryAuthorizationException) {
CloudFoundryAuthorizationException cfException = (CloudFoundryAuthorizationException) ex;
return new SecurityResponse(cfException.getStatusCode(), "{\"security_error\":\"" + cfException.getMessage() + "\"}");
return new SecurityResponse(cfException.getStatusCode(),
"{\"security_error\":\"" + cfException.getMessage() + "\"}");
}
return new SecurityResponse(HttpStatus.INTERNAL_SERVER_ERROR, ex.getMessage());
return new SecurityResponse(HttpStatus.INTERNAL_SERVER_ERROR,
ex.getMessage());
}
return SecurityResponse.success();
}
private void check(HttpServletRequest request, String path)
throws Exception {
private void check(HttpServletRequest request, String path) throws Exception {
Token token = getToken(request);
this.tokenValidator.validate(token);
AccessLevel accessLevel = this.cloudFoundrySecurityService
.getAccessLevel(token.toString(), this.applicationId);
if (!accessLevel.isAccessAllowed(path)) {
throw new CloudFoundryAuthorizationException(CloudFoundryAuthorizationException.Reason.ACCESS_DENIED,
throw new CloudFoundryAuthorizationException(
CloudFoundryAuthorizationException.Reason.ACCESS_DENIED,
"Access denied");
}
accessLevel.put(request);
@ -100,7 +103,8 @@ class CloudFoundrySecurityInterceptor {
String bearerPrefix = "bearer ";
if (authorization == null
|| !authorization.toLowerCase().startsWith(bearerPrefix)) {
throw new CloudFoundryAuthorizationException(CloudFoundryAuthorizationException.Reason.MISSING_AUTHORIZATION,
throw new CloudFoundryAuthorizationException(
CloudFoundryAuthorizationException.Reason.MISSING_AUTHORIZATION,
"Authorization header is missing or invalid");
}
return new Token(authorization.substring(bearerPrefix.length()));
@ -116,7 +120,7 @@ class CloudFoundrySecurityInterceptor {
private final String message;
SecurityResponse(HttpStatus status) {
this (status, null);
this(status, null);
}
SecurityResponse(HttpStatus status, String message) {
@ -135,7 +139,7 @@ class CloudFoundrySecurityInterceptor {
static SecurityResponse success() {
return new SecurityResponse(HttpStatus.OK);
}
}
}

View File

@ -50,18 +50,20 @@ import org.springframework.web.servlet.HandlerMapping;
import org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping;
/**
* A custom {@link RequestMappingInfoHandlerMapping} that makes web endpoints available
* on Cloudfoundry specific URLS over HTTP using Spring MVC.
* A custom {@link RequestMappingInfoHandlerMapping} that makes web endpoints available on
* Cloudfoundry specific URLS over HTTP using Spring MVC.
*
* @author Madhura Bhave
*/
class CloudFoundryWebEndpointServletHandlerMapping extends AbstractWebEndpointServletHandlerMapping {
class CloudFoundryWebEndpointServletHandlerMapping
extends AbstractWebEndpointServletHandlerMapping {
private final Method handle = ReflectionUtils.findMethod(OperationHandler.class,
"handle", HttpServletRequest.class, Map.class);
private final Method links = ReflectionUtils.findMethod(
CloudFoundryWebEndpointServletHandlerMapping.class, "links", HttpServletRequest.class, HttpServletResponse.class);
CloudFoundryWebEndpointServletHandlerMapping.class, "links",
HttpServletRequest.class, HttpServletResponse.class);
private static final Log logger = LogFactory
.getLog(CloudFoundryWebEndpointServletHandlerMapping.class);
@ -70,7 +72,10 @@ class CloudFoundryWebEndpointServletHandlerMapping extends AbstractWebEndpointSe
private final EndpointLinksResolver endpointLinksResolver = new EndpointLinksResolver();
CloudFoundryWebEndpointServletHandlerMapping(String endpointPath, Collection<EndpointInfo<WebEndpointOperation>> webEndpoints, CorsConfiguration corsConfiguration, CloudFoundrySecurityInterceptor securityInterceptor) {
CloudFoundryWebEndpointServletHandlerMapping(String endpointPath,
Collection<EndpointInfo<WebEndpointOperation>> webEndpoints,
CorsConfiguration corsConfiguration,
CloudFoundrySecurityInterceptor securityInterceptor) {
super(endpointPath, webEndpoints, corsConfiguration);
this.securityInterceptor = securityInterceptor;
}
@ -81,27 +86,32 @@ class CloudFoundryWebEndpointServletHandlerMapping extends AbstractWebEndpointSe
}
@ResponseBody
private Map<String, Map<String, Link>> links(HttpServletRequest request, HttpServletResponse response) {
CloudFoundrySecurityInterceptor.SecurityResponse securityResponse = this.securityInterceptor.preHandle(request, "");
private Map<String, Map<String, Link>> links(HttpServletRequest request,
HttpServletResponse response) {
CloudFoundrySecurityInterceptor.SecurityResponse securityResponse = this.securityInterceptor
.preHandle(request, "");
if (!securityResponse.getStatus().equals(HttpStatus.OK)) {
sendFailureResponse(response, securityResponse);
}
AccessLevel accessLevel = AccessLevel.get(request);
Map<String, Link> links = this.endpointLinksResolver
.resolveLinks(getEndpoints(), request.getRequestURL().toString());
Map<String, Link> links = this.endpointLinksResolver.resolveLinks(getEndpoints(),
request.getRequestURL().toString());
Map<String, Link> filteredLinks = new LinkedHashMap<>();
if (accessLevel == null) {
return Collections.singletonMap("_links", filteredLinks);
}
filteredLinks = links.entrySet().stream()
.filter(e -> e.getKey().equals("self") || accessLevel.isAccessAllowed(e.getKey()))
.filter(e -> e.getKey().equals("self")
|| accessLevel.isAccessAllowed(e.getKey()))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
return Collections.singletonMap("_links", filteredLinks);
}
private void sendFailureResponse(HttpServletResponse response, CloudFoundrySecurityInterceptor.SecurityResponse securityResponse) {
private void sendFailureResponse(HttpServletResponse response,
CloudFoundrySecurityInterceptor.SecurityResponse securityResponse) {
try {
response.sendError(securityResponse.getStatus().value(), securityResponse.getMessage());
response.sendError(securityResponse.getStatus().value(),
securityResponse.getMessage());
}
catch (Exception ex) {
logger.debug("Failed to send error response", ex);
@ -111,7 +121,9 @@ class CloudFoundryWebEndpointServletHandlerMapping extends AbstractWebEndpointSe
@Override
protected void registerMappingForOperation(WebEndpointOperation operation) {
registerMapping(createRequestMappingInfo(operation),
new OperationHandler(operation.getInvoker(), operation.getId(), this.securityInterceptor), this.handle);
new OperationHandler(operation.getInvoker(), operation.getId(),
this.securityInterceptor),
this.handle);
}
/**
@ -125,7 +137,8 @@ class CloudFoundryWebEndpointServletHandlerMapping extends AbstractWebEndpointSe
private final CloudFoundrySecurityInterceptor securityInterceptor;
OperationHandler(OperationInvoker operationInvoker, String id, CloudFoundrySecurityInterceptor securityInterceptor) {
OperationHandler(OperationInvoker operationInvoker, String id,
CloudFoundrySecurityInterceptor securityInterceptor) {
this.operationInvoker = operationInvoker;
this.endpointId = id;
this.securityInterceptor = securityInterceptor;
@ -135,7 +148,8 @@ class CloudFoundryWebEndpointServletHandlerMapping extends AbstractWebEndpointSe
@ResponseBody
public Object handle(HttpServletRequest request,
@RequestBody(required = false) Map<String, String> body) {
CloudFoundrySecurityInterceptor.SecurityResponse securityResponse = this.securityInterceptor.preHandle(request, this.endpointId);
CloudFoundrySecurityInterceptor.SecurityResponse securityResponse = this.securityInterceptor
.preHandle(request, this.endpointId);
if (!securityResponse.getStatus().equals(HttpStatus.OK)) {
return failureResponse(securityResponse);
}
@ -155,8 +169,10 @@ class CloudFoundryWebEndpointServletHandlerMapping extends AbstractWebEndpointSe
}
}
private Object failureResponse(CloudFoundrySecurityInterceptor.SecurityResponse response) {
return handleResult(new WebEndpointResponse<>(response.getMessage(), response.getStatus().value()));
private Object failureResponse(
CloudFoundrySecurityInterceptor.SecurityResponse response) {
return handleResult(new WebEndpointResponse<>(response.getMessage(),
response.getStatus().value()));
}
private Object handleResult(Object result) {
@ -179,4 +195,3 @@ class CloudFoundryWebEndpointServletHandlerMapping extends AbstractWebEndpointSe
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2016 the original author or authors.
* Copyright 2012-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -91,4 +91,3 @@ class SkipSslVerificationHttpRequestFactory extends SimpleClientHttpRequestFacto
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2016 the original author or authors.
* Copyright 2012-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@ -32,7 +32,7 @@ import java.util.regex.PatternSyntaxException;
* @author Phillip Webb
* @author Sergei Egorov
* @author Andy Wilkinson
* @since 2.0.0
* @author Dylian Bego
*/
abstract class NamePatternFilter<T> {

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2016 the original author or authors.
* Copyright 2012-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2016 the original author or authors.
* Copyright 2012-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@ -16,7 +16,9 @@
package org.springframework.boot.actuate.endpoint.web;
import java.io.Closeable;
import java.io.File;
import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.management.ManagementFactory;
@ -206,12 +208,7 @@ public class HeapDumpWebEndpoint {
@Override
public void close() throws IOException {
try {
readableChannel.close();
}
finally {
deleteFile();
}
closeThenDeleteFile(readableChannel);
}
@Override
@ -224,62 +221,25 @@ public class HeapDumpWebEndpoint {
@Override
public InputStream getInputStream() throws IOException {
InputStream delegate = super.getInputStream();
return new InputStream() {
@Override
public int read() throws IOException {
return delegate.read();
}
@Override
public int read(byte[] b) throws IOException {
return delegate.read(b);
}
@Override
public int read(byte[] b, int off, int len) throws IOException {
return delegate.read(b, off, len);
}
@Override
public long skip(long n) throws IOException {
return delegate.skip(n);
}
@Override
public int available() throws IOException {
return delegate.available();
}
return new FilterInputStream(super.getInputStream()) {
@Override
public void close() throws IOException {
try {
delegate.close();
}
finally {
deleteFile();
}
}
@Override
public synchronized void mark(int readlimit) {
delegate.mark(readlimit);
}
@Override
public synchronized void reset() throws IOException {
delegate.reset();
}
@Override
public boolean markSupported() {
return delegate.markSupported();
closeThenDeleteFile(this.in);
}
};
}
private void closeThenDeleteFile(Closeable closeable) throws IOException {
try {
closeable.close();
}
finally {
deleteFile();
}
}
private void deleteFile() {
try {
Files.delete(getFile().toPath());

View File

@ -35,8 +35,7 @@ public class HealthIndicatorFactory {
* @return a {@link HealthIndicator} that delegates to the specified
* {@code healthIndicators}.
*/
public HealthIndicator createHealthIndicator(
HealthAggregator healthAggregator,
public HealthIndicator createHealthIndicator(HealthAggregator healthAggregator,
Map<String, HealthIndicator> healthIndicators) {
Assert.notNull(healthAggregator, "HealthAggregator must not be null");
Assert.notNull(healthIndicators, "HealthIndicators must not be null");

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2015 the original author or authors.
* Copyright 2012-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2015 the original author or authors.
* Copyright 2012-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2016 the original author or authors.
* Copyright 2012-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2016 the original author or authors.
* Copyright 2012-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@ -118,10 +118,9 @@ public class ConditionalOnEnabledEndpointTests {
@Test
public void disabledEvenWithEnabledGeneralProperties() {
this.contextRunner.withUserConfiguration(FooConfig.class)
.withPropertyValues("endpoints.default.enabled=true",
"endpoints.default.web.enabled=true",
"endpoints.default.jmx.enabled=true", "endpoints.foo.enabled=false")
this.contextRunner.withUserConfiguration(FooConfig.class).withPropertyValues(
"endpoints.default.enabled=true", "endpoints.default.web.enabled=true",
"endpoints.default.jmx.enabled=true", "endpoints.foo.enabled=false")
.run((context) -> assertThat(context).doesNotHaveBean("foo"));
}

View File

@ -41,7 +41,8 @@ public class DefaultEndpointObjectNameFactoryTests {
private final MockEnvironment environment = new MockEnvironment();
private final JmxEndpointExporterProperties properties = new JmxEndpointExporterProperties(this.environment);
private final JmxEndpointExporterProperties properties = new JmxEndpointExporterProperties(
this.environment);
private final MBeanServer mBeanServer = mock(MBeanServer.class);
@ -50,23 +51,23 @@ public class DefaultEndpointObjectNameFactoryTests {
@Test
public void generateObjectName() {
ObjectName objectName = generateObjectName(endpoint("Test"));
assertThat(objectName.toString()).isEqualTo(
"org.springframework.boot:type=Endpoint,name=Test");
assertThat(objectName.toString())
.isEqualTo("org.springframework.boot:type=Endpoint,name=Test");
}
@Test
public void generateObjectNameWithCapitalizedId() {
ObjectName objectName = generateObjectName(endpoint("test"));
assertThat(objectName.toString()).isEqualTo(
"org.springframework.boot:type=Endpoint,name=Test");
assertThat(objectName.toString())
.isEqualTo("org.springframework.boot:type=Endpoint,name=Test");
}
@Test
public void generateObjectNameWithCustomDomain() {
this.properties.setDomain("com.example.acme");
ObjectName objectName = generateObjectName(endpoint("test"));
assertThat(objectName.toString()).isEqualTo(
"com.example.acme:type=Endpoint,name=Test");
assertThat(objectName.toString())
.isEqualTo("com.example.acme:type=Endpoint,name=Test");
}
@Test
@ -86,17 +87,18 @@ public class DefaultEndpointObjectNameFactoryTests {
ObjectName objectName = generateObjectName(endpoint("test"));
assertThat(objectName.getKeyProperty("counter")).isEqualTo("42");
assertThat(objectName.getKeyProperty("foo")).isEqualTo("bar");
assertThat(objectName.toString()).startsWith(
"org.springframework.boot:type=Endpoint,name=Test,");
assertThat(objectName.toString())
.startsWith("org.springframework.boot:type=Endpoint,name=Test,");
}
@Test
public void generateObjectNameWithDuplicate() throws MalformedObjectNameException {
this.contextId = "testContext";
given(this.mBeanServer.queryNames(new ObjectName(
"org.springframework.boot:type=Endpoint,name=Test,*"), null))
.willReturn(Collections.singleton(
new ObjectName("org.springframework.boot:type=Endpoint,name=Test")));
given(this.mBeanServer.queryNames(
new ObjectName("org.springframework.boot:type=Endpoint,name=Test,*"),
null)).willReturn(
Collections.singleton(new ObjectName(
"org.springframework.boot:type=Endpoint,name=Test")));
ObjectName objectName = generateObjectName(endpoint("test"));
assertThat(objectName.toString()).isEqualTo(
"org.springframework.boot:type=Endpoint,name=Test,context=testContext");

View File

@ -57,25 +57,18 @@ public class WebMvcEndpointInfrastructureAutoConfigurationTests {
@Test
public void webEndpointsAreDisabledByDefault() {
this.contextRunner.run(context -> {
MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(context).build();
assertThat(isExposed(mockMvc, HttpMethod.GET, "/application/autoconfig"))
.isFalse();
assertThat(isExposed(mockMvc, HttpMethod.GET, "/application/beans")).isFalse();
assertThat(isExposed(mockMvc, HttpMethod.GET, "/application/configprops"))
.isFalse();
assertThat(isExposed(mockMvc, HttpMethod.GET, "/application/env")).isFalse();
assertThat(isExposed(mockMvc, HttpMethod.GET, "/application/health"))
.isFalse();
assertThat(isExposed(mockMvc, HttpMethod.GET, "/application/info")).isFalse();
assertThat(isExposed(mockMvc, HttpMethod.GET, "/application/mappings"))
.isFalse();
assertThat(isExposed(mockMvc, HttpMethod.GET, "/application/metrics"))
.isFalse();
assertThat(isExposed(mockMvc, HttpMethod.POST, "/application/shutdown"))
.isFalse();
assertThat(isExposed(mockMvc, HttpMethod.GET, "/application/threaddump"))
.isFalse();
assertThat(isExposed(mockMvc, HttpMethod.GET, "/application/trace")).isFalse();
MockMvc mvc = MockMvcBuilders.webAppContextSetup(context).build();
assertThat(isExposed(mvc, HttpMethod.GET, "autoconfig")).isFalse();
assertThat(isExposed(mvc, HttpMethod.GET, "beans")).isFalse();
assertThat(isExposed(mvc, HttpMethod.GET, "configprops")).isFalse();
assertThat(isExposed(mvc, HttpMethod.GET, "env")).isFalse();
assertThat(isExposed(mvc, HttpMethod.GET, "health")).isFalse();
assertThat(isExposed(mvc, HttpMethod.GET, "info")).isFalse();
assertThat(isExposed(mvc, HttpMethod.GET, "mappings")).isFalse();
assertThat(isExposed(mvc, HttpMethod.GET, "metrics")).isFalse();
assertThat(isExposed(mvc, HttpMethod.POST, "shutdown")).isFalse();
assertThat(isExposed(mvc, HttpMethod.GET, "threaddump")).isFalse();
assertThat(isExposed(mvc, HttpMethod.GET, "trace")).isFalse();
});
}
@ -84,60 +77,45 @@ public class WebMvcEndpointInfrastructureAutoConfigurationTests {
WebApplicationContextRunner contextRunner = this.contextRunner
.withPropertyValues("endpoints.default.web.enabled=true");
contextRunner.run(context -> {
MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(context).build();
assertThat(isExposed(mockMvc, HttpMethod.GET, "/application/autoconfig"))
.isTrue();
assertThat(isExposed(mockMvc, HttpMethod.GET, "/application/beans"))
.isTrue();
assertThat(isExposed(mockMvc, HttpMethod.GET, "/application/configprops"))
.isTrue();
assertThat(isExposed(mockMvc, HttpMethod.GET, "/application/env")).isTrue();
assertThat(isExposed(mockMvc, HttpMethod.GET, "/application/health"))
.isTrue();
assertThat(isExposed(mockMvc, HttpMethod.GET, "/application/info")).isTrue();
assertThat(isExposed(mockMvc, HttpMethod.GET, "/application/mappings"))
.isTrue();
assertThat(isExposed(mockMvc, HttpMethod.GET, "/application/metrics"))
.isTrue();
assertThat(isExposed(mockMvc, HttpMethod.POST, "/application/shutdown"))
.isFalse();
assertThat(isExposed(mockMvc, HttpMethod.GET, "/application/threaddump"))
.isTrue();
assertThat(isExposed(mockMvc, HttpMethod.GET, "/application/trace"))
.isTrue();
MockMvc mvc = MockMvcBuilders.webAppContextSetup(context).build();
assertThat(isExposed(mvc, HttpMethod.GET, "autoconfig")).isTrue();
assertThat(isExposed(mvc, HttpMethod.GET, "beans")).isTrue();
assertThat(isExposed(mvc, HttpMethod.GET, "configprops")).isTrue();
assertThat(isExposed(mvc, HttpMethod.GET, "env")).isTrue();
assertThat(isExposed(mvc, HttpMethod.GET, "health")).isTrue();
assertThat(isExposed(mvc, HttpMethod.GET, "info")).isTrue();
assertThat(isExposed(mvc, HttpMethod.GET, "mappings")).isTrue();
assertThat(isExposed(mvc, HttpMethod.GET, "metrics")).isTrue();
assertThat(isExposed(mvc, HttpMethod.POST, "shutdown")).isFalse();
assertThat(isExposed(mvc, HttpMethod.GET, "threaddump")).isTrue();
assertThat(isExposed(mvc, HttpMethod.GET, "trace")).isTrue();
});
}
@Test
public void singleWebEndpointCanBeEnabled() {
WebApplicationContextRunner contextRunner = this.contextRunner.withPropertyValues(
"endpoints.default.web.enabled=false", "endpoints.beans.web.enabled=true");
"endpoints.default.web.enabled=false",
"endpoints.beans.web.enabled=true");
contextRunner.run((context) -> {
MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(context).build();
assertThat(isExposed(mockMvc, HttpMethod.GET, "/application/autoconfig"))
.isFalse();
assertThat(isExposed(mockMvc, HttpMethod.GET, "/application/beans")).isTrue();
assertThat(isExposed(mockMvc, HttpMethod.GET, "/application/configprops"))
.isFalse();
assertThat(isExposed(mockMvc, HttpMethod.GET, "/application/env")).isFalse();
assertThat(isExposed(mockMvc, HttpMethod.GET, "/application/health"))
.isFalse();
assertThat(isExposed(mockMvc, HttpMethod.GET, "/application/info")).isFalse();
assertThat(isExposed(mockMvc, HttpMethod.GET, "/application/mappings"))
.isFalse();
assertThat(isExposed(mockMvc, HttpMethod.GET, "/application/metrics"))
.isFalse();
assertThat(isExposed(mockMvc, HttpMethod.POST, "/application/shutdown"))
.isFalse();
assertThat(isExposed(mockMvc, HttpMethod.GET, "/application/threaddump"))
.isFalse();
assertThat(isExposed(mockMvc, HttpMethod.GET, "/application/trace"))
.isFalse();
MockMvc mvc = MockMvcBuilders.webAppContextSetup(context).build();
assertThat(isExposed(mvc, HttpMethod.GET, "autoconfig")).isFalse();
assertThat(isExposed(mvc, HttpMethod.GET, "beans")).isTrue();
assertThat(isExposed(mvc, HttpMethod.GET, "configprops")).isFalse();
assertThat(isExposed(mvc, HttpMethod.GET, "env")).isFalse();
assertThat(isExposed(mvc, HttpMethod.GET, "health")).isFalse();
assertThat(isExposed(mvc, HttpMethod.GET, "info")).isFalse();
assertThat(isExposed(mvc, HttpMethod.GET, "mappings")).isFalse();
assertThat(isExposed(mvc, HttpMethod.GET, "metrics")).isFalse();
assertThat(isExposed(mvc, HttpMethod.POST, "shutdown")).isFalse();
assertThat(isExposed(mvc, HttpMethod.GET, "threaddump")).isFalse();
assertThat(isExposed(mvc, HttpMethod.GET, "trace")).isFalse();
});
}
private boolean isExposed(MockMvc mockMvc, HttpMethod method, String path)
throws Exception {
path = "/application/" + path;
MvcResult mvcResult = mockMvc.perform(request(method, path)).andReturn();
int status = mvcResult.getResponse().getStatus();
if (status == HttpStatus.SC_OK) {

View File

@ -254,9 +254,8 @@ public class EndpointEnablementProviderTests {
@Test
public void specificEnabledOverrideHasNoEffectWithUnrelatedTechProperty() {
validate(
getEndpointEnablement("foo", true, EndpointExposure.JMX,
"endpoints.default.enabled=false", "endpoints.default.web.enabled=true"),
validate(getEndpointEnablement("foo", true, EndpointExposure.JMX,
"endpoints.default.enabled=false", "endpoints.default.web.enabled=true"),
false, "found property endpoints.default.enabled");
}
@ -264,8 +263,8 @@ public class EndpointEnablementProviderTests {
public void specificDisabledWithEndpointPropertyEvenWithEnabledGeneralProperties() {
EndpointEnablement enablement = getEndpointEnablement("foo", true,
EndpointExposure.WEB, "endpoints.default.enabled=true",
"endpoints.default.web.enabled=true", "endpoints.default.jmx.enabled=true",
"endpoints.foo.enabled=false");
"endpoints.default.web.enabled=true",
"endpoints.default.jmx.enabled=true", "endpoints.foo.enabled=false");
validate(enablement, false, "found property endpoints.foo.enabled");
}
@ -273,8 +272,9 @@ public class EndpointEnablementProviderTests {
public void specificDisabledWithTechPropertyEvenWithEnabledGeneralProperties() {
EndpointEnablement enablement = getEndpointEnablement("foo", true,
EndpointExposure.WEB, "endpoints.default.enabled=true",
"endpoints.default.web.enabled=true", "endpoints.default.jmx.enabled=true",
"endpoints.foo.enabled=true", "endpoints.foo.web.enabled=false");
"endpoints.default.web.enabled=true",
"endpoints.default.jmx.enabled=true", "endpoints.foo.enabled=true",
"endpoints.foo.web.enabled=false");
validate(enablement, false, "found property endpoints.foo.web.enabled");
}

View File

@ -73,9 +73,7 @@ public class WebEndpointManagementContextConfigurationTests {
contextRunner.run((context) -> {
HealthWebEndpointExtension extension = context
.getBean(HealthWebEndpointExtension.class);
@SuppressWarnings("unchecked")
Map<String, Integer> statusMappings = ((HealthStatusHttpMapper) ReflectionTestUtils
.getField(extension, "statusHttpMapper")).getStatusMapping();
Map<String, Integer> statusMappings = getStatusMapping(extension);
assertThat(statusMappings).containsEntry("DOWN", 503);
assertThat(statusMappings).containsEntry("OUT_OF_SERVICE", 503);
assertThat(statusMappings).containsEntry("CUSTOM", 500);
@ -102,9 +100,7 @@ public class WebEndpointManagementContextConfigurationTests {
contextRunner.run((context) -> {
StatusWebEndpointExtension extension = context
.getBean(StatusWebEndpointExtension.class);
@SuppressWarnings("unchecked")
Map<String, Integer> statusMappings = ((HealthStatusHttpMapper) ReflectionTestUtils
.getField(extension, "statusHttpMapper")).getStatusMapping();
Map<String, Integer> statusMappings = getStatusMapping(extension);
assertThat(statusMappings).containsEntry("DOWN", 503);
assertThat(statusMappings).containsEntry("OUT_OF_SERVICE", 503);
assertThat(statusMappings).containsEntry("CUSTOM", 500);
@ -161,8 +157,7 @@ public class WebEndpointManagementContextConfigurationTests {
}
private void beanIsAutoConfigured(Class<?> beanType, Class<?>... config) {
contextRunner()
.withPropertyValues("endpoints.default.web.enabled:true")
contextRunner().withPropertyValues("endpoints.default.web.enabled:true")
.withUserConfiguration(config)
.run((context) -> assertThat(context).hasSingleBean(beanType));
}
@ -178,6 +173,11 @@ public class WebEndpointManagementContextConfigurationTests {
AutoConfigurations.of(WebEndpointManagementContextConfiguration.class));
}
private Map<String, Integer> getStatusMapping(Object extension) {
return ((HealthStatusHttpMapper) ReflectionTestUtils.getField(extension,
"statusHttpMapper")).getStatusMapping();
}
@Configuration
static class HealthEndpointConfiguration {

View File

@ -63,28 +63,30 @@ public class JolokiaManagementContextConfigurationTests {
@Test
public void customPath() {
this.contextRunner.withPropertyValues("management.jolokia.enabled=true",
"management.jolokia.path=/lokia").run(
isDefinedOnPath("/application/lokia/*"));
this.contextRunner
.withPropertyValues("management.jolokia.enabled=true",
"management.jolokia.path=/lokia")
.run(isDefinedOnPath("/application/lokia/*"));
}
@Test
public void customManagementPath() {
this.contextRunner.withPropertyValues("management.jolokia.enabled=true",
"management.context-path=/admin").run(
isDefinedOnPath("/admin/jolokia/*"));
this.contextRunner
.withPropertyValues("management.jolokia.enabled=true",
"management.context-path=/admin")
.run(isDefinedOnPath("/admin/jolokia/*"));
}
@Test
public void customInitParameters() {
this.contextRunner.withPropertyValues("management.jolokia.enabled=true",
"management.jolokia.config.debug=true").run((context) -> {
assertThat(context).hasSingleBean(ServletRegistrationBean.class);
ServletRegistrationBean<?> registrationBean = context
.getBean(ServletRegistrationBean.class);
assertThat(registrationBean.getInitParameters())
.containsOnly(entry("debug", "true"));
});
assertThat(context).hasSingleBean(ServletRegistrationBean.class);
ServletRegistrationBean<?> registrationBean = context
.getBean(ServletRegistrationBean.class);
assertThat(registrationBean.getInitParameters())
.containsOnly(entry("debug", "true"));
});
}
private ContextConsumer<AssertableWebApplicationContext> isDefinedOnPath(

View File

@ -385,8 +385,10 @@ public class MetricFilterAutoConfigurationTests {
public void doesNotRecordRolledUpMetricsIfConfigured() throws Exception {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
context.register(Config.class, MetricFilterAutoConfiguration.class);
TestPropertyValues.of("management.metrics.filter.gauge-submissions=",
"management.metrics.filter.counter-submissions=").applyTo(context);
TestPropertyValues
.of("management.metrics.filter.gauge-submissions=",
"management.metrics.filter.counter-submissions=")
.applyTo(context);
context.refresh();
Filter filter = context.getBean(Filter.class);
MockHttpServletRequest request = new MockHttpServletRequest("PUT", "/test/path");

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2016 the original author or authors.
* Copyright 2012-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2016 the original author or authors.
* Copyright 2012-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2016 the original author or authors.
* Copyright 2012-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2016 the original author or authors.
* Copyright 2012-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2016 the original author or authors.
* Copyright 2012-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -39,11 +39,10 @@ final class AuthorizationExceptionMatcher {
public boolean matches(Object object) {
return ((object instanceof CloudFoundryAuthorizationException)
&& ((CloudFoundryAuthorizationException) object)
.getReason() == reason);
.getReason() == reason);
}
};
}
}

View File

@ -59,8 +59,7 @@ public class CloudFoundryActuatorAutoConfigurationTests {
this.context = new AnnotationConfigWebApplicationContext();
this.context.setServletContext(new MockServletContext());
this.context.register(SecurityAutoConfiguration.class,
WebMvcAutoConfiguration.class,
JacksonAutoConfiguration.class,
WebMvcAutoConfiguration.class, JacksonAutoConfiguration.class,
DispatcherServletAutoConfiguration.class,
HttpMessageConvertersAutoConfiguration.class,
PropertyPlaceholderAutoConfiguration.class,
@ -80,7 +79,8 @@ public class CloudFoundryActuatorAutoConfigurationTests {
@Test
public void cloudFoundryPlatformActive() throws Exception {
CloudFoundryWebEndpointServletHandlerMapping handlerMapping = getHandlerMapping();
assertThat(handlerMapping.getEndpointPath()).isEqualTo("/cloudfoundryapplication");
assertThat(handlerMapping.getEndpointPath())
.isEqualTo("/cloudfoundryapplication");
CorsConfiguration corsConfiguration = (CorsConfiguration) ReflectionTestUtils
.getField(handlerMapping, "corsConfiguration");
assertThat(corsConfiguration.getAllowedOrigins()).contains("*");
@ -136,9 +136,9 @@ public class CloudFoundryActuatorAutoConfigurationTests {
.of("VCAP_APPLICATION:---", "vcap.application.application_id:my-app-id")
.applyTo(this.context);
this.context.refresh();
CloudFoundryWebEndpointServletHandlerMapping handlerMapping = this.context.getBean(
"cloudFoundryWebEndpointServletHandlerMapping",
CloudFoundryWebEndpointServletHandlerMapping.class);
CloudFoundryWebEndpointServletHandlerMapping handlerMapping = this.context
.getBean("cloudFoundryWebEndpointServletHandlerMapping",
CloudFoundryWebEndpointServletHandlerMapping.class);
Object securityInterceptor = ReflectionTestUtils.getField(handlerMapping,
"securityInterceptor");
Object interceptorSecurityService = ReflectionTestUtils
@ -152,7 +152,8 @@ public class CloudFoundryActuatorAutoConfigurationTests {
.of("VCAP_APPLICATION:---", "vcap.application.application_id:my-app-id")
.applyTo(this.context);
this.context.refresh();
FilterChainProxy securityFilterChain = (FilterChainProxy) this.context.getBean("springSecurityFilterChain");
FilterChainProxy securityFilterChain = (FilterChainProxy) this.context
.getBean("springSecurityFilterChain");
SecurityFilterChain chain = securityFilterChain.getFilterChains().get(0);
MockHttpServletRequest request = new MockHttpServletRequest();
request.setServletPath("/cloudfoundryapplication/my-path");
@ -165,8 +166,9 @@ public class CloudFoundryActuatorAutoConfigurationTests {
@Test
public void cloudFoundryPlatformInactive() throws Exception {
this.context.refresh();
assertThat(this.context.containsBean("cloudFoundryWebEndpointServletHandlerMapping"))
.isFalse();
assertThat(
this.context.containsBean("cloudFoundryWebEndpointServletHandlerMapping"))
.isFalse();
}
@Test

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2016 the original author or authors.
* Copyright 2012-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@ -23,8 +23,6 @@ import java.util.function.BiConsumer;
import java.util.function.Consumer;
import org.junit.Test;
import org.mockito.BDDMockito;
import org.mockito.Mockito;
import org.springframework.boot.endpoint.CachingConfiguration;
import org.springframework.boot.endpoint.ConversionServiceOperationParameterMapper;
@ -52,39 +50,40 @@ import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.BDDMockito.given;
import static org.mockito.BDDMockito.willThrow;
import static org.mockito.Mockito.mock;
/**
* Integration tests for web endpoints exposed using Spring MVC
* on CloudFoundry.
* Integration tests for web endpoints exposed using Spring MVC on CloudFoundry.
*
* @author Madhura Bhave
*/
public class CloudFoundryMvcWebEndpointIntegrationTests {
private static TokenValidator tokenValidator = Mockito.mock(TokenValidator.class);
private static TokenValidator tokenValidator = mock(TokenValidator.class);
private static CloudFoundrySecurityService securityService = Mockito.mock(CloudFoundrySecurityService.class);
private static CloudFoundrySecurityService securityService = mock(
CloudFoundrySecurityService.class);
@Test
public void operationWithSecurityInterceptorForbidden() throws Exception {
BDDMockito.doNothing().when(tokenValidator).validate(any());
given(securityService.getAccessLevel(any(), eq("app-id"))).willReturn(AccessLevel.RESTRICTED);
given(securityService.getAccessLevel(any(), eq("app-id")))
.willReturn(AccessLevel.RESTRICTED);
load(TestEndpointConfiguration.class, (client) -> {
client.get().uri("/cfApplication/test").accept(MediaType.APPLICATION_JSON)
.header("Authorization", "bearer " + mockAccessToken())
.exchange().expectStatus().isEqualTo(HttpStatus.FORBIDDEN);
.header("Authorization", "bearer " + mockAccessToken()).exchange()
.expectStatus().isEqualTo(HttpStatus.FORBIDDEN);
});
}
@Test
public void operationWithSecurityInterceptorSuccess() throws Exception {
BDDMockito.doNothing().when(tokenValidator).validate(any());
given(securityService.getAccessLevel(any(), eq("app-id"))).willReturn(AccessLevel.FULL);
given(securityService.getAccessLevel(any(), eq("app-id")))
.willReturn(AccessLevel.FULL);
load(TestEndpointConfiguration.class, (client) -> {
client.get().uri("/cfApplication/test").accept(MediaType.APPLICATION_JSON)
.header("Authorization", "bearer " + mockAccessToken())
.exchange().expectStatus().isEqualTo(HttpStatus.OK);
.header("Authorization", "bearer " + mockAccessToken()).exchange()
.expectStatus().isEqualTo(HttpStatus.OK);
});
}
@ -103,14 +102,14 @@ public class CloudFoundryMvcWebEndpointIntegrationTests {
@Test
public void linksToOtherEndpointsWithFullAccess() {
BDDMockito.doNothing().when(tokenValidator).validate(any());
given(securityService.getAccessLevel(any(), eq("app-id"))).willReturn(AccessLevel.FULL);
given(securityService.getAccessLevel(any(), eq("app-id")))
.willReturn(AccessLevel.FULL);
load(TestEndpointConfiguration.class,
(client) -> client.get().uri("/cfApplication").accept(MediaType.APPLICATION_JSON)
.header("Authorization", "bearer " + mockAccessToken())
.exchange().expectStatus().isOk().expectBody()
.jsonPath("_links.length()").isEqualTo(5)
.jsonPath("_links.self.href").isNotEmpty()
(client) -> client.get().uri("/cfApplication")
.accept(MediaType.APPLICATION_JSON)
.header("Authorization", "bearer " + mockAccessToken()).exchange()
.expectStatus().isOk().expectBody().jsonPath("_links.length()")
.isEqualTo(5).jsonPath("_links.self.href").isNotEmpty()
.jsonPath("_links.self.templated").isEqualTo(false)
.jsonPath("_links.info.href").isNotEmpty()
.jsonPath("_links.info.templated").isEqualTo(false)
@ -124,33 +123,35 @@ public class CloudFoundryMvcWebEndpointIntegrationTests {
@Test
public void linksToOtherEndpointsForbidden() {
CloudFoundryAuthorizationException exception = new CloudFoundryAuthorizationException(CloudFoundryAuthorizationException.Reason.INVALID_TOKEN, "invalid-token");
BDDMockito.doThrow(exception).when(tokenValidator).validate(any());
CloudFoundryAuthorizationException exception = new CloudFoundryAuthorizationException(
CloudFoundryAuthorizationException.Reason.INVALID_TOKEN, "invalid-token");
willThrow(exception).given(tokenValidator).validate(any());
load(TestEndpointConfiguration.class,
(client) -> client.get().uri("/cfApplication").accept(MediaType.APPLICATION_JSON)
.header("Authorization", "bearer " + mockAccessToken())
.exchange().expectStatus().isUnauthorized());
(client) -> client.get().uri("/cfApplication")
.accept(MediaType.APPLICATION_JSON)
.header("Authorization", "bearer " + mockAccessToken()).exchange()
.expectStatus().isUnauthorized());
}
@Test
public void linksToOtherEndpointsWithRestrictedAccess() {
BDDMockito.doNothing().when(tokenValidator).validate(any());
given(securityService.getAccessLevel(any(), eq("app-id"))).willReturn(AccessLevel.RESTRICTED);
given(securityService.getAccessLevel(any(), eq("app-id")))
.willReturn(AccessLevel.RESTRICTED);
load(TestEndpointConfiguration.class,
(client) -> client.get().uri("/cfApplication").accept(MediaType.APPLICATION_JSON)
.header("Authorization", "bearer " + mockAccessToken())
.exchange().expectStatus().isOk().expectBody()
.jsonPath("_links.length()").isEqualTo(2)
.jsonPath("_links.self.href").isNotEmpty()
(client) -> client.get().uri("/cfApplication")
.accept(MediaType.APPLICATION_JSON)
.header("Authorization", "bearer " + mockAccessToken()).exchange()
.expectStatus().isOk().expectBody().jsonPath("_links.length()")
.isEqualTo(2).jsonPath("_links.self.href").isNotEmpty()
.jsonPath("_links.self.templated").isEqualTo(false)
.jsonPath("_links.info.href").isNotEmpty()
.jsonPath("_links.info.templated").isEqualTo(false)
.jsonPath("_links.env").doesNotExist()
.jsonPath("_links.test").doesNotExist()
.jsonPath("_links.test-part").doesNotExist());
.jsonPath("_links.env").doesNotExist().jsonPath("_links.test")
.doesNotExist().jsonPath("_links.test-part").doesNotExist());
}
private AnnotationConfigServletWebServerApplicationContext createApplicationContext(Class<?>... config) {
private AnnotationConfigServletWebServerApplicationContext createApplicationContext(
Class<?>... config) {
return new AnnotationConfigServletWebServerApplicationContext(config);
}
@ -159,14 +160,13 @@ public class CloudFoundryMvcWebEndpointIntegrationTests {
}
private void load(Class<?> configuration, Consumer<WebTestClient> clientConsumer) {
BiConsumer<ApplicationContext, WebTestClient> consumer = (context, client) -> clientConsumer.accept(client);
AnnotationConfigServletWebServerApplicationContext context = createApplicationContext(configuration, CloudFoundryMvcConfiguration.class);
BiConsumer<ApplicationContext, WebTestClient> consumer = (context,
client) -> clientConsumer.accept(client);
AnnotationConfigServletWebServerApplicationContext context = createApplicationContext(
configuration, CloudFoundryMvcConfiguration.class);
try {
consumer.accept(context,
WebTestClient.bindToServer()
.baseUrl(
"http://localhost:" + getPort(context))
.build());
consumer.accept(context, WebTestClient.bindToServer()
.baseUrl("http://localhost:" + getPort(context)).build());
}
finally {
context.close();
@ -185,17 +185,20 @@ public class CloudFoundryMvcWebEndpointIntegrationTests {
@Bean
public CloudFoundrySecurityInterceptor interceptor() {
return new CloudFoundrySecurityInterceptor(tokenValidator, securityService, "app-id");
return new CloudFoundrySecurityInterceptor(tokenValidator, securityService,
"app-id");
}
@Bean
public CloudFoundryWebEndpointServletHandlerMapping cloudFoundryWebEndpointServletHandlerMapping(
WebAnnotationEndpointDiscoverer webEndpointDiscoverer, CloudFoundrySecurityInterceptor interceptor) {
WebAnnotationEndpointDiscoverer webEndpointDiscoverer,
CloudFoundrySecurityInterceptor interceptor) {
CorsConfiguration corsConfiguration = new CorsConfiguration();
corsConfiguration.setAllowedOrigins(Arrays.asList("http://example.com"));
corsConfiguration.setAllowedMethods(Arrays.asList("GET", "POST"));
return new CloudFoundryWebEndpointServletHandlerMapping("/cfApplication",
webEndpointDiscoverer.discoverEndpoints(), corsConfiguration, interceptor);
webEndpointDiscoverer.discoverEndpoints(), corsConfiguration,
interceptor);
}
@Bean
@ -302,4 +305,3 @@ public class CloudFoundryMvcWebEndpointIntegrationTests {
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2016 the original author or authors.
* Copyright 2012-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -19,7 +19,6 @@ package org.springframework.boot.actuate.cloudfoundry;
import org.junit.Before;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.BDDMockito;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
@ -30,6 +29,7 @@ import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.util.Base64Utils;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.verify;
/**
@ -62,13 +62,15 @@ public class CloudFoundrySecurityInterceptorTests {
this.request.setMethod("OPTIONS");
this.request.addHeader(HttpHeaders.ORIGIN, "http://example.com");
this.request.addHeader(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD, "GET");
CloudFoundrySecurityInterceptor.SecurityResponse response = this.interceptor.preHandle(this.request, "/a");
CloudFoundrySecurityInterceptor.SecurityResponse response = this.interceptor
.preHandle(this.request, "/a");
assertThat(response.getStatus()).isEqualTo(HttpStatus.OK);
}
@Test
public void preHandleWhenTokenIsMissingShouldReturnFalse() throws Exception {
CloudFoundrySecurityInterceptor.SecurityResponse response = this.interceptor.preHandle(this.request, "/a");
CloudFoundrySecurityInterceptor.SecurityResponse response = this.interceptor
.preHandle(this.request, "/a");
assertThat(response.getStatus())
.isEqualTo(Reason.MISSING_AUTHORIZATION.getStatus());
}
@ -76,7 +78,8 @@ public class CloudFoundrySecurityInterceptorTests {
@Test
public void preHandleWhenTokenIsNotBearerShouldReturnFalse() throws Exception {
this.request.addHeader("Authorization", mockAccessToken());
CloudFoundrySecurityInterceptor.SecurityResponse response = this.interceptor.preHandle(this.request, "/a");
CloudFoundrySecurityInterceptor.SecurityResponse response = this.interceptor
.preHandle(this.request, "/a");
assertThat(response.getStatus())
.isEqualTo(Reason.MISSING_AUTHORIZATION.getStatus());
}
@ -86,7 +89,8 @@ public class CloudFoundrySecurityInterceptorTests {
this.interceptor = new CloudFoundrySecurityInterceptor(this.tokenValidator,
this.securityService, null);
this.request.addHeader("Authorization", "bearer " + mockAccessToken());
CloudFoundrySecurityInterceptor.SecurityResponse response = this.interceptor.preHandle(this.request, "/a");
CloudFoundrySecurityInterceptor.SecurityResponse response = this.interceptor
.preHandle(this.request, "/a");
assertThat(response.getStatus())
.isEqualTo(Reason.SERVICE_UNAVAILABLE.getStatus());
}
@ -97,7 +101,8 @@ public class CloudFoundrySecurityInterceptorTests {
this.interceptor = new CloudFoundrySecurityInterceptor(this.tokenValidator, null,
"my-app-id");
this.request.addHeader("Authorization", "bearer " + mockAccessToken());
CloudFoundrySecurityInterceptor.SecurityResponse response = this.interceptor.preHandle(this.request, "/a");
CloudFoundrySecurityInterceptor.SecurityResponse response = this.interceptor
.preHandle(this.request, "/a");
assertThat(response.getStatus())
.isEqualTo(Reason.SERVICE_UNAVAILABLE.getStatus());
}
@ -106,20 +111,21 @@ public class CloudFoundrySecurityInterceptorTests {
public void preHandleWhenAccessIsNotAllowedShouldReturnFalse() throws Exception {
String accessToken = mockAccessToken();
this.request.addHeader("Authorization", "bearer " + accessToken);
BDDMockito.given(this.securityService.getAccessLevel(accessToken, "my-app-id"))
given(this.securityService.getAccessLevel(accessToken, "my-app-id"))
.willReturn(AccessLevel.RESTRICTED);
CloudFoundrySecurityInterceptor.SecurityResponse response = this.interceptor.preHandle(this.request, "/a");
assertThat(response.getStatus())
.isEqualTo(Reason.ACCESS_DENIED.getStatus());
CloudFoundrySecurityInterceptor.SecurityResponse response = this.interceptor
.preHandle(this.request, "/a");
assertThat(response.getStatus()).isEqualTo(Reason.ACCESS_DENIED.getStatus());
}
@Test
public void preHandleSuccessfulWithFullAccess() throws Exception {
String accessToken = mockAccessToken();
this.request.addHeader("Authorization", "Bearer " + accessToken);
BDDMockito.given(this.securityService.getAccessLevel(accessToken, "my-app-id"))
given(this.securityService.getAccessLevel(accessToken, "my-app-id"))
.willReturn(AccessLevel.FULL);
CloudFoundrySecurityInterceptor.SecurityResponse response = this.interceptor.preHandle(this.request, "/a");
CloudFoundrySecurityInterceptor.SecurityResponse response = this.interceptor
.preHandle(this.request, "/a");
ArgumentCaptor<Token> tokenArgumentCaptor = ArgumentCaptor.forClass(Token.class);
verify(this.tokenValidator).validate(tokenArgumentCaptor.capture());
Token token = tokenArgumentCaptor.getValue();
@ -133,9 +139,10 @@ public class CloudFoundrySecurityInterceptorTests {
public void preHandleSuccessfulWithRestrictedAccess() throws Exception {
String accessToken = mockAccessToken();
this.request.addHeader("Authorization", "Bearer " + accessToken);
BDDMockito.given(this.securityService.getAccessLevel(accessToken, "my-app-id"))
given(this.securityService.getAccessLevel(accessToken, "my-app-id"))
.willReturn(AccessLevel.RESTRICTED);
CloudFoundrySecurityInterceptor.SecurityResponse response = this.interceptor.preHandle(this.request, "info");
CloudFoundrySecurityInterceptor.SecurityResponse response = this.interceptor
.preHandle(this.request, "info");
ArgumentCaptor<Token> tokenArgumentCaptor = ArgumentCaptor.forClass(Token.class);
verify(this.tokenValidator).validate(tokenArgumentCaptor.capture());
Token token = tokenArgumentCaptor.getValue();

View File

@ -137,4 +137,3 @@ public class TokenTests {
}
}

View File

@ -266,4 +266,3 @@ public class TokenValidatorTests {
}
}

View File

@ -46,8 +46,8 @@ public class HealthEndpointTests {
.withDetail("first", "1").build());
healthIndicators.put("upAgain", () -> new Health.Builder().status(Status.UP)
.withDetail("second", "2").build());
HealthEndpoint endpoint = new HealthEndpoint(createHealthIndicator(
healthIndicators));
HealthEndpoint endpoint = new HealthEndpoint(
createHealthIndicator(healthIndicators));
Health health = endpoint.health();
assertThat(health.getStatus()).isEqualTo(Status.UP);
assertThat(health.getDetails()).containsOnlyKeys("up", "upAgain");
@ -59,8 +59,8 @@ public class HealthEndpointTests {
private HealthIndicator createHealthIndicator(
Map<String, HealthIndicator> healthIndicators) {
return new HealthIndicatorFactory().createHealthIndicator(
new OrderedHealthAggregator(), healthIndicators);
return new HealthIndicatorFactory()
.createHealthIndicator(new OrderedHealthAggregator(), healthIndicators);
}
}

View File

@ -43,8 +43,8 @@ public class StatusEndpointTests {
.withDetail("first", "1").build());
healthIndicators.put("upAgain", () -> new Health.Builder().status(Status.UP)
.withDetail("second", "2").build());
StatusEndpoint endpoint = new StatusEndpoint(createHealthIndicator(
healthIndicators));
StatusEndpoint endpoint = new StatusEndpoint(
createHealthIndicator(healthIndicators));
Health health = endpoint.health();
assertThat(health.getStatus()).isEqualTo(Status.UP);
assertThat(health.getDetails()).isEmpty();
@ -52,8 +52,8 @@ public class StatusEndpointTests {
private HealthIndicator createHealthIndicator(
Map<String, HealthIndicator> healthIndicators) {
return new HealthIndicatorFactory().createHealthIndicator(
new OrderedHealthAggregator(), healthIndicators);
return new HealthIndicatorFactory()
.createHealthIndicator(new OrderedHealthAggregator(), healthIndicators);
}
}

View File

@ -65,8 +65,7 @@ public class MvcEndpointCorsIntegrationTests {
EndpointInfrastructureAutoConfiguration.class,
EndpointAutoConfiguration.class, ManagementContextAutoConfiguration.class,
ServletEndpointAutoConfiguration.class);
TestPropertyValues.of("endpoints.default.web.enabled:true")
.applyTo(this.context);
TestPropertyValues.of("endpoints.default.web.enabled:true").applyTo(this.context);
}
@Test
@ -144,8 +143,10 @@ public class MvcEndpointCorsIntegrationTests {
@Test
public void allowedMethodsCanBeConfigured() throws Exception {
TestPropertyValues.of("management.endpoints.cors.allowed-origins:foo.example.com",
"management.endpoints.cors.allowed-methods:GET,HEAD").applyTo(this.context);
TestPropertyValues
.of("management.endpoints.cors.allowed-origins:foo.example.com",
"management.endpoints.cors.allowed-methods:GET,HEAD")
.applyTo(this.context);
createMockMvc()
.perform(options("/application/beans")
.header(HttpHeaders.ORIGIN, "foo.example.com")
@ -156,16 +157,20 @@ public class MvcEndpointCorsIntegrationTests {
@Test
public void credentialsCanBeAllowed() throws Exception {
TestPropertyValues.of("management.endpoints.cors.allowed-origins:foo.example.com",
"management.endpoints.cors.allow-credentials:true").applyTo(this.context);
TestPropertyValues
.of("management.endpoints.cors.allowed-origins:foo.example.com",
"management.endpoints.cors.allow-credentials:true")
.applyTo(this.context);
performAcceptedCorsRequest().andExpect(
header().string(HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS, "true"));
}
@Test
public void credentialsCanBeDisabled() throws Exception {
TestPropertyValues.of("management.endpoints.cors.allowed-origins:foo.example.com",
"management.endpoints.cors.allow-credentials:false").applyTo(this.context);
TestPropertyValues
.of("management.endpoints.cors.allowed-origins:foo.example.com",
"management.endpoints.cors.allow-credentials:false")
.applyTo(this.context);
performAcceptedCorsRequest().andExpect(
header().doesNotExist(HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS));
}

View File

@ -69,8 +69,8 @@ public class MvcEndpointIntegrationTests {
this.context = new AnnotationConfigWebApplicationContext();
this.context.register(SecureConfiguration.class);
MockMvc mockMvc = createSecureMockMvc();
mockMvc.perform(get("/application/beans")
.accept(MediaType.APPLICATION_JSON)).andExpect(status().isUnauthorized());
mockMvc.perform(get("/application/beans").accept(MediaType.APPLICATION_JSON))
.andExpect(status().isUnauthorized());
}
@Test
@ -80,8 +80,8 @@ public class MvcEndpointIntegrationTests {
TestPropertyValues.of("management.context-path:/management")
.applyTo(this.context);
MockMvc mockMvc = createSecureMockMvc();
mockMvc.perform(get("/management/beans")
.accept(MediaType.APPLICATION_JSON)).andExpect(status().isUnauthorized());
mockMvc.perform(get("/management/beans").accept(MediaType.APPLICATION_JSON))
.andExpect(status().isUnauthorized());
}
@Test
@ -92,8 +92,7 @@ public class MvcEndpointIntegrationTests {
this.context = new AnnotationConfigWebApplicationContext();
this.context.register(SecureConfiguration.class);
TestPropertyValues.of("management.context-path:/management",
"endpoints.default.web.enabled=true")
.applyTo(this.context);
"endpoints.default.web.enabled=true").applyTo(this.context);
MockMvc mockMvc = createSecureMockMvc();
mockMvc.perform(get("/management/beans")).andExpect(status().isOk());
}
@ -137,7 +136,7 @@ public class MvcEndpointIntegrationTests {
}
@Import(DefaultConfiguration.class)
@ImportAutoConfiguration({ SecurityAutoConfiguration.class})
@ImportAutoConfiguration({ SecurityAutoConfiguration.class })
static class SecureConfiguration {
}

View File

@ -57,8 +57,8 @@ public class StatusEndpointWebIntegrationTests {
context.getBean("alphaHealthIndicator", TestHealthIndicator.class)
.setHealth(Health.down().build());
client.get().uri("/application/status").exchange().expectStatus()
.isEqualTo(HttpStatus.SERVICE_UNAVAILABLE)
.expectBody().json("{\"status\":\"DOWN\"}");
.isEqualTo(HttpStatus.SERVICE_UNAVAILABLE).expectBody()
.json("{\"status\":\"DOWN\"}");
}
@Configuration

View File

@ -78,9 +78,8 @@ import org.springframework.web.util.DefaultUriBuilderFactory.EncodingMode;
* The {@link PropertySource PropertySources} that belong to the application context's
* {@link org.springframework.core.env.Environment} are reset at the end of every test.
* This means that {@link TestPropertyValues} can be used in a test without affecting the
* {@code Environment} of other tests in the same class.
* The runner always sets the flag `endpoints.default.web.enabled` to true so that web
* endpoints are enabled.
* {@code Environment} of other tests in the same class. The runner always sets the flag
* `endpoints.default.web.enabled` to true so that web endpoints are enabled.
*
* @author Andy Wilkinson
*/
@ -266,7 +265,8 @@ public class WebEndpointsRunner extends Suite {
private ReactiveWebEndpointsRunner(Class<?> klass) throws InitializationError {
super(klass, "Reactive", (classes) -> {
ReactiveWebServerApplicationContext context = new ReactiveWebServerApplicationContext();
TestPropertyValues.of("endpoints.default.web.enabled:true").applyTo(context);
TestPropertyValues.of("endpoints.default.web.enabled:true")
.applyTo(context);
classes.add(ReactiveInfrastructureConfiguration.class);
context.register(classes.toArray(new Class<?>[classes.size()]));
context.refresh();

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2016 the original author or authors.
* Copyright 2012-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@ -62,8 +62,8 @@ public class HealthIndicatorFactoryTests {
private HealthIndicator createHealthIndicator(
Map<String, HealthIndicator> healthIndicators) {
return new HealthIndicatorFactory().createHealthIndicator(
new OrderedHealthAggregator(), healthIndicators);
return new HealthIndicatorFactory()
.createHealthIndicator(new OrderedHealthAggregator(), healthIndicators);
}
}

View File

@ -51,12 +51,14 @@ public class RedisHealthIndicatorTests {
@Test
public void indicatorExists() {
new ApplicationContextRunner().withConfiguration(AutoConfigurations.of(
RedisAutoConfiguration.class, EndpointAutoConfiguration.class,
HealthIndicatorAutoConfiguration.class)).run((context) -> {
assertThat(context).hasSingleBean(RedisConnectionFactory.class);
assertThat(context).hasSingleBean(RedisHealthIndicator.class);
});
new ApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(RedisAutoConfiguration.class,
EndpointAutoConfiguration.class,
HealthIndicatorAutoConfiguration.class))
.run((context) -> {
assertThat(context).hasSingleBean(RedisConnectionFactory.class);
assertThat(context).hasSingleBean(RedisHealthIndicator.class);
});
}
@Test
@ -74,8 +76,8 @@ public class RedisHealthIndicatorTests {
@Test
public void redisIsDown() throws Exception {
RedisConnection redisConnection = mock(RedisConnection.class);
given(redisConnection.info()).willThrow(
new RedisConnectionFailureException("Connection failed"));
given(redisConnection.info())
.willThrow(new RedisConnectionFailureException("Connection failed"));
RedisHealthIndicator healthIndicator = createHealthIndicator(redisConnection);
Health health = healthIndicator.health();
assertThat(health.getStatus()).isEqualTo(Status.DOWN);
@ -83,9 +85,9 @@ public class RedisHealthIndicatorTests {
.contains("Connection failed");
}
private RedisHealthIndicator createHealthIndicator(
RedisConnection redisConnection) {
RedisConnectionFactory redisConnectionFactory = mock(RedisConnectionFactory.class);
private RedisHealthIndicator createHealthIndicator(RedisConnection redisConnection) {
RedisConnectionFactory redisConnectionFactory = mock(
RedisConnectionFactory.class);
given(redisConnectionFactory.getConnection()).willReturn(redisConnection);
return new RedisHealthIndicator(redisConnectionFactory);
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2016 the original author or authors.
* Copyright 2012-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2016 the original author or authors.
* Copyright 2012-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@ -50,12 +50,12 @@ import org.springframework.util.ReflectionUtils;
/**
* Configuration for a Spring Security in-memory {@link AuthenticationManager}. Can be
* disabled by providing a bean of type {@link AuthenticationManager}, {@link AuthenticationProvider}
* or {@link UserDetailsService}. The value provided by this configuration will become the "global"
* authentication manager (from Spring Security), or the parent of the global instance.
* Thus it acts as a fallback when no others are provided, is used by method security if
* enabled, and as a parent authentication manager for "local" authentication managers in
* individual filter chains.
* disabled by providing a bean of type {@link AuthenticationManager},
* {@link AuthenticationProvider} or {@link UserDetailsService}. The value provided by
* this configuration will become the "global" authentication manager (from Spring
* Security), or the parent of the global instance. Thus it acts as a fallback when no
* others are provided, is used by method security if enabled, and as a parent
* authentication manager for "local" authentication managers in individual filter chains.
*
* @author Dave Syer
* @author Rob Winch
@ -63,8 +63,8 @@ import org.springframework.util.ReflectionUtils;
*/
@Configuration
@ConditionalOnBean(ObjectPostProcessor.class)
@ConditionalOnMissingBean({ AuthenticationManager.class,
AuthenticationProvider.class, UserDetailsService.class})
@ConditionalOnMissingBean({ AuthenticationManager.class, AuthenticationProvider.class,
UserDetailsService.class })
@Order(0)
public class AuthenticationManagerConfiguration {
@ -102,8 +102,8 @@ public class AuthenticationManagerConfiguration {
* {@link GlobalAuthenticationConfigurerAdapter#init(AuthenticationManagerBuilder)}
* exists that adds a {@link SecurityConfigurer} to the
* {@link AuthenticationManagerBuilder}.</li>
* <li>{@link AuthenticationManagerConfiguration}
* adds {@link SpringBootAuthenticationConfigurerAdapter} so it is after the
* <li>{@link AuthenticationManagerConfiguration} adds
* {@link SpringBootAuthenticationConfigurerAdapter} so it is after the
* {@link SecurityConfigurer} in the first step.</li>
* <li>We then can default an {@link AuthenticationProvider} if necessary. Note we can
* only invoke the
@ -169,10 +169,9 @@ public class AuthenticationManagerConfiguration {
return;
}
String password = UUID.randomUUID().toString();
logger.info(String.format("%n%nUsing default security password: %s%n",
password));
withUser("user").password(password)
.roles();
logger.info(
String.format("%n%nUsing default security password: %s%n", password));
withUser("user").password(password).roles();
setField(auth, "defaultUserDetailsService", getUserDetailsService());
super.configure(auth);
}

View File

@ -63,9 +63,11 @@ public class SecurityAutoConfiguration {
}
@Bean
public SpringBootSecurity springBootSecurity(EndpointPathResolver endpointPathResolver,
public SpringBootSecurity springBootSecurity(
EndpointPathResolver endpointPathResolver,
ObjectProvider<ErrorController> errorController) {
return new SpringBootSecurity(endpointPathResolver, errorController.getIfAvailable());
return new SpringBootSecurity(endpointPathResolver,
errorController.getIfAvailable());
}
@Bean

View File

@ -73,8 +73,7 @@ public class SecurityFilterAutoConfiguration {
return null;
}
return securityProperties.getFilterDispatcherTypes().stream()
.map((type) -> DispatcherType.valueOf(type.name()))
.collect(Collectors
.map((type) -> DispatcherType.valueOf(type.name())).collect(Collectors
.collectingAndThen(Collectors.toSet(), EnumSet::copyOf));
}

View File

@ -66,8 +66,8 @@ public class SecurityProperties implements SecurityPrerequisite {
/**
* Security filter chain dispatcher types.
*/
private Set<DispatcherType> filterDispatcherTypes = new HashSet<>(Arrays.asList(
DispatcherType.ASYNC, DispatcherType.ERROR, DispatcherType.REQUEST));
private Set<DispatcherType> filterDispatcherTypes = new HashSet<>(Arrays
.asList(DispatcherType.ASYNC, DispatcherType.ERROR, DispatcherType.REQUEST));
public Basic getBasic() {
return this.basic;

View File

@ -31,7 +31,6 @@ import org.springframework.security.web.util.matcher.RequestMatcher;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
/**
* Provides request matchers that can be used to configure security for static resources
* and the error controller path in a custom {@link WebSecurityConfigurerAdapter}.
@ -68,8 +67,8 @@ public final class SpringBootSecurity {
Assert.notEmpty(ids, "At least one endpoint id must be specified.");
List<String> pathList = Arrays.asList(ids);
if (pathList.contains(ALL_ENDPOINTS)) {
return new AntPathRequestMatcher(this.endpointPathResolver.resolvePath(
ALL_ENDPOINTS), null);
return new AntPathRequestMatcher(
this.endpointPathResolver.resolvePath(ALL_ENDPOINTS), null);
}
return getEndpointsRequestMatcher(pathList);
}
@ -140,4 +139,3 @@ public final class SpringBootSecurity {
}
}

View File

@ -29,10 +29,10 @@ import org.springframework.security.config.annotation.web.configuration.WebSecur
/**
* The default configuration for web security. It relies on Spring Security's
* content-negotiation strategy to determine what sort of authentication to use.
* If the user specifies their own {@link WebSecurityConfigurerAdapter}, this will
* back-off completely and the users should specify all the bits that they want to
* configure as part of the custom security configuration.
* content-negotiation strategy to determine what sort of authentication to use. If the
* user specifies their own {@link WebSecurityConfigurerAdapter}, this will back-off
* completely and the users should specify all the bits that they want to configure as
* part of the custom security configuration.
*
* @author Madhura Bhave
* @since 2.0.0
@ -52,6 +52,7 @@ public class SpringBootWebSecurityConfiguration {
super.configure(http);
http.csrf().disable();
}
}
}

View File

@ -39,5 +39,5 @@ import org.springframework.security.config.annotation.web.configuration.WebSecur
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
@EnableWebSecurity
public class WebSecurityEnablerConfiguration {
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2015 the original author or authors.
* Copyright 2012-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@ -86,7 +86,7 @@ public class OAuth2RestOperationsConfiguration {
@Configuration
@ConditionalOnBean(OAuth2ClientConfiguration.class)
@Conditional({OAuth2ClientIdCondition.class, NoClientCredentialsCondition.class})
@Conditional({ OAuth2ClientIdCondition.class, NoClientCredentialsCondition.class })
@Import(OAuth2ProtectedResourceDetailsConfiguration.class)
protected static class SessionScopedConfiguration {

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2016 the original author or authors.
* Copyright 2012-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@ -55,8 +55,7 @@ class SessionRepositoryFilterConfiguration {
return null;
}
return servletProperties.getFilterDispatcherTypes().stream()
.map((type) -> DispatcherType.valueOf(type.name()))
.collect(Collectors
.map((type) -> DispatcherType.valueOf(type.name())).collect(Collectors
.collectingAndThen(Collectors.toSet(), EnumSet::copyOf));
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2016 the original author or authors.
* Copyright 2012-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@ -95,8 +95,8 @@ public class FlywayAutoConfigurationTests {
@Test
public void createDataSource() throws Exception {
TestPropertyValues.of("spring.flyway.url:jdbc:hsqldb:mem:flywaytest", "spring.flyway.user:sa")
.applyTo(this.context);
TestPropertyValues.of("spring.flyway.url:jdbc:hsqldb:mem:flywaytest",
"spring.flyway.user:sa").applyTo(this.context);
registerAndRefresh(EmbeddedDataSourceConfiguration.class,
FlywayAutoConfiguration.class,
PropertyPlaceholderAutoConfiguration.class);
@ -162,7 +162,8 @@ public class FlywayAutoConfigurationTests {
@Test
public void changeLogDoesNotExist() throws Exception {
TestPropertyValues.of("spring.flyway.locations:file:no-such-dir").applyTo(this.context);
TestPropertyValues.of("spring.flyway.locations:file:no-such-dir")
.applyTo(this.context);
this.thrown.expect(BeanCreationException.class);
registerAndRefresh(EmbeddedDataSourceConfiguration.class,
FlywayAutoConfiguration.class,

View File

@ -318,7 +318,8 @@ public class DataSourceAutoConfigurationTests {
@Override
protected Class<?> loadClass(String name, boolean resolve)
throws ClassNotFoundException {
for (EmbeddedDatabaseConnection candidate : EmbeddedDatabaseConnection.values()) {
for (EmbeddedDatabaseConnection candidate : EmbeddedDatabaseConnection
.values()) {
if (name.equals(candidate.getDriverClassName())) {
throw new ClassNotFoundException();
}
@ -328,5 +329,4 @@ public class DataSourceAutoConfigurationTests {
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2016 the original author or authors.
* Copyright 2012-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2016 the original author or authors.
* Copyright 2012-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@ -160,7 +160,8 @@ public class LiquibaseAutoConfigurationTests {
@Test
public void testOverrideDefaultSchema() throws Exception {
TestPropertyValues.of("spring.liquibase.default-schema:public").applyTo(this.context);
TestPropertyValues.of("spring.liquibase.default-schema:public")
.applyTo(this.context);
this.context.register(EmbeddedDataSourceConfiguration.class,
LiquibaseAutoConfiguration.class,
PropertyPlaceholderAutoConfiguration.class);
@ -182,9 +183,8 @@ public class LiquibaseAutoConfigurationTests {
@Test
public void testOverrideDataSource() throws Exception {
TestPropertyValues
.of("spring.liquibase.url:jdbc:hsqldb:mem:liquibase", "spring.liquibase.user:sa")
.applyTo(this.context);
TestPropertyValues.of("spring.liquibase.url:jdbc:hsqldb:mem:liquibase",
"spring.liquibase.user:sa").applyTo(this.context);
this.context.register(EmbeddedDataSourceConfiguration.class,
LiquibaseAutoConfiguration.class,
PropertyPlaceholderAutoConfiguration.class);
@ -198,7 +198,8 @@ public class LiquibaseAutoConfigurationTests {
@Test(expected = BeanCreationException.class)
public void testChangeLogDoesNotExist() throws Exception {
TestPropertyValues.of("spring.liquibase.change-log:classpath:/no-such-changelog.yaml")
TestPropertyValues
.of("spring.liquibase.change-log:classpath:/no-such-changelog.yaml")
.applyTo(this.context);
this.context.register(EmbeddedDataSourceConfiguration.class,
LiquibaseAutoConfiguration.class,
@ -220,7 +221,8 @@ public class LiquibaseAutoConfigurationTests {
@Test
public void testOverrideLabels() throws Exception {
TestPropertyValues.of("spring.liquibase.labels:test, production").applyTo(this.context);
TestPropertyValues.of("spring.liquibase.labels:test, production")
.applyTo(this.context);
this.context.register(EmbeddedDataSourceConfiguration.class,
LiquibaseAutoConfiguration.class,
PropertyPlaceholderAutoConfiguration.class);
@ -232,7 +234,8 @@ public class LiquibaseAutoConfigurationTests {
@Test
@SuppressWarnings("unchecked")
public void testOverrideParameters() throws Exception {
TestPropertyValues.of("spring.liquibase.parameters.foo:bar").applyTo(this.context);
TestPropertyValues.of("spring.liquibase.parameters.foo:bar")
.applyTo(this.context);
this.context.register(EmbeddedDataSourceConfiguration.class,
LiquibaseAutoConfiguration.class,
PropertyPlaceholderAutoConfiguration.class);

View File

@ -298,8 +298,8 @@ public class SecurityAutoConfigurationTests {
this.context.setServletContext(new MockServletContext());
this.context.register(SecurityAutoConfiguration.class);
this.context.refresh();
String password = this.outputCapture.toString().split("Using default security password: ")[1]
.split("\n")[0].trim();
String password = this.outputCapture.toString()
.split("Using default security password: ")[1].split("\n")[0].trim();
AuthenticationManager manager = this.context.getBean(AuthenticationManager.class);
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(
"user", password);
@ -307,16 +307,17 @@ public class SecurityAutoConfigurationTests {
}
@Test
public void testCustomAuthenticationDoesNotCreateDefaultUser()
throws Exception {
public void testCustomAuthenticationDoesNotCreateDefaultUser() throws Exception {
this.context = new AnnotationConfigWebApplicationContext();
this.context.setServletContext(new MockServletContext());
this.context.register(AuthenticationManagerCustomizer.class,
SecurityAutoConfiguration.class);
this.context.refresh();
AuthenticationManager manager = this.context.getBean(AuthenticationManager.class);
assertThat(this.outputCapture.toString()).doesNotContain("Using default security password: ");
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("foo", "bar");
assertThat(this.outputCapture.toString())
.doesNotContain("Using default security password: ");
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(
"foo", "bar");
assertThat(manager.authenticate(token)).isNotNull();
}

View File

@ -61,13 +61,12 @@ public class SecurityFilterAutoConfigurationEarlyInitializationTests {
@Test
public void testSecurityFilterDoesNotCauseEarlyInitialization() throws Exception {
try (AnnotationConfigServletWebServerApplicationContext context = new AnnotationConfigServletWebServerApplicationContext()) {
TestPropertyValues.of("server.port:0")
.applyTo(context);
TestPropertyValues.of("server.port:0").applyTo(context);
context.register(Config.class);
context.refresh();
int port = context.getWebServer().getPort();
String password = this.outputCapture.toString().split("Using default security password: ")[1]
.split("\n")[0].trim();
String password = this.outputCapture.toString()
.split("Using default security password: ")[1].split("\n")[0].trim();
new TestRestTemplate("user", password)
.getForEntity("http://localhost:" + port, Object.class);
// If early initialization occurred a ConverterNotFoundException is thrown
@ -80,8 +79,8 @@ public class SecurityFilterAutoConfigurationEarlyInitializationTests {
ConverterBean.class })
@ImportAutoConfiguration({ WebMvcAutoConfiguration.class,
JacksonAutoConfiguration.class, HttpMessageConvertersAutoConfiguration.class,
DispatcherServletAutoConfiguration.class,
SecurityAutoConfiguration.class, SecurityFilterAutoConfiguration.class,
DispatcherServletAutoConfiguration.class, SecurityAutoConfiguration.class,
SecurityFilterAutoConfiguration.class,
PropertyPlaceholderAutoConfiguration.class })
static class Config {

View File

@ -46,15 +46,16 @@ public class SpringBootSecurityTests {
private MockHttpServletRequest request = new MockHttpServletRequest();
private static String[] STATIC_RESOURCES = new String[]{"/css/**", "/js/**",
"/images/**", "/webjars/**", "/**/favicon.ico"};
private static String[] STATIC_RESOURCES = new String[] { "/css/**", "/js/**",
"/images/**", "/webjars/**", "/**/favicon.ico" };
@Rule
public ExpectedException thrown = ExpectedException.none();
@Before
public void setUp() throws Exception {
this.bootSecurity = new SpringBootSecurity(this.endpointPathResolver, this.errorController);
this.bootSecurity = new SpringBootSecurity(this.endpointPathResolver,
this.errorController);
}
@Test
@ -65,7 +66,8 @@ public class SpringBootSecurityTests {
}
@Test
public void endpointIdsShouldReturnRequestMatcherWithEndpointPaths() throws Exception {
public void endpointIdsShouldReturnRequestMatcherWithEndpointPaths()
throws Exception {
RequestMatcher requestMatcher = this.bootSecurity.endpointIds("id-1", "id-2");
assertThat(requestMatcher).isInstanceOf(OrRequestMatcher.class);
this.request.setServletPath("/test/id-1");
@ -77,8 +79,10 @@ public class SpringBootSecurityTests {
}
@Test
public void endpointIdsShouldReturnRequestMatcherWithAllEndpointPaths() throws Exception {
RequestMatcher requestMatcher = this.bootSecurity.endpointIds(SpringBootSecurity.ALL_ENDPOINTS);
public void endpointIdsShouldReturnRequestMatcherWithAllEndpointPaths()
throws Exception {
RequestMatcher requestMatcher = this.bootSecurity
.endpointIds(SpringBootSecurity.ALL_ENDPOINTS);
this.request.setServletPath("/test/id-1");
assertThat(requestMatcher.matches(this.request)).isTrue();
this.request.setServletPath("/test/id-2");
@ -112,7 +116,8 @@ public class SpringBootSecurityTests {
}
@Test
public void staticResourcesShouldReturnRequestMatcherWithStaticResources() throws Exception {
public void staticResourcesShouldReturnRequestMatcherWithStaticResources()
throws Exception {
RequestMatcher requestMatcher = this.bootSecurity.staticResources();
assertThat(requestMatcher).isInstanceOf(OrRequestMatcher.class);
for (String resource : STATIC_RESOURCES) {
@ -122,7 +127,8 @@ public class SpringBootSecurityTests {
}
@Test
public void errorShouldReturnRequestMatcherWithErrorControllerPath() throws Exception {
public void errorShouldReturnRequestMatcherWithErrorControllerPath()
throws Exception {
RequestMatcher requestMatcher = this.bootSecurity.error();
assertThat(requestMatcher).isInstanceOf(AntPathRequestMatcher.class);
this.request.setServletPath("/test/error");
@ -152,6 +158,7 @@ public class SpringBootSecurityTests {
public String getErrorPath() {
return "/test/error";
}
}
@Endpoint(id = "id-1")
@ -167,4 +174,5 @@ public class SpringBootSecurityTests {
static class FakeEndpoint {
}
}

View File

@ -22,6 +22,7 @@ import org.junit.rules.ExpectedException;
import org.mockito.Mockito;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.boot.WebApplicationType;
import org.springframework.boot.autoconfigure.security.SecurityProperties;
import org.springframework.boot.autoconfigure.web.servlet.MockServletWebServerFactory;
import org.springframework.boot.builder.SpringApplicationBuilder;
@ -77,8 +78,7 @@ public class OAuth2RestOperationsConfigurationTests {
TestPropertyValues.of("security.oauth2.client.client-id=acme")
.applyTo(this.environment);
initializeContext(ConfigForRequestScopedConfiguration.class, false);
assertThat(this.context.containsBean("oauth2ClientContext"))
.isTrue();
assertThat(this.context.containsBean("oauth2ClientContext")).isTrue();
}
@Test
@ -93,8 +93,7 @@ public class OAuth2RestOperationsConfigurationTests {
TestPropertyValues.of("security.oauth2.client.client-id=acme")
.applyTo(this.environment);
initializeContext(ConfigForSessionScopedConfiguration.class, false);
assertThat(this.context.containsBean("oauth2ClientContext"))
.isTrue();
assertThat(this.context.containsBean("oauth2ClientContext")).isTrue();
}
@Test
@ -104,10 +103,11 @@ public class OAuth2RestOperationsConfigurationTests {
this.context.getBean(DefaultOAuth2ClientContext.class);
}
private void initializeContext(Class<?> configuration, boolean isClientCredentials) {
private void initializeContext(Class<?> configuration, boolean clientCredentials) {
this.context = new SpringApplicationBuilder(configuration)
.environment(this.environment)
.web(!isClientCredentials).run();
.environment(this.environment).web(clientCredentials
? WebApplicationType.NONE : WebApplicationType.SERVLET)
.run();
}
@Configuration
@ -123,7 +123,8 @@ public class OAuth2RestOperationsConfigurationTests {
@Configuration
@Import({ OAuth2ClientConfiguration.class, OAuth2RestOperationsConfiguration.class })
protected static class ConfigForSessionScopedConfiguration extends WebApplicationConfiguration {
protected static class ConfigForSessionScopedConfiguration
extends WebApplicationConfiguration {
@Bean
public SecurityProperties securityProperties() {
@ -133,7 +134,8 @@ public class OAuth2RestOperationsConfigurationTests {
}
@Configuration
protected static class ConfigForRequestScopedConfiguration extends WebApplicationConfiguration {
protected static class ConfigForRequestScopedConfiguration
extends WebApplicationConfiguration {
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2016 the original author or authors.
* Copyright 2012-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2016 the original author or authors.
* Copyright 2012-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2016 the original author or authors.
* Copyright 2012-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2015 the original author or authors.
* Copyright 2012-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -29,7 +29,8 @@ public class HelloWebSecurityApplication {
@Bean
public UserDetailsService userDetailsService() throws Exception {
InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
manager.createUser(User.withUsername("user").password("password").roles("USER").build());
manager.createUser(
User.withUsername("user").password("password").roles("USER").build());
return manager;
}

View File

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<!-- Your own application should inherit from spring-boot-starter-parent -->

View File

@ -4,7 +4,6 @@ import org.springframework.boot.autoconfigure.security.SpringBootSecurity;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
@Configuration
@ -18,13 +17,14 @@ public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("user").password("password").authorities("ROLE_USER").and()
.withUser("admin").password("admin").authorities("ROLE_ACTUATOR", "ROLE_USER");
auth.inMemoryAuthentication().withUser("user").password("password")
.authorities("ROLE_USER").and().withUser("admin").password("admin")
.authorities("ROLE_ACTUATOR", "ROLE_USER");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http.authorizeRequests()
.requestMatchers(this.bootSecurity.endpointIds("status", "info")).permitAll()
.requestMatchers(this.bootSecurity.endpointIds(SpringBootSecurity.ALL_ENDPOINTS)).hasRole("ACTUATOR")
@ -35,6 +35,7 @@ public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
.cors()
.and()
.httpBasic();
// @formatter:on
}
}

View File

@ -12,14 +12,10 @@ import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.web.client.LocalHostUriTemplateHandler;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus;
import org.springframework.http.RequestEntity;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit4.SpringRunner;
@ -41,7 +37,7 @@ public class CorsSampleActuatorApplicationTests {
private TestRestTemplate testRestTemplate;
@Autowired
ApplicationContext applicationContext;
private ApplicationContext applicationContext;
@Before
public void setUp() throws Exception {

View File

@ -39,7 +39,7 @@ import static org.assertj.core.api.Assertions.assertThat;
*/
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT, properties = {
"management.port=0", "management.context-path=/admin"})
"management.port=0", "management.context-path=/admin" })
@DirtiesContext
public class InsecureManagementPortAndPathSampleActuatorApplicationTests {
@ -51,7 +51,6 @@ public class InsecureManagementPortAndPathSampleActuatorApplicationTests {
@Test
public void testHome() throws Exception {
@SuppressWarnings("rawtypes")
ResponseEntity<String> entity = new TestRestTemplate("user", "password")
.getForEntity("http://localhost:" + this.port, String.class);
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
@ -77,9 +76,10 @@ public class InsecureManagementPortAndPathSampleActuatorApplicationTests {
@Test
public void testMissing() throws Exception {
ResponseEntity<String> entity = new TestRestTemplate("admin", "admin").getForEntity(
"http://localhost:" + this.managementPort + "/admin/missing",
String.class);
ResponseEntity<String> entity = new TestRestTemplate("admin", "admin")
.getForEntity(
"http://localhost:" + this.managementPort + "/admin/missing",
String.class);
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.NOT_FOUND);
assertThat(entity.getBody()).contains("\"status\":404");
}

View File

@ -44,22 +44,22 @@ public class SampleActuatorCustomSecurityApplicationTests {
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.INTERNAL_SERVER_ERROR);
@SuppressWarnings("unchecked")
Map<String, Object> body = entity.getBody();
assertThat((String)body.get("message")).contains("Expected exception in controller");
assertThat((String) body.get("message"))
.contains("Expected exception in controller");
}
@Test
public void testInsecureStaticResources() throws Exception {
@SuppressWarnings("rawtypes")
ResponseEntity<String> entity = this.restTemplate.getForEntity("/css/bootstrap.min.css", String.class);
ResponseEntity<String> entity = this.restTemplate
.getForEntity("/css/bootstrap.min.css", String.class);
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
assertThat(entity.getBody()).contains("body");
}
@Test
public void insecureActuator() throws Exception {
@SuppressWarnings("rawtypes")
ResponseEntity<String> entity = this.restTemplate.getForEntity("/application/status",
String.class);
ResponseEntity<String> entity = this.restTemplate
.getForEntity("/application/status", String.class);
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
assertThat(entity.getBody()).contains("\"status\":\"UP\"");
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2014 the original author or authors.
* Copyright 2012-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -29,7 +29,8 @@ public class SampleActuatorLog4J2Application {
@Bean
public UserDetailsService userDetailsService() throws Exception {
InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
manager.createUser(User.withUsername("user").password("password").roles("USER").build());
manager.createUser(
User.withUsername("user").password("password").roles("USER").build());
return manager;
}

View File

@ -65,17 +65,16 @@ public class SampleActuatorLog4J2ApplicationTests {
@Test
public void validateLoggersEndpoint() throws Exception {
this.mvc.perform(get("/application/loggers/org.apache.coyote.http11.Http11NioProtocol")
.header("Authorization", "Basic " + getBasicAuth()))
this.mvc.perform(
get("/application/loggers/org.apache.coyote.http11.Http11NioProtocol")
.header("Authorization", "Basic " + getBasicAuth()))
.andExpect(status().isOk())
.andExpect(content().string(equalTo("{\"configuredLevel\":\"WARN\","
+ "\"effectiveLevel\":\"WARN\"}")));
}
private String getBasicAuth() {
return new String(Base64.getEncoder()
.encode(("user:password").getBytes()));
return new String(Base64.getEncoder().encode(("user:password").getBytes()));
}
}

View File

@ -36,7 +36,8 @@ public class SampleActuatorUiApplication {
@Bean
public UserDetailsService userDetailsService() throws Exception {
InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
manager.createUser(User.withUsername("user").password("password").roles("USER").build());
manager.createUser(
User.withUsername("user").password("password").roles("USER").build());
return manager;
}

View File

@ -54,9 +54,9 @@ public class SampleActuatorUiApplicationTests {
public void testHome() throws Exception {
HttpHeaders headers = new HttpHeaders();
headers.setAccept(Arrays.asList(MediaType.TEXT_HTML));
ResponseEntity<String> entity = this.restTemplate.withBasicAuth("user", getPassword())
.exchange("/", HttpMethod.GET,
new HttpEntity<Void>(headers), String.class);
ResponseEntity<String> entity = this.restTemplate
.withBasicAuth("user", getPassword()).exchange("/", HttpMethod.GET,
new HttpEntity<Void>(headers), String.class);
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
assertThat(entity.getBody()).contains("<title>Hello");
}
@ -72,8 +72,8 @@ public class SampleActuatorUiApplicationTests {
@Test
public void testMetrics() throws Exception {
@SuppressWarnings("rawtypes")
ResponseEntity<Map> entity = this.restTemplate.getForEntity("/application/metrics",
Map.class);
ResponseEntity<Map> entity = this.restTemplate
.getForEntity("/application/metrics", Map.class);
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.UNAUTHORIZED);
}
@ -81,9 +81,9 @@ public class SampleActuatorUiApplicationTests {
public void testError() throws Exception {
HttpHeaders headers = new HttpHeaders();
headers.setAccept(Arrays.asList(MediaType.TEXT_HTML));
ResponseEntity<String> entity = this.restTemplate.withBasicAuth("user", getPassword())
.exchange("/error",
HttpMethod.GET, new HttpEntity<Void>(headers), String.class);
ResponseEntity<String> entity = this.restTemplate
.withBasicAuth("user", getPassword()).exchange("/error", HttpMethod.GET,
new HttpEntity<Void>(headers), String.class);
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.INTERNAL_SERVER_ERROR);
assertThat(entity.getBody()).contains("<html>").contains("<body>")
.contains("Please contact the operator with the above information");

View File

@ -22,7 +22,6 @@ import org.springframework.boot.actuate.health.HealthIndicator;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
@ -38,17 +37,20 @@ public class SampleActuatorApplication {
@Bean
public UserDetailsService userDetailsService() throws Exception {
InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
manager.createUser(User.withUsername("user").password("password").roles("USER").build());
manager.createUser(
User.withUsername("user").password("password").roles("USER").build());
return manager;
}
@Bean
public HealthIndicator helloHealthIndicator() {
return new HealthIndicator() {
@Override
public Health health() {
return Health.up().withDetail("hello", "world").build();
}
};
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2016 the original author or authors.
* Copyright 2012-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2016 the original author or authors.
* Copyright 2012-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

Some files were not shown because too many files have changed in this diff Show More