0

I have a ResourceServer defined which is currently validating an AccessToken using a public key. This is working as expected.

I would like to retain the sensitivity behavior of the Actuator endpoints and use OAuth for the Sensitive endpoints.

The default behavior in Spring boot is using some form of Basic Auth to secure the Actuator endpoints. How can I switch to OAuth for the Sensitive Endpoints?

Things I have tried:

  1. management.security.enabled=false (disables all form of security to all the Actuator endpoints)
  2. security.basic.enabled=false (doesn't seem to do anything at all afaik)

How do I go about achieving the desired behavior?

Edit-1: Adding the configuration of the ResourceServer

@Configuration
@EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {

}

# OAuth2 Resource Configuration
security.oauth2.resource.filter-order=3
security.oauth2.resource.jwt.key-value=-----BEGIN PUBLIC KEY----- \
ABCD|\
-----END PUBLIC KEY-----

Edit-2: Logs with management.security.enabled=false

2018-04-04 09:38:52,428 [restartedMain  ] INFO    o.s.s.w.DefaultSecurityFilterChain.<init>(ln:43) - Creating filter chain: OrRequestMatcher [requestMatchers=[Ant [pattern='/css/**'], Ant [pattern='/js/**'], Ant [pattern='/images/**'], Ant [pattern='/webjars/**'], Ant [pattern='/**/favicon.ico'], Ant [pattern='/error']]], []
2018-04-04 09:38:52,428 [restartedMain  ] INFO    o.s.s.w.DefaultSecurityFilterChain.<init>(ln:43) - Creating filter chain: org.springframework.boot.actuate.autoconfigure.ManagementWebSecurityAutoConfiguration$LazyEndpointPathRequestMatcher@cba0b40, []
2018-04-04 09:38:52,517 [restartedMain  ] DEBUG   o.s.s.w.a.e.ExpressionBasedFilterInvocationSecurityMetadataSource.processMap(ln:74) - Adding web access control expression 'hasAnyRole('ROLE_USER','ROLE_ACTUATOR')', for org.springframework.security.web.util.matcher.AnyRequestMatcher@1
2018-04-04 09:38:52,527 [restartedMain  ] DEBUG   o.s.s.a.i.AbstractSecurityInterceptor.afterPropertiesSet(ln:180) - Validated configuration attributes
2018-04-04 09:38:52,528 [restartedMain  ] DEBUG   o.s.s.a.i.AbstractSecurityInterceptor.afterPropertiesSet(ln:180) - Validated configuration attributes
2018-04-04 09:38:52,537 [restartedMain  ] INFO    o.s.s.w.DefaultSecurityFilterChain.<init>(ln:43) - Creating filter chain: Ant [pattern='/h2-console/**'], [org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@2f0907e7, org.springframework.security.web.context.SecurityContextPersistenceFilter@7d0c8fcd, org.springframework.security.web.header.HeaderWriterFilter@1deb6ece, org.springframework.security.web.authentication.logout.LogoutFilter@54ae565a, org.springframework.security.web.authentication.www.BasicAuthenticationFilter@101e66ff, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@48870c1e, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@2c3aa8cc, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@43db62cc, org.springframework.security.web.session.SessionManagementFilter@1c417a06, org.springframework.security.web.access.ExceptionTranslationFilter@6af61e6, org.springframework.security.web.access.intercept.FilterSecurityInterceptor@e2595cc]
2018-04-04 09:38:52,559 [restartedMain  ] DEBUG   o.s.s.w.a.e.ExpressionBasedFilterInvocationSecurityMetadataSource.processMap(ln:74) - Adding web access control expression 'authenticated', for org.springframework.security.web.util.matcher.AnyRequestMatcher@1
2018-04-04 09:38:52,560 [restartedMain  ] DEBUG   o.s.s.a.i.AbstractSecurityInterceptor.afterPropertiesSet(ln:180) - Validated configuration attributes
2018-04-04 09:38:52,560 [restartedMain  ] DEBUG   o.s.s.a.i.AbstractSecurityInterceptor.afterPropertiesSet(ln:180) - Validated configuration attributes
2018-04-04 09:38:52,561 [restartedMain  ] INFO    o.s.s.w.DefaultSecurityFilterChain.<init>(ln:43) - Creating filter chain: org.springframework.security.web.util.matcher.AnyRequestMatcher@1, [org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@71c85f60, org.springframework.security.web.context.SecurityContextPersistenceFilter@3867025d, org.springframework.security.web.header.HeaderWriterFilter@1fe578f, org.springframework.security.web.authentication.logout.LogoutFilter@6bcc7bbf, org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationProcessingFilter@52f4e578, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@2a57cae0, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@5966b20a, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@10e17172, org.springframework.security.web.session.SessionManagementFilter@440ed2d3, org.springframework.security.web.access.ExceptionTranslationFilter@76cc8ddc, org.springframework.security.web.access.intercept.FilterSecurityInterceptor@72a6a42e]
2018-04-04 09:38:52,565 [restartedMain  ] DEBUG   o.s.s.w.a.e.ExpressionBasedFilterInvocationSecurityMetadataSource.processMap(ln:74) - Adding web access control expression 'hasAnyRole('ROLE_USER','ROLE_ACTUATOR')', for org.springframework.security.web.util.matcher.AnyRequestMatcher@1
2018-04-04 09:38:52,566 [restartedMain  ] DEBUG   o.s.s.a.i.AbstractSecurityInterceptor.afterPropertiesSet(ln:180) - Validated configuration attributes
2018-04-04 09:38:52,566 [restartedMain  ] DEBUG   o.s.s.a.i.AbstractSecurityInterceptor.afterPropertiesSet(ln:180) - Validated configuration attributes
2018-04-04 09:38:52,567 [restartedMain  ] INFO    o.s.s.w.DefaultSecurityFilterChain.<init>(ln:43) - Creating filter chain: OrRequestMatcher [requestMatchers=[Ant [pattern='/**']]], [org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@3b9584b5, org.springframework.security.web.context.SecurityContextPersistenceFilter@2181d916, org.springframework.security.web.header.HeaderWriterFilter@5ed5886a, org.springframework.security.web.authentication.logout.LogoutFilter@74909e09, org.springframework.security.web.authentication.www.BasicAuthenticationFilter@5b76b0e4, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@7c129fed, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@ef6dedd, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@6c8179fb, org.springframework.security.web.session.SessionManagementFilter@4d36e557, org.springframework.security.web.access.ExceptionTranslationFilter@1868a4d7, org.springframework.security.web.access.intercept.FilterSecurityInterceptor@15c448ac]


2018-04-04 09:39:53,545 [nio-8080-exec-1] DEBUG   o.s.s.w.u.m.OrRequestMatcher.matches(ln:65) - Trying to match using Ant [pattern='/metrics']
2018-04-04 09:39:53,545 [nio-8080-exec-1] DEBUG   o.s.s.w.u.m.AntPathRequestMatcher.matches(ln:157) - Checking match of request : '/metrics'; against '/metrics'
2018-04-04 09:39:53,545 [nio-8080-exec-1] DEBUG   o.s.s.w.u.m.OrRequestMatcher.matches(ln:68) - matched
2018-04-04 09:39:53,545 [nio-8080-exec-1] DEBUG   o.s.s.w.FilterChainProxy.doFilterInternal(ln:201) - /metrics has an empty filter list


2018-04-04 09:41:57,195 [nio-8080-exec-5] DEBUG   o.s.s.w.FilterChainProxy$VirtualFilterChain.doFilter(ln:325) - /customers at position 5 of 11 in additional filter chain; firing Filter: 'OAuth2AuthenticationProcessingFilter'
2018-04-04 09:41:57,196 [nio-8080-exec-5] DEBUG   o.s.s.o.p.a.BearerTokenExtractor.extractToken(ln:54) - Token not found in headers. Trying request parameters.
2018-04-04 09:41:57,196 [nio-8080-exec-5] DEBUG   o.s.s.o.p.a.BearerTokenExtractor.extractToken(ln:57) - Token not found in request parameters.  Not an OAuth2 request.
2018-04-04 09:41:57,196 [nio-8080-exec-5] DEBUG   o.s.s.o.p.a.OAuth2AuthenticationProcessingFilter.doFilter(ln:141) - No token in request, will continue chain.
2018-04-04 09:41:57,196 [nio-8080-exec-5] DEBUG   o.s.s.w.FilterChainProxy$VirtualFilterChain.doFilter(ln:325) - /customers at position 6 of 11 in additional filter chain; firing Filter: 'RequestCacheAwareFilter'
2018-04-04 09:41:57,196 [nio-8080-exec-5] DEBUG   o.s.s.w.FilterChainProxy$VirtualFilterChain.doFilter(ln:325) - /customers at position 7 of 11 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter'
2018-04-04 09:41:57,198 [nio-8080-exec-5] DEBUG   o.s.s.w.FilterChainProxy$VirtualFilterChain.doFilter(ln:325) - /customers at position 8 of 11 in additional filter chain; firing Filter: 'AnonymousAuthenticationFilter'
2018-04-04 09:41:57,198 [nio-8080-exec-5] DEBUG   o.s.s.w.a.AnonymousAuthenticationFilter.doFilter(ln:100) - Populated SecurityContextHolder with anonymous token: 'org.springframework.security.authentication.AnonymousAuthenticationToken@9055c2bc: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@b364: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: null; Granted Authorities: ROLE_ANONYMOUS'
2018-04-04 09:41:57,199 [nio-8080-exec-5] DEBUG   o.s.s.w.FilterChainProxy$VirtualFilterChain.doFilter(ln:325) - /customers at position 9 of 11 in additional filter chain; firing Filter: 'SessionManagementFilter'
2018-04-04 09:41:57,199 [nio-8080-exec-5] DEBUG   o.s.s.w.s.SessionManagementFilter.doFilter(ln:124) - Requested session ID A2BB697A35FC287599CE86AA715115CA is invalid.
2018-04-04 09:41:57,199 [nio-8080-exec-5] DEBUG   o.s.s.w.FilterChainProxy$VirtualFilterChain.doFilter(ln:325) - /customers at position 10 of 11 in additional filter chain; firing Filter: 'ExceptionTranslationFilter'
2018-04-04 09:41:57,199 [nio-8080-exec-5] DEBUG   o.s.s.w.FilterChainProxy$VirtualFilterChain.doFilter(ln:325) - /customers at position 11 of 11 in additional filter chain; firing Filter: 'FilterSecurityInterceptor'
2018-04-04 09:41:57,200 [nio-8080-exec-5] DEBUG   o.s.s.a.i.AbstractSecurityInterceptor.beforeInvocation(ln:219) - Secure object: FilterInvocation: URL: /customers; Attributes: [#oauth2.throwOnError(authenticated)]
2018-04-04 09:41:57,200 [nio-8080-exec-5] DEBUG   o.s.s.a.i.AbstractSecurityInterceptor.authenticateIfRequired(ln:348) - Previously Authenticated: org.springframework.security.authentication.AnonymousAuthenticationToken@9055c2bc: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@b364: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: null; Granted Authorities: ROLE_ANONYMOUS
2018-04-04 09:41:57,205 [nio-8080-exec-5] DEBUG   o.s.s.a.v.AffirmativeBased.decide(ln:66) - Voter: org.springframework.security.web.access.expression.WebExpressionVoter@794e8437, returned: -1
2018-04-04 09:41:57,207 [nio-8080-exec-5] DEBUG   o.s.s.w.a.ExceptionTranslationFilter.handleSpringSecurityException(ln:173) - Access is denied (user is anonymous); redirecting to authentication entry point
org.springframework.security.access.AccessDeniedException: Access is denied
srini
  • 544
  • 1
  • 11
  • 23

1 Answers1

0

The brute force way is to just explicitly secure your actuator endpoints in your WebSecurityConfigurerAdapter. Something like this should do it:

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.formLogin()
            .and()
            .httpBasic().disable()
            .anonymous().disable()
            .authorizeRequests().anyRequest().authenticated();
    }

Have a look at this tutorial. Following on from that, you should be able to secure any endpoint with an appropriate matcher in the configuration.

thomi
  • 1,603
  • 1
  • 24
  • 31
  • Thank you for the response. I had tried this approach but found that it secures any and all calls to the actuator endpoints. For example: the default behavior of having some non-secure endpoints like /info or /health is gone. Is there any way to retain the default security behavior of actuator and secure it with oauth instead of basic? – srini Apr 02 '18 at 17:17
  • There is a property: `security.oauth2.resource.filter-order`, which you can set to 3. This places the oauth2 filter in front of the actuator endpoints, so they should be secured using oauth2. See this answer: https://stackoverflow.com/questions/43526821/setting-spring-boot-actuator-with-oauth2-in-the-authorisation-server – thomi Apr 03 '18 at 04:57
  • It appears that I was mistaken in my earlier comment. When configuring the WebSecurityConfigurerAdapter, security on the Actuator is not disabled. The filter-order property merely switches the oAuth filter to have an higher order compared to the Actuator's filter. So once I pass a valid token, the Actuator's filter blocks the request with a 401. So at this time I am at least looking at a solution where I can secure all the Actuator endpoints via OAuth. There is this post where @dur has highlighted that when a ResourceServer is configured, WebSecurityConfigurerAdapter is not required. – srini Apr 04 '18 at 01:28
  • Here is the link to the other post. https://stackoverflow.com/questions/48629266/do-i-need-resource-server-with-spring-security-oauth2 – srini Apr 04 '18 at 01:28