在没有安全性的测试项目中,执行器按预期工作。然而,在“真实”项目中却没有。该项目确实依赖于:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
应用程序的其余部分确实无法使Actuator工作。 IE转到URL时出现403错误。
另外在日志记录中设置了调试级别。这是我认为重要的线。
o.s.s.w.util.matcher.AndRequestMatcher : Trying to match using NegatedRequestMatcher [requestMatcher=Ant [pattern='/uploadtest/**']]
o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/actuator/env'; against '/uploadtest/**'
o.s.s.w.u.matcher.NegatedRequestMatcher : matches = true
o.s.s.w.util.matcher.AndRequestMatcher : All requestMatchers returned true
o.s.security.web.csrf.CsrfFilter : Invalid CSRF token found for http://localhost:8080/actuator/env
o.s.s.w.header.writers.HstsHeaderWriter : Not injecting HSTS header since it did not match the requestMatcher org.springframework.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher@3dfbb2f7
w.c.HttpSessionSecurityContextRepository : SecurityContext is empty or contents are anonymous - context will not be stored in HttpSession.
o.s.s.w.a.ExceptionTranslationFilter : Chain processed normally
s.s.w.c.SecurityContextPersistenceFilter : SecurityContextHolder now cleared, as request processing completed
然后是:
w.c.HttpSessionSecurityContextRepository : SecurityContext is empty or contents are anonymous - context will not be stored in HttpSession.
yFilter$SessionRepositoryResponseWrapper : Skip invoking on
yFilter$SessionRepositoryResponseWrapper : Skip invoking on
o.s.w.s.m.m.a.HttpEntityMethodProcessor : Written [{timestamp=Thu Aug 30 18:59:42 UTC 2018, status=403, error=Forbidden, message=Forbidden, path=/actuator/env}] as "application/json" using [org.springframework.http.converter.json.MappingJackson2HttpMessageConverter@6039e284]
yFilter$SessionRepositoryResponseWrapper : Skip invoking on
o.s.web.servlet.DispatcherServlet : Null ModelAndView returned to DispatcherServlet with name 'dispatcherServlet': assuming HandlerAdapter completed request handling
另外在web上查看并添加了我认为禁用安全性的这个类:
import org.springframework.boot.actuate.autoconfigure.security.servlet.EndpointRequest;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
@Order(101)
@Configuration
public class ActuatorSecurity extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.requestMatcher(EndpointRequest.toAnyEndpoint())
.authorizeRequests()
.anyRequest().permitAll();
}
}
所以我的问题是,在安全性开启的同时,我需要做些什么改变才能让执行器工作?
更多的日志:
o.s.security.web.FilterChainProxy : /actuator/env at position 1 of 15 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
o.s.security.web.FilterChainProxy : /actuator/env at position 2 of 15 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
w.c.HttpSessionSecurityContextRepository : No HttpSession currently exists
w.c.HttpSessionSecurityContextRepository : No SecurityContext was available from the HttpSession: null. A new one will be created.
o.s.security.web.FilterChainProxy : /actuator/env at position 3 of 15 in additional filter chain; firing Filter: 'HeaderWriterFilter'
o.s.security.web.FilterChainProxy : /actuator/env at position 4 of 15 in additional filter chain; firing Filter: 'CorsAttributeFilter'
o.s.security.web.FilterChainProxy : /actuator/env at position 5 of 15 in additional filter chain; firing Filter: 'CorsFilter'
o.s.security.web.FilterChainProxy : /actuator/env at position 6 of 15 in additional filter chain; firing Filter: 'LogoutFilter'
o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant [pattern='/logout', GET]
o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/actuator/env'; against '/logout'
o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant [pattern='/logout', POST]
o.s.s.w.u.matcher.AntPathRequestMatcher : Request 'GET /actuator/env' doesn't match 'POST /logout
o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant [pattern='/logout', PUT]
o.s.s.w.u.matcher.AntPathRequestMatcher : Request 'GET /actuator/env' doesn't match 'PUT /logout
o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant [pattern='/logout', DELETE]
o.s.s.w.u.matcher.AntPathRequestMatcher : Request 'GET /actuator/env' doesn't match 'DELETE /logout
o.s.s.web.util.matcher.OrRequestMatcher : No matches found
o.s.security.web.FilterChainProxy : /actuator/env at position 7 of 15 in additional filter chain; firing Filter: 'BasicAuthenticationFilter'
o.s.security.web.FilterChainProxy : /actuator/env at position 8 of 15 in additional filter chain; firing Filter: 'RequestCacheAwareFilter'
o.s.security.web.FilterChainProxy : /actuator/env at position 9 of 15 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter'
o.s.security.web.FilterChainProxy : /actuator/env at position 10 of 15 in additional filter chain; firing Filter: 'AnonymousAuthenticationFilter'
o.s.s.w.a.AnonymousAuthenticationFilter : Populated SecurityContextHolder with anonymous token: 'org.springframework.security.authentication.AnonymousAuthenticationToken@7bccedb2: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@957e: RemoteIpAddress: 127.0.0.1; SessionId: null; Granted Authorities: ROLE_ANONYMOUS'
o.s.security.web.FilterChainProxy : /actuator/env at position 11 of 15 in additional filter chain; firing Filter: 'SessionManagementFilter'
o.s.security.web.FilterChainProxy : /actuator/env at position 12 of 15 in additional filter chain; firing Filter: 'ExceptionTranslationFilter'
o.s.security.web.FilterChainProxy : /actuator/env at position 13 of 15 in additional filter chain; firing Filter: 'FilterSecurityInterceptor'
o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/actuator/env'; against '/'
o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/actuator/env'; against '/login'
o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/actuator/env'; against '/bower_components/**/*'
o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/actuator/env'; against '/app/**/*'
o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/actuator/env'; against '/index.html'
o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/actuator/env'; against '/home.html'
o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/actuator/env'; against '/signin.html'
o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/actuator/env'; against '/favicon.ico'
o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/actuator/env'; against '/user/**'
o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/actuator/env'; against '/test/**'
o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/actuator/env'; against '/cache/**'
o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/actuator/env'; against '/LitmusTest/**'
o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/actuator/env'; against '/uploadtest/**'
o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/actuator/env'; against '/rest/**'
o.s.s.w.a.i.FilterSecurityInterceptor : Public object - authentication not attempted
o.s.b.f.s.DefaultListableBeanFactory : Returning cached instance of singleton bean 'delegatingApplicationListener'
o.s.b.f.s.DefaultListableBeanFactory : Returning cached instance of singleton bean 'authorizationAuditListener'
o.s.security.web.FilterChainProxy : /actuator/env at position 14 of 15 in additional filter chain; firing Filter: 'CsrfFilter'
o.s.s.w.h.S.SESSION_LOGGER : A new session was created. To help you troubleshoot where the session was created we provided a StackTrace (this is not an error). You can prevent this from appearing by disabling DEBUG logging for org.springframework.session.web.http.SessionRepositoryFilter.SESSION_LOGGER
java.lang.RuntimeException: For debugging purposes only (not an error)
at org.springframework.session.web.http.SessionRepositoryFilter$SessionRepositoryRequestWrapper.getSession(SessionRepositoryFilter.java:367) [spring-session-1.2.1.RELEASE.jar:na]
big stack trace
o.s.s.w.util.matcher.AndRequestMatcher : Trying to match using NegatedRequestMatcher [requestMatcher=Ant [pattern='/']]
o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/actuator/env'; against '/'
o.s.s.w.u.matcher.NegatedRequestMatcher : matches = true
o.s.s.w.util.matcher.AndRequestMatcher : Trying to match using NegatedRequestMatcher [requestMatcher=Ant [pattern='/login']]
o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/actuator/env'; against '/login'
o.s.s.w.u.matcher.NegatedRequestMatcher : matches = true
o.s.s.w.util.matcher.AndRequestMatcher : Trying to match using NegatedRequestMatcher [requestMatcher=Ant [pattern='/bower_components/**/*']]
o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/actuator/env'; against '/bower_components/**/*'
o.s.s.w.u.matcher.NegatedRequestMatcher : matches = true
o.s.s.w.util.matcher.AndRequestMatcher : Trying to match using NegatedRequestMatcher [requestMatcher=Ant [pattern='/app/**/*']]
o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/actuator/env'; against '/app/**/*'
o.s.s.w.u.matcher.NegatedRequestMatcher : matches = true
o.s.s.w.util.matcher.AndRequestMatcher : Trying to match using NegatedRequestMatcher [requestMatcher=Ant [pattern='/index.html']]
o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/actuator/env'; against '/index.html'
o.s.s.w.u.matcher.NegatedRequestMatcher : matches = true
o.s.s.w.util.matcher.AndRequestMatcher : Trying to match using NegatedRequestMatcher [requestMatcher=Ant [pattern='/home.html']]
o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/actuator/env'; against '/home.html'
o.s.s.w.u.matcher.NegatedRequestMatcher : matches = true
o.s.s.w.util.matcher.AndRequestMatcher : Trying to match using NegatedRequestMatcher [requestMatcher=Ant [pattern='/signin.html']]
o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/actuator/env'; against '/signin.html'
o.s.s.w.u.matcher.NegatedRequestMatcher : matches = true
o.s.s.w.util.matcher.AndRequestMatcher : Trying to match using NegatedRequestMatcher [requestMatcher=Ant [pattern='/favicon.ico']]
o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/actuator/env'; against '/favicon.ico'
o.s.s.w.u.matcher.NegatedRequestMatcher : matches = true
o.s.s.w.util.matcher.AndRequestMatcher : Trying to match using NegatedRequestMatcher [requestMatcher=Ant [pattern='/user/**']]
o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/actuator/env'; against '/user/**'
o.s.s.w.u.matcher.NegatedRequestMatcher : matches = true
o.s.s.w.util.matcher.AndRequestMatcher : Trying to match using NegatedRequestMatcher [requestMatcher=Ant [pattern='/test/**']]
o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/actuator/env'; against '/test/**'
o.s.s.w.u.matcher.NegatedRequestMatcher : matches = true
o.s.s.w.util.matcher.AndRequestMatcher : Trying to match using NegatedRequestMatcher [requestMatcher=Ant [pattern='/cache/**']]
o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/actuator/env'; against '/cache/**'
o.s.s.w.u.matcher.NegatedRequestMatcher : matches = true
o.s.s.w.util.matcher.AndRequestMatcher : Trying to match using NegatedRequestMatcher [requestMatcher=Ant [pattern='/LitmusTest/**']]
o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/actuator/env'; against '/LitmusTest/**'
o.s.s.w.u.matcher.NegatedRequestMatcher : matches = true
o.s.s.w.util.matcher.AndRequestMatcher : Trying to match using NegatedRequestMatcher [requestMatcher=Ant [pattern='/uploadtest/**']]
o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/actuator/env'; against '/uploadtest/**'
o.s.s.w.u.matcher.NegatedRequestMatcher : matches = true
o.s.s.w.util.matcher.AndRequestMatcher : All requestMatchers returned true
o.s.security.web.csrf.CsrfFilter : Invalid CSRF token found for http://localhost:8080/actuator/env
o.s.s.w.header.writers.HstsHeaderWriter : Not injecting HSTS header since it did not match the requestMatcher org.springframework.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher@3dfbb2f7
w.c.HttpSessionSecurityContextRepository : SecurityContext is empty or contents are anonymous - context will not be stored in HttpSession.
o.s.s.w.a.ExceptionTranslationFilter : Chain processed normally
s.s.w.c.SecurityContextPersistenceFilter : SecurityContextHolder now cleared, as request processing completed
o.s.security.web.FilterChainProxy : /error at position 1 of 15 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
o.s.security.web.FilterChainProxy : /error at position 2 of 15 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
w.c.HttpSessionSecurityContextRepository : HttpSession returned null object for SPRING_SECURITY_CONTEXT
w.c.HttpSessionSecurityContextRepository : No SecurityContext was available from the HttpSession: org.springframework.session.web.http.SessionRepositoryFilter$SessionRepositoryRequestWrapper$HttpSessionWrapper@77f87f2. A new one will be created.
o.s.security.web.FilterChainProxy : /error at position 3 of 15 in additional filter chain; firing Filter: 'HeaderWriterFilter'
o.s.security.web.FilterChainProxy : /error at position 4 of 15 in additional filter chain; firing Filter: 'CorsAttributeFilter'
o.s.security.web.FilterChainProxy : /error at position 5 of 15 in additional filter chain; firing Filter: 'CorsFilter'
o.s.security.web.FilterChainProxy : /error at position 6 of 15 in additional filter chain; firing Filter: 'LogoutFilter'
您可以通过在HttpSecurity配置中添加这样的行来禁用给定url模式的csrf验证:
.and().csrf().ignoringAntMatchers("/actuator/**")
由于执行器端点不是状态变化,因此CSRF不是威胁。 This answer on Stackexchange explains why